Skip to content

[Bug] ArrowFlight SQL result automatically converts timezone naive date to UTC (which is wrong) #65741

Closed

Description

@wushilin

Search before asking

  • 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

details = get_connection_details("doris", flightsql=True)
connection = flightsql.connect(
uri=f"{details['driver']}://{details['hostname']}:{details['port']}",
db_kwargs={
DatabaseOptions.USERNAME.value: details["username"],
DatabaseOptions.PASSWORD.value: details["pwd"],
},
)

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()

field = table.schema.field("ts")
print("Arrow field:", field)
print("Field metadata:", field.metadata)
print("Value:", table["ts"].to_pylist())

connection.close()

Anything Else?

No response

Are you willing to submit PR?

  • Yes I am willing to submit a PR!

Code of Conduct

Activity

  1. zclllyybb commented on Jul 17, 2026

    @zclllyybb
    Contributor

    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.
  2. morningman commented on Jul 17, 2026

    @morningman
    Contributor

    link to #65615

  3. wushilin commented on Nov 7, 2026

    @wushilin
    Author

    Closing

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions