Skip to content

Commit 50bdbe7

Browse files
authored
feat(cubesql): Add separate ungrouped_scan flag to wrapper replacer context (#9120)
It is used to track whether `WrappedSelect` actually wraps ungrouped scan as opposed to old flag, which is used as push to Cube enabler. Changes in cost are necessary because now ungrouped scans are tracked, we are getting proper values in `wrapped_select_ungrouped_scan` cost component, it would count the `WrappedSelect(ungrouped_scan=true)` nodes in extracted plan. And with old cost it would turns any ungrouped scan under wrapper more expensive than plan with same amount of wrappers (usually it's just 1 anyway), but with more nodes outside wrapper. Consider consuming projection: `Projection(WrappedSelect(ungrouped_scan=true))` vs `WrappedSelect(from=WrappedSelect(ungrouped_scan=true), ungrouped_scan=true)`. Plan with `Projection` would have `ast_size_outside_wrapper=1 wrapped_select_ungrouped_scan=1`, plan with `WrappedSelect` - `ast_size_outside_wrapper=0 wrapped_select_ungrouped_scan=2`, and second one is preferrable. Also couple of related fixes: * Mark distinct WrappedSelect as grouped * Depend on a ungrouped flag for grouped join part: Wrapper can be ungrouped=true, push_to_cube=false, and this is unexpected in ungrouped-grouped join.
1 parent bb86016 commit 50bdbe7

24 files changed

+268
-59
lines changed

rust/cubesql/cubesql/src/compile/rewrite/cost.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,8 +255,8 @@ pub struct CubePlanCost {
255255
non_pushed_down_limit_sort: i64,
256256
joins: usize,
257257
wrapper_nodes: i64,
258-
wrapped_select_ungrouped_scan: usize,
259258
ast_size_outside_wrapper: usize,
259+
wrapped_select_ungrouped_scan: usize,
260260
filters: i64,
261261
structure_points: i64,
262262
filter_members: i64,

rust/cubesql/cubesql/src/compile/rewrite/mod.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,13 @@ crate::plan_to_language! {
469469
// Known qualifiers of grouped subqueries
470470
// Used to allow to rewrite columns from them even with push to Cube enabled
471471
grouped_subqueries: Vec<String>,
472+
// When `member` is logical plan this means it is actually ungrouped, even when push_to_cube is disabled.
473+
// When `member` is expression it just acts as a pull-through from pushdown.
474+
// It will be filled by every wrapper replacer producer rule, essentially same way as
475+
// ungrouped_scan flag in wrapped_select is filled:
476+
// fixed false for aggregation, copy inner value for projection.
477+
// This flag should make roundtrip from top to bottom and back.
478+
ungrouped_scan: bool,
472479
},
473480
WrapperPushdownReplacer {
474481
member: Arc<LogicalPlan>,
@@ -1974,9 +1981,10 @@ fn wrapper_replacer_context(
19741981
in_projection: impl Display,
19751982
cube_members: impl Display,
19761983
grouped_subqueries: impl Display,
1984+
ungrouped_scan: impl Display,
19771985
) -> String {
19781986
format!(
1979-
"(WrapperReplacerContext {alias_to_cube} {push_to_cube} {in_projection} {cube_members} {grouped_subqueries})",
1987+
"(WrapperReplacerContext {alias_to_cube} {push_to_cube} {in_projection} {cube_members} {grouped_subqueries} {ungrouped_scan})",
19801988
)
19811989
}
19821990

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

Lines changed: 44 additions & 0 deletions
Large diffs are not rendered by default.

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ impl WrapperRules {
3939
"?in_projection",
4040
"?cube_members",
4141
"?grouped_subqueries",
42+
"?ungrouped_scan",
4243
),
4344
)],
4445
"?distinct",
@@ -51,6 +52,7 @@ impl WrapperRules {
5152
"?in_projection",
5253
"?cube_members",
5354
"?grouped_subqueries",
55+
"?ungrouped_scan",
5456
),
5557
),
5658
self.transform_agg_fun_expr("?fun", "?distinct", "?alias_to_cube"),

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ impl WrapperRules {
3333
"?in_projection",
3434
"?cube_members",
3535
"?grouped_subqueries",
36+
"?ungrouped_scan",
3637
),
3738
),
3839
"?op",
@@ -44,6 +45,7 @@ impl WrapperRules {
4445
"?in_projection",
4546
"?cube_members",
4647
"?grouped_subqueries",
48+
"?ungrouped_scan",
4749
),
4850
),
4951
),
@@ -55,6 +57,7 @@ impl WrapperRules {
5557
"?in_projection",
5658
"?cube_members",
5759
"?grouped_subqueries",
60+
"?ungrouped_scan",
5861
),
5962
),
6063
self.transform_binary_expr("?op", "?alias_to_cube"),

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ impl WrapperRules {
3333
"?in_projection",
3434
"?cube_members",
3535
"?grouped_subqueries",
36+
"?ungrouped_scan",
3637
),
3738
),
3839
wrapper_pullup_replacer(
@@ -43,6 +44,7 @@ impl WrapperRules {
4344
"?in_projection",
4445
"?cube_members",
4546
"?grouped_subqueries",
47+
"?ungrouped_scan",
4648
),
4749
),
4850
wrapper_pullup_replacer(
@@ -53,6 +55,7 @@ impl WrapperRules {
5355
"?in_projection",
5456
"?cube_members",
5557
"?grouped_subqueries",
58+
"?ungrouped_scan",
5659
),
5760
),
5861
),
@@ -64,6 +67,7 @@ impl WrapperRules {
6467
"?in_projection",
6568
"?cube_members",
6669
"?grouped_subqueries",
70+
"?ungrouped_scan",
6771
),
6872
),
6973
self.transform_case_expr("?alias_to_cube"),

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ impl WrapperRules {
2525
"?in_projection",
2626
"?cube_members",
2727
"?grouped_subqueries",
28+
"?ungrouped_scan",
2829
),
2930
),
3031
wrapper_pullup_replacer(
@@ -35,6 +36,7 @@ impl WrapperRules {
3536
"?in_projection",
3637
"?cube_members",
3738
"?grouped_subqueries",
39+
"?ungrouped_scan",
3840
),
3941
),
4042
),
@@ -50,6 +52,7 @@ impl WrapperRules {
5052
"WrapperReplacerContextInProjection:true",
5153
"?cube_members",
5254
"?grouped_subqueries",
55+
"?ungrouped_scan",
5356
),
5457
),
5558
wrapper_pullup_replacer(
@@ -60,6 +63,7 @@ impl WrapperRules {
6063
"WrapperReplacerContextInProjection:true",
6164
"?cube_members",
6265
"?grouped_subqueries",
66+
"?ungrouped_scan",
6367
),
6468
),
6569
self.pushdown_simple_measure("?name", "?cube_members"),
@@ -75,6 +79,7 @@ impl WrapperRules {
7579
"?in_projection",
7680
"?cube_members",
7781
"?grouped_subqueries",
82+
"?ungrouped_scan",
7883
),
7984
),
8085
wrapper_pullup_replacer(
@@ -85,6 +90,7 @@ impl WrapperRules {
8590
"?in_projection",
8691
"?cube_members",
8792
"?grouped_subqueries",
93+
"?ungrouped_scan",
8894
),
8995
),
9096
self.pushdown_dimension(

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

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ use crate::{
66
transforming_rewrite, wrapper_pullup_replacer, wrapper_replacer_context,
77
CubeScanAliasToCube, CubeScanLimit, CubeScanOffset, CubeScanUngrouped, LogicalPlanLanguage,
88
WrapperReplacerContextAliasToCube, WrapperReplacerContextGroupedSubqueries,
9-
WrapperReplacerContextPushToCube,
9+
WrapperReplacerContextPushToCube, WrapperReplacerContextUngroupedScan,
1010
},
11-
var, var_iter,
11+
copy_flag, var, var_iter,
1212
};
1313
use egg::Subst;
1414

