Skip to content

Commit 9d5794e

Browse files
authored
fix(cubesql): Improve Trino SQL push down compatibility (#9861)
Signed-off-by: Alex Qyoun-ae <[email protected]>
1 parent 54b1553 commit 9d5794e

File tree

4 files changed

+52
-1
lines changed

4 files changed

+52
-1
lines changed

packages/cubejs-schema-compiler/src/adapter/PrestodbQuery.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ export class PrestodbQuery extends BaseQuery {
136136
const templates = super.sqlTemplates();
137137
templates.functions.DATETRUNC = 'DATE_TRUNC({{ args_concat }})';
138138
templates.functions.DATEPART = 'DATE_PART({{ args_concat }})';
139+
templates.functions.DATEDIFF = 'DATE_DIFF(\'{{ date_part }}\', {{ args[1] }}, {{ args[2] }})';
139140
templates.functions.CURRENTDATE = 'CURRENT_DATE';
140141
delete templates.functions.PERCENTILECONT;
141142
templates.statements.select = '{% if ctes %} WITH \n' +

rust/cubesql/cubesql/src/compile/date_parser.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@ use crate::compile::engine::df::scan::DataFusionError;
22
use chrono::{NaiveDate, NaiveDateTime};
33

44
pub fn parse_date_str(s: &str) -> Result<NaiveDateTime, DataFusionError> {
5-
let parsed = NaiveDateTime::parse_from_str(s, "%Y-%m-%dT%H:%M:%S%.f")
5+
let parsed = NaiveDateTime::parse_from_str(s, "%Y-%m-%d %H:%M:%S")
66
.or_else(|_| NaiveDateTime::parse_from_str(s, "%Y-%m-%d %H:%M:%S%.f"))
77
.or_else(|_| NaiveDateTime::parse_from_str(s, "%Y-%m-%dT%H:%M:%S"))
8+
.or_else(|_| NaiveDateTime::parse_from_str(s, "%Y-%m-%d %H:%M:%S%.f UTC"))
9+
.or_else(|_| NaiveDateTime::parse_from_str(s, "%Y-%m-%dT%H:%M:%S%.f"))
810
.or_else(|_| NaiveDateTime::parse_from_str(s, "%Y-%m-%dT%H:%M:%S%.fZ"))
911
.or_else(|_| {
1012
NaiveDate::parse_from_str(s, "%Y-%m-%d").map(|date| date.and_hms_opt(0, 0, 0).unwrap())

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

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17267,4 +17267,51 @@ LIMIT {{ limit }}{% endif %}"#.to_string(),
1726717267
let sql = logical_plan.find_cube_scan_wrapped_sql().wrapped_sql.sql;
1726817268
assert!(sql.contains("CAST(1 AS VARCHAR)"));
1726917269
}
17270+
17271+
#[tokio::test]
17272+
async fn test_trino_datediff() {
17273+
if !Rewriter::sql_push_down_enabled() {
17274+
return;
17275+
}
17276+
init_testing_logger();
17277+
17278+
let query_plan = convert_select_to_query_plan_customized(
17279+
r#"
17280+
SELECT
17281+
KibanaSampleDataEcommerce.id,
17282+
KibanaSampleDataEcommerce.order_date,
17283+
KibanaSampleDataEcommerce.last_mod,
17284+
DATEDIFF(
17285+
day,
17286+
KibanaSampleDataEcommerce.order_date,
17287+
KibanaSampleDataEcommerce.last_mod
17288+
) as conv_date_diff,
17289+
COUNT(*)
17290+
FROM KibanaSampleDataEcommerce
17291+
WHERE (
17292+
KibanaSampleDataEcommerce.order_date > cast('2025-01-01T00:00:00.000' as timestamp)
17293+
AND KibanaSampleDataEcommerce.order_date < cast('2025-01-01T23:59:59.999' as timestamp)
17294+
AND KibanaSampleDataEcommerce.customer_gender = 'test'
17295+
)
17296+
GROUP BY 1, 2, 3, 4
17297+
"#
17298+
.to_string(),
17299+
DatabaseProtocol::PostgreSQL,
17300+
vec![(
17301+
"functions/DATEDIFF".to_string(),
17302+
"DATE_DIFF('{{ date_part }}', {{ args[1] }}, {{ args[2] }})".to_string(),
17303+
)],
17304+
)
17305+
.await;
17306+
17307+
let physical_plan = query_plan.as_physical_plan().await.unwrap();
17308+
println!(
17309+
"Physical plan: {}",
17310+
displayable(physical_plan.as_ref()).indent()
17311+
);
17312+
17313+
let logical_plan = query_plan.as_logical_plan();
17314+
let sql = logical_plan.find_cube_scan_wrapped_sql().wrapped_sql.sql;
17315+
assert!(sql.contains("DATE_DIFF('day', "));
17316+
}
1727017317
}

rust/cubesql/pg-srv/src/values/timestamp.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ impl FromProtocolValue for TimestampValue {
157157
// more formats, so let's align this with parse_date_str function from cubesql crate.
158158
let parsed_datetime = NaiveDateTime::parse_from_str(as_str, "%Y-%m-%d %H:%M:%S")
159159
.or_else(|_| NaiveDateTime::parse_from_str(as_str, "%Y-%m-%d %H:%M:%S%.f"))
160+
.or_else(|_| NaiveDateTime::parse_from_str(as_str, "%Y-%m-%d %H:%M:%S%.f UTC"))
160161
.or_else(|_| NaiveDateTime::parse_from_str(as_str, "%Y-%m-%dT%H:%M:%S"))
161162
.or_else(|_| NaiveDateTime::parse_from_str(as_str, "%Y-%m-%dT%H:%M:%S%.f"))
162163
.or_else(|_| NaiveDateTime::parse_from_str(as_str, "%Y-%m-%dT%H:%M:%S%.fZ"))

0 commit comments

Comments
 (0)