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
64 changes: 62 additions & 2 deletions src/query/src/range_select/plan_rewrite.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ use datafusion_expr::execution_props::ExecutionProps;
use datafusion_expr::expr::WildcardOptions;
use datafusion_expr::simplify::SimplifyContext;
use datafusion_expr::{
Aggregate, Analyze, Explain, Expr, ExprSchemable, Extension, LogicalPlan, LogicalPlanBuilder,
Projection,
Aggregate, Analyze, Cast, Explain, Expr, ExprSchemable, Extension, LogicalPlan,
LogicalPlanBuilder, Projection,
};
use datafusion_optimizer::simplify_expressions::ExprSimplifier;
use datatypes::prelude::ConcreteDataType;
Expand Down Expand Up @@ -548,19 +548,37 @@ fn have_range_in_exprs(exprs: &[Expr]) -> bool {
fn interval_only_in_expr(expr: &Expr) -> bool {
let mut all_interval = true;
let _ = expr.apply(|expr| {
// A cast expression for an interval.
if matches!(
expr,
Expr::Cast(Cast{
expr,
data_type: DataType::Interval(_)
}) if matches!(&**expr, Expr::Literal(ScalarValue::Utf8(_)))
) {
// Stop checking the sub `expr`,
// which is a `Utf8` type and has already been tested above.
return Ok(TreeNodeRecursion::Stop);
}

if !matches!(
expr,
Expr::Literal(ScalarValue::IntervalDayTime(_))
| Expr::Literal(ScalarValue::IntervalMonthDayNano(_))
| Expr::Literal(ScalarValue::IntervalYearMonth(_))
| Expr::BinaryExpr(_)
| Expr::Cast(Cast {
data_type: DataType::Interval(_),
..
})
) {
all_interval = false;
Ok(TreeNodeRecursion::Stop)
} else {
Ok(TreeNodeRecursion::Continue)
}
});

all_interval
}

Expand All @@ -569,6 +587,7 @@ mod test {

use std::error::Error;

use arrow::datatypes::IntervalUnit;
use catalog::memory::MemoryCatalogManager;
use catalog::RegisterTableRequest;
use common_catalog::consts::{DEFAULT_CATALOG_NAME, DEFAULT_SCHEMA_NAME};
Expand Down Expand Up @@ -844,6 +863,15 @@ mod test {
parse_duration_expr(&args, 0).unwrap(),
parse_duration("1y4w").unwrap()
);
// test cast expression
let args = vec![Expr::Cast(Cast {
expr: Box::new(Expr::Literal(ScalarValue::Utf8(Some("15 minutes".into())))),
data_type: DataType::Interval(IntervalUnit::MonthDayNano),
})];
assert_eq!(
parse_duration_expr(&args, 0).unwrap(),
parse_duration("15m").unwrap()
);
// test index err
assert!(parse_duration_expr(&args, 10).is_err());
// test evaluate expr
Expand Down Expand Up @@ -958,5 +986,37 @@ mod test {
)))),
});
assert!(interval_only_in_expr(&expr));

let expr = Expr::BinaryExpr(BinaryExpr {
left: Box::new(Expr::Cast(Cast {
expr: Box::new(Expr::Literal(ScalarValue::Utf8(Some(
"15 minute".to_string(),
)))),
data_type: DataType::Interval(IntervalUnit::MonthDayNano),
})),
op: Operator::Minus,
right: Box::new(Expr::Literal(ScalarValue::IntervalDayTime(Some(
IntervalDayTime::new(10, 0).into(),
)))),
});
assert!(interval_only_in_expr(&expr));

let expr = Expr::Cast(Cast {
expr: Box::new(Expr::BinaryExpr(BinaryExpr {
left: Box::new(Expr::Cast(Cast {
expr: Box::new(Expr::Literal(ScalarValue::Utf8(Some(
"15 minute".to_string(),
)))),
data_type: DataType::Interval(IntervalUnit::MonthDayNano),
})),
op: Operator::Minus,
right: Box::new(Expr::Literal(ScalarValue::IntervalDayTime(Some(
IntervalDayTime::new(10, 0).into(),
)))),
})),
data_type: DataType::Interval(IntervalUnit::MonthDayNano),
});

assert!(interval_only_in_expr(&expr));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ FROM (
UNION ALL
SELECT '[8.0]' AS v
)
WHERE vec_kth_elem(v, 0) > 2.0;
WHERE vec_kth_elem(v, 0) > 2.0 ORDER BY first_elem;

+----------------------+------------+
| v | first_elem |
Expand Down
2 changes: 1 addition & 1 deletion tests/cases/standalone/common/function/vector/vector.sql
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ FROM (
UNION ALL
SELECT '[8.0]' AS v
)
WHERE vec_kth_elem(v, 0) > 2.0;
WHERE vec_kth_elem(v, 0) > 2.0 ORDER BY first_elem;

SELECT vec_to_string(vec_subvector('[1.0,2.0,3.0,4.0,5.0]', 0, 3));

Expand Down
57 changes: 57 additions & 0 deletions tests/cases/standalone/common/range/interval.result
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,63 @@ SELECT ts, host, min(val) RANGE (INTERVAL '1' day) FROM host ALIGN (INTERVAL '1'
| 1971-01-02T00:00:00 | host2 | 6 |
+---------------------+-------+---------------------------------------------------------------------------------------------------------+

SELECT ts, host, min(val) RANGE ('1 day'::INTERVAL) FROM host ALIGN ('1 day'::INTERVAL) ORDER BY host, ts;

+---------------------+-------+-----------------------------------+
| ts | host | min(host.val) RANGE Utf8("1 day") |
+---------------------+-------+-----------------------------------+
| 1970-01-01T00:00:00 | host1 | 0 |
| 1971-01-02T00:00:00 | host1 | 2 |
| 1970-01-01T00:00:00 | host2 | 4 |
| 1971-01-02T00:00:00 | host2 | 6 |
+---------------------+-------+-----------------------------------+

SELECT ts, host, min(val) RANGE ('1 hour'::INTERVAL) FROM host ALIGN ('1 hour'::INTERVAL) ORDER BY host, ts;

+---------------------+-------+------------------------------------+
| ts | host | min(host.val) RANGE Utf8("1 hour") |
+---------------------+-------+------------------------------------+
| 1970-01-01T01:00:00 | host1 | 0 |
| 1970-01-01T02:00:00 | host1 | 1 |
| 1971-01-02T03:00:00 | host1 | 2 |
| 1971-01-02T04:00:00 | host1 | 3 |
| 1970-01-01T01:00:00 | host2 | 4 |
| 1970-01-01T02:00:00 | host2 | 5 |
| 1971-01-02T03:00:00 | host2 | 6 |
| 1971-01-02T04:00:00 | host2 | 7 |
+---------------------+-------+------------------------------------+

SELECT ts, host, min(val) RANGE ('30 minute'::INTERVAL + '30 minute'::INTERVAL) FROM host ALIGN ('30 minute'::INTERVAL + '30 minute'::INTERVAL) ORDER BY host, ts;

+---------------------+-------+-----------------------------------------------------------+
| ts | host | min(host.val) RANGE Utf8("30 minute") + Utf8("30 minute") |
+---------------------+-------+-----------------------------------------------------------+
| 1970-01-01T01:00:00 | host1 | 0 |
| 1970-01-01T02:00:00 | host1 | 1 |
| 1971-01-02T03:00:00 | host1 | 2 |
| 1971-01-02T04:00:00 | host1 | 3 |
| 1970-01-01T01:00:00 | host2 | 4 |
| 1970-01-01T02:00:00 | host2 | 5 |
| 1971-01-02T03:00:00 | host2 | 6 |
| 1971-01-02T04:00:00 | host2 | 7 |
+---------------------+-------+-----------------------------------------------------------+

--- Test nested cast, even though it is meaningless ----
SELECT ts, host, min(val) RANGE ((INTERVAL '1' hour)::INTERVAL) FROM host ALIGN ('1 hour'::INTERVAL::INTERVAL) ORDER BY host, ts;

+---------------------+-------+---------------------------------------------------------------------------------------------------------------------+
| ts | host | min(host.val) RANGE IntervalMonthDayNano("IntervalMonthDayNano { months: 0, days: 0, nanoseconds: 3600000000000 }") |
+---------------------+-------+---------------------------------------------------------------------------------------------------------------------+
| 1970-01-01T01:00:00 | host1 | 0 |
| 1970-01-01T02:00:00 | host1 | 1 |
| 1971-01-02T03:00:00 | host1 | 2 |
| 1971-01-02T04:00:00 | host1 | 3 |
| 1970-01-01T01:00:00 | host2 | 4 |
| 1970-01-01T02:00:00 | host2 | 5 |
| 1971-01-02T03:00:00 | host2 | 6 |
| 1971-01-02T04:00:00 | host2 | 7 |
+---------------------+-------+---------------------------------------------------------------------------------------------------------------------+

DROP TABLE host;

Affected Rows: 0
Expand Down
9 changes: 9 additions & 0 deletions tests/cases/standalone/common/range/interval.sql
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,13 @@ SELECT ts, host, min(val) RANGE (INTERVAL '1 year') FROM host ALIGN (INTERVAL '1

SELECT ts, host, min(val) RANGE (INTERVAL '1' day) FROM host ALIGN (INTERVAL '1' day) ORDER BY host, ts;

SELECT ts, host, min(val) RANGE ('1 day'::INTERVAL) FROM host ALIGN ('1 day'::INTERVAL) ORDER BY host, ts;

SELECT ts, host, min(val) RANGE ('1 hour'::INTERVAL) FROM host ALIGN ('1 hour'::INTERVAL) ORDER BY host, ts;

SELECT ts, host, min(val) RANGE ('30 minute'::INTERVAL + '30 minute'::INTERVAL) FROM host ALIGN ('30 minute'::INTERVAL + '30 minute'::INTERVAL) ORDER BY host, ts;

--- Test nested cast, even though it is meaningless ----
SELECT ts, host, min(val) RANGE ((INTERVAL '1' hour)::INTERVAL) FROM host ALIGN ('1 hour'::INTERVAL::INTERVAL) ORDER BY host, ts;

DROP TABLE host;