You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[Bug] ArrowFlight SQL result automatically converts timezone naive date to UTC (which is wrong) #65741
I had searched in the issues and found no similar issues.
Version
When using arrow to execute sql:
SELECT CAST('2026-07-02 01:36:22.069504' AS DATETIME(6)) AS ts
What's Wrong?
The result is automatically converted to UTC.
2026-07-02 01:36:22.069504+00:00
What You Expected?
The result sould be
2026-07-02 01:36:22.069504
This is the wrong assumption. the original timestamp might be local timezone timestamp.
How to Reproduce?
Execute
SELECT CAST('2026-07-02 01:36:22.069504' AS DATETIME(6)) AS ts
in python:
import adbc_driver_flightsql.dbapi as flightsql
from adbc_driver_manager import DatabaseOptions
from q_secrets import get_connection_details
with connection.cursor() as cursor:
cursor.execute("SELECT CAST('2026-07-02 01:36:22.069504' AS DATETIME(6)) AS ts")
table = cursor.fetch_arrow_table()
Breakwater-GitHub-Analysis-Slot: slot_a66f91e21aeb
This content is generated by AI for reference only.
Initial assessment: this looks like a real Arrow Flight SQL type-mapping bug for DATETIMEV2, not only a Python client display issue.
I checked current upstream/master because the issue does not specify an affected Doris version. The relevant path is:
CAST(... AS DATETIME(6)) is a DATETIMEV2(6) result.
In be/src/format/arrow/arrow_row_batch.cpp, convert_to_arrow_type() currently handles TYPE_TIMESTAMPTZ and TYPE_DATETIMEV2 in the same branch and creates arrow::TimestampType(unit, timezone). The nearby TODO already notes that these types may need to be distinguished.
The Arrow Flight result sink builds that schema with state->timezone() in be/src/exec/operator/result_sink_operator.cpp, so the Arrow field receives non-empty timezone metadata.
DataTypeDateTimeV2SerDe::write_column_to_arrow() then reads timestamp_type->timezone() and, when it is non-empty, serializes the value using the session timezone. With a UTC session/default timezone, PyArrow/ADBC will naturally return a timezone-aware Python value such as 2026-07-02 01:36:22.069504+00:00.
That behavior is probably wrong for ordinary Doris DATETIME / DATETIMEV2: it is a timezone-naive wall-clock type, while an Arrow timestamp with timezone has instant semantics. The timezone-aware Arrow representation is appropriate for TIMESTAMPTZ, but should not be reused for DATETIMEV2.
Suggested fix direction:
Split TYPE_DATETIMEV2 and TYPE_TIMESTAMPTZ in Arrow schema conversion.
For TYPE_DATETIMEV2, emit an Arrow timestamp with the correct unit but without timezone metadata, or another explicitly timezone-naive representation.
Keep timezone-aware Arrow metadata for TYPE_TIMESTAMPTZ.
Add coverage that checks the Arrow schema, not only the rendered row values. The existing regression-test/suites/arrow_flight_sql_p0/test_select.groovy covers datetime(6) result values, but it appears to compare converted output and does not assert that the Arrow field timezone is empty.
Missing information that would help confirm the exact user-facing scope:
Doris build/version, since the issue body currently omits it.
The session value of @@time_zone when the query is run.
The exact printed Arrow field: line, plus PyArrow / ADBC driver versions.
Whether the same query through the MySQL protocol returns the expected timezone-naive text.
Activity
zclllyybb commentedon Jul 17, 2026
Breakwater-GitHub-Analysis-Slot: slot_a66f91e21aeb
This content is generated by AI for reference only.
Initial assessment: this looks like a real Arrow Flight SQL type-mapping bug for
DATETIMEV2, not only a Python client display issue.I checked current
upstream/masterbecause the issue does not specify an affected Doris version. The relevant path is:CAST(... AS DATETIME(6))is aDATETIMEV2(6)result.be/src/format/arrow/arrow_row_batch.cpp,convert_to_arrow_type()currently handlesTYPE_TIMESTAMPTZandTYPE_DATETIMEV2in the same branch and createsarrow::TimestampType(unit, timezone). The nearby TODO already notes that these types may need to be distinguished.state->timezone()inbe/src/exec/operator/result_sink_operator.cpp, so the Arrow field receives non-empty timezone metadata.DataTypeDateTimeV2SerDe::write_column_to_arrow()then readstimestamp_type->timezone()and, when it is non-empty, serializes the value using the session timezone. With a UTC session/default timezone, PyArrow/ADBC will naturally return a timezone-aware Python value such as2026-07-02 01:36:22.069504+00:00.That behavior is probably wrong for ordinary Doris
DATETIME/DATETIMEV2: it is a timezone-naive wall-clock type, while an Arrow timestamp with timezone has instant semantics. The timezone-aware Arrow representation is appropriate forTIMESTAMPTZ, but should not be reused forDATETIMEV2.Suggested fix direction:
TYPE_DATETIMEV2andTYPE_TIMESTAMPTZin Arrow schema conversion.TYPE_DATETIMEV2, emit an Arrow timestamp with the correct unit but without timezone metadata, or another explicitly timezone-naive representation.TYPE_TIMESTAMPTZ.regression-test/suites/arrow_flight_sql_p0/test_select.groovycoversdatetime(6)result values, but it appears to compare converted output and does not assert that the Arrow field timezone is empty.Missing information that would help confirm the exact user-facing scope:
@@time_zonewhen the query is run.Arrow field:line, plus PyArrow / ADBC driver versions.morningman commentedon Jul 17, 2026
link to #65615
wushilin commentedon Nov 7, 2026
Closing