From ffc8f5257dfaefaac60f87dd134b3ce2ddf8ebef Mon Sep 17 00:00:00 2001 From: Mikhail Cheshkov Date: Wed, 2 Apr 2025 12:13:44 +0200 Subject: [PATCH] fix(cubesql): Penalize CrossJoins in favor of wrapper --- .../cubesql/src/compile/rewrite/cost.rs | 1 + .../compile/test/test_cube_join_grouped.rs | 56 +++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/rust/cubesql/cubesql/src/compile/rewrite/cost.rs b/rust/cubesql/cubesql/src/compile/rewrite/cost.rs index 40e5594c854b5..0246b93f159ad 100644 --- a/rust/cubesql/cubesql/src/compile/rewrite/cost.rs +++ b/rust/cubesql/cubesql/src/compile/rewrite/cost.rs @@ -64,6 +64,7 @@ impl BestCubePlan { let joins = match enode { LogicalPlanLanguage::Join(_) => 1, + LogicalPlanLanguage::CrossJoin(_) => 1, _ => 0, }; diff --git a/rust/cubesql/cubesql/src/compile/test/test_cube_join_grouped.rs b/rust/cubesql/cubesql/src/compile/test/test_cube_join_grouped.rs index 4f04f3f9483bb..d60c8fb138d9f 100644 --- a/rust/cubesql/cubesql/src/compile/test/test_cube_join_grouped.rs +++ b/rust/cubesql/cubesql/src/compile/test/test_cube_join_grouped.rs @@ -843,3 +843,59 @@ GROUP BY .sql .contains(r#"CAST(${MultiTypeCube.dim_str1} AS STRING)"#)); } + +/// Simple query, but complex join condition representation with +/// CrossJoin(CubeScan, CubeScan) is penalized, and Wrapper is preferred +#[tokio::test] +async fn test_crossjoin_extraction() { + if !Rewriter::sql_push_down_enabled() { + return; + } + init_testing_logger(); + + let query_plan = convert_select_to_query_plan( + // language=PostgreSQL + r#" +SELECT "t0"."measure" +FROM + MultiTypeCube + INNER JOIN ( + SELECT + dim_str0, + AVG(avgPrice) AS "measure" + FROM + MultiTypeCube + GROUP BY 1 + ) "t0" + ON (MultiTypeCube.dim_str0 IS NOT DISTINCT FROM "t0".dim_str0) +LIMIT 1 +; + "# + .to_string(), + DatabaseProtocol::PostgreSQL, + ) + .await; + + let physical_plan = query_plan.as_physical_plan().await.unwrap(); + println!( + "Physical plan: {}", + displayable(physical_plan.as_ref()).indent() + ); + + let request = query_plan + .as_logical_plan() + .find_cube_scan_wrapped_sql() + .request; + + assert_eq!(request.ungrouped, Some(true)); + + assert_eq!(request.subquery_joins.as_ref().unwrap().len(), 1); + + let subquery = &request.subquery_joins.unwrap()[0]; + + assert!(!subquery.sql.contains("ungrouped")); + assert_eq!(subquery.join_type, "INNER"); + assert!(subquery + .on + .contains(r#"${MultiTypeCube.dim_str0} IS NOT DISTINCT FROM \"t0\".\"dim_str0\""#)); +}