finished adding type aware parser for time and timstamp#37965
finished adding type aware parser for time and timstamp#37965manasagar wants to merge 5 commits intoapache:masterfrom
Conversation
terrymanu
left a comment
There was a problem hiding this comment.
Thanks for the effort to make the text protocol type-aware and for adding initial time-related tests—this is the right direction.
Change requests:
- Root cause still unresolved: the proxy returns java.sql.Timestamp, which still goes through each.toString() and keeps the .0 suffix. Issue #37437 remains.
- Time zone semantics are broken: the OffsetDateTime branch forces withOffsetSameInstant(UTC) and emits +00, diverging from PostgreSQL’s session time zone output and risking visible offsets.
- Trailing-zero handling is inconsistent: OffsetTime always pads to 6 decimals, so 10:00:00.0+05:30 becomes 10:00:00.000000+05:30; LocalTime/LocalDateTime precision and trimming still don’t align with PostgreSQL rules.
- Type detection: relying on instanceof misses the main Timestamp path from JDBC. The formatter should pick behavior based on column type, not just runtime class.
- Tests don’t cover the failing scenario (timestamp without fractional seconds) or timestamptz/timetz behavior, so the fix isn’t demonstrated and regressions aren’t guarded.
- Please keep ResultSetUtils untouched for this issue; the correct place to fix is the PostgreSQL text protocol formatter, not the generic JDBC conversion utilities.
Recommended next steps:
- In PostgreSQLDataRowPacket.writeTextValue, format timestamp/timestamptz/time/timetz per PostgreSQL text protocol: max 6 fractional digits, trim trailing zeros, preserve session time zone.
- Base formatting on column type, not only runtime instanceof, so Timestamp values are handled.
- Add tests for the reported case and for timestamptz/timetz outputs to prove the fix.
Please address these before we merge; happy to review the next revision.
274ff90 to
ee5134d
Compare
I have implemented the column value based type checking . |
terrymanu
left a comment
There was a problem hiding this comment.
Cannot merge yet.
Below is a ready-to-post English review comment:
Thanks for the update. I reviewed the latest version (head 3fd4977) and compared it with the previous CHANGES_REQUESTED items.
Merge Verdict: Not Mergeable
Reviewed Scope:
database/protocol/dialect/postgresql/src/main/java/org/apache/shardingsphere/database/protocol/postgresql/packet/command/query/PostgreSQLDataRowPacket.javadatabase/protocol/dialect/postgresql/src/test/java/org/apache/shardingsphere/database/protocol/postgresql/packet/command/query/PostgreSQLDataRowPacketTest.javaproxy/frontend/dialect/postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/query/simple/PostgreSQLComQueryExecutor.javaproxy/frontend/dialect/postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/query/extended/Portal.javaproxy/frontend/dialect/opengauss/src/main/java/org/apache/shardingsphere/proxy/frontend/opengauss/command/query/simple/OpenGaussComQueryExecutor.java
Compliance Gate: PASS
Rule ID: RULE-COD-062
Rule Source: CODE_OF_CONDUCT.md:62
Commands:
rg '\.java$' /tmp/pr37965_files_all.txt(exit 0)rg -nP '\([^)]*\bOptional<[^>]+>\s+\w+[^)]*\)' <changed_java_files>(exit 1, no matches)
Major issues:
- Type-domain mismatch (root cause still not reliably fixed):
columnTypescomes from JDBC types (QueryHeader.getColumnType()), but formatter branches compare PostgreSQL OIDs.- Evidence:
proxy/backend/dialect/postgresql/src/main/java/org/apache/shardingsphere/proxy/backend/postgresql/response/header/query/PostgreSQLQueryHeaderBuilder.java:41 - Evidence:
database/protocol/dialect/postgresql/src/main/java/org/apache/shardingsphere/database/protocol/postgresql/packet/command/query/PostgreSQLDataRowPacket.java:119 - This can bypass the new timestamp/time formatting paths and fall back to
toString().
- Potential NPE in extended-query execute path:
columnTypesis set indescribe()but used in row packet generation.- Evidence:
proxy/frontend/dialect/postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/query/extended/Portal.java:134 - Evidence:
database/protocol/dialect/postgresql/src/main/java/org/apache/shardingsphere/database/protocol/postgresql/packet/command/query/PostgreSQLDataRowPacket.java:81 - If execute runs without describe,
columnTypescan be null.
- TIMESTAMPTZ still forces UTC for
Timestamp:
- Evidence:
database/protocol/dialect/postgresql/src/main/java/org/apache/shardingsphere/database/protocol/postgresql/packet/command/query/PostgreSQLDataRowPacket.java:138 - This still conflicts with the prior request to preserve session time-zone semantics.
Status of previous CHANGES_REQUESTED items:
- Root cause (
Timestampformatting path): Not fixed - Time-zone semantics: Partially fixed
- Trailing-zero handling: Mostly fixed
- Column-type-based formatting: Partially fixed (implementation issue above)
- Tests for failing scenarios: Partially fixed (unit coverage improved, but real type path mismatch not covered)
- Keep
ResultSetUtilsuntouched: Fixed
Latest commit changes (3fd4977):
- Added column-type-aware formatting in
PostgreSQLDataRowPacket. - Added/expanded formatter tests in
PostgreSQLDataRowPacketTest. - Passed
columnTypesfrom PostgreSQL/openGauss query executors and portal to data row packet.
Please address the three blocking issues above, then I can re-review quickly.
|
@terrymanu sorry about the delay |
|
Currently failing because of the environment CI/ Cl not allowing systemdefault |
terrymanu
left a comment
There was a problem hiding this comment.
Thanks for the update and for addressing the JDBC type-domain mismatch in the latest head (999d519).
The direction is correct, but there are still merge blockers.
Merge Verdict: Not Mergeable
Please address the following before merge:
-
CI is still failing on the latest head.
- Failing check: CI
- Link: https://github.com/apache/shardingsphere/actions/runs/22060374783/job/63738841170
- We need all required checks green first.
-
Time zone semantics are still not stable for timestamptz/timetz formatting.
- Current code uses system default zone and current date:
- database/protocol/dialect/postgresql/src/main/java/org/apache/shardingsphere/database/protocol/postgresql/packet/command/query/PostgreSQLDataRowPacket.java:129
- database/protocol/dialect/postgresql/src/main/java/org/apache/shardingsphere/database/protocol/postgresql/packet/command/query/PostgreSQLDataRowPacket.java:141
- database/protocol/dialect/postgresql/src/main/java/org/apache/shardingsphere/database/protocol/postgresql/packet/command/query/PostgreSQLDataRowPacket.java:145
- This can vary by host timezone/DST and may diverge from session-timezone behavior.
- Please switch to session-timezone-aware formatting.
- Current code uses system default zone and current date:
-
There is a protocol consistency risk when columnTypes is shorter than data.
- Column count is written as data.size(), but the row loop breaks early if column types are exhausted:
- database/protocol/dialect/postgresql/src/main/java/org/apache/shardingsphere/database/protocol/postgresql/packet/command/query/PostgreSQLDataRowPacket.java:82
- database/protocol/dialect/postgresql/src/main/java/org/apache/shardingsphere/database/protocol/postgresql/packet/command/query/PostgreSQLDataRowPacket.java:90
- Please avoid early break and use a safe fallback type instead.
- Column count is written as data.size(), but the row loop breaks early if column types are exhausted:
-
Tests are still not mapped one-to-one with all new fix points.
- The new columnTypes propagation in simple/extended/openGauss paths is not fully validated with dedicated regression assertions.
- Please add targeted tests for:
- execute-before-describe path in Portal
- columnTypes/data size mismatch handling
- session-timezone output behavior for timestamptz/timetz
Once these are fixed and CI is green, I can re-review quickly.
terrymanu
left a comment
There was a problem hiding this comment.
Thanks for the update. I reviewed the latest head, and the overall direction is good, but there are still blockers before merge.
Merge Verdict: Not Mergeable
What is in the right direction
- The fix now targets the real root-cause path for Timestamp text formatting (.0 suffix), not only fallback logic.
- JDBC type-domain alignment and columnTypes propagation in simple/extended paths are improved.
- The previous execute-before-describe null-path risk is addressed.
- CI status for the latest head is green, which is a good step.
Change requests
- Please fix session timezone parsing logic before merge.
- Current timezone extraction uses ZoneId.getAvailableZoneIds().contains(tzName) in:
- proxy/frontend/dialect/postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/query/simple/PostgreSQLComQueryExecutor.java
- proxy/frontend/dialect/postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/query/extended/Portal.java
- proxy/frontend/dialect/opengauss/src/main/java/org/apache/shardingsphere/proxy/frontend/opengauss/command/query/simple/OpenGaussComQueryExecutor.java
- This rejects valid PostgreSQL-style offset values such as +05:30, and falls back to UTC, which can break TIMESTAMPTZ/TIMETZ semantics.
- Please parse timezone directly with safe fallback (including quoted values and offset forms), instead of filtering by available zone ID set.
- Please make the session-timezone source chain explicit and reliable.
- The current flow still does not fully prove that PostgreSQL/openGauss session timezone is consistently recorded and consumed for row formatting.
- Please either:
- complete the replay/record path for timezone variables, or
- switch to an existing authoritative session-timezone source in connection/session context.
- Also please add targeted regression tests for offset timezone values (for example +05:30) to prevent fallback-to-UTC regressions.
Newly introduced issue (needs fix or rollback)
- The new timezone extraction implementation introduced a compatibility regression risk by rejecting valid offset timezone values and defaulting to UTC.
- Please fix this behavior or roll back this part.
Please continue refining this PR. Once the above items are addressed, I can do a focused re-review quickly.
|
@terrymanu ## Update Summary This PR has been updated with significant enhancements in the latest commit ( Key Changes:
|
|
I have added seperate replay for both openGauss and postgres right now it only propogate timestamp due to the requirement |
terrymanu
left a comment
There was a problem hiding this comment.
Decision
- Merge Verdict: Not Mergeable
- Reviewed Scope: database/protocol/dialect/postgresql/.../PostgreSQLDataRowPacket.java, database/protocol/dialect/postgresql/.../PostgreSQLDataRowPacketTest.java, proxy/frontend/dialect/postgresql/.../PostgreSQLComQueryExecutor.java, proxy/frontend/dialect/
postgresql/.../Portal.java, proxy/frontend/dialect/opengauss/.../OpenGaussComQueryExecutor.java, proxy/backend/core/.../RequiredSessionVariableRecorder.java, new PostgreSQL/openGauss replay providers + their tests/resources. - Not Reviewed Scope: live PostgreSQL/openGauss end-to-end runtime behavior with real server/session timezone settings.
- Need Expert Review: Yes (PostgreSQL protocol/timezone semantics).
Positive direction is clear: the root .0 formatting path for Timestamp is directly addressed, CI is green, and targeted tests pass.
Major Issues
- TIMESTAMPTZ/TIMETZ session-timezone semantics are still not proven/correct on the real driver path.
- Evidence: OffsetDateTime is formatted directly without session-zone normalization in database/protocol/dialect/postgresql/src/main/java/org/apache/shardingsphere/database/protocol/postgresql/packet/command/query/PostgreSQLDataRowPacket.java:145.
- Evidence: session timezone is sourced only from replayed session vars in proxy/frontend/dialect/postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/query/simple/PostgreSQLComQueryExecutor.java:140, proxy/frontend/dialect/postgresql/
src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/query/extended/Portal.java:235, proxy/frontend/dialect/opengauss/src/main/java/org/apache/shardingsphere/proxy/frontend/opengauss/command/query/simple/OpenGaussComQueryExecutor.java:140. - Risk: PGJDBC docs say returned OffsetDateTime is UTC; output can stay UTC instead of session timezone.
- Recommendation: normalize tz values to session zone (or explicitly keep UTC with documented compatibility rationale) and prove with integration tests.
- Tz-branch routing depends on JDBC types that may not be emitted as expected by PGJDBC.
- Evidence: formatter branches rely on Types.TIMESTAMP_WITH_TIMEZONE/Types.TIME_WITH_TIMEZONE in database/protocol/dialect/postgresql/src/main/java/org/apache/shardingsphere/database/protocol/postgresql/packet/command/query/PostgreSQLDataRowPacket.java:129 and database/
protocol/dialect/postgresql/src/main/java/org/apache/shardingsphere/database/protocol/postgresql/packet/command/query/PostgreSQLDataRowPacket.java:141. - Evidence: upstream value loading falls back to generic getObject for non-covered JDBC types in database/connector/core/src/main/java/org/apache/shardingsphere/database/connector/core/resultset/ResultSetMapper.java:93.
- Inference from source: PGJDBC may still expose TIMESTAMPTZ metadata as Types.TIMESTAMP (issue #1766), which can bypass intended tz-specific formatting.
- Recommendation: add contract/integration tests that start from ResultSetMetaData + ResultSetMapper and assert final wire text for timestamptz/timetz.
Newly Introduced Risk
- Per-value timezone parsing in hot row-write path.
- Evidence: repeated zone parsing/checks in database/protocol/dialect/postgresql/src/main/java/org/apache/shardingsphere/database/protocol/postgresql/packet/command/query/PostgreSQLDataRowPacket.java:217 and database/protocol/dialect/postgresql/src/main/java/org/apache/
shardingsphere/database/protocol/postgresql/packet/command/query/PostgreSQLDataRowPacket.java:222. - Recommendation: parse/cache session ZoneId once per packet.
Multi-Round Comparison
- Fixed: column-types propagation + execute-before-describe null-path; CI now green.
- Partially fixed: timezone offset parsing/replay wiring.
- Unresolved: real-driver tz semantics for timestamptz/timetz.
- New risk: per-row zone parsing overhead.
|
Hi @manasagar |
Fixes #37437
Before committing this PR, I'm sure that I have checked the following options:
./mvnw clean install -B -T1C -Dmaven.javadoc.skip -Dmaven.jacoco.skip -e.Changes proposed in this pull request:
In the PostgreSQL text protocol write path (PostgreSQLDataRowPacket#writeTextValue), used type-aware formatting for timestamp/timestamptz/date/time instead of generic toString().
PostgreSQL 17 Temporal Data Behavior
TIME'10:00:00'10:00:00TIME'10:00:00.0'10:00:00TIME'10:00:00.1'10:00:00.1TIMETZ'10:00:00+05:30'10:00:00+05:30TIMETZ'10:00:00.1+05:30'10:00:00.100000+05:30TIMETZ'10:00:00.0'10:00:00TIMESTAMP'2026-02-04 10:00:00'2026-02-04 10:00:00TIMESTAMP'2026-02-04 10:00:00.0'2026-02-04 10:00:00TIMESTAMP'2026-02-04 10:00:00.1'2026-02-04 10:00:00.1TIMESTAMPTZ'2026-02-04 10:00:00.0+05:30'2026-02-04 04:30:00+00TIMESTAMPTZ'2026-02-04 10:00:00.1+05:30'2026-02-04 04:30:00.1+00Key Points:
.0fractional seconds are truncatedTIMETZpads fractional seconds to 6 digitsTIMESTAMPTZconverts to UTC when timezone is specified