@@ -49,6 +49,7 @@ impl WrapperRules {
4949
"WrapperReplacerContextInProjection:false",
5050
"?members",
5151
"?grouped_subqueries_out",
52+
"?ungrouped_scan_out",
5253
),
5354
),
5455
"CubeScanWrapperFinalized:false",
@@ -62,6 +63,7 @@ impl WrapperRules {
6263
"?alias_to_cube_out",
6364
"?push_to_cube_out",
6465
"?grouped_subqueries_out",
66+
"?ungrouped_scan_out",
6567
),
6668
),
6769
rewrite(
@@ -85,6 +87,7 @@ impl WrapperRules {
8587
alias_to_cube_var_out: &'static str,
8688
push_to_cube_out_var: &'static str,
8789
grouped_subqueries_out_var: &'static str,
90+
ungrouped_scan_out_var: &'static str,
8891
) -> impl Fn(&mut CubeEGraph, &mut Subst) -> bool {
8992
let members_var = var!(members_var);
9093
let alias_to_cube_var = var!(alias_to_cube_var);
@@ -94,6 +97,7 @@ impl WrapperRules {
9497
let alias_to_cube_var_out = var!(alias_to_cube_var_out);
9598
let push_to_cube_out_var = var!(push_to_cube_out_var);
9699
let grouped_subqueries_out_var = var!(grouped_subqueries_out_var);
100+
let ungrouped_scan_out_var = var!(ungrouped_scan_out_var);
97101
move |egraph, subst| {
98102
let mut has_no_limit_or_offset = true;
99103
for limit in var_iter!(egraph[subst[limit_var]], CubeScanLimit).cloned() {
@@ -103,6 +107,17 @@ impl WrapperRules {
103107
has_no_limit_or_offset &= offset.is_none();
104108
}
105109

110+
if !copy_flag!(
111+
egraph,
112+
subst,
113+
ungrouped_cube_var,
114+
CubeScanUngrouped,
115+
ungrouped_scan_out_var,
116+
WrapperReplacerContextUngroupedScan
117+
) {
118+
return false;
119+
}
120+
106121
if let Some(_) = egraph[subst[members_var]].data.member_name_to_expr {
107122
for alias_to_cube in
108123
var_iter!(egraph[subst[alias_to_cube_var]], CubeScanAliasToCube).cloned()

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ impl WrapperRules {
5151
"?select_alias",
5252
"WrappedSelectDistinct:true",
5353
"WrappedSelectPushToCube:false",
54-
"?select_ungrouped_scan",
54+
"WrappedSelectUngroupedScan:false",
5555
),
5656
"?context",
5757
),

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ impl WrapperRules {
2525
"?in_projection",
2626
"?cube_members",
2727
"?grouped_subqueries",
28+
"?ungrouped_scan",
2829
),
2930
),
3031
wrapper_pullup_replacer(
@@ -35,6 +36,7 @@ impl WrapperRules {
3536
"?in_projection",
3637
"?cube_members",
3738
"?grouped_subqueries",
39+
"?ungrouped_scan",
3840
),
3941
),
4042
],
@@ -50,6 +52,7 @@ impl WrapperRules {
5052
"?in_projection",
5153
"?cube_members",
5254
"?grouped_subqueries",
55+
"?ungrouped_scan",
5356
),
5457
),
5558
self.transform_date_part_expr("?alias_to_cube"),

0 commit comments

Comments
 (0)