Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 41 additions & 1 deletion rust/cubesql/cubesql/src/compile/engine/df/wrapper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crate::{
extract_exprlist_from_groupping_set,
rules::{
filters::Decimal,
utils::{DecomposedDayTime, DecomposedMonthDayNano},
utils::{granularity_str_to_int_order, DecomposedDayTime, DecomposedMonthDayNano},
},
LikeType, WrappedSelectType,
},
Expand Down Expand Up @@ -2520,6 +2520,46 @@ impl WrappedSelectNode {
))
}
Expr::ScalarFunction { fun, args } => {
if args.len() == 2 {
if let (
BuiltinScalarFunction::DateTrunc,
Expr::Literal(ScalarValue::Utf8(Some(granularity))),
Expr::Column(column),
Some(PushToCubeContext {
ungrouped_scan_node,
known_join_subqueries,
}),
) = (&fun, &args[0], &args[1], push_to_cube_context)
{
let granularity = granularity.to_ascii_lowercase();
// Security check to prevent SQL injection
if granularity_str_to_int_order(&granularity, Some(false)).is_some()
&& subqueries.get(&column.flat_name()).is_none()
&& !column
.relation
.as_ref()
.map(|relation| known_join_subqueries.contains(relation))
.unwrap_or(false)
{
if let Ok(MemberField::Member(regular_member)) =
Self::find_member_in_ungrouped_scan(ungrouped_scan_node, column)
{
// TODO: check if member is a time dimension
if let MemberField::Member(time_dimension_member) =
MemberField::time_dimension(
regular_member.member.clone(),
granularity,
)
{
return Ok((
format!("${{{}}}", time_dimension_member.field_name),
sql_query,
));
}
}
}
}
}
if let BuiltinScalarFunction::DatePart = &fun {
if args.len() >= 2 {
match &args[0] {
Expand Down
3 changes: 1 addition & 2 deletions rust/cubesql/cubesql/src/compile/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14572,8 +14572,7 @@ ORDER BY "source"."str0" ASC

let logical_plan = query_plan.as_logical_plan();
let sql = logical_plan.find_cube_scan_wrapped_sql().wrapped_sql.sql;
assert!(sql.contains("DATETIME_TRUNC("));
assert!(sql.contains("WEEK(MONDAY)"));
assert!(sql.contains(".week"));
}

#[tokio::test]
Expand Down
4 changes: 2 additions & 2 deletions rust/cubesql/cubesql/src/compile/test/test_wrapper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1657,11 +1657,11 @@ GROUP BY
let dimensions = request.dimensions.unwrap();
assert_eq!(dimensions.len(), 1);
let dimension = &dimensions[0];
assert!(dimension.contains("DATE_TRUNC"));
assert!(dimension.contains(".day"));
let segments = request.segments.unwrap();
assert_eq!(segments.len(), 1);
let segment = &segments[0];
assert!(segment.contains("DATE_TRUNC"));
assert!(segment.contains(".day"));
}

/// Aggregation with falsy filter should NOT get pushed to CubeScan with limit=0
Expand Down
Loading