Skip to content

Commit 7c43db3

Browse files
committed
fix(cubesql): Match reverse Tableau year-month extract filter
Signed-off-by: Alex Qyoun-ae <[email protected]>
1 parent 9274201 commit 7c43db3

File tree

2 files changed

+140
-8
lines changed

2 files changed

+140
-8
lines changed

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

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17883,4 +17883,72 @@ LIMIT {{ limit }}{% endif %}"#.to_string(),
1788317883
}
1788417884
)
1788517885
}
17886+
17887+
#[tokio::test]
17888+
async fn test_tableau_trunc_extract_year_and_month_rev() {
17889+
if !Rewriter::sql_push_down_enabled() {
17890+
return;
17891+
}
17892+
init_testing_logger();
17893+
17894+
let logical_plan = convert_select_to_query_plan(
17895+
r#"
17896+
SELECT SUM("KibanaSampleDataEcommerce"."sumPrice") AS "sum:sumPrice:ok"
17897+
FROM "public"."KibanaSampleDataEcommerce" "KibanaSampleDataEcommerce"
17898+
WHERE (
17899+
"KibanaSampleDataEcommerce"."id" != 0
17900+
AND CAST(TRUNC(EXTRACT(YEAR FROM "KibanaSampleDataEcommerce"."order_date")) AS INTEGER) = 2024
17901+
AND CAST(TRUNC(EXTRACT(MONTH FROM "KibanaSampleDataEcommerce"."order_date")) AS INTEGER) = 2
17902+
AND "KibanaSampleDataEcommerce"."customer_gender" IS NOT NULL
17903+
)
17904+
HAVING COUNT(1) > 0
17905+
"#
17906+
.to_string(),
17907+
DatabaseProtocol::PostgreSQL,
17908+
)
17909+
.await
17910+
.as_logical_plan();
17911+
17912+
assert_eq!(
17913+
logical_plan.find_cube_scan().request,
17914+
V1LoadRequestQuery {
17915+
measures: Some(vec!["KibanaSampleDataEcommerce.sumPrice".to_string(),]),
17916+
dimensions: Some(vec![]),
17917+
segments: Some(vec![]),
17918+
time_dimensions: Some(vec![V1LoadRequestQueryTimeDimension {
17919+
dimension: "KibanaSampleDataEcommerce.order_date".to_string(),
17920+
granularity: None,
17921+
date_range: Some(json!(vec![
17922+
"2024-02-01".to_string(),
17923+
"2024-02-29".to_string(),
17924+
])),
17925+
}]),
17926+
order: Some(vec![]),
17927+
filters: Some(vec![
17928+
V1LoadRequestQueryFilterItem {
17929+
member: Some("KibanaSampleDataEcommerce.id".to_string()),
17930+
operator: Some("notEquals".to_string()),
17931+
values: Some(vec!["0".to_string()]),
17932+
or: None,
17933+
and: None,
17934+
},
17935+
V1LoadRequestQueryFilterItem {
17936+
member: Some("KibanaSampleDataEcommerce.customer_gender".to_string()),
17937+
operator: Some("set".to_string()),
17938+
values: None,
17939+
or: None,
17940+
and: None,
17941+
},
17942+
V1LoadRequestQueryFilterItem {
17943+
member: Some("KibanaSampleDataEcommerce.count".to_string()),
17944+
operator: Some("gt".to_string()),
17945+
values: Some(vec!["0".to_string()]),
17946+
or: None,
17947+
and: None,
17948+
},
17949+
]),
17950+
..Default::default()
17951+
}
17952+
)
17953+
}
1788617954
}

rust/cubesql/cubesql/src/compile/rewrite/rules/filters.rs

Lines changed: 72 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1773,6 +1773,70 @@ impl RewriteRules for FilterRules {
17731773
"?filter_aliases",
17741774
),
17751775
),
1776+
// The filter set above may be inverted, let's account for that as well
1777+
rewrite(
1778+
"extract-trunc-year-and-month-equals-reverse",
1779+
filter_replacer(
1780+
binary_expr(
1781+
binary_expr(
1782+
self.fun_expr(
1783+
"Trunc",
1784+
vec![self.fun_expr(
1785+
"DatePart",
1786+
vec![literal_string("year"), column_expr("?column")],
1787+
)],
1788+
),
1789+
"=",
1790+
literal_expr("?year"),
1791+
),
1792+
"AND",
1793+
binary_expr(
1794+
self.fun_expr(
1795+
"Trunc",
1796+
vec![self.fun_expr(
1797+
"DatePart",
1798+
vec![literal_string("month"), column_expr("?column")],
1799+
)],
1800+
),
1801+
"=",
1802+
literal_expr("?month"),
1803+
),
1804+
),
1805+
"?alias_to_cube",
1806+
"?members",
1807+
"?filter_aliases",
1808+
),
1809+
filter_replacer(
1810+
binary_expr(
1811+
binary_expr(
1812+
self.fun_expr(
1813+
"Trunc",
1814+
vec![self.fun_expr(
1815+
"DatePart",
1816+
vec![literal_string("month"), column_expr("?column")],
1817+
)],
1818+
),
1819+
"=",
1820+
literal_expr("?month"),
1821+
),
1822+
"AND",
1823+
binary_expr(
1824+
self.fun_expr(
1825+
"Trunc",
1826+
vec![self.fun_expr(
1827+
"DatePart",
1828+
vec![literal_string("year"), column_expr("?column")],
1829+
)],
1830+
),
1831+
"=",
1832+
literal_expr("?year"),
1833+
),
1834+
),
1835+
"?alias_to_cube",
1836+
"?members",
1837+
"?filter_aliases",
1838+
),
1839+
),
17761840
// When the filter set above is paired with other filters, it needs to be
17771841
// regrouped for the above rewrite rule to match
17781842
rewrite(
@@ -1787,11 +1851,11 @@ impl RewriteRules for FilterRules {
17871851
"Trunc",
17881852
vec![self.fun_expr(
17891853
"DatePart",
1790-
vec![literal_string("month"), column_expr("?column")],
1854+
vec![literal_expr("?gran1"), column_expr("?column")],
17911855
)],
17921856
),
17931857
"=",
1794-
literal_expr("?month"),
1858+
literal_expr("?val1"),
17951859
),
17961860
),
17971861
"AND",
@@ -1800,11 +1864,11 @@ impl RewriteRules for FilterRules {
18001864
"Trunc",
18011865
vec![self.fun_expr(
18021866
"DatePart",
1803-
vec![literal_string("year"), column_expr("?column")],
1867+
vec![literal_expr("?gran2"), column_expr("?column")],
18041868
)],
18051869
),
18061870
"=",
1807-
literal_expr("?year"),
1871+
literal_expr("?val2"),
18081872
),
18091873
),
18101874
"?alias_to_cube",
@@ -1821,23 +1885,23 @@ impl RewriteRules for FilterRules {
18211885
"Trunc",
18221886
vec![self.fun_expr(
18231887
"DatePart",
1824-
vec![literal_string("month"), column_expr("?column")],
1888+
vec![literal_expr("?gran1"), column_expr("?column")],
18251889
)],
18261890
),
18271891
"=",
1828-
literal_expr("?month"),
1892+
literal_expr("?val1"),
18291893
),
18301894
"AND",
18311895
binary_expr(
18321896
self.fun_expr(
18331897
"Trunc",
18341898
vec![self.fun_expr(
18351899
"DatePart",
1836-
vec![literal_string("year"), column_expr("?column")],
1900+
vec![literal_expr("?gran2"), column_expr("?column")],
18371901
)],
18381902
),
18391903
"=",
1840-
literal_expr("?year"),
1904+
literal_expr("?val2"),
18411905
),
18421906
),
18431907
),

0 commit comments

Comments
 (0)