Skip to content

Commit 9f38839

Browse files
committed
feat(cubesql): Push down Tableau year-month-day IN number filter to CubeScan
Signed-off-by: Alex Qyoun-ae <[email protected]>
1 parent 644fbd4 commit 9f38839

File tree

2 files changed

+497
-14
lines changed

2 files changed

+497
-14
lines changed

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

Lines changed: 135 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15685,8 +15685,8 @@ LIMIT {{ limit }}{% endif %}"#.to_string(),
1568515685
dimension: "KibanaSampleDataEcommerce.order_date".to_string(),
1568615686
granularity: Some("year".to_string()),
1568715687
date_range: Some(json!(vec![
15688-
"2019-01-01 00:00:00.000".to_string(),
15689-
"2023-12-31 23:59:59.999".to_string()
15688+
"2019-01-01T00:00:00.000Z".to_string(),
15689+
"2023-12-31T23:59:59.999Z".to_string()
1569015690
])),
1569115691
}]),
1569215692
order: Some(vec![]),
@@ -15744,8 +15744,8 @@ LIMIT {{ limit }}{% endif %}"#.to_string(),
1574415744
member: Some("KibanaSampleDataEcommerce.order_date".to_string()),
1574515745
operator: Some("inDateRange".to_string()),
1574615746
values: Some(vec![
15747-
"2019-01-01 00:00:00.000".to_string(),
15748-
"2019-03-31 23:59:59.999".to_string(),
15747+
"2019-01-01T00:00:00.000Z".to_string(),
15748+
"2019-03-31T23:59:59.999Z".to_string(),
1574915749
]),
1575015750
or: None,
1575115751
and: None,
@@ -15754,8 +15754,8 @@ LIMIT {{ limit }}{% endif %}"#.to_string(),
1575415754
member: Some("KibanaSampleDataEcommerce.order_date".to_string()),
1575515755
operator: Some("inDateRange".to_string()),
1575615756
values: Some(vec![
15757-
"2020-01-01 00:00:00.000".to_string(),
15758-
"2020-03-31 23:59:59.999".to_string(),
15757+
"2020-01-01T00:00:00.000Z".to_string(),
15758+
"2020-03-31T23:59:59.999Z".to_string(),
1575915759
]),
1576015760
or: None,
1576115761
and: None,
@@ -15764,8 +15764,8 @@ LIMIT {{ limit }}{% endif %}"#.to_string(),
1576415764
member: Some("KibanaSampleDataEcommerce.order_date".to_string()),
1576515765
operator: Some("inDateRange".to_string()),
1576615766
values: Some(vec![
15767-
"2021-01-01 00:00:00.000".to_string(),
15768-
"2021-03-31 23:59:59.999".to_string(),
15767+
"2021-01-01T00:00:00.000Z".to_string(),
15768+
"2021-03-31T23:59:59.999Z".to_string(),
1576915769
]),
1577015770
or: None,
1577115771
and: None,
@@ -15774,8 +15774,8 @@ LIMIT {{ limit }}{% endif %}"#.to_string(),
1577415774
member: Some("KibanaSampleDataEcommerce.order_date".to_string()),
1577515775
operator: Some("inDateRange".to_string()),
1577615776
values: Some(vec![
15777-
"2022-01-01 00:00:00.000".to_string(),
15778-
"2022-03-31 23:59:59.999".to_string(),
15777+
"2022-01-01T00:00:00.000Z".to_string(),
15778+
"2022-03-31T23:59:59.999Z".to_string(),
1577915779
]),
1578015780
or: None,
1578115781
and: None,
@@ -15784,8 +15784,8 @@ LIMIT {{ limit }}{% endif %}"#.to_string(),
1578415784
member: Some("KibanaSampleDataEcommerce.order_date".to_string()),
1578515785
operator: Some("inDateRange".to_string()),
1578615786
values: Some(vec![
15787-
"2023-01-01 00:00:00.000".to_string(),
15788-
"2023-03-31 23:59:59.999".to_string(),
15787+
"2023-01-01T00:00:00.000Z".to_string(),
15788+
"2023-03-31T23:59:59.999Z".to_string(),
1578915789
]),
1579015790
or: None,
1579115791
and: None,
@@ -17792,4 +17792,127 @@ LIMIT {{ limit }}{% endif %}"#.to_string(),
1779217792
}
1779317793
)
1779417794
}
17795+
17796+
#[tokio::test]
17797+
async fn test_tableau_year_month_in_number() {
17798+
if !Rewriter::sql_push_down_enabled() {
17799+
return;
17800+
}
17801+
init_testing_logger();
17802+
17803+
let logical_plan = convert_select_to_query_plan(
17804+
r#"
17805+
SELECT
17806+
COUNT("KibanaSampleDataEcommerce"."count") AS "cnt:count:ok",
17807+
CAST("KibanaSampleDataEcommerce"."customer_gender" AS TEXT) AS "customer_gender"
17808+
FROM "public"."KibanaSampleDataEcommerce" "KibanaSampleDataEcommerce"
17809+
WHERE (
17810+
(
17811+
(
17812+
CAST(
17813+
TRUNC(EXTRACT(YEAR FROM "KibanaSampleDataEcommerce"."order_date"))
17814+
AS INTEGER) * 100
17815+
) + CAST(
17816+
TRUNC(EXTRACT(MONTH FROM "KibanaSampleDataEcommerce"."order_date"))
17817+
AS INTEGER
17818+
)
17819+
) IN (202501, 202502, 202503, 202504)
17820+
AND CAST("KibanaSampleDataEcommerce"."customer_gender" AS TEXT) = 'value'
17821+
)
17822+
GROUP BY 2
17823+
"#
17824+
.to_string(),
17825+
DatabaseProtocol::PostgreSQL,
17826+
)
17827+
.await
17828+
.as_logical_plan();
17829+
17830+
assert_eq!(
17831+
logical_plan.find_cube_scan().request,
17832+
V1LoadRequestQuery {
17833+
measures: Some(vec!["KibanaSampleDataEcommerce.count".to_string(),]),
17834+
dimensions: Some(vec![
17835+
"KibanaSampleDataEcommerce.customer_gender".to_string(),
17836+
]),
17837+
segments: Some(vec![]),
17838+
time_dimensions: Some(vec![V1LoadRequestQueryTimeDimension {
17839+
dimension: "KibanaSampleDataEcommerce.order_date".to_string(),
17840+
granularity: None,
17841+
date_range: Some(json!(vec![
17842+
"2025-01-01T00:00:00.000Z".to_string(),
17843+
"2025-04-30T23:59:59.999Z".to_string(),
17844+
])),
17845+
}]),
17846+
order: Some(vec![]),
17847+
filters: Some(vec![V1LoadRequestQueryFilterItem {
17848+
member: Some("KibanaSampleDataEcommerce.customer_gender".to_string()),
17849+
operator: Some("equals".to_string()),
17850+
values: Some(vec!["value".to_string()]),
17851+
or: None,
17852+
and: None,
17853+
},]),
17854+
..Default::default()
17855+
}
17856+
)
17857+
}
17858+
17859+
#[tokio::test]
17860+
async fn test_tableau_year_month_day_eq_number() {
17861+
if !Rewriter::sql_push_down_enabled() {
17862+
return;
17863+
}
17864+
init_testing_logger();
17865+
17866+
let logical_plan = convert_select_to_query_plan(
17867+
r#"
17868+
SELECT
17869+
COUNT("KibanaSampleDataEcommerce"."count") AS "cnt:count:ok",
17870+
CAST("KibanaSampleDataEcommerce"."customer_gender" AS TEXT) AS "customer_gender"
17871+
FROM "public"."KibanaSampleDataEcommerce" "KibanaSampleDataEcommerce"
17872+
WHERE (
17873+
(
17874+
(
17875+
(
17876+
CAST(TRUNC(
17877+
EXTRACT(YEAR FROM "KibanaSampleDataEcommerce"."order_date")
17878+
) AS INTEGER) * 10000
17879+
) + (
17880+
CAST(TRUNC(
17881+
EXTRACT(MONTH FROM "KibanaSampleDataEcommerce"."order_date")
17882+
) AS INTEGER) * 100
17883+
)
17884+
) + CAST(TRUNC(
17885+
EXTRACT(DAY FROM "KibanaSampleDataEcommerce"."order_date")
17886+
) AS INTEGER)
17887+
) = 20250218
17888+
)
17889+
GROUP BY 2
17890+
"#
17891+
.to_string(),
17892+
DatabaseProtocol::PostgreSQL,
17893+
)
17894+
.await
17895+
.as_logical_plan();
17896+
17897+
assert_eq!(
17898+
logical_plan.find_cube_scan().request,
17899+
V1LoadRequestQuery {
17900+
measures: Some(vec!["KibanaSampleDataEcommerce.count".to_string(),]),
17901+
dimensions: Some(vec![
17902+
"KibanaSampleDataEcommerce.customer_gender".to_string(),
17903+
]),
17904+
segments: Some(vec![]),
17905+
time_dimensions: Some(vec![V1LoadRequestQueryTimeDimension {
17906+
dimension: "KibanaSampleDataEcommerce.order_date".to_string(),
17907+
granularity: None,
17908+
date_range: Some(json!(vec![
17909+
"2025-02-18T00:00:00.000Z".to_string(),
17910+
"2025-02-18T23:59:59.999Z".to_string(),
17911+
])),
17912+
}]),
17913+
order: Some(vec![]),
17914+
..Default::default()
17915+
}
17916+
)
17917+
}
1779517918
}

0 commit comments

Comments
 (0)