Filing gate: ① a defect with a named landing site: packages/drivers/driver-sql/src/sql-driver.ts, the mysql2 connection options (withUtcSession sets timezone: 'Z', and a URL connection reaches it too through withConnectBound) and the MySQL read presentation. They feed mysql2 3.23.1's lib/packets/packet.js parseDate / parseDateTime.
Finding class (a). reach: was measured at the public REST door (below).
The domain:engine execution seat 1 (session_01Bvd69VPa6puiNzzPUroDBx) filed this from its #20240 dev's patch-round report (finding 5), re-measured by the delta review of PR #20261 (record 5858382903). ⛔ Filed bare: routing and grading are triage's. ⛔ Not a claim.
What happens
Measured at e46218674b (base) and at PR #20261's head, which are identical for every cell below. The stack is SqlDriver on a live MySQL 8.0.46 (server time_zone='+08:00', as CI runs it) through mysql2 3.23.1, via REST POST /api/v1/data/:object and POST /api/v1/data/:object/query.
| field |
written |
stored (CAST(… AS CHAR)) |
returned by …/query |
date |
"0009-03-04" |
0009-03-04 |
"1909-03-04" |
date |
"0099-03-04" |
0099-03-04 |
"1999-03-04" |
date |
"0000-06-15" |
0000-06-15 |
"1900-06-15" |
date |
"0999-06-15" |
0999-06-15 |
"999-06-15" at base; "0999-06-15" once PR #20261 lands |
datetime |
"0009-03-04T10:00:00.000Z" |
0009-03-04 10:00:00.000 |
"2004-09-03T10:00:00.000Z" |
datetime |
0099-… / 0000-… |
stored right |
1999-03-04T10:00Z / 2000-06-15T10:00Z |
- The write is right and the read is wrong.
where placed_on $eq "0009-03-04" finds the row, then presents it as 1909-03-04. $eq "1909-03-04" finds nothing.
- Mechanism (read from source, measured live):
parseDate under timezone: 'Z' rebuilds a DATE as new Date(Date.UTC(y, m-1, d)), and the default / 'local' zones use new Date(y, m-1, d). Both map a year 0..99 to 1900..1999.
parseDateTime hands '0009-03-04 10:00:00.000Z' to V8's non-ISO Date parser, which reads it as 2004-09-03.
- SQLite and PostgreSQL read these years right.
- No measured writer stores these years. The reach is the public door, not an observed caller.
Suggested shape (⛔ not a ruling)
- The review measured two remedy hints.
dateStrings: true (for DATE and DATETIME) hands back the exact stored text. A '+00:00' zone takes mysql2's padded string-constructor arm for DATE only.
- Whichever is chosen, the read presentation must then go through the one storage rule (
temporalStorageForm), as the other dialects do.
- Pin it on live MySQL for years 9, 99, 0, 999 and a 2026 control, on
date and datetime, through the engine and REST.
Filing-gate answers
Dedupe words: mysql date year below 100 read back 1900s · mysql2 parseDate Date.UTC year 0009 1909 · mysql datetime year 9 presented 2004
Filing gate: ① a defect with a named landing site:
packages/drivers/driver-sql/src/sql-driver.ts, the mysql2 connection options (withUtcSessionsetstimezone: 'Z', and a URL connection reaches it too throughwithConnectBound) and the MySQL read presentation. They feed mysql2 3.23.1'slib/packets/packet.jsparseDate/parseDateTime.Finding class (a).
reach:was measured at the public REST door (below).The
domain:engineexecution seat 1 (session_01Bvd69VPa6puiNzzPUroDBx) filed this from its #20240 dev's patch-round report (finding 5), re-measured by the delta review of PR #20261 (record 5858382903). ⛔ Filed bare: routing and grading are triage's. ⛔ Not a claim.What happens
Measured at
e46218674b(base) and at PR #20261's head, which are identical for every cell below. The stack is SqlDriver on a live MySQL 8.0.46 (servertime_zone='+08:00', as CI runs it) through mysql2 3.23.1, via RESTPOST /api/v1/data/:objectandPOST /api/v1/data/:object/query.CAST(… AS CHAR))…/querydate"0009-03-04"0009-03-04"1909-03-04"date"0099-03-04"0099-03-04"1999-03-04"date"0000-06-15"0000-06-15"1900-06-15"date"0999-06-15"0999-06-15"999-06-15"at base;"0999-06-15"once PR #20261 landsdatetime"0009-03-04T10:00:00.000Z"0009-03-04 10:00:00.000"2004-09-03T10:00:00.000Z"datetime0099-…/0000-…1999-03-04T10:00Z/2000-06-15T10:00Zwhere placed_on $eq "0009-03-04"finds the row, then presents it as1909-03-04.$eq "1909-03-04"finds nothing.parseDateundertimezone: 'Z'rebuilds a DATE asnew Date(Date.UTC(y, m-1, d)), and the default /'local'zones usenew Date(y, m-1, d). Both map a year 0..99 to 1900..1999.parseDateTimehands'0009-03-04 10:00:00.000Z'to V8's non-ISODateparser, which reads it as 2004-09-03.Suggested shape (⛔ not a ruling)
dateStrings: true(forDATEandDATETIME) hands back the exact stored text. A'+00:00'zone takes mysql2's padded string-constructor arm forDATEonly.temporalStorageForm), as the other dialects do.dateanddatetime, through the engine and REST.Filing-gate answers
domain:engine, the owner ofdriver-sql). It is a different mechanism and position from temporal values outside the years a four-digit text or a backend holds: adatetimecomparand for year 10000 or −1 misorders on memory/SQLite and 500s on PostgreSQL; adatein year 0000 500s on PostgreSQL; adatewrite stores+010000-…verbatim #20264 (years outside what a text or backend holds) and coretemporalStorageForm: thedatearm leaves a year outside 1000..9999 unpadded — over REST the epoch-ms number for 0999-06-15 counts$gt0 /$lt7 on InMemoryDriver and SQLite (correct 6 / 0); its ISO string counts 6 / 0 #20240 (the rule's padding), so it is not folded into either.closedincluded:mysql date year below 100 read back 1900s mysql2 parseDate→ temporal values outside the years a four-digit text or a backend holds: adatetimecomparand for year 10000 or −1 misorders on memory/SQLite and 500s on PostgreSQL; adatein year 0000 500s on PostgreSQL; adatewrite stores+010000-…verbatim #20264, MySQL: Field.datetime maps to TIMESTAMP (range ends 2038-01-19) and binds a Date in the process-local timezone #3942 and Field.date defaultValue NOW() records the server-timezone calendar day on Postgres — and the DDL is invalid on MySQL 8.0 #4022, none this;mysql2 timezone Z date read wrong century Date.UTC two digit year→ MySQL: Field.datetime maps to TIMESTAMP (range ends 2038-01-19) and binds a Date in the process-local timezone #3942, driver-sql: every Field.date read from PostgreSQL is one day early when the process TZ is east of UTC — toDateOnly() reads UTC components off a local-midnight Date #11389 (PostgreSQL day-early, fixed) and Field.date defaultValue NOW() records the server-timezone calendar day on Postgres — and the DDL is invalid on MySQL 8.0 #4022, none this.Dedupe words:
mysql date year below 100 read back 1900s·mysql2 parseDate Date.UTC year 0009 1909·mysql datetime year 9 presented 2004