Skip to content

Commit 2bca186

Browse files
authored
[fix] Add type coercion from NULL to Interval to make date_bin more postgres compatible (apache#20499) (#89)
## Which issue does this PR close? <!-- We generally require a GitHub issue to be filed for all bug fixes and enhancements and this helps us generate change logs for our releases. You can link an issue to this PR using the GitHub syntax. For example `Closes apache#123` indicates that this PR will close issue apache#123. --> - Closes apache#20502 ## Rationale for this change The following query is failing with the following error: `SELECT date_bin(NULL, TIMESTAMP '2023-01-01 12:30:00', TIMESTAMP '2023-01-01 12:00:00') ` `Error: Error during planning: Failed to coerce arguments to satisfy a call to 'date_bin' function: coercion from Null, Timestamp(ns), Timestamp(ns) to the signature OneOf([....])` ## What changes are included in this PR? Fix `date_bin(NULL, ...)` to return `NULL` instead of a planning error by allowing Nulls to coerce to Interva. ## Are these changes tested? I added a sqllogictest case to verify the query executes and returns `NULL`. ## Are there any user-facing changes? <!-- If there are user-facing changes then we may require documentation to be updated before approving the PR. --> <!-- If there are any breaking changes to public APIs, please add the `api change` label. --> Yes, previously `date_bin(NULL, ...) `returned a planning error. It now returns NULL. (cherry picked from commit e937cad)
1 parent 7ed98ff commit 2bca186

3 files changed

Lines changed: 19 additions & 1 deletion

File tree

datafusion/expr/src/type_coercion/functions.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -873,7 +873,7 @@ fn coerced_from<'a>(
873873
Timestamp(TimeUnit::Nanosecond, None),
874874
Null | Timestamp(_, None) | Date32 | Utf8 | LargeUtf8,
875875
) => Some(type_into.clone()),
876-
(Interval(_), Utf8 | LargeUtf8) => Some(type_into.clone()),
876+
(Interval(_), Null | Utf8 | LargeUtf8) => Some(type_into.clone()),
877877
// We can go into a Utf8View from a Utf8 or LargeUtf8
878878
(Utf8View, Utf8 | LargeUtf8 | Null) => Some(type_into.clone()),
879879
// Any type can be coerced into strings

datafusion/functions/src/datetime/date_bin.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,12 @@ fn date_bin_impl(
392392
origin: &ColumnarValue,
393393
) -> Result<ColumnarValue> {
394394
let stride = match stride {
395+
ColumnarValue::Scalar(s) if s.is_null() => {
396+
// NULL stride -> NULL result (standard SQL NULL propagation)
397+
return Ok(ColumnarValue::Scalar(ScalarValue::try_from(
398+
array.data_type(),
399+
)?));
400+
}
395401
ColumnarValue::Scalar(ScalarValue::IntervalDayTime(Some(v))) => {
396402
let (days, ms) = IntervalDayTimeType::to_parts(*v);
397403
let nanos = (TimeDelta::try_days(days as i64).unwrap()

datafusion/sqllogictest/test_files/datetime/timestamps.slt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -771,6 +771,18 @@ select to_timestamp_seconds(cast (1 as int));
771771
## test date_bin function
772772
##########
773773

774+
# NULL stride should return NULL, not a planning error
775+
query P
776+
SELECT date_bin(NULL, TIMESTAMP '2023-01-01 12:30:00', TIMESTAMP '2023-01-01 12:00:00')
777+
----
778+
NULL
779+
780+
# NULL stride should return NULL, not a planning error
781+
query P
782+
SELECT date_bin(NULL, TIMESTAMP '2023-01-01 12:30:00')
783+
----
784+
NULL
785+
774786
# invalid second arg type
775787
query error
776788
SELECT DATE_BIN(INTERVAL '0 second', 25, TIMESTAMP '1970-01-01T00:00:00Z')

0 commit comments

Comments
 (0)