Skip to content

Commit b4b0f05

Browse files
authored
feat(cubesql): Always Prefer SQL push down over aggregation in Datafusion (#7751)
* feat(cubesql): Always Prefer SQL push down over aggregation in Datafusion * Bring back ScalarValue::Int32(_) as it was already removed * Bring back ScalarValue::Int32(_) as it was already removed
1 parent 73b5c0d commit b4b0f05

File tree

2 files changed

+74
-6
lines changed

2 files changed

+74
-6
lines changed

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

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4294,6 +4294,46 @@ limit
42944294
);
42954295
}
42964296

4297+
#[tokio::test]
4298+
async fn powerbi_date_range_min_max() {
4299+
if !Rewriter::sql_push_down_enabled() {
4300+
return;
4301+
}
4302+
init_logger();
4303+
4304+
let query_plan = convert_select_to_query_plan(
4305+
r#"select
4306+
max("rows"."order_date") as "a0",
4307+
min("rows"."order_date") as "a1"
4308+
from
4309+
(
4310+
select
4311+
"order_date"
4312+
from
4313+
"public"."KibanaSampleDataEcommerce" "$Table"
4314+
) "rows" "#
4315+
.to_string(),
4316+
DatabaseProtocol::PostgreSQL,
4317+
)
4318+
.await;
4319+
4320+
let logical_plan = query_plan.as_logical_plan();
4321+
assert_eq!(
4322+
logical_plan.find_cube_scan().request,
4323+
V1LoadRequestQuery {
4324+
measures: Some(vec![]),
4325+
dimensions: Some(vec![]),
4326+
segments: Some(vec![]),
4327+
time_dimensions: None,
4328+
order: None,
4329+
limit: None,
4330+
offset: None,
4331+
filters: None,
4332+
ungrouped: Some(true),
4333+
}
4334+
);
4335+
}
4336+
42974337
#[tokio::test]
42984338
async fn powerbi_inner_decimal_cast() {
42994339
init_logger();

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

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
use crate::{
22
compile::{
33
rewrite::{
4-
rules::utils::granularity_str_to_int_order, CubeScanWrapped, DimensionName,
5-
LogicalPlanLanguage, MemberErrorPriority, ScalarUDFExprFun, TimeDimensionGranularity,
4+
rules::utils::granularity_str_to_int_order, CubeScanUngrouped, CubeScanWrapped,
5+
DimensionName, LogicalPlanLanguage, MemberErrorPriority, ScalarUDFExprFun,
6+
TimeDimensionGranularity,
67
},
78
MetaContext,
89
},
@@ -44,6 +45,7 @@ pub struct CubePlanCost {
4445
member_errors: i64,
4546
// TODO if pre-aggregation can be used for window functions, then it'd be suboptimal
4647
non_pushed_down_window: i64,
48+
ungrouped_aggregates: usize,
4749
wrapper_nodes: i64,
4850
ast_size_outside_wrapper: usize,
4951
cube_members: i64,
@@ -54,6 +56,7 @@ pub struct CubePlanCost {
5456
ast_size_without_alias: usize,
5557
ast_size: usize,
5658
ast_size_inside_wrapper: usize,
59+
ungrouped_nodes: usize,
5760
}
5861

5962
#[derive(Debug, Clone, Eq, PartialEq)]
@@ -101,9 +104,9 @@ impl CubePlanCostAndState {
101104
}
102105
}
103106

104-
pub fn finalize(&self) -> Self {
107+
pub fn finalize(&self, enode: &LogicalPlanLanguage) -> Self {
105108
Self {
106-
cost: self.cost.finalize(&self.state),
109+
cost: self.cost.finalize(&self.state, enode),
107110
state: self.state.clone(),
108111
}
109112
}
@@ -129,6 +132,7 @@ impl CubePlanCost {
129132
empty_wrappers: self.empty_wrappers + other.empty_wrappers,
130133
ast_size_outside_wrapper: self.ast_size_outside_wrapper
131134
+ other.ast_size_outside_wrapper,
135+
ungrouped_aggregates: self.ungrouped_aggregates + other.ungrouped_aggregates,
132136
wrapper_nodes: self.wrapper_nodes + other.wrapper_nodes,
133137
cube_scan_nodes: self.cube_scan_nodes + other.cube_scan_nodes,
134138
time_dimensions_used_as_dimensions: self.time_dimensions_used_as_dimensions
@@ -139,10 +143,11 @@ impl CubePlanCost {
139143
ast_size_without_alias: self.ast_size_without_alias + other.ast_size_without_alias,
140144
ast_size: self.ast_size + other.ast_size,
141145
ast_size_inside_wrapper: self.ast_size_inside_wrapper + other.ast_size_inside_wrapper,
146+
ungrouped_nodes: self.ungrouped_nodes + other.ungrouped_nodes,
142147
}
143148
}
144149

145-
pub fn finalize(&self, state: &CubePlanState) -> Self {
150+
pub fn finalize(&self, state: &CubePlanState, enode: &LogicalPlanLanguage) -> Self {
146151
Self {
147152
replacers: self.replacers,
148153
table_scans: self.table_scans,
@@ -176,11 +181,27 @@ impl CubePlanCost {
176181
} + self.empty_wrappers,
177182
time_dimensions_used_as_dimensions: self.time_dimensions_used_as_dimensions,
178183
max_time_dimensions_granularity: self.max_time_dimensions_granularity,
184+
ungrouped_aggregates: match state {
185+
CubePlanState::Wrapped => 0,
186+
CubePlanState::Unwrapped(_) => {
187+
if let LogicalPlanLanguage::Aggregate(_) = enode {
188+
if self.ungrouped_nodes > 0 {
189+
1
190+
} else {
191+
0
192+
}
193+
} else {
194+
0
195+
}
196+
}
197+
CubePlanState::Wrapper => 0,
198+
} + self.ungrouped_aggregates,
179199
wrapper_nodes: self.wrapper_nodes,
180200
cube_scan_nodes: self.cube_scan_nodes,
181201
ast_size_without_alias: self.ast_size_without_alias,
182202
ast_size: self.ast_size,
183203
ast_size_inside_wrapper: self.ast_size_inside_wrapper,
204+
ungrouped_nodes: self.ungrouped_nodes,
184205
}
185206
}
186207
}
@@ -338,6 +359,11 @@ impl CostFunction<LogicalPlanLanguage> for BestCubePlan {
338359
_ => 1,
339360
};
340361

362+
let ungrouped_nodes = match enode {
363+
LogicalPlanLanguage::CubeScanUngrouped(CubeScanUngrouped(true)) => 1,
364+
_ => 0,
365+
};
366+
341367
let initial_cost = CubePlanCostAndState {
342368
cost: CubePlanCost {
343369
replacers: this_replacers,
@@ -352,13 +378,15 @@ impl CostFunction<LogicalPlanLanguage> for BestCubePlan {
352378
time_dimensions_used_as_dimensions,
353379
max_time_dimensions_granularity,
354380
structure_points,
381+
ungrouped_aggregates: 0,
355382
wrapper_nodes,
356383
empty_wrappers: 0,
357384
ast_size_outside_wrapper: 0,
358385
ast_size_inside_wrapper,
359386
cube_scan_nodes,
360387
ast_size_without_alias,
361388
ast_size: 1,
389+
ungrouped_nodes,
362390
},
363391
state: match enode {
364392
LogicalPlanLanguage::CubeScanWrapped(CubeScanWrapped(true)) => {
@@ -375,7 +403,7 @@ impl CostFunction<LogicalPlanLanguage> for BestCubePlan {
375403
let child = costs(*id);
376404
cost.add_child(&child)
377405
})
378-
.finalize();
406+
.finalize(enode);
379407
res
380408
}
381409
}

0 commit comments

Comments
 (0)