Skip to content

Commit eb5d8e9

Browse files
committed
feat(cubesql): Allow to pullup over WrappedSelect(from=CubeScan(ungrouped=true)) with enabled push to Cube
This is necessary to build proper representations for flattening
1 parent 99ec7af commit eb5d8e9

File tree

1 file changed

+136
-0
lines changed

1 file changed

+136
-0
lines changed

rust/cubesql/cubesql/src/compile/rewrite/rules/wrapper/wrapper_pull_up.rs

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,128 @@ impl WrapperRules {
131131
"?ungrouped_scan_out",
132132
),
133133
),
134+
// This rule would introduce new representations:
135+
// replacers from node on top of this node would be able to run with enabled push to Cube.
136+
// However, those representation are not valid on their own, they are necessary
137+
// for flattening to work.
138+
// So, they will be disallowed to pullup by nontrivial pullup rules.
139+
// Also note that trivial pullup rules are allowed to pullup without additional checks,
140+
// because it checks that `from` is not WrappedSelect, so push=true in input can be valid
141+
// There's no equivalent for non-trivial pullup, because it has WrappedSelect in `from`,
142+
// so there's no way to use push to Cube even after flattening
143+
transforming_rewrite(
144+
"wrapper-pull-up-to-cube-scan-non-wrapped-select-with-push",
145+
cube_scan_wrapper(
146+
wrapped_select(
147+
"?select_type",
148+
wrapper_pullup_replacer(
149+
"?projection_expr",
150+
"?alias_to_cube",
151+
"?push_to_cube",
152+
"?ungrouped_scan",
153+
"?in_projection",
154+
"?cube_members",
155+
),
156+
wrapper_pullup_replacer(
157+
"?subqueries",
158+
"?alias_to_cube",
159+
"?push_to_cube",
160+
"?ungrouped_scan",
161+
"?in_projection",
162+
"?cube_members",
163+
),
164+
wrapper_pullup_replacer(
165+
"?group_expr",
166+
"?alias_to_cube",
167+
"?push_to_cube",
168+
"?ungrouped_scan",
169+
"?in_projection",
170+
"?cube_members",
171+
),
172+
wrapper_pullup_replacer(
173+
"?aggr_expr",
174+
"?alias_to_cube",
175+
"?push_to_cube",
176+
"?ungrouped_scan",
177+
"?in_projection",
178+
"?cube_members",
179+
),
180+
wrapper_pullup_replacer(
181+
"?window_expr",
182+
"?alias_to_cube",
183+
"?push_to_cube",
184+
"?ungrouped_scan",
185+
"?in_projection",
186+
"?cube_members",
187+
),
188+
wrapper_pullup_replacer(
189+
"?cube_scan_input",
190+
"?alias_to_cube",
191+
"?push_to_cube",
192+
"?ungrouped_scan",
193+
"?in_projection",
194+
"?cube_members",
195+
),
196+
wrapped_select_joins_empty_tail(),
197+
wrapper_pullup_replacer(
198+
"?filter_expr",
199+
"?alias_to_cube",
200+
"?push_to_cube",
201+
"?ungrouped_scan",
202+
"?in_projection",
203+
"?cube_members",
204+
),
205+
wrapped_select_having_expr_empty_tail(),
206+
"WrappedSelectLimit:None",
207+
"WrappedSelectOffset:None",
208+
wrapper_pullup_replacer(
209+
"?order_expr",
210+
"?alias_to_cube",
211+
"?push_to_cube",
212+
"?ungrouped_scan",
213+
"?in_projection",
214+
"?cube_members",
215+
),
216+
"?select_alias",
217+
"?select_distinct",
218+
"WrappedSelectPushToCube:true",
219+
"WrappedSelectUngroupedScan:true",
220+
),
221+
"CubeScanWrapperFinalized:false",
222+
),
223+
cube_scan_wrapper(
224+
wrapper_pullup_replacer(
225+
wrapped_select(
226+
"?select_type",
227+
"?projection_expr",
228+
"?subqueries",
229+
"?group_expr",
230+
"?aggr_expr",
231+
"?window_expr",
232+
"?cube_scan_input",
233+
wrapped_select_joins_empty_tail(),
234+
"?filter_expr",
235+
wrapped_select_having_expr_empty_tail(),
236+
"WrappedSelectLimit:None",
237+
"WrappedSelectOffset:None",
238+
"?order_expr",
239+
"?select_alias",
240+
"?select_distinct",
241+
"WrappedSelectPushToCube:true",
242+
"WrappedSelectUngroupedScan:true",
243+
),
244+
"?alias_to_cube",
245+
// This would allow next LP node on top of this to use push even when from=WrappedSelect(from=CubeScan)
246+
// Wrapper like that would be incorrect, so they will be disallowed by pullup rules for WrappedSelect(from=WrappedSelect) case
247+
"WrapperPullupReplacerPushToCube:true",
248+
"WrapperPullupReplacerUngroupedScan:true",
249+
"?in_projection",
250+
"?cube_members",
251+
),
252+
"CubeScanWrapperFinalized:false",
253+
),
254+
self.transform_pull_up_wrapper_select_for_push("?cube_scan_input"),
255+
),
134256
transforming_rewrite(
135257
"wrapper-pull-up-to-cube-scan-non-trivial-wrapped-select",
136258
cube_scan_wrapper(
@@ -324,6 +446,20 @@ impl WrapperRules {
324446
}
325447
}
326448

449+
fn transform_pull_up_wrapper_select_for_push(
450+
&self,
451+
cube_scan_input_var: &'static str,
452+
) -> impl Fn(&mut CubeEGraph, &mut Subst) -> bool {
453+
let cube_scan_input_var = var!(cube_scan_input_var);
454+
move |egraph, subst| {
455+
for _ in var_list_iter!(egraph[subst[cube_scan_input_var]], WrappedSelect).cloned() {
456+
return false;
457+
}
458+
459+
true
460+
}
461+
}
462+
327463
fn transform_pull_up_non_trivial_wrapper_select(
328464
&self,
329465
select_type_var: &'static str,

0 commit comments

Comments
 (0)