-
Notifications
You must be signed in to change notification settings - Fork 2k
feat(cubesql): Flatten filter rules #10940
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -15,7 +15,7 @@ use crate::{ | |
| var, var_iter, | ||
| }; | ||
| use datafusion::{ | ||
| arrow::datatypes::{DataType, TimeUnit}, | ||
| arrow::datatypes::{DataType, DataType as ArrowDataType, TimeUnit}, | ||
| logical_plan::DFSchema, | ||
| scalar::ScalarValue, | ||
| }; | ||
|
|
@@ -409,6 +409,52 @@ impl RewriteRules for DateRules { | |
| "?new_granularity", | ||
| ), | ||
| ), | ||
| // ThoughtSpot's PostgreSQL quarter start calculation uses INTERVAL arithmetic | ||
| // that is incompatible with non-PostgreSQL dialects. Recognize the pattern and | ||
| // replace with DATE_TRUNC('quarter', col) which all dialects support. | ||
| rewrite( | ||
| "thoughtspot-pg-quarter-start-to-date-trunc", | ||
| alias_expr( | ||
| binary_expr( | ||
| cast_expr_explicit( | ||
| binary_expr( | ||
| binary_expr( | ||
| binary_expr( | ||
| self.fun_expr( | ||
| "DatePart", | ||
| vec![literal_string("year"), column_expr("?column")], | ||
| ), | ||
| "||", | ||
| literal_string("-"), | ||
| ), | ||
| "||", | ||
| self.fun_expr( | ||
| "DatePart", | ||
| vec![literal_string("month"), column_expr("?column")], | ||
| ), | ||
| ), | ||
| "||", | ||
| literal_string("-01"), | ||
| ), | ||
| ArrowDataType::Date32, | ||
| ), | ||
| "+", | ||
| binary_expr( | ||
| binary_expr("?mod_part", "*", "?neg_one"), | ||
| "*", | ||
| "?interval_val", | ||
| ), | ||
| ), | ||
| "?alias", | ||
| ), | ||
| alias_expr( | ||
| self.fun_expr( | ||
| "DateTrunc", | ||
| vec![literal_string("quarter"), column_expr("?column")], | ||
| ), | ||
| "?alias", | ||
| ), | ||
| ), | ||
|
Comment on lines
+415
to
+457
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is an unconditional For example, a different expression tree that happens to have the same shape ( Consider either:
This would prevent false-positive matches on structurally similar but semantically different expressions. |
||
| // AGE function seems to be a popular choice for this date arithmetic, | ||
| // but it is not supported in SQL push down by most dialects. | ||
| transforming_rewrite_with_root( | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,10 +1,10 @@ | ||
| use crate::{ | ||
| compile::rewrite::{ | ||
| aggregate, cube_scan, flatten_pushdown_replacer, projection, | ||
| aggregate, cube_scan, filter, flatten_pushdown_replacer, projection, | ||
|
Check warning on line 3 in rust/cubesql/cubesql/src/compile/rewrite/rules/flatten/top_level.rs
|
||
| rewriter::{CubeEGraph, CubeRewrite}, | ||
| rules::{flatten::FlattenRules, replacer_flat_push_down_node, replacer_push_down_node}, | ||
| transforming_chain_rewrite_with_root, FlattenPushdownReplacerInnerAlias, ListType, | ||
| LogicalPlanLanguage, ProjectionAlias, | ||
| transforming_chain_rewrite_with_root, | ||
| FlattenPushdownReplacerInnerAlias, ListType, LogicalPlanLanguage, ProjectionAlias, | ||
| }, | ||
| var, var_iter, | ||
| }; | ||
|
|
@@ -159,6 +159,90 @@ | |
| ), | ||
| )]); | ||
|
|
||
| rules.extend(vec![transforming_chain_rewrite_with_root( | ||
| "flatten-filter-pushdown", | ||
| aggregate( | ||
| "?filter_node", | ||
| "?outer_group_expr", | ||
| "?outer_aggregate_expr", | ||
| "AggregateSplit:false", | ||
| ), | ||
| vec![ | ||
| ("?filter_node", filter("?filter_expr", "?inner_projection")), | ||
| ( | ||
| "?inner_projection", | ||
| projection( | ||
| "?inner_projection_expr", | ||
| "?cube_scan", | ||
| "?inner_projection_alias", | ||
| "ProjectionSplit:false", | ||
| ), | ||
| ), | ||
| ( | ||
| "?cube_scan", | ||
| cube_scan( | ||
| "?alias_to_cube", | ||
| "?members", | ||
| "?filters", | ||
| "?orders", | ||
| "?limit", | ||
| "?offset", | ||
| "CubeScanSplit:false", | ||
| "?can_pushdown_join", | ||
| "CubeScanWrapped:false", | ||
| "?ungrouped", | ||
| "?join_hints", | ||
| ), | ||
| ), | ||
| ], | ||
| aggregate( | ||
| filter( | ||
| flatten_pushdown_replacer( | ||
| "?filter_expr", | ||
| "?inner_projection_expr", | ||
| "?inner_alias", | ||
| "FlattenPushdownReplacerTopLevel:false", | ||
| ), | ||
| cube_scan( | ||
| "?alias_to_cube", | ||
| "?members", | ||
| "?filters", | ||
| "?orders", | ||
| "?limit", | ||
| "?offset", | ||
| "CubeScanSplit:false", | ||
| "?can_pushdown_join", | ||
| "CubeScanWrapped:false", | ||
| "?ungrouped", | ||
| "?join_hints", | ||
| ), | ||
| ), | ||
| flatten_pushdown_replacer( | ||
| "?outer_group_expr", | ||
| "?inner_projection_expr", | ||
| "?inner_alias", | ||
| "FlattenPushdownReplacerTopLevel:false", | ||
| ), | ||
| flatten_pushdown_replacer( | ||
| "?outer_aggregate_expr", | ||
| "?inner_projection_expr", | ||
| "?inner_alias", | ||
| "FlattenPushdownReplacerTopLevel:false", | ||
| ), | ||
| "AggregateSplit:false", | ||
| ), | ||
| self.flatten_aggregate( | ||
| "?inner_projection", | ||
| "?cube_scan", | ||
| "?members", | ||
| "?inner_projection_expr", | ||
| "?outer_group_expr", | ||
| "?outer_aggregate_expr", | ||
| "?inner_projection_alias", | ||
| "?inner_alias", | ||
| ), | ||
| )]); | ||
|
|
||
| if self.config_obj.push_down_pull_up_split() { | ||
| Self::flat_list_pushdown_rules( | ||
| "flatten-projection-expr", | ||
|
|
@@ -175,11 +259,20 @@ | |
| ListType::AggregateGroupExpr, | ||
| rules, | ||
| ); | ||
| Self::flat_list_pushdown_rules( | ||
| "flatten-scalar-fun-args", | ||
| ListType::ScalarFunctionExprArgs, | ||
| rules, | ||
| ); | ||
| } else { | ||
| Self::list_pushdown_rules("flatten-projection-expr", "ProjectionExpr", rules); | ||
| Self::list_pushdown_rules("flatten-aggregate-expr", "AggregateAggrExpr", rules); | ||
| Self::list_pushdown_rules("flatten-group-expr", "AggregateGroupExpr", rules); | ||
| Self::list_pushdown_rules("flatten-scalar-fun-args", "ScalarFunctionExprArgs", rules); | ||
| } | ||
| Self::list_pushdown_rules("flatten-udf-fun-args", "ScalarUDFExprArgs", rules); | ||
| Self::list_pushdown_rules("flatten-agg-fun-args", "AggregateFunctionExprArgs", rules); | ||
| Self::list_pushdown_rules("flatten-udaf-fun-args", "AggregateUDFExprArgs", rules); | ||
|
Comment on lines
+273
to
+275
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These three new If/when these list types get added to the |
||
| } | ||
|
|
||
| pub fn flatten_projection( | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit:
DataTypeis imported twice — once asDataTypeand once asDataType as ArrowDataType. Since they're the same type, you can just useDataTypedirectly on line 445 instead of introducing the alias.(And use
DataType::Date32on line 445 instead ofArrowDataType::Date32.)