Skip to content

Commit 9a73857

Browse files
authored
fix(databricks-jdbc-driver): Fix extract epoch from timestamp SQL Generation (#9160)
* fix(databricks-jdbc-driver): Fix extract epoch from timestamp SQL Generation * add tests
1 parent 0f9566e commit 9a73857

File tree

2 files changed

+52
-1
lines changed

2 files changed

+52
-1
lines changed

packages/cubejs-databricks-jdbc-driver/src/DatabricksQuery.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ export class DatabricksQuery extends BaseQuery {
197197
templates.functions.GREATEST = 'GREATEST({{ args_concat }})';
198198
templates.functions.TRUNC = 'CASE WHEN ({{ args[0] }}) >= 0 THEN FLOOR({{ args_concat }}) ELSE CEIL({{ args_concat }}) END';
199199
templates.expressions.timestamp_literal = 'from_utc_timestamp(\'{{ value }}\', \'UTC\')';
200-
templates.expressions.extract = 'EXTRACT({{ date_part }} FROM {{ expr }})';
200+
templates.expressions.extract = '{% if date_part|lower == "epoch" %}unix_timestamp({{ expr }}){% else %}EXTRACT({{ date_part }} FROM {{ expr }}){% endif %}';
201201
templates.expressions.interval_single_date_part = 'INTERVAL \'{{ num }}\' {{ date_part }}';
202202
templates.quotes.identifiers = '`';
203203
templates.quotes.escape = '``';

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

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15945,6 +15945,57 @@ LIMIT {{ limit }}{% endif %}"#.to_string(),
1594515945
assert!(sql.contains(" AS DECIMAL(38,10))"));
1594615946
}
1594715947

15948+
#[tokio::test]
15949+
async fn test_extract_epoch_pushdown() {
15950+
if !Rewriter::sql_push_down_enabled() {
15951+
return;
15952+
}
15953+
init_testing_logger();
15954+
15955+
let query = "
15956+
SELECT LOWER(customer_gender),
15957+
MAX(CAST(FLOOR(EXTRACT(EPOCH FROM order_date) / 31536000) AS bigint)) AS max_years
15958+
FROM KibanaSampleDataEcommerce
15959+
GROUP BY 1
15960+
";
15961+
15962+
// Generic
15963+
let query_plan =
15964+
convert_select_to_query_plan(query.to_string(), DatabaseProtocol::PostgreSQL).await;
15965+
15966+
let physical_plan = query_plan.as_physical_plan().await.unwrap();
15967+
println!(
15968+
"Physical plan: {}",
15969+
displayable(physical_plan.as_ref()).indent()
15970+
);
15971+
15972+
let logical_plan = query_plan.as_logical_plan();
15973+
let sql = logical_plan.find_cube_scan_wrapped_sql().wrapped_sql.sql;
15974+
assert!(sql.contains("EXTRACT(EPOCH"));
15975+
15976+
// Databricks
15977+
let query_plan = convert_select_to_query_plan_customized(
15978+
query.to_string(),
15979+
DatabaseProtocol::PostgreSQL,
15980+
vec![
15981+
("expressions/timestamp_literal".to_string(), "from_utc_timestamp('{{ value }}', 'UTC')".to_string()),
15982+
("expressions/extract".to_string(), "{% if date_part|lower == \"epoch\" %}unix_timestamp({{ expr }}){% else %}EXTRACT({{ date_part }} FROM {{ expr }}){% endif %}".to_string()),
15983+
],
15984+
)
15985+
.await;
15986+
15987+
let physical_plan = query_plan.as_physical_plan().await.unwrap();
15988+
println!(
15989+
"Physical plan: {}",
15990+
displayable(physical_plan.as_ref()).indent()
15991+
);
15992+
15993+
let logical_plan = query_plan.as_logical_plan();
15994+
let sql = logical_plan.find_cube_scan_wrapped_sql().wrapped_sql.sql;
15995+
assert!(!sql.contains("EXTRACT(EPOCH"));
15996+
assert!(sql.contains("unix_timestamp"));
15997+
}
15998+
1594815999
#[tokio::test]
1594916000
async fn test_push_down_to_grouped_query_with_filters() {
1595016001
if !Rewriter::sql_push_down_enabled() {

0 commit comments

Comments
 (0)