@@ -9,7 +9,7 @@ use parking_lot::Mutex;
9
9
use re_sorbet:: { BatchType , SorbetBatch } ;
10
10
use re_viewer_context:: AsyncRuntimeHandle ;
11
11
12
- use crate :: table_blueprint:: TableBlueprint ;
12
+ use crate :: table_blueprint:: { PartitionLinksSpec , SortBy , TableBlueprint } ;
13
13
use crate :: RequestedObject ;
14
14
15
15
/// Make sure we escape column names correctly for datafusion.
@@ -24,25 +24,50 @@ fn col(name: &str) -> datafusion::logical_expr::Expr {
24
24
datafusion_col ( format ! ( "{name:?}" ) )
25
25
}
26
26
27
+ /// The subset of [`TableBlueprint`] that is actually handled by datafusion.
28
+ ///
29
+ /// In general, there are aspects of a table blueprint that are handled by the UI in an immediate
30
+ /// mode fashion (e.g. is a column visible?), and other aspects that are handled by datafusion (e.g.
31
+ /// sorting). This struct is for the latter.
32
+ #[ derive( Debug , Clone , PartialEq , Eq , Default ) ]
33
+ struct DataFusionQueryData {
34
+ pub sort_by : Option < SortBy > ,
35
+ pub partition_links : Option < PartitionLinksSpec > ,
36
+ }
37
+
38
+ impl From < & TableBlueprint > for DataFusionQueryData {
39
+ fn from ( value : & TableBlueprint ) -> Self {
40
+ let TableBlueprint {
41
+ sort_by,
42
+ partition_links,
43
+ } = value;
44
+
45
+ Self {
46
+ sort_by : sort_by. clone ( ) ,
47
+ partition_links : partition_links. clone ( ) ,
48
+ }
49
+ }
50
+ }
51
+
27
52
/// A table blueprint along with the context required to execute the corresponding datafusion query.
28
53
#[ derive( Clone ) ]
29
54
struct DataFusionQuery {
30
55
session_ctx : Arc < SessionContext > ,
31
56
table_ref : TableReference ,
32
57
33
- blueprint : TableBlueprint ,
58
+ query_data : DataFusionQueryData ,
34
59
}
35
60
36
61
impl DataFusionQuery {
37
62
fn new (
38
63
session_ctx : Arc < SessionContext > ,
39
64
table_ref : TableReference ,
40
- blueprint : TableBlueprint ,
65
+ query_data : DataFusionQueryData ,
41
66
) -> Self {
42
67
Self {
43
68
session_ctx,
44
69
table_ref,
45
- blueprint ,
70
+ query_data ,
46
71
}
47
72
}
48
73
@@ -53,10 +78,10 @@ impl DataFusionQuery {
53
78
async fn execute ( self ) -> Result < Vec < SorbetBatch > , DataFusionError > {
54
79
let mut dataframe = self . session_ctx . table ( self . table_ref ) . await ?;
55
80
56
- let TableBlueprint {
81
+ let DataFusionQueryData {
57
82
sort_by,
58
83
partition_links,
59
- } = & self . blueprint ;
84
+ } = & self . query_data ;
60
85
61
86
// Important: the needs to happen first, in case we sort/filter/etc. based on that
62
87
// particular column.
@@ -103,12 +128,12 @@ impl PartialEq for DataFusionQuery {
103
128
let Self {
104
129
session_ctx,
105
130
table_ref,
106
- blueprint ,
131
+ query_data ,
107
132
} = self ;
108
133
109
134
Arc :: ptr_eq ( session_ctx, & other. session_ctx )
110
135
&& table_ref == & other. table_ref
111
- && blueprint == & other. blueprint
136
+ && query_data == & other. query_data
112
137
}
113
138
}
114
139
@@ -119,6 +144,9 @@ type RequestedSorbetBatches = RequestedObject<Result<Vec<SorbetBatch>, DataFusio
119
144
pub struct DataFusionAdapter {
120
145
id : egui:: Id ,
121
146
147
+ /// The current table blueprint
148
+ blueprint : TableBlueprint ,
149
+
122
150
/// The query used to produce the dataframe.
123
151
query : DataFusionQuery ,
124
152
@@ -149,10 +177,12 @@ impl DataFusionAdapter {
149
177
let adapter = ui. data ( |data| data. get_temp :: < Self > ( id) ) ;
150
178
151
179
let adapter = adapter. unwrap_or_else ( || {
152
- let query = DataFusionQuery :: new ( Arc :: clone ( session_ctx) , table_ref, initial_blueprint) ;
180
+ let initial_query = DataFusionQueryData :: from ( & initial_blueprint) ;
181
+ let query = DataFusionQuery :: new ( Arc :: clone ( session_ctx) , table_ref, initial_query) ;
153
182
154
183
let table_state = Self {
155
184
id,
185
+ blueprint : initial_blueprint,
156
186
requested_sorbet_batches : Arc :: new ( Mutex :: new ( RequestedObject :: new_with_repaint (
157
187
runtime,
158
188
ui. ctx ( ) . clone ( ) ,
@@ -175,7 +205,7 @@ impl DataFusionAdapter {
175
205
}
176
206
177
207
pub fn blueprint ( & self ) -> & TableBlueprint {
178
- & self . query . blueprint
208
+ & self . blueprint
179
209
}
180
210
181
211
/// Update the query and save the state to egui's memory.
@@ -188,8 +218,12 @@ impl DataFusionAdapter {
188
218
ui : & egui:: Ui ,
189
219
new_blueprint : TableBlueprint ,
190
220
) {
191
- if self . query . blueprint != new_blueprint {
192
- self . query . blueprint = new_blueprint;
221
+ self . blueprint = new_blueprint;
222
+
223
+ // retrigger a new datafusion query if required.
224
+ let new_query_data = DataFusionQueryData :: from ( & self . blueprint ) ;
225
+ if self . query . query_data != new_query_data {
226
+ self . query . query_data = new_query_data;
193
227
194
228
let mut dataframe = self . requested_sorbet_batches . lock ( ) ;
195
229
0 commit comments