Skip to content

Commit c3f92b6

Browse files
MazterQyouigorlukanin
authored andcommitted
feat(cubesql): Push down Tableau year-month-day IN number filter to CubeScan (#10068)
Signed-off-by: Alex Qyoun-ae <[email protected]>
1 parent 7c687dc commit c3f92b6

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
@@ -15764,8 +15764,8 @@ LIMIT {{ limit }}{% endif %}"#.to_string(),
1576415764
dimension: "KibanaSampleDataEcommerce.order_date".to_string(),
1576515765
granularity: Some("year".to_string()),
1576615766
date_range: Some(json!(vec![
15767-
"2019-01-01 00:00:00.000".to_string(),
15768-
"2023-12-31 23:59:59.999".to_string()
15767+
"2019-01-01T00:00:00.000Z".to_string(),
15768+
"2023-12-31T23:59:59.999Z".to_string()
1576915769
])),
1577015770
}]),
1577115771
order: Some(vec![]),
@@ -15823,8 +15823,8 @@ LIMIT {{ limit }}{% endif %}"#.to_string(),
1582315823
member: Some("KibanaSampleDataEcommerce.order_date".to_string()),
1582415824
operator: Some("inDateRange".to_string()),
1582515825
values: Some(vec![
15826-
"2019-01-01 00:00:00.000".to_string(),
15827-
"2019-03-31 23:59:59.999".to_string(),
15826+
"2019-01-01T00:00:00.000Z".to_string(),
15827+
"2019-03-31T23:59:59.999Z".to_string(),
1582815828
]),
1582915829
or: None,
1583015830
and: None,
@@ -15833,8 +15833,8 @@ LIMIT {{ limit }}{% endif %}"#.to_string(),
1583315833
member: Some("KibanaSampleDataEcommerce.order_date".to_string()),
1583415834
operator: Some("inDateRange".to_string()),
1583515835
values: Some(vec![
15836-
"2020-01-01 00:00:00.000".to_string(),
15837-
"2020-03-31 23:59:59.999".to_string(),
15836+
"2020-01-01T00:00:00.000Z".to_string(),
15837+
"2020-03-31T23:59:59.999Z".to_string(),
1583815838
]),
1583915839
or: None,
1584015840
and: None,
@@ -15843,8 +15843,8 @@ LIMIT {{ limit }}{% endif %}"#.to_string(),
1584315843
member: Some("KibanaSampleDataEcommerce.order_date".to_string()),
1584415844
operator: Some("inDateRange".to_string()),
1584515845
values: Some(vec![
15846-
"2021-01-01 00:00:00.000".to_string(),
15847-
"2021-03-31 23:59:59.999".to_string(),
15846+
"2021-01-01T00:00:00.000Z".to_string(),
15847+
"2021-03-31T23:59:59.999Z".to_string(),
1584815848
]),
1584915849
or: None,
1585015850
and: None,
@@ -15853,8 +15853,8 @@ LIMIT {{ limit }}{% endif %}"#.to_string(),
1585315853
member: Some("KibanaSampleDataEcommerce.order_date".to_string()),
1585415854
operator: Some("inDateRange".to_string()),
1585515855
values: Some(vec![
15856-
"2022-01-01 00:00:00.000".to_string(),
15857-
"2022-03-31 23:59:59.999".to_string(),
15856+
"2022-01-01T00:00:00.000Z".to_string(),
15857+
"2022-03-31T23:59:59.999Z".to_string(),
1585815858
]),
1585915859
or: None,
1586015860
and: None,
@@ -15863,8 +15863,8 @@ LIMIT {{ limit }}{% endif %}"#.to_string(),
1586315863
member: Some("KibanaSampleDataEcommerce.order_date".to_string()),
1586415864
operator: Some("inDateRange".to_string()),
1586515865
values: Some(vec![
15866-
"2023-01-01 00:00:00.000".to_string(),
15867-
"2023-03-31 23:59:59.999".to_string(),
15866+
"2023-01-01T00:00:00.000Z".to_string(),
15867+
"2023-03-31T23:59:59.999Z".to_string(),
1586815868
]),
1586915869
or: None,
1587015870
and: None,
@@ -17871,4 +17871,127 @@ LIMIT {{ limit }}{% endif %}"#.to_string(),
1787117871
}
1787217872
)
1787317873
}
17874+
17875+
#[tokio::test]
17876+
async fn test_tableau_year_month_in_number() {
17877+
if !Rewriter::sql_push_down_enabled() {
17878+
return;
17879+
}
17880+
init_testing_logger();
17881+
17882+
let logical_plan = convert_select_to_query_plan(
17883+
r#"
17884+
SELECT
17885+
COUNT("KibanaSampleDataEcommerce"."count") AS "cnt:count:ok",
17886+
CAST("KibanaSampleDataEcommerce"."customer_gender" AS TEXT) AS "customer_gender"
17887+
FROM "public"."KibanaSampleDataEcommerce" "KibanaSampleDataEcommerce"
17888+
WHERE (
17889+
(
17890+
(
17891+
CAST(
17892+
TRUNC(EXTRACT(YEAR FROM "KibanaSampleDataEcommerce"."order_date"))
17893+
AS INTEGER) * 100
17894+
) + CAST(
17895+
TRUNC(EXTRACT(MONTH FROM "KibanaSampleDataEcommerce"."order_date"))
17896+
AS INTEGER
17897+
)
17898+
) IN (202501, 202502, 202503, 202504)
17899+
AND CAST("KibanaSampleDataEcommerce"."customer_gender" AS TEXT) = 'value'
17900+
)
17901+
GROUP BY 2
17902+
"#
17903+
.to_string(),
17904+
DatabaseProtocol::PostgreSQL,
17905+
)
17906+
.await
17907+
.as_logical_plan();
17908+
17909+
assert_eq!(
17910+
logical_plan.find_cube_scan().request,
17911+
V1LoadRequestQuery {
17912+
measures: Some(vec!["KibanaSampleDataEcommerce.count".to_string(),]),
17913+
dimensions: Some(vec![
17914+
"KibanaSampleDataEcommerce.customer_gender".to_string(),
17915+
]),
17916+
segments: Some(vec![]),
17917+
time_dimensions: Some(vec![V1LoadRequestQueryTimeDimension {
17918+
dimension: "KibanaSampleDataEcommerce.order_date".to_string(),
17919+
granularity: None,
17920+
date_range: Some(json!(vec![
17921+
"2025-01-01T00:00:00.000Z".to_string(),
17922+
"2025-04-30T23:59:59.999Z".to_string(),
17923+
])),
17924+
}]),
17925+
order: Some(vec![]),
17926+
filters: Some(vec![V1LoadRequestQueryFilterItem {
17927+
member: Some("KibanaSampleDataEcommerce.customer_gender".to_string()),
17928+
operator: Some("equals".to_string()),
17929+
values: Some(vec!["value".to_string()]),
17930+
or: None,
17931+
and: None,
17932+
},]),
17933+
..Default::default()
17934+
}
17935+
)
17936+
}
17937+
17938+
#[tokio::test]
17939+
async fn test_tableau_year_month_day_eq_number() {
17940+
if !Rewriter::sql_push_down_enabled() {
17941+
return;
17942+
}
17943+
init_testing_logger();
17944+
17945+
let logical_plan = convert_select_to_query_plan(
17946+
r#"
17947+
SELECT
17948+
COUNT("KibanaSampleDataEcommerce"."count") AS "cnt:count:ok",
17949+
CAST("KibanaSampleDataEcommerce"."customer_gender" AS TEXT) AS "customer_gender"
17950+
FROM "public"."KibanaSampleDataEcommerce" "KibanaSampleDataEcommerce"
17951+
WHERE (
17952+
(
17953+
(
17954+
(
17955+
CAST(TRUNC(
17956+
EXTRACT(YEAR FROM "KibanaSampleDataEcommerce"."order_date")
17957+
) AS INTEGER) * 10000
17958+
) + (
17959+
CAST(TRUNC(
17960+
EXTRACT(MONTH FROM "KibanaSampleDataEcommerce"."order_date")
17961+
) AS INTEGER) * 100
17962+
)
17963+
) + CAST(TRUNC(
17964+
EXTRACT(DAY FROM "KibanaSampleDataEcommerce"."order_date")
17965+
) AS INTEGER)
17966+
) = 20250218
17967+
)
17968+
GROUP BY 2
17969+
"#
17970+
.to_string(),
17971+
DatabaseProtocol::PostgreSQL,
17972+
)
17973+
.await
17974+
.as_logical_plan();
17975+
17976+
assert_eq!(
17977+
logical_plan.find_cube_scan().request,
17978+
V1LoadRequestQuery {
17979+
measures: Some(vec!["KibanaSampleDataEcommerce.count".to_string(),]),
17980+
dimensions: Some(vec![
17981+
"KibanaSampleDataEcommerce.customer_gender".to_string(),
17982+
]),
17983+
segments: Some(vec![]),
17984+
time_dimensions: Some(vec![V1LoadRequestQueryTimeDimension {
17985+
dimension: "KibanaSampleDataEcommerce.order_date".to_string(),
17986+
granularity: None,
17987+
date_range: Some(json!(vec![
17988+
"2025-02-18T00:00:00.000Z".to_string(),
17989+
"2025-02-18T23:59:59.999Z".to_string(),
17990+
])),
17991+
}]),
17992+
order: Some(vec![]),
17993+
..Default::default()
17994+
}
17995+
)
17996+
}
1787417997
}

0 commit comments

Comments
 (0)