Skip to content

Commit 7616fd8

Browse files
committed
feat(cubesql): Flatten aggregation of WrappedSelect with filters
Some queries in tests reduced to a single CubeScan with member expressions, so tests have changed
1 parent a19f88a commit 7616fd8

File tree

4 files changed

+420
-94
lines changed

4 files changed

+420
-94
lines changed

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

Lines changed: 166 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -7242,51 +7242,88 @@ ORDER BY
72427242
displayable(physical_plan.as_ref()).indent()
72437243
);
72447244

7245+
fn trivial_member_expr(cube: &str, member: &str, alias: &str) -> String {
7246+
json!({
7247+
"cube_name": cube,
7248+
"alias": alias,
7249+
"cube_params": [cube],
7250+
"expr": format!("${{{cube}.{member}}}"),
7251+
"grouping_set": null,
7252+
})
7253+
.to_string()
7254+
}
7255+
72457256
assert_eq!(
7246-
query_plan.as_logical_plan().find_cube_scan().request,
7257+
query_plan
7258+
.as_logical_plan()
7259+
.find_cube_scan_wrapper()
7260+
.request
7261+
.unwrap(),
72477262
V1LoadRequestQuery {
72487263
measures: Some(vec![
7249-
"WideCube.measure1".to_string(),
7250-
"WideCube.measure2".to_string(),
7251-
"WideCube.measure3".to_string(),
7252-
"WideCube.measure4".to_string(),
7264+
json!({
7265+
"cube_name": "WideCube",
7266+
"alias": "max_source_measu",
7267+
"cube_params": ["WideCube"],
7268+
"expr": "${WideCube.measure1}",
7269+
"grouping_set": null,
7270+
})
7271+
.to_string(),
7272+
json!({
7273+
"cube_name": "WideCube",
7274+
"alias": "max_source_measu_1",
7275+
"cube_params": ["WideCube"],
7276+
"expr": "${WideCube.measure2}",
7277+
"grouping_set": null,
7278+
})
7279+
.to_string(),
7280+
json!({
7281+
"cube_name": "WideCube",
7282+
"alias": "sum_source_measu",
7283+
"cube_params": ["WideCube"],
7284+
"expr": "${WideCube.measure3}",
7285+
"grouping_set": null,
7286+
})
7287+
.to_string(),
7288+
json!({
7289+
"cube_name": "WideCube",
7290+
"alias": "max_source_measu_2",
7291+
"cube_params": ["WideCube"],
7292+
"expr": "${WideCube.measure4}",
7293+
"grouping_set": null,
7294+
})
7295+
.to_string(),
72537296
]),
72547297
dimensions: Some(vec![
7255-
"WideCube.dim1".to_string(),
7256-
"WideCube.dim2".to_string(),
7257-
"WideCube.dim3".to_string(),
7258-
"WideCube.dim4".to_string(),
7298+
trivial_member_expr("WideCube", "dim2", "dim2"),
7299+
trivial_member_expr("WideCube", "dim3", "dim3"),
7300+
trivial_member_expr("WideCube", "dim4", "dim4"),
7301+
json!({
7302+
"cube_name": "WideCube",
7303+
"alias": "pivot_grouping",
7304+
"cube_params": ["WideCube"],
7305+
"expr": "0",
7306+
"grouping_set": null,
7307+
})
7308+
.to_string()
72597309
]),
72607310
segments: Some(vec![]),
7261-
order: Some(vec![]),
7311+
order: Some(vec![
7312+
vec!["dim2".to_string(), "asc".to_string(),],
7313+
vec!["dim3".to_string(), "asc".to_string(),],
7314+
vec!["dim4".to_string(), "asc".to_string(),],
7315+
vec!["pivot_grouping".to_string(), "asc".to_string(),],
7316+
]),
72627317
filters: Some(vec![V1LoadRequestQueryFilterItem {
72637318
member: Some("WideCube.dim1".to_string()),
72647319
operator: Some("equals".to_string()),
72657320
values: Some(vec!["foo".to_string()]),
72667321
or: None,
72677322
and: None,
7268-
}]),
7269-
ungrouped: Some(true),
7323+
},]),
72707324
..Default::default()
72717325
}
72727326
);
7273-
assert!(!query_plan
7274-
.as_logical_plan()
7275-
.find_cube_scan_wrapper()
7276-
.wrapped_sql
7277-
.unwrap()
7278-
.sql
7279-
.contains("ungrouped"));
7280-
7281-
let re = Regex::new(r#"\[[[:space:]]*"dim2",[[:space:]]*"asc"[[:space:]]*\]"#).unwrap();
7282-
assert!(re.is_match(
7283-
&query_plan
7284-
.as_logical_plan()
7285-
.find_cube_scan_wrapper()
7286-
.wrapped_sql
7287-
.unwrap()
7288-
.sql
7289-
));
72907327
}
72917328

