Describe the bug
When datafusion.execution.time_zone is set, to_timestamp() on a string input declares a
return type of Timestamp(ns, <tz>) but produces an array of Timestamp(ns, None). The
declared type and the produced array disagree, so any plan that materializes the column
fails at execution. Planning succeeds — EXPLAIN returns a plan for both queries below.
To Reproduce
datafusion-cli 55.0.0:
SET datafusion.execution.time_zone = 'UTC';
SELECT to_timestamp(s) AS v FROM (VALUES ('2026-01-01T00:00:00')) AS t(s);
Error: Arrow error: Invalid argument error: column types must match schema types,
expected Timestamp(ns, "UTC") but found Timestamp(ns) at column index 0
Not specific to UTC:
SET datafusion.execution.time_zone = 'America/New_York';
SELECT to_timestamp(s) AS v FROM (VALUES ('2026-01-01T00:00:00')) AS t(s);
-- expected Timestamp(ns, "America/New_York") but found Timestamp(ns) at column index 0
A second symptom: because the planner trusts the declared type, it inserts no coercion
before comparing against another timezone-aware value, so the comparison reaches the Arrow
kernel with mismatched types:
SET datafusion.execution.time_zone = 'UTC';
SELECT to_timestamp(concat('2026-01-01T00:00:0', (value % 10)::text)) <= now() AS cmp
FROM generate_series(1, 3) AS t(value);
Error: Arrow error: Invalid argument error:
Invalid comparison operation: Timestamp(ns) <= Timestamp(ns, "UTC")
Unaffected, for contrast:
- Numeric input:
to_timestamp(1767225600) returns Timestamp(ns, "UTC"); declared and
actual agree.
- Default config (
datafusion.execution.time_zone unset): declared is Timestamp(ns, None)
and matches the array, so nothing fails.
Expected behavior
to_timestamp on a string input should produce an array annotated with the execution
timezone, matching what return_type advertises.
return_type returns Timestamp(Nanosecond, self.timezone.clone()), and the string branch
does receive the configured timezone (it is passed into the parse helper). The gap appears
to be that the resulting array is not annotated with it.
Additional context
Reproduced on datafusion-cli 54.0.0 and 55.0.0.
Related:
Describe the bug
When
datafusion.execution.time_zoneis set,to_timestamp()on a string input declares areturn type of
Timestamp(ns, <tz>)but produces an array ofTimestamp(ns, None). Thedeclared type and the produced array disagree, so any plan that materializes the column
fails at execution. Planning succeeds —
EXPLAINreturns a plan for both queries below.To Reproduce
datafusion-cli 55.0.0:
Not specific to UTC:
A second symptom: because the planner trusts the declared type, it inserts no coercion
before comparing against another timezone-aware value, so the comparison reaches the Arrow
kernel with mismatched types:
Unaffected, for contrast:
to_timestamp(1767225600)returnsTimestamp(ns, "UTC"); declared andactual agree.
datafusion.execution.time_zoneunset): declared isTimestamp(ns, None)and matches the array, so nothing fails.
Expected behavior
to_timestampon a string input should produce an array annotated with the executiontimezone, matching what
return_typeadvertises.return_typereturnsTimestamp(Nanosecond, self.timezone.clone()), and the string branchdoes receive the configured timezone (it is passed into the parse helper). The gap appears
to be that the resulting array is not annotated with it.
Additional context
Reproduced on datafusion-cli 54.0.0 and 55.0.0.
Related:
to_timestamprespectdatafusion.execution.time_zone.to_timestamp_*discards the timezone of already-timezone-aware inputs #23841 — a separate issue in the same family from Respect execution timezone in to_timestamp and related functions #19078 (already-zoned inputs havingtheir timezone discarded).
nowaware of execution timezone #17993 / fix: Use dynamic timezone in now() function for accurate timestamp #18017 — the equivalent change fornow(), which reads the config at executiontime rather than capturing it.
to_timestampbehaves consistently with PostgreSQL #13351 — umbrella issue for PostgreSQL-consistentto_timestampsemantics.from_unixtime.