Skip to content

fix: sql_variant rows read by their own type, no crash on a failed cell (#497); numeric strings keep a double's value (#498) - #499

Merged
TimelordUK merged 1 commit into
masterfrom
fix/variant-and-numeric-string
Oct 24, 2026
Merged

TimelordUK merged 1 commit into
masterfrom
fix/variant-and-numeric-string

Conversation

@TimelordUK

Copy link
Copy Markdown
Owner

Fixes #497. Partly fixes #498 (doubles only; decimal/money as text is still open, see below).

#497

  • d_variant wrote the first row's base type into the column definition, so every later row of a sql_variant column was read as that type. It now dispatches each row on its own type, and stores a NULL from its first SQLGetData (a second read returns SQL_NO_DATA, which lost the row).
  • The 0xC0000005: a failed cell left a hole that fromQueryResult dereferenced. A missing cell is now null, and a failed cell ends the fetch: the partial row is dropped and the query ends in an error. When the driver gives no diagnostic, the error is ours (HY000 cannot read column N), so a failed read is never silent.
  • bigint max read as a double came back as INT64_MIN; the range check now uses bounds that are exact as doubles.

#498 part 1: under numeric strings a double is String(n)'s text ("1e-10", "1.5e+300"), not %f ("0.000000").

Still open (owner's call): decimal/money/smallmoney are still read as a double, so digits beyond a double are lost; prepared statements bind numeric as a double. Reading SQL_DECIMAL as text fixes it, but the driver's text keeps the scale ("5.00") and has no leading zero (".0000001").

Tests

  • Corpus scripts issue-497, issue-497-ns (agreed: every base type first, followed by all the others, with numeric strings off and on) and issue-498 (known-bug, pins what is still open). Before the fix, issue-497 was PROCESS FAILED 3221225477.
  • Unit tests in params-complete-refactored.test.js.
  • The replay now keeps whole rows for scripts (column values replay), and the recorder prints native bigints.
  • Full suite on Windows / ODBC 18: 1190 passing, 1 pending.

🤖 Generated with Claude Code

…ed cell (#497); numeric strings keep a double's value (#498)

- d_variant dispatched on the column's definition and overwrote it with the first row's
  base type, so every later row was read as that type. It now dispatches each row on its
  own type, and stores a NULL from its first read (a second read of a NULL is SQL_NO_DATA).
- a failed cell left a hole in the row that building the JS rows dereferenced (0xC0000005).
  A missing cell is now null, and a failed cell ends the fetch: the partial row is dropped
  and the query ends in an error, ours if the driver gave none.
- bigint max read as a double came back as INT64_MIN: range bounds now exact as doubles.
- under numeric strings a double is String(n)'s text ("1e-10"), not %f ("0.000000").
  decimal and money still go through a double (#498 part 2, open).
- corpus scripts issue-497 (+ -ns, agreed) and issue-498 (known-bug); the replay keeps
  whole rows for scripts; the recorder prints native bigints; unit tests for both.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant