Skip to content

Commit

Permalink
feat(cubesql): Support DATE with compound identifier
Browse files Browse the repository at this point in the history
  • Loading branch information
ovr committed Dec 17, 2021
1 parent 030c981 commit fa959d8
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 6 deletions.
4 changes: 2 additions & 2 deletions packages/cubejs-backend-native/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion rust/cubesql/src/compile/context.rs
Expand Up @@ -340,7 +340,7 @@ impl QueryContext {
)))
}
}
[ast::FunctionArg::Unnamed(ast::Expr::Identifier(_i))] => {
[ast::FunctionArg::Unnamed(_)] => {
let possible_dimension_name = self.unpack_identifier_from_arg(&f.args[0])?;

if let Some(r) = self.find_dimension_for_identifier(&possible_dimension_name) {
Expand Down
46 changes: 43 additions & 3 deletions rust/cubesql/src/compile/mod.rs
Expand Up @@ -304,6 +304,8 @@ fn str_to_date_function(f: &ast::Function) -> CompilationResult<CompiledExpressi
Ok(CompiledExpression::DateLiteral(parsed_date))
}

// DATE(expr)
// Extracts the date part of the date or datetime expression expr.
fn date_function(f: &ast::Function, ctx: &QueryContext) -> CompilationResult<CompiledExpression> {
let date_expr = match f.args.as_slice() {
[ast::FunctionArg::Unnamed(date_expr)] => date_expr,
Expand All @@ -315,7 +317,29 @@ fn date_function(f: &ast::Function, ctx: &QueryContext) -> CompilationResult<Com
}
};

Ok(compile_expression(&date_expr, &ctx)?)
let compiled = compile_expression(&date_expr, &ctx)?;
match compiled {
date @ CompiledExpression::DateLiteral(_) => Ok(date),
CompiledExpression::StringLiteral(ref input) => {
let parsed_date = Utc
.datetime_from_str(input.as_str(), "%Y-%m-%d %H:%M:%S.%f")
.map_err(|e| {
CompilationError::User(format!(
"Unable to parse {}, err: {}",
input,
e.to_string(),
))
})?;

Ok(CompiledExpression::DateLiteral(parsed_date))
}
_ => {
return Err(CompilationError::User(format!(
"Wrong type of argument (date), must be DateLiteral, actual: {:?}",
f
)))
}
}
}

fn now_function(f: &ast::Function) -> CompilationResult<CompiledExpression> {
Expand Down Expand Up @@ -1162,6 +1186,7 @@ fn compile_where(
)));
}
},
ast::Expr::Nested(nested) => compile_where_expression(nested, ctx)?,
inlist @ ast::Expr::InList { .. } => compile_where_expression(inlist, ctx)?,
isnull @ ast::Expr::IsNull { .. } => compile_where_expression(isnull, ctx)?,
isnotnull @ ast::Expr::IsNotNull { .. } => compile_where_expression(isnotnull, ctx)?,
Expand Down Expand Up @@ -2473,9 +2498,10 @@ mod tests {
// ["DATE(DATE_SUB(order_date, INTERVAL DAYOFWEEK(order_date) - 1 DAY))".to_string(), "week".to_string()],
["DATE(DATE_SUB(order_date, INTERVAL DAYOFMONTH(order_date) - 1 DAY))".to_string(), "month".to_string()],
["DATE(DATE_SUB(order_date, INTERVAL DAYOFYEAR(order_date) - 1 DAY))".to_string(), "year".to_string()],
// Simple DATE
["DATE(order_date)".to_string(), "day".to_string()],
// With escaping by `
["DATE(`order_date`)".to_string(), "day".to_string()],
["DATE(`KibanaSampleDataEcommerce`.`order_date`)".to_string(), "day".to_string()],
// With DATE_ADD
["DATE_ADD(DATE(order_date), INTERVAL HOUR(order_date) HOUR)".to_string(), "hour".to_string()],
["DATE_ADD(DATE(order_date), INTERVAL HOUR(`order_date`) HOUR)".to_string(), "hour".to_string()],
Expand Down Expand Up @@ -2527,7 +2553,7 @@ mod tests {
#[test]
fn test_where_filter_daterange() {
let to_check = vec![
// // Filter push down to TD (day)
// Filter push down to TD (day) - Superset
(
"COUNT(*), DATE(order_date) AS __timestamp".to_string(),
"order_date >= STR_TO_DATE('2021-08-31 00:00:00.000000', '%Y-%m-%d %H:%i:%s.%f') AND order_date < STR_TO_DATE('2021-09-07 00:00:00.000000', '%Y-%m-%d %H:%i:%s.%f')".to_string(),
Expand All @@ -2540,6 +2566,20 @@ mod tests {
])),
}])
),
// Filter push down to TD (day) - Superset
(
"COUNT(*), DATE(order_date) AS __timestamp".to_string(),
// Now replaced with exact date
"`KibanaSampleDataEcommerce`.`order_date` >= date(date_add(date('2021-09-30 00:00:00.000000'), INTERVAL -30 day)) AND `KibanaSampleDataEcommerce`.`order_date` < date('2021-09-07 00:00:00.000000')".to_string(),
Some(vec![V1LoadRequestQueryTimeDimension {
dimension: "KibanaSampleDataEcommerce.order_date".to_string(),
granularity: Some("day".to_string()),
date_range: Some(json!(vec![
"2021-08-31T00:00:00.000Z".to_string(),
"2021-09-06T23:59:59.999Z".to_string()
])),
}])
),
// Create a new TD (dateRange filter pushdown)
(
"COUNT(*)".to_string(),
Expand Down

0 comments on commit fa959d8

Please sign in to comment.