Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Duration vs Interval comparisons and Interval as LHS #11876

Merged
merged 2 commits into from
Aug 8, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
4 changes: 3 additions & 1 deletion datafusion/expr/src/type_coercion/binary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1123,7 +1123,9 @@ fn temporal_coercion(lhs_type: &DataType, rhs_type: &DataType) -> Option<DataTyp
use arrow::datatypes::TimeUnit::*;

match (lhs_type, rhs_type) {
(Interval(_), Interval(_)) => Some(Interval(MonthDayNano)),
(Interval(_) | Duration(_), Interval(_) | Duration(_)) => {
Some(Interval(MonthDayNano))
}
(Date64, Date32) | (Date32, Date64) => Some(Date64),
(Timestamp(_, None), Date64) | (Date64, Timestamp(_, None)) => {
Some(Timestamp(Nanosecond, None))
Expand Down
6 changes: 6 additions & 0 deletions datafusion/sql/src/expr/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,12 @@ impl<'a, S: ContextProvider> SqlToRel<'a, S> {
let df_op = match op {
BinaryOperator::Plus => Operator::Plus,
BinaryOperator::Minus => Operator::Minus,
BinaryOperator::Eq => Operator::Eq,
BinaryOperator::NotEq => Operator::NotEq,
BinaryOperator::Gt => Operator::Gt,
BinaryOperator::GtEq => Operator::GtEq,
BinaryOperator::Lt => Operator::Lt,
BinaryOperator::LtEq => Operator::LtEq,
_ => {
return not_impl_err!("Unsupported interval operator: {op:?}");
}
Expand Down
31 changes: 31 additions & 0 deletions datafusion/sql/tests/cases/plan_to_sql.rs
Original file line number Diff line number Diff line change
Expand Up @@ -549,3 +549,34 @@ fn test_pretty_roundtrip() -> Result<()> {

Ok(())
}

fn sql_round_trip(query: &str, expect: &str) {
let statement = Parser::new(&GenericDialect {})
.try_with_sql(query)
.unwrap()
.parse_statement()
.unwrap();

let context = MockContextProvider::default();
let sql_to_rel = SqlToRel::new(&context);
let plan = sql_to_rel.sql_statement_to_plan(statement).unwrap();

let roundtrip_statement = plan_to_sql(&plan).unwrap();
assert_eq!(roundtrip_statement.to_string(), expect);
}

#[test]
fn test_interval_lhs_eq() {
sql_round_trip(
"select interval '2 seconds' = interval '2 seconds'",
"SELECT (INTERVAL '0 YEARS 0 MONS 0 DAYS 0 HOURS 0 MINS 2.000000000 SECS' = INTERVAL '0 YEARS 0 MONS 0 DAYS 0 HOURS 0 MINS 2.000000000 SECS')",
);
}

#[test]
fn test_interval_lhs_lt() {
sql_round_trip(
"select interval '2 seconds' < interval '2 seconds'",
"SELECT (INTERVAL '0 YEARS 0 MONS 0 DAYS 0 HOURS 0 MINS 2.000000000 SECS' < INTERVAL '0 YEARS 0 MONS 0 DAYS 0 HOURS 0 MINS 2.000000000 SECS')",
);
}
37 changes: 37 additions & 0 deletions datafusion/sqllogictest/test_files/timestamps.slt
Original file line number Diff line number Diff line change
Expand Up @@ -3109,6 +3109,43 @@ SELECT * FROM VALUES
2024-02-01T08:00:00Z
2023-12-31T23:00:00Z

# interval vs. duration comparison
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might also be worth adding tests (could be in a follow on PR) for the other operators enabled in this PR
<=, =, !=, >, and >=

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added all cases here.

query B
select (now() - now()) < interval '1 seconds';
----
true

query B
select arrow_cast(123, 'Duration(Nanosecond)') < interval '200 nanoseconds';
----
true

query B
select arrow_cast(123, 'Duration(Nanosecond)') < interval '100 nanoseconds';
----
false

query B
select arrow_cast(123, 'Duration(Nanosecond)') < interval '1 seconds';
----
true

query B
select interval '1 seconds' < arrow_cast(123, 'Duration(Nanosecond)')
----
false

# interval as LHS
query B
select interval '2 seconds' = interval '2 seconds';
----
true

query B
select interval '1 seconds' < interval '2 seconds';
----
true

statement ok
drop table t;

Expand Down