Why
Two separate defects in the v7 Oracle dialect have now been traced to the same cause: the v7 port
(3a92f263a, #18050) reproduced the shape of v6 code while dropping behaviour that v6 relied on.
- A date-literal guard lost its value check. v6 validated the parsed date via a
moment round-trip
before accepting a TO_DATE/TO_TIMESTAMP_TZ literal. The v7 port kept the structural checks and
dropped the value check. git log --all -S "Invalid date value for TO_DATE" returns only the v6
commit.
DATEONLY inline escaping became infinitely recursive. v6 called options.escape; v7 calls
this.escape, which re-enters toBindableValue with no terminating branch. The practical effect is
that any inline (non-bind) DATEONLY comparison on Oracle throws
RangeError: Maximum call stack size exceeded — i.e. the feature has never worked on v7.
Both were found independently, by different routes, within the same week. Neither was found by tests.
Two confirmed regressions from one port is a pattern rather than a coincidence, and the sensible
assumption is that there are more.
What to do
A systematic behavioural diff of the v6 and v7 Oracle dialects — not a code re-read, which is what
missed these in the first place. Suggested approach:
- For each method the port touched, compare v6 and v7 output for the same inputs, including the
edge/invalid inputs v6's guards were written to reject. The interesting cases are the ones where v6
threw and v7 returns something.
- Pay particular attention to anywhere v6 called a validation helper (
moment, options.escape, a
format assertion) and v7 inlined or replaced it.
git log -S on the distinctive strings in v6's guards is a cheap way to find checks with no v7
counterpart — it is how both known cases were confirmed.
Test-coverage gap to close alongside
Both regressions survived because of the shape of the Oracle test suite rather than its size:
- No test anywhere puts a
DATEONLY value in a where clause, on any dialect. The only Oracle
DATEONLY coverage exercises the bind path (create, findOne({ where: { id } })), which never
reaches inline escaping.
- The date-literal guard is exercised only through an Oracle integration job, so it is invisible to
the always-on unit run.
Adding inline/where-path coverage for the Oracle data types would have caught both, and is worth doing
regardless of what the audit turns up.
Related
Created by Opus 5 with Claude Code, supervised by @WikiRik.
Why
Two separate defects in the v7 Oracle dialect have now been traced to the same cause: the v7 port
(
3a92f263a, #18050) reproduced the shape of v6 code while dropping behaviour that v6 relied on.momentround-tripbefore accepting a
TO_DATE/TO_TIMESTAMP_TZliteral. The v7 port kept the structural checks anddropped the value check.
git log --all -S "Invalid date value for TO_DATE"returns only the v6commit.
DATEONLYinline escaping became infinitely recursive. v6 calledoptions.escape; v7 callsthis.escape, which re-enterstoBindableValuewith no terminating branch. The practical effect isthat any inline (non-bind)
DATEONLYcomparison on Oracle throwsRangeError: Maximum call stack size exceeded— i.e. the feature has never worked on v7.Both were found independently, by different routes, within the same week. Neither was found by tests.
Two confirmed regressions from one port is a pattern rather than a coincidence, and the sensible
assumption is that there are more.
What to do
A systematic behavioural diff of the v6 and v7 Oracle dialects — not a code re-read, which is what
missed these in the first place. Suggested approach:
edge/invalid inputs v6's guards were written to reject. The interesting cases are the ones where v6
threw and v7 returns something.
moment,options.escape, aformat assertion) and v7 inlined or replaced it.
git log -Son the distinctive strings in v6's guards is a cheap way to find checks with no v7counterpart — it is how both known cases were confirmed.
Test-coverage gap to close alongside
Both regressions survived because of the shape of the Oracle test suite rather than its size:
DATEONLYvalue in awhereclause, on any dialect. The only OracleDATEONLYcoverage exercises the bind path (create,findOne({ where: { id } })), which neverreaches inline escaping.
the always-on unit run.
Adding inline/
where-path coverage for the Oracle data types would have caught both, and is worth doingregardless of what the audit turns up.
Related
Created by Opus 5 with Claude Code, supervised by @WikiRik.