72927329
#[tokio::test]
@@ -11611,15 +11648,39 @@ ORDER BY "source"."str0" ASC
1161111648
.await
1161211649
.as_logical_plan();
1161311650

11614-
let sql = logical_plan
11615-
.find_cube_scan_wrapper()
11616-
.wrapped_sql
11617-
.unwrap()
11618-
.sql;
11619-
11620-
assert!(sql.contains("LOWER("));
11621-
assert!(sql.contains("GROUP BY "));
11622-
assert!(sql.contains("ORDER BY "));
11651+
assert_eq!(
11652+
logical_plan
11653+
.find_cube_scan_wrapper()
11654+
.request
11655+
.unwrap(),
11656+
V1LoadRequestQuery {
11657+
measures: Some(vec![]),
11658+
dimensions: Some(vec![
11659+
json!({
11660+
"cube_name": "KibanaSampleDataEcommerce",
11661+
"alias": "ta_1_order_date_",
11662+
"cube_params": ["KibanaSampleDataEcommerce", "Logs"],
11663+
"expr": "((${KibanaSampleDataEcommerce.order_date} = DATE('1994-05-01')) OR (${KibanaSampleDataEcommerce.order_date} = DATE('1996-05-03')))",
11664+
"grouping_set": null,
11665+
}).to_string(),
11666+
]),
11667+
segments: Some(vec![
11668+
json!({
11669+
"cube_name": "KibanaSampleDataEcommerce",
11670+
"alias": "lower_ta_2_conte",
11671+
"cube_params": ["KibanaSampleDataEcommerce", "Logs"],
11672+
"expr": "(LOWER(${Logs.content}) = $0$)",
11673+
"grouping_set": null,
11674+
}).to_string(),
11675+
]),
11676+
time_dimensions: None,
11677+
order: Some(vec![]),
11678+
limit: None,
11679+
offset: None,
11680+
filters: None,
11681+
ungrouped: None,
11682+
}
11683+
);
1162311684
}
1162411685

1162511686
#[tokio::test]
@@ -11873,20 +11934,46 @@ ORDER BY "source"."str0" ASC
1187311934
);
1187411935

1187511936
assert_eq!(
11876-
query_plan.as_logical_plan().find_cube_scan().request,
11937+
query_plan
11938+
.as_logical_plan()
11939+
.find_cube_scan_wrapper()
11940+
.request
11941+
.unwrap(),
1187711942
V1LoadRequestQuery {
1187811943
measures: Some(vec![]),
11879-
dimensions: Some(vec![]),
11880-
segments: Some(vec![]),
11944+
dimensions: Some(vec![
11945+
json!({
11946+
"cube_name": "KibanaSampleDataEcommerce",
11947+
"alias": "customer_gender",
11948+
"cube_params": ["KibanaSampleDataEcommerce"],
11949+
"expr": "${KibanaSampleDataEcommerce.customer_gender}",
11950+
"grouping_set": null,
11951+
}).to_string(),
11952+
json!({
11953+
"cube_name": "KibanaSampleDataEcommerce",
11954+
"alias": "cast_dateadd_utf",
11955+
"cube_params": ["KibanaSampleDataEcommerce"],
11956+
"expr": "CAST(DATE_ADD(${KibanaSampleDataEcommerce.order_date}, INTERVAL '2 DAY') AS DATE)",
11957+
"grouping_set": null,
11958+
}).to_string(),
11959+
json!({
11960+
"cube_name": "KibanaSampleDataEcommerce",
11961+
"alias": "dateadd_utf8__se",
11962+
"cube_params": ["KibanaSampleDataEcommerce"],
11963+
"expr": "DATE_ADD(${KibanaSampleDataEcommerce.order_date}, INTERVAL '2000000 MILLISECOND')",
11964+
"grouping_set": null,
11965+
}).to_string(),
11966+
]),
11967+
segments: Some(vec![
11968+
json!({
11969+
"cube_name": "KibanaSampleDataEcommerce",
11970+
"alias": "dateadd_utf8__da",
11971+
"cube_params": ["KibanaSampleDataEcommerce"],
11972+
"expr": "(DATE_ADD(${KibanaSampleDataEcommerce.order_date}, INTERVAL '2 DAY') < DATE('2014-06-02'))",
11973+
"grouping_set": null,
11974+
}).to_string(),
11975+
]),
1188111976
order: Some(vec![]),
11882-
filters: Some(vec![V1LoadRequestQueryFilterItem {
11883-
member: Some("KibanaSampleDataEcommerce.order_date".to_string(),),
11884-
operator: Some("beforeDate".to_string(),),
11885-
values: Some(vec!["2014-05-31T00:00:00.000Z".to_string()]),
11886-
or: None,
11887-
and: None,
11888-
}]),
11889-
ungrouped: Some(true),
1189011977
..Default::default()
1189111978
}
1189211979
)
@@ -12671,53 +12758,39 @@ ORDER BY "source"."str0" ASC
1267112758
.await
1267212759
.as_logical_plan();
1267312760

12674-
let end_date = chrono::Utc::now().date_naive() - chrono::Duration::days(1);
12675-
let start_date = end_date - chrono::Duration::days(29);
12761+
let end_date = chrono::Utc::now().date_naive();
12762+
let start_date = end_date - chrono::Duration::days(30);
1267612763
assert_eq!(
12677-
logical_plan.find_cube_scan().request,
12764+
logical_plan.find_cube_scan_wrapper().request.unwrap(),
1267812765
V1LoadRequestQuery {
12679-
measures: Some(vec![]),
12680-
dimensions: Some(vec![]),
12681-
segments: Some(vec![]),
12682-
time_dimensions: Some(vec![V1LoadRequestQueryTimeDimension {
12683-
dimension: "KibanaSampleDataEcommerce.order_date".to_string(),
12684-
granularity: None,
12685-
date_range: Some(json!(vec![
12686-
format!("{}T00:00:00.000Z", start_date),
12687-
format!("{}T23:59:59.999Z", end_date),
12688-
]))
12689-
}]),
12766+
measures: Some(vec![
12767+
json!({
12768+
"cube_name": "KibanaSampleDataEcommerce",
12769+
"alias": "avg_kibanasample",
12770+
"cube_params": ["KibanaSampleDataEcommerce"],
12771+
"expr": "${KibanaSampleDataEcommerce.avgPrice}",
12772+
"grouping_set": null,
12773+
}).to_string(),
12774+
]),
12775+
dimensions: Some(vec![
12776+
json!({
12777+
"cube_name": "KibanaSampleDataEcommerce",
12778+
"alias": "cast_kibanasampl",
12779+
"cube_params": ["KibanaSampleDataEcommerce"],
12780+
"expr": "CAST(${KibanaSampleDataEcommerce.order_date} AS DATE)",
12781+
"grouping_set": null,
12782+
}).to_string(),
12783+
]),
12784+
segments: Some(vec![
12785+
json!({
12786+
"cube_name": "KibanaSampleDataEcommerce",
12787+
"alias": "kibanasampledata",
12788+
"cube_params": ["KibanaSampleDataEcommerce"],
12789+
"expr": format!("(((${{KibanaSampleDataEcommerce.order_date}} >= DATE('{start_date}')) AND (${{KibanaSampleDataEcommerce.order_date}} < DATE('{end_date}'))) AND (((${{KibanaSampleDataEcommerce.notes}} = $0$) OR (${{KibanaSampleDataEcommerce.notes}} = $1$)) OR (${{KibanaSampleDataEcommerce.notes}} = $2$)))"),
12790+
"grouping_set": null,
12791+
}).to_string(),
12792+
]),
1269012793
order: Some(vec![]),
12691-
filters: Some(vec![V1LoadRequestQueryFilterItem {
12692-
member: None,
12693-
operator: None,
12694-
values: None,
12695-
or: Some(vec![
12696-
json!(V1LoadRequestQueryFilterItem {
12697-
member: Some("KibanaSampleDataEcommerce.notes".to_string()),
12698-
operator: Some("equals".to_string()),
12699-
values: Some(vec!["note1".to_string()]),
12700-
or: None,
12701-
and: None,
12702-
}),
12703-
json!(V1LoadRequestQueryFilterItem {
12704-
member: Some("KibanaSampleDataEcommerce.notes".to_string()),
12705-
operator: Some("equals".to_string()),
12706-
values: Some(vec!["note2".to_string()]),
12707-
or: None,
12708-
and: None,
12709-
}),
12710-
json!(V1LoadRequestQueryFilterItem {
12711-
member: Some("KibanaSampleDataEcommerce.notes".to_string()),
12712-
operator: Some("equals".to_string()),
12713-
values: Some(vec!["note3".to_string()]),
12714-
or: None,
12715-
and: None,
12716-
}),
12717-
]),
12718-
and: None
12719-
}]),
12720-
ungrouped: Some(true),
1272112794
..Default::default()
1272212795
}
1272312796
)

0 commit comments

Comments
 (0)