Problem
date_trunc(granularity, ts) on a timezone-aware ts column is much slower than on a timezone-naive column, even when the timezone is a fixed UTC offset (+00:00, +05:30, ...) where no DST is involved.
The fast arithmetic path in date_trunc is gated on the timezone being absent (parsed_tz.is_none()), so any timezone-aware input — including UTC and other fixed offsets — falls into the per-value chrono DateTime<Tz> conversion path, even though a fixed offset truncates identically to a timezone-naive value shifted by that offset.
Additionally, the chrono path eagerly allocates a DataFusionError per value via ok_or(exec_datafusion_err!(...)) even on the success path.
Proposal
Detect fixed-offset timezones (same grammar arrow uses: ±HH, ±HHMM, ±HH:MM, plus UTC) and route them through the existing integer paths: truncate_tz(v) == truncate_naive(v + offset) - offset. Keep the per-value chrono path only for named IANA timezones (DST), and use lazy ok_or_else error construction in that path.
Problem
date_trunc(granularity, ts)on a timezone-awaretscolumn is much slower than on a timezone-naive column, even when the timezone is a fixed UTC offset (+00:00,+05:30, ...) where no DST is involved.The fast arithmetic path in
date_truncis gated on the timezone being absent (parsed_tz.is_none()), so any timezone-aware input — including UTC and other fixed offsets — falls into the per-value chronoDateTime<Tz>conversion path, even though a fixed offset truncates identically to a timezone-naive value shifted by that offset.Additionally, the chrono path eagerly allocates a
DataFusionErrorper value viaok_or(exec_datafusion_err!(...))even on the success path.Proposal
Detect fixed-offset timezones (same grammar arrow uses:
±HH,±HHMM,±HH:MM, plusUTC) and route them through the existing integer paths:truncate_tz(v) == truncate_naive(v + offset) - offset. Keep the per-value chrono path only for named IANA timezones (DST), and use lazyok_or_elseerror construction in that path.