[fix](timestamptz) Report TIMESTAMPTZ as string to MySQL clients#63292
Conversation
TIMESTAMPTZ result rows are serialized as timezone-aware strings in the MySQL binary protocol. FE metadata used to advertise them as MYSQL_TYPE_DATETIME, so Connector/J decoded the length-encoded string bytes as a MySQL datetime binary payload and failed with Invalid length (32) for type TIMESTAMP when ResultSet.getString read a server-prepared result. Change PrimitiveType.toMysqlType() to return MYSQL_TYPE_STRING for TIMESTAMPTZ, adjust the field packet length and decimals to string semantics, and make the FE local binary result path write TIMESTAMPTZ through the string fallback instead of the datetime binary layout. BE serialization already uses push_timestamptz -> push_string, so no BE payload change is needed. Add a field-packet unit test and a regression suite that forces ServerPreparedStatement and compares direct ResultSet.getString(ts) with CAST(ts AS STRING). Verification: - ./run-fe-ut.sh --run org.apache.doris.mysql.MysqlSerializerVarbinaryTest - ./run-regression-test.sh --run -d datatype_p0/timestamptz -s test_timestamptz_jdbc_binary_protocol
|
Thank you for your contribution to Apache Doris. Please clearly describe your PR:
|
|
/review |
|
run buildall |
TPC-H: Total hot run time: 31294 ms |
TPC-DS: Total hot run time: 169528 ms |
FE Regression Coverage ReportIncrement line coverage |
|
/review |
There was a problem hiding this comment.
Review Summary
No blocking findings identified in the GitHub PR diff. The change is focused on making TIMESTAMPTZ MySQL metadata match the string payload used by result serialization, and the added unit/regression coverage targets that behavior.
Critical checkpoint conclusions:
- Goal and tests: The PR addresses the reported Connector/J binary protocol mismatch for TIMESTAMPTZ and includes FE metadata unit coverage plus a server-prepared JDBC regression test.
- Scope: The effective PR diff is small and focused on TIMESTAMPTZ MySQL protocol metadata/result serialization behavior.
- Concurrency and lifecycle: No new shared mutable state, locks, threads, or lifecycle-sensitive objects are introduced.
- Configuration and compatibility: No new config items or persisted storage formats are added. The protocol metadata change is behavior-changing but aligned with the existing string row payload.
- Parallel code paths: The relevant MysqlSerializer field metadata paths share the same helper methods; FE local binary rows now fall through to string serialization for TIMESTAMPTZ, matching BE row-buffer behavior.
- Test coverage: The new tests cover field packet metadata and a server-prepared JDBC getString path. I did not run tests locally in this review runner.
- Observability, transactions, FE-BE variables, data writes: Not applicable to this PR.
- User focus: No additional user-provided review focus was present.
The TIMESTAMPTZ MySQL metadata fix now reports TIMESTAMPTZ columns as string fields to JDBC clients. That makes direct TIMESTAMPTZ query results use Doris' timezone-aware textual representation instead of the MySQL driver's previous ISO-style timestamp formatting. Refresh the affected regression baselines for datatype TIMESTAMPTZ casts, date-function document cases, and the Paimon TIMESTAMPTZ external table case. The Paimon direct scanner outputs are aligned with the TeamCity external-regression real result and the corresponding cast output format. Verification: ./run-regression-test.sh --conf /tmp/doris-regression-conf-9737.groovy --run -d datatype_p0/timestamptz -s test_timestamptz_cast; ./run-regression-test.sh --conf /tmp/doris-regression-conf-9737.groovy --run -d datatype_p0/timestamptz -s test_cast_timestamptz; ./run-regression-test.sh --conf /tmp/doris-regression-conf-9737.groovy --run -d doc/sql-manual/sql-functions -s doc_date_functions_test. All passed.
|
run buildall |
TPC-H: Total hot run time: 31144 ms |
TPC-DS: Total hot run time: 169912 ms |
FE Regression Coverage ReportIncrement line coverage |
|
/review |
|
PR approved by at least one committer and no changes requested. |
|
PR approved by anyone and no changes requested. |
There was a problem hiding this comment.
Reviewed the GitHub PR diff (TIMESTAMPTZ MySQL/JDBC metadata and regression output updates). I did not find blocking issues.\n\nCritical checkpoint conclusions:\n- Goal/test coverage: The change reports TIMESTAMPTZ as string metadata and adds FE unit plus JDBC server-prepared regression coverage for ResultSet.getString; related baselines are updated.\n- Scope/focus: The actual PR diff is focused on TIMESTAMPTZ MySQL protocol metadata and expected output changes.\n- Concurrency/lifecycle: No new concurrency or lifecycle-sensitive code paths were introduced.\n- Configuration/compatibility: No new config items; this is a user-visible protocol metadata/output behavior change and the tests cover the intended new behavior.\n- Parallel paths: FE local binary result serialization and type metadata were both updated; BE already serializes TIMESTAMPTZ as strings.\n- Data correctness/transactions/persistence: No transaction, persistence, or storage visibility paths are changed.\n- Performance/observability: No meaningful performance impact or additional observability need identified.\n- User focus: No additional user-provided focus points were supplied.
TIMESTAMPTZ result rows are serialized as timezone-aware strings in the MySQL binary protocol. FE metadata used to advertise them as MYSQL_TYPE_DATETIME, so Connector/J decoded the length-encoded string bytes as a MySQL datetime binary payload and failed with Invalid length (32) for type TIMESTAMP when ResultSet.getString read a server-prepared result.
Change PrimitiveType.toMysqlType() to return MYSQL_TYPE_STRING for TIMESTAMPTZ, adjust the field packet length and decimals to string semantics, and make the FE local binary result path write TIMESTAMPTZ through the string fallback instead of the datetime binary layout. BE serialization already uses push_timestamptz -> push_string, so no BE payload change is needed.
Add a field-packet unit test and a regression suite that forces ServerPreparedStatement and compares direct ResultSet.getString(ts) with CAST(ts AS STRING).