diff --git a/rust/cubesql/cubesql/src/compile/rewrite/cost.rs b/rust/cubesql/cubesql/src/compile/rewrite/cost.rs index 2d46d8dfc5bff..ac7880d046f32 100644 --- a/rust/cubesql/cubesql/src/compile/rewrite/cost.rs +++ b/rust/cubesql/cubesql/src/compile/rewrite/cost.rs @@ -4,7 +4,7 @@ use crate::{ compile::rewrite::{ rules::utils::granularity_str_to_int_order, CubeScanUngrouped, CubeScanWrapped, DimensionName, LogicalPlanLanguage, MemberErrorPriority, ScalarUDFExprFun, - TimeDimensionGranularity, WrappedSelectUngroupedScan, + TimeDimensionGranularity, WrappedSelectPushToCube, WrappedSelectUngroupedScan, }, transport::{MetaContext, V1CubeMetaDimensionExt}, }; @@ -186,6 +186,11 @@ impl BestCubePlan { _ => 0, }; + let wrapped_select_non_push_to_cube = match enode { + LogicalPlanLanguage::WrappedSelectPushToCube(WrappedSelectPushToCube(false)) => 1, + _ => 0, + }; + let wrapped_select_ungrouped_scan = match enode { LogicalPlanLanguage::WrappedSelectUngroupedScan(WrappedSelectUngroupedScan(true)) => 1, _ => 0, @@ -215,6 +220,7 @@ impl BestCubePlan { ungrouped_aggregates: 0, wrapper_nodes, joins, + wrapped_select_non_push_to_cube, wrapped_select_ungrouped_scan, empty_wrappers: 0, ast_size_outside_wrapper: 0, @@ -239,6 +245,7 @@ impl BestCubePlan { /// - `member_errors` > `wrapper_nodes` - use SQL push down where possible if cube scan can't be detected /// - `non_pushed_down_window` > `wrapper_nodes` - prefer to always push down window functions /// - `non_pushed_down_limit_sort` > `wrapper_nodes` - prefer to always push down limit-sort expressions +/// - `wrapped_select_non_push_to_cube` > `wrapped_select_ungrouped_scan` - otherwise cost would prefer any aggregation, even non-push-to-Cube /// - match errors by priority - optimize for more specific errors #[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq)] pub struct CubePlanCost { @@ -256,6 +263,7 @@ pub struct CubePlanCost { joins: usize, wrapper_nodes: i64, ast_size_outside_wrapper: usize, + wrapped_select_non_push_to_cube: usize, wrapped_select_ungrouped_scan: usize, filters: i64, structure_points: i64, @@ -382,6 +390,8 @@ impl CubePlanCost { + other.ast_size_outside_wrapper, ungrouped_aggregates: self.ungrouped_aggregates + other.ungrouped_aggregates, wrapper_nodes: self.wrapper_nodes + other.wrapper_nodes, + wrapped_select_non_push_to_cube: self.wrapped_select_non_push_to_cube + + other.wrapped_select_non_push_to_cube, wrapped_select_ungrouped_scan: self.wrapped_select_ungrouped_scan + other.wrapped_select_ungrouped_scan, cube_scan_nodes: self.cube_scan_nodes + other.cube_scan_nodes, @@ -468,6 +478,7 @@ impl CubePlanCost { } + self.ungrouped_aggregates, unwrapped_subqueries: self.unwrapped_subqueries, wrapper_nodes: self.wrapper_nodes, + wrapped_select_non_push_to_cube: self.wrapped_select_non_push_to_cube, wrapped_select_ungrouped_scan: self.wrapped_select_ungrouped_scan, cube_scan_nodes: self.cube_scan_nodes, ast_size_without_alias: self.ast_size_without_alias, diff --git a/rust/cubesql/cubesql/src/compile/test/test_wrapper.rs b/rust/cubesql/cubesql/src/compile/test/test_wrapper.rs index fc6267d32c44e..04d51514f805c 100644 --- a/rust/cubesql/cubesql/src/compile/test/test_wrapper.rs +++ b/rust/cubesql/cubesql/src/compile/test/test_wrapper.rs @@ -1417,3 +1417,41 @@ async fn wrapper_agg_dimension_over_limit() { .sql .contains("\"ungrouped\": true")); } + +/// Simple wrapper with cast should have explicit members, not zero +#[tokio::test] +async fn wrapper_cast_limit_explicit_members() { + if !Rewriter::sql_push_down_enabled() { + return; + } + init_testing_logger(); + + let query_plan = convert_select_to_query_plan( + // language=PostgreSQL + r#" + SELECT + CAST(dim_date0 AS DATE) AS "dim_date0" + FROM + MultiTypeCube + LIMIT 10 + ; + "# + .to_string(), + DatabaseProtocol::PostgreSQL, + ) + .await; + + let physical_plan = query_plan.as_physical_plan().await.unwrap(); + println!( + "Physical plan: {}", + displayable(physical_plan.as_ref()).indent() + ); + + // Query should mention just a single member + let request = query_plan + .as_logical_plan() + .find_cube_scan_wrapped_sql() + .request; + assert_eq!(request.measures.unwrap().len(), 1); + assert_eq!(request.dimensions.unwrap().len(), 0); +}