Skip to content

fix: preserve timezone-ness when creating predicates - #94

Merged
gabotechs merged 1 commit into
apache:mainfrom
BauplanLabs:colin/scalar-timestamptz
Nov 3, 2026
Merged

gabotechs merged 1 commit into
apache:mainfrom
BauplanLabs:colin/scalar-timestamptz

Conversation

@colinmarc

@colinmarc colinmarc commented Nov 2, 2026 •

Copy link
Copy Markdown
Contributor

Given a ScalarValue timestamp with a timezone attached, we should create Datum::timestamptz_*, instead of a naked Datum::timestamp. Note that the latter type doesn't actually store the time zone, only the equivalent UTC stamp.

See apache/iceberg-rust#3574 for context. Specifically, main here is depending on a conversion which would be removed in that PR (see this comment).

@gabotechs gabotechs left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Left some suggestions around comments and tests, but nothing blocking, so +1 from me. Thanks!

Comment thread crates/datafusion/src/read/predicate.rs Outdated
Comment on lines +465 to +467
//
// Note: for types with TZ, the timestamp value itself is always UTC,
// even if the timezone is not.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nit: maybe something like "Arrow stores tz-aware timestamps as UTC epoch values, the tz string only affects display, so they map straight to Iceberg timestamptz"? Reads a bit clearer to me. Might also be worth splitting this from the TimestampSecond/Millisecond note above, they're kind of unrelated now.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Updated.

CREATE TABLE default.default.test_timestamp_seconds (id INT NOT NULL, ts TIMESTAMP(0))

statement ok
SET datafusion.execution.time_zone = 'UTC'

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Could you add a short comment on why this is needed? I'm guessing it's so ::TIMESTAMPTZ ends up as +00:00. Also it sticks around for anything added to this file later, so maybe reset it at the end next to the DROP.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

It's confusing, but without it the CREATE TABLE ends up with a normal timestamp column, even with TIMESTAMP WITH TIME ZONE specified.

2

query TT
EXPLAIN SELECT id FROM default.default.test_timestamptz WHERE ts_us > '2023-01-05T00:00:00+00:00'::TIMESTAMPTZ

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can we also cover the mixed cases? e.g. ts_us > CAST('2023-01-05' AS TIMESTAMP) (tz column vs naive literal), and a naive TIMESTAMP column vs a ::TIMESTAMPTZ literal. Once the upstream conversion is gone a mismatched datum would fail to bind and I think the query would just error, so it'd be good to lock in that coercion either gives us a matching literal or skips pushdown.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done.

Given a `ScalarValue` timestamp with a timezone attached, we should
create `Datum::timestamptz_*`, instead of a naked `Datum::timestamp`.
Note that the latter type doesn't actually store the time zone, only the
equivalent UTC stamp.
@colinmarc
colinmarc force-pushed the colin/scalar-timestamptz branch from 0570418 to 379eb0d Compare November 2, 2026 17:07
@gabotechs

Copy link
Copy Markdown
Contributor

Thanks @colinmarc!

@gabotechs
gabotechs merged commit 256c4b7 into apache:main Nov 3, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants