This is an automated email from the ASF dual-hosted git repository.
alamb pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/datafusion.git
The following commit(s) were added to refs/heads/main by this push:
new ecd9f36628 FIX : Incorrect NULL handling in BETWEEN expression (#14007)
ecd9f36628 is described below
commit ecd9f3662865f67fb710f323e903fa623e33e2d6
Author: Namgung Chan <[email protected]>
AuthorDate: Mon Jan 6 03:06:00 2025 +0900
FIX : Incorrect NULL handling in BETWEEN expression (#14007)
* submodule update
* FIX : Incorrect NULL handling in BETWEEN expression
* Revert "submodule update"
This reverts commit 72431aadeaf33a27775a88c41931572a0b66bae3.
* fix incorrect unit test
* move sqllogictest to expr
---
datafusion/optimizer/src/analyzer/type_coercion.rs | 15 +++++++++++++--
datafusion/optimizer/tests/optimizer_integration.rs | 5 +++--
datafusion/sqllogictest/test_files/expr.slt | 17 +++++++++++++++++
3 files changed, 33 insertions(+), 4 deletions(-)
diff --git a/datafusion/optimizer/src/analyzer/type_coercion.rs
b/datafusion/optimizer/src/analyzer/type_coercion.rs
index 89dd4ca60a..70bcd553a9 100644
--- a/datafusion/optimizer/src/analyzer/type_coercion.rs
+++ b/datafusion/optimizer/src/analyzer/type_coercion.rs
@@ -426,7 +426,7 @@ impl TreeNodeRewriter for TypeCoercionRewriter<'_> {
))
})?;
let high_type = high.get_type(self.schema)?;
- let high_coerced_type = comparison_coercion(&expr_type,
&low_type)
+ let high_coerced_type = comparison_coercion(&expr_type,
&high_type)
.ok_or_else(|| {
DataFusionError::Internal(format!(
"Failed to coerce types {expr_type} and
{high_type} in BETWEEN expression"
@@ -1458,7 +1458,7 @@ mod test {
let empty = empty_with_type(Utf8);
let plan = LogicalPlan::Filter(Filter::try_new(expr, empty)?);
let expected =
- "Filter: a BETWEEN Utf8(\"2002-05-08\") AND
CAST(CAST(Utf8(\"2002-05-08\") AS Date32) + IntervalYearMonth(\"1\") AS Utf8)\
+ "Filter: CAST(a AS Date32) BETWEEN CAST(Utf8(\"2002-05-08\") AS
Date32) AND CAST(Utf8(\"2002-05-08\") AS Date32) + IntervalYearMonth(\"1\")\
\n EmptyRelation";
assert_analyzed_plan_eq(Arc::new(TypeCoercion::new()), plan, expected)
}
@@ -1480,6 +1480,17 @@ mod test {
assert_analyzed_plan_eq(Arc::new(TypeCoercion::new()), plan, expected)
}
+ #[test]
+ fn between_null() -> Result<()> {
+ let expr = lit(ScalarValue::Null).between(lit(ScalarValue::Null),
lit(2i64));
+ let empty = empty();
+ let plan = LogicalPlan::Filter(Filter::try_new(expr, empty)?);
+ let expected =
+ "Filter: CAST(NULL AS Int64) BETWEEN CAST(NULL AS Int64) AND
Int64(2)\
+ \n EmptyRelation";
+ assert_analyzed_plan_eq(Arc::new(TypeCoercion::new()), plan, expected)
+ }
+
#[test]
fn is_bool_for_type_coercion() -> Result<()> {
// is true
diff --git a/datafusion/optimizer/tests/optimizer_integration.rs
b/datafusion/optimizer/tests/optimizer_integration.rs
index 2361679857..29fac5cc3d 100644
--- a/datafusion/optimizer/tests/optimizer_integration.rs
+++ b/datafusion/optimizer/tests/optimizer_integration.rs
@@ -76,8 +76,9 @@ fn subquery_filter_with_cast() -> Result<()> {
\n SubqueryAlias: __scalar_sq_1\
\n Aggregate: groupBy=[[]], aggr=[[avg(CAST(test.col_int32 AS
Float64))]]\
\n Projection: test.col_int32\
- \n Filter: test.col_utf8 >= Utf8(\"2002-05-08\") AND
test.col_utf8 <= Utf8(\"2002-05-13\")\
- \n TableScan: test projection=[col_int32, col_utf8]";
+ \n Filter: __common_expr_5 >= Date32(\"2002-05-08\") AND
__common_expr_5 <= Date32(\"2002-05-13\")\
+ \n Projection: CAST(test.col_utf8 AS Date32) AS
__common_expr_5, test.col_int32\
+ \n TableScan: test projection=[col_int32, col_utf8]";
assert_eq!(expected, format!("{plan}"));
Ok(())
}
diff --git a/datafusion/sqllogictest/test_files/expr.slt
b/datafusion/sqllogictest/test_files/expr.slt
index 577c7ede90..1647d61bf7 100644
--- a/datafusion/sqllogictest/test_files/expr.slt
+++ b/datafusion/sqllogictest/test_files/expr.slt
@@ -1963,3 +1963,20 @@ drop table t;
statement ok
set datafusion.sql_parser.dialect = 'Generic';
+
+# test between expression with null
+query I
+select 1 where null between null and null;
+----
+
+query T
+select 'A' where null between null and null;
+----
+
+query I
+select 1 where null between null and 2;
+----
+
+query T
+select 'A' where null between 2 and null;
+---
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]