Doris-Breakwater commented on issue #66953: URL: https://github.com/apache/doris/issues/66953#issuecomment-5341117735
Breakwater-GitHub-Analysis-Slot: slot_7de645b9cb28 Initial assessment: this is not a simple type-name bug in v4.1.3. The reported `CHAR` metadata is intentional for the MySQL wire protocol, but the report exposes a real client-compatibility limitation for Go/GORM callers that scan a `TIMESTAMPTZ` result directly into `time.Time`. Verified facts: - In the v4.1.3 source, [`PrimitiveType.TIMESTAMPTZ` maps to `MYSQL_TYPE_STRING`](https://github.com/apache/doris/blob/4.1.3/fe/fe-common/src/main/java/org/apache/doris/catalog/PrimitiveType.java#L430-L431). That protocol type is code 254 and Doris names it `CHAR` in [`MysqlColType`](https://github.com/apache/doris/blob/4.1.3/fe/fe-common/src/main/java/org/apache/doris/catalog/MysqlColType.java#L56-L58). Therefore, `DatabaseTypeName() == "CHAR"` is consistent with the metadata Doris sends; it is not a GORM-only renaming. - This was a deliberate fix in [PR #63292](https://github.com/apache/doris/pull/63292). Doris previously advertised the value as MySQL `DATETIME`, while the row payload was actually a length-encoded, timezone-aware string such as `yyyy-MM-dd HH:mm:ss[.ffffff]+HH:mm`. Server-prepared Connector/J queries consequently tried to decode string bytes as a MySQL temporal binary value and failed. The fix aligned the metadata with the existing string payload and added text/binary protocol coverage. - The standard MySQL column-definition type enum has no distinct `TIMESTAMPTZ` type code. Merely changing the advertised type to `TIMESTAMP`/`DATETIME` without also changing the payload and defining the timezone semantics would reintroduce a metadata/payload mismatch. A MySQL temporal binary value also has no field for the rendered UTC offset. - The commonly used `go-sql-driver/mysql` maps MySQL `fieldTypeString` to [`DatabaseTypeName() == "CHAR"`](https://github.com/go-sql-driver/mysql/blob/master/fields.go#L795-L812). Such a column is normally delivered as bytes/string, not `time.Time`; `parseTime=true` only affects MySQL temporal column types, so it does not by itself make this direct `TIMESTAMPTZ` scan work. Likely failure mechanism (not yet fully verified for this report): GORM is receiving a string/`[]byte` for the column and `database/sql` cannot assign that directly to the struct's `time.Time` field. The issue does not include the exact driver, versions, DSN, or scan error, so we should not claim that this is the reporter's exact path until those details are supplied. Information needed from the reporter: 1. The GORM dialect/import path and version, underlying Go SQL driver and version, and a redacted DSN (especially `parseTime`, `loc`, and whether native prepared statements are used). 2. The exact DDL, insert value, SELECT, struct definition, and complete error text. 3. A minimal `database/sql` reproduction without GORM that prints `rows.ColumnTypes()` (`DatabaseTypeName`, `ScanType`) and attempts both `Scan(&stringValue)` and `Scan(&timeValue)`. 4. Whether the failure occurs with a normal text query, a server-prepared/binary query, or both, plus `SELECT @@time_zone` and one raw string value returned for the column. 5. The required semantic contract: must the returned value preserve the explicit offset, or is a session-time-zone wall-clock `time.Time` with the offset removed acceptable? Suggested next steps: - Treat this as a MySQL-protocol/Go-client compatibility or feature-design issue rather than reverting the existing mapping immediately. The issue currently has no labels; a compatibility/enhancement classification is more accurate unless the requested evidence shows a different payload bug. - For an immediate workaround that preserves the offset, scan into `string`, `sql.NullString`, or a custom `sql.Scanner`/GORM data type and parse Doris's offset-aware textual form. If losing the explicit offset is acceptable, test `CAST(ts AS DATETIMEV2(6))` with `parseTime=true`; this uses the session timezone, so the semantic tradeoff must be explicit. - If automatic `time.Time` support is adopted, design it as a protocol-compatible contract rather than only changing `DatabaseTypeName`. Add Go integration tests for both text and prepared/binary queries, checking `ColumnTypes()`, direct scanning, NULL, fractional precision, positive/negative offsets, and session-time-zone conversion. An opt-in conversion/cast may be safer than changing the current offset-preserving result contract for every MySQL client. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected] --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
