Skip to content

Allow constant expressions in date_part - #23997

Draft
Adam-Alani wants to merge 2 commits into
apache:mainfrom
Adam-Alani:adam.alani/fix-date-part-constant-arguments
Draft

Allow constant expressions in date_part#23997
Adam-Alani wants to merge 2 commits into
apache:mainfrom
Adam-Alani:adam.alani/fix-date-part-constant-arguments

Conversation

@Adam-Alani

Copy link
Copy Markdown

Why

date_part currently determines its return field before constant folding runs, so a valid constant expression such as CAST('epoch' AS VARCHAR) is rejected because it is not a direct literal. This change is stacked on #22851, which makes the function's return type value-independent and PostgreSQL-compatible.

What

This allows foldable constant expressions in the first argument of date_part while preserving runtime validation that the evaluated value is a non-null scalar string. It adds regression coverage for a casted epoch argument and updates type expectations added since #22851 was opened.

How

Return-field inference now uses only the temporal argument's nullability and always reports Float64; it no longer inspects the unsimplified first argument. The normal expression simplifier can therefore fold casts and other constant expressions before execution, where the existing scalar-value validation still applies.

Validated with:

cargo test --test sqllogictests -p datafusion-sqllogictest -- datetime/date_part.slt

Depends on #22851.

`date_part` previously returned `Int32` for most parts (year, month, day,
hour, minute, second, etc.), `Int64` for `nanosecond`, and `Float64` for
`epoch`. This is inconsistent and disagrees with PostgreSQL, which is
defined to return `double precision` for `date_part` regardless of the
part being extracted:
https://www.postgresql.org/docs/current/functions-datetime.html

Change `DatePartFunc::return_field_from_args` to always advertise
`Float64`, and cast the kernel result to `Float64` at the end of
`invoke_with_args` (the underlying arrow kernels still produce
`Int32`/`Int64` for non-epoch parts; this is a no-op cast for `epoch`).

`preimage` is updated to also accept `Float64` literals so
`date_part('year', col) = 2024` still gets pushed down as a date range
after type coercion turns the `2024` literal into `Float64`.

The Spark `date_part` wrapper now wraps the simplified DataFusion call
in a cast back to `Int32` so that Spark-side behavior (and its existing
sqllogictests) are preserved.

Tests and docs updated:
- `datafusion/sqllogictest/test_files/datetime/date_part.slt`,
  `datetime/timestamps.slt`, `clickbench.slt`, `group_by.slt`
  switched from `query I[I...]` to `query R[R...]` for `date_part`
  outputs (and `arrow_typeof` results updated from `Int32`/`Int64`
  to `Float64`).
- `docs/source/user-guide/sql/scalar_functions.md` and
  `docs/source/user-guide/expressions.md` regenerated.
Defer first-argument value validation until execution now that the return type is value-independent, allowing casts and other foldable constants.
@github-actions github-actions Bot added documentation Improvements or additions to documentation sqllogictest SQL Logic Tests (.slt) functions Changes to functions implementation spark labels Jul 30, 2026
@Adam-Alani Adam-Alani changed the title [QECO-1569] Allow constant expressions in date_part Allow constant expressions in date_part Jul 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation functions Changes to functions implementation spark sqllogictest SQL Logic Tests (.slt)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant