From 3e6cc01076a19ba45bf221744bf4db66afafca21 Mon Sep 17 00:00:00 2001 From: TimelordUK Date: Sat, 24 Oct 2026 18:21:02 +0100 Subject: [PATCH] fix: read each sql_variant row by its own type, never crash on a failed 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) --- cpp/include/js/columns/number_column.h | 4 +- cpp/include/js/columns/result_set.h | 6 + cpp/src/js/columns/result_set.cpp | 3 + cpp/src/js/js_object_mapper.cpp | 4 +- cpp/src/odbc/odbc_statement_legacy.cpp | 38 ++- test/contract/HANDOVER.md | 27 +- test/contract/corpus/scripts/issue-497-ns.txt | 236 ++++++++++++++++++ test/contract/corpus/scripts/issue-497.txt | 236 ++++++++++++++++++ test/contract/corpus/scripts/issue-498.txt | 66 +++++ .../native/scripts/issue-497-ns.win32.json | 1 + .../native/scripts/issue-497.win32.json | 1 + .../native/scripts/issue-498.win32.json | 1 + test/contract/recorder.js | 1 + test/contract/repro/i497.js | 36 +++ test/contract/repro/i498.js | 36 +++ test/contract/run-one.js | 3 +- test/contract/scripts/issue-497-ns.js | 4 + test/contract/scripts/issue-497.js | 38 +++ test/contract/scripts/issue-498.js | 49 ++++ test/params-complete-refactored.test.js | 62 +++++ 20 files changed, 837 insertions(+), 15 deletions(-) create mode 100644 test/contract/corpus/scripts/issue-497-ns.txt create mode 100644 test/contract/corpus/scripts/issue-497.txt create mode 100644 test/contract/corpus/scripts/issue-498.txt create mode 100644 test/contract/native/scripts/issue-497-ns.win32.json create mode 100644 test/contract/native/scripts/issue-497.win32.json create mode 100644 test/contract/native/scripts/issue-498.win32.json create mode 100644 test/contract/repro/i497.js create mode 100644 test/contract/repro/i498.js create mode 100644 test/contract/scripts/issue-497-ns.js create mode 100644 test/contract/scripts/issue-497.js create mode 100644 test/contract/scripts/issue-498.js diff --git a/cpp/include/js/columns/number_column.h b/cpp/include/js/columns/number_column.h index 60073644..d0a252b4 100644 --- a/cpp/include/js/columns/number_column.h +++ b/cpp/include/js/columns/number_column.h @@ -18,8 +18,10 @@ class NumberColumn : public Column { NumberColumn(int id, shared_ptr storage) : Column(id), value((*storage->doublevec_ptr)[0]) {} + // the same text as String(n) in JS: the shortest string that reads back as the same + // double. to_wstring is %f, six decimal places and no exponent (1e-10 gave "0.000000", #498) inline Napi::Object ToString(Napi::Env env) override { - return AsString(env, value); + return Napi::Number::New(env, value).ToString().As(); } inline Napi::Object ToNative(Napi::Env env) override { diff --git a/cpp/include/js/columns/result_set.h b/cpp/include/js/columns/result_set.h index 499ae2c3..9763152e 100644 --- a/cpp/include/js/columns/result_set.h +++ b/cpp/include/js/columns/result_set.h @@ -40,6 +40,12 @@ class ResultSet { void add_column(size_t row_id, const shared_ptr& column); Napi::Object get_entry(Napi::Env env, const ColumnDefinition& definition); shared_ptr get_column(size_t row_id, size_t id) const; + // forget rows from row_id on: a row whose read failed part way + void drop_rows_from(size_t row_id) { + if (_rows.size() > row_id) { + _rows.resize(row_id); + } + } size_t get_result_count() const { return _rows.size(); } diff --git a/cpp/src/js/columns/result_set.cpp b/cpp/src/js/columns/result_set.cpp index b7ff49af..b1d148a2 100644 --- a/cpp/src/js/columns/result_set.cpp +++ b/cpp/src/js/columns/result_set.cpp @@ -11,6 +11,9 @@ shared_ptr ResultSet::get_column(const size_t row_id, const size_t colum return nullptr; } const auto& row = _rows[row_id]; + if (column_id >= row.size()) { + return nullptr; + } return row[column_id]; } diff --git a/cpp/src/js/js_object_mapper.cpp b/cpp/src/js/js_object_mapper.cpp index 4742398f..b8f14a8f 100644 --- a/cpp/src/js/js_object_mapper.cpp +++ b/cpp/src/js/js_object_mapper.cpp @@ -89,7 +89,9 @@ Napi::Object JsObjectMapper::fromQueryResult(const Napi::Env& env, auto row_array = Napi::Array::New(env, column_count); results_array.Set(static_cast(row_id), row_array); for (auto c = 0; c < column_count; ++c) { - row_array.Set(static_cast(c), resultset->get_column(row_id, c)->ToValue(env)); + // a cell never stored (its read failed) is null, not a dereference of nothing + const auto column = resultset->get_column(row_id, c); + row_array.Set(static_cast(c), column ? column->ToValue(env) : env.Null()); } } diff --git a/cpp/src/odbc/odbc_statement_legacy.cpp b/cpp/src/odbc/odbc_statement_legacy.cpp index 60216ef9..52d9c923 100644 --- a/cpp/src/odbc/odbc_statement_legacy.cpp +++ b/cpp/src/odbc/odbc_statement_legacy.cpp @@ -259,9 +259,21 @@ bool OdbcStatementLegacy::fetch_read(const size_t number_rows) { const auto column_count = static_cast(_resultset->get_column_count()); for (auto c = 0; c < column_count; ++c) { const auto& definition = _resultset->get_meta_data(c); - res = dispatch(definition.dataType, row_id, c); - if (!res) { - break; + const auto errors = _errors->size(); + if (!dispatch(definition.dataType, row_id, c)) { + // a cell that cannot be read ends the fetch with its error: drop the part of the row + // already read, rather than go on and leave a row with holes in it (#497) + _resultset->drop_rows_from(row_id); + if (_errors->size() == errors) { + // the read failed with no diagnostic from the driver: the query must still end in + // an error, not look complete with its remaining rows missing + const auto msg = "[msnodesql] cannot read column " + std::to_string(c) + " of the result"; + const auto error = make_shared("HY000", msg.c_str(), 0, 0, "", "", 0); + _errors->push_back(error); + _errorHandler->AddError(error); + set_state(OdbcStatementState::STATEMENT_ERROR); + } + return false; } } } @@ -1505,6 +1517,12 @@ bool OdbcStatementLegacy::d_variant( SQL_LOG_DEBUG_STREAM("[" << _handle.toString() << "] d_variant failed to get data"); return false; } + // a NULL is known from this first read; a second SQLGetData on the column would return + // SQL_NO_DATA, and the row would be lost + if (iv == SQL_NULL_DATA) { + _resultset->add_column(row_id, make_shared(column)); + return true; + } // Figure out the type ret = _odbcApi->SQLColAttribute(statement.get_handle(), column + 1, @@ -1517,11 +1535,9 @@ bool OdbcStatementLegacy::d_variant( SQL_LOG_DEBUG_STREAM("[" << _handle.toString() << "] d_variant failed to get variant type"); return false; } - // set the definiton to actual data underlying data type. - auto& definition = _resultset->get_meta_data(static_cast(column)); - definition.dataType = static_cast(variant_type); - const auto res = dispatch(definition.dataType, row_id, column); - return res; + // read this row by its own base type. the column stays SQL_SS_VARIANT, so every row is + // resolved again: rows of one variant column can each hold a different type (#497) + return dispatch(static_cast(variant_type), row_id, column); } bool OdbcStatementLegacy::d_time( @@ -1940,9 +1956,9 @@ bool OdbcStatementLegacy::get_data_decimal(const size_t row_id, const size_t col } const auto v2 = trunc(v); - if (v2 == v && - v2 >= static_cast(numeric_limits::min()) && - v2 <= static_cast(numeric_limits::max())) { + // the bounds are exact as doubles: INT64_MAX is not, and rounds up to 2^63, which does not + // fit in an int64 (bigint max read as a double came back as INT64_MIN) + if (v2 == v && v2 >= -9223372036854775808.0 && v2 < 9223372036854775808.0) { auto bi = static_cast(v); const auto col = make_shared(column, bi); if (_numericStringEnabled) { diff --git a/test/contract/HANDOVER.md b/test/contract/HANDOVER.md index bf6571fe..cf1df23d 100644 --- a/test/contract/HANDOVER.md +++ b/test/contract/HANDOVER.md @@ -1,6 +1,6 @@ # Handover: the v6 event contract (from the 5.6.0 regressions, #478 – #481) -Started 2026-10-15 from dhensby's reports. Last updated 2026-10-18. The newest state is +Started 2026-10-15 from dhensby's reports. Last updated 2026-10-24. The newest state is first; the dated Progress sections below have the detail, and the older sections are history. ## Where we are — end of 2026-10-18 @@ -32,6 +32,31 @@ the contract below. Workarounds for a missing or doubled `done` (node-mssql 12.7 break. Then decide the node-mssql guard: an RC on `next` for dhensby, node-mssql-shaped scenarios, or their suite as a canary job. +## Progress — 2026-10-24: #497 (sql_variant) and #498 (numeric strings) + +Both reported by dhensby against 6.0.0; both reproduced here (ODBC 18), the crash included. +Repros in `repro/i497.js`, `repro/i498.js`; corpus `scripts/issue-497` (+ `-ns`, agreed) and +`scripts/issue-498` (known-bug). Unit tests in `test/params-complete-refactored.test.js`. + +- **#497 fixed.** `d_variant` wrote the first row's base type into the column's definition, 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 `SQLGetData` (a second read of a NULL is `SQL_NO_DATA`, which lost the row). +- **The 0xC0000005 crash fixed.** A failed cell left a hole in the row, and building the JS rows + dereferenced it. `get_column` and `fromQueryResult` now give null for a missing cell, and a + failed cell ends the fetch: the partial row is dropped and the query ends in an error - one of + ours (HY000 "cannot read column N") if the driver gave none, so a failed read is never silent. + Still open: the rows read before it in the same fetch batch are not delivered. +- **bigint max read as a double** came back as INT64_MIN: the int64 range check used bounds + that round to 2^63. Bounds exact as doubles now. +- **#498 part 1 fixed:** a double under numeric strings is `String(n)`'s text (`"1e-10"`), not `%f`. +- **#498 part 2 open, the owner's call:** `decimal`, `money` and `smallmoney` are still read as a + double, so under numeric strings digits beyond a double are lost (`decimal(38,2)` with 20 + integer digits, large `money`); a prepared statement binds `numeric` as a double too. The fix, + reading `SQL_DECIMAL` as text like `SQL_NUMERIC`, changes what users get: the driver's text + keeps the scale (`"5.00"`) and has no leading zero (`".0000001"`, as `numeric` already does). +- The replay keeps whole rows for scripts now (`run-one.js`), so a script's column values replay. + A transcript stops at 400 lines: split a script that needs more (as `issue-497-ns`). + ## Progress — 2026-10-22: node-mssql against v6 node-mssql's own msnodesqlv8 suite (`npx mocha --exit -t 30000 test/msnodesqlv8` in a clone, diff --git a/test/contract/corpus/scripts/issue-497-ns.txt b/test/contract/corpus/scripts/issue-497-ns.txt new file mode 100644 index 00000000..d91ad615 --- /dev/null +++ b/test/contract/corpus/scripts/issue-497-ns.txt @@ -0,0 +1,236 @@ +# scenario: scripts/issue-497-ns +# status: agreed +# script: test/contract/scripts/issue-497-ns.js +== int first, numeric strings on +int-ns: submitted +int-ns: meta i,v +int-ns: row +int-ns: column 0 "1" +int-ns: column 1 "7" +int-ns: row +int-ns: column 0 "2" +int-ns: column 1 "9223372036854775807" +int-ns: row +int-ns: column 0 "3" +int-ns: column 1 "1.50" +int-ns: row +int-ns: column 0 "4" +int-ns: column 1 "2.25e-9" +int-ns: row +int-ns: column 0 "5" +int-ns: column 1 "abc" +int-ns: row +int-ns: column 0 "6" +int-ns: column 1 2020-01-02T00:00:00.000Z +int-ns: row +int-ns: column 0 "7" +int-ns: column 1 true +int-ns: row +int-ns: column 0 "8" +int-ns: column 1 null +int-ns: done +int-ns: free +== bigint first, numeric strings on +bigint-ns: submitted +bigint-ns: meta i,v +bigint-ns: row +bigint-ns: column 0 "1" +bigint-ns: column 1 "9223372036854775807" +bigint-ns: row +bigint-ns: column 0 "2" +bigint-ns: column 1 "7" +bigint-ns: row +bigint-ns: column 0 "3" +bigint-ns: column 1 "1.50" +bigint-ns: row +bigint-ns: column 0 "4" +bigint-ns: column 1 "2.25e-9" +bigint-ns: row +bigint-ns: column 0 "5" +bigint-ns: column 1 "abc" +bigint-ns: row +bigint-ns: column 0 "6" +bigint-ns: column 1 2020-01-02T00:00:00.000Z +bigint-ns: row +bigint-ns: column 0 "7" +bigint-ns: column 1 true +bigint-ns: row +bigint-ns: column 0 "8" +bigint-ns: column 1 null +bigint-ns: done +bigint-ns: free +== decimal first, numeric strings on +decimal-ns: submitted +decimal-ns: meta i,v +decimal-ns: row +decimal-ns: column 0 "1" +decimal-ns: column 1 "1.50" +decimal-ns: row +decimal-ns: column 0 "2" +decimal-ns: column 1 "7" +decimal-ns: row +decimal-ns: column 0 "3" +decimal-ns: column 1 "9223372036854775807" +decimal-ns: row +decimal-ns: column 0 "4" +decimal-ns: column 1 "2.25e-9" +decimal-ns: row +decimal-ns: column 0 "5" +decimal-ns: column 1 "abc" +decimal-ns: row +decimal-ns: column 0 "6" +decimal-ns: column 1 2020-01-02T00:00:00.000Z +decimal-ns: row +decimal-ns: column 0 "7" +decimal-ns: column 1 true +decimal-ns: row +decimal-ns: column 0 "8" +decimal-ns: column 1 null +decimal-ns: done +decimal-ns: free +== float first, numeric strings on +float-ns: submitted +float-ns: meta i,v +float-ns: row +float-ns: column 0 "1" +float-ns: column 1 "2.25e-9" +float-ns: row +float-ns: column 0 "2" +float-ns: column 1 "7" +float-ns: row +float-ns: column 0 "3" +float-ns: column 1 "9223372036854775807" +float-ns: row +float-ns: column 0 "4" +float-ns: column 1 "1.50" +float-ns: row +float-ns: column 0 "5" +float-ns: column 1 "abc" +float-ns: row +float-ns: column 0 "6" +float-ns: column 1 2020-01-02T00:00:00.000Z +float-ns: row +float-ns: column 0 "7" +float-ns: column 1 true +float-ns: row +float-ns: column 0 "8" +float-ns: column 1 null +float-ns: done +float-ns: free +== nvarchar first, numeric strings on +nvarchar-ns: submitted +nvarchar-ns: meta i,v +nvarchar-ns: row +nvarchar-ns: column 0 "1" +nvarchar-ns: column 1 "abc" +nvarchar-ns: row +nvarchar-ns: column 0 "2" +nvarchar-ns: column 1 "7" +nvarchar-ns: row +nvarchar-ns: column 0 "3" +nvarchar-ns: column 1 "9223372036854775807" +nvarchar-ns: row +nvarchar-ns: column 0 "4" +nvarchar-ns: column 1 "1.50" +nvarchar-ns: row +nvarchar-ns: column 0 "5" +nvarchar-ns: column 1 "2.25e-9" +nvarchar-ns: row +nvarchar-ns: column 0 "6" +nvarchar-ns: column 1 2020-01-02T00:00:00.000Z +nvarchar-ns: row +nvarchar-ns: column 0 "7" +nvarchar-ns: column 1 true +nvarchar-ns: row +nvarchar-ns: column 0 "8" +nvarchar-ns: column 1 null +nvarchar-ns: done +nvarchar-ns: free +== datetime first, numeric strings on +datetime-ns: submitted +datetime-ns: meta i,v +datetime-ns: row +datetime-ns: column 0 "1" +datetime-ns: column 1 2020-01-02T00:00:00.000Z +datetime-ns: row +datetime-ns: column 0 "2" +datetime-ns: column 1 "7" +datetime-ns: row +datetime-ns: column 0 "3" +datetime-ns: column 1 "9223372036854775807" +datetime-ns: row +datetime-ns: column 0 "4" +datetime-ns: column 1 "1.50" +datetime-ns: row +datetime-ns: column 0 "5" +datetime-ns: column 1 "2.25e-9" +datetime-ns: row +datetime-ns: column 0 "6" +datetime-ns: column 1 "abc" +datetime-ns: row +datetime-ns: column 0 "7" +datetime-ns: column 1 true +datetime-ns: row +datetime-ns: column 0 "8" +datetime-ns: column 1 null +datetime-ns: done +datetime-ns: free +== bit first, numeric strings on +bit-ns: submitted +bit-ns: meta i,v +bit-ns: row +bit-ns: column 0 "1" +bit-ns: column 1 true +bit-ns: row +bit-ns: column 0 "2" +bit-ns: column 1 "7" +bit-ns: row +bit-ns: column 0 "3" +bit-ns: column 1 "9223372036854775807" +bit-ns: row +bit-ns: column 0 "4" +bit-ns: column 1 "1.50" +bit-ns: row +bit-ns: column 0 "5" +bit-ns: column 1 "2.25e-9" +bit-ns: row +bit-ns: column 0 "6" +bit-ns: column 1 "abc" +bit-ns: row +bit-ns: column 0 "7" +bit-ns: column 1 2020-01-02T00:00:00.000Z +bit-ns: row +bit-ns: column 0 "8" +bit-ns: column 1 null +bit-ns: done +bit-ns: free +== null first, numeric strings on +null-ns: submitted +null-ns: meta i,v +null-ns: row +null-ns: column 0 "1" +null-ns: column 1 null +null-ns: row +null-ns: column 0 "2" +null-ns: column 1 "7" +null-ns: row +null-ns: column 0 "3" +null-ns: column 1 "9223372036854775807" +null-ns: row +null-ns: column 0 "4" +null-ns: column 1 "1.50" +null-ns: row +null-ns: column 0 "5" +null-ns: column 1 "2.25e-9" +null-ns: row +null-ns: column 0 "6" +null-ns: column 1 "abc" +null-ns: row +null-ns: column 0 "7" +null-ns: column 1 2020-01-02T00:00:00.000Z +null-ns: row +null-ns: column 0 "8" +null-ns: column 1 true +null-ns: done +null-ns: free +check ok diff --git a/test/contract/corpus/scripts/issue-497.txt b/test/contract/corpus/scripts/issue-497.txt new file mode 100644 index 00000000..a5ffc38d --- /dev/null +++ b/test/contract/corpus/scripts/issue-497.txt @@ -0,0 +1,236 @@ +# scenario: scripts/issue-497 +# status: agreed +# script: test/contract/scripts/issue-497.js +== int first, numeric strings off +int: submitted +int: meta i,v +int: row +int: column 0 1 +int: column 1 7 +int: row +int: column 0 2 +int: column 1 9223372036854775807n +int: row +int: column 0 3 +int: column 1 1.5 +int: row +int: column 0 4 +int: column 1 2.25e-9 +int: row +int: column 0 5 +int: column 1 "abc" +int: row +int: column 0 6 +int: column 1 2020-01-02T00:00:00.000Z +int: row +int: column 0 7 +int: column 1 true +int: row +int: column 0 8 +int: column 1 null +int: done +int: free +== bigint first, numeric strings off +bigint: submitted +bigint: meta i,v +bigint: row +bigint: column 0 1 +bigint: column 1 9223372036854775807n +bigint: row +bigint: column 0 2 +bigint: column 1 7 +bigint: row +bigint: column 0 3 +bigint: column 1 1.5 +bigint: row +bigint: column 0 4 +bigint: column 1 2.25e-9 +bigint: row +bigint: column 0 5 +bigint: column 1 "abc" +bigint: row +bigint: column 0 6 +bigint: column 1 2020-01-02T00:00:00.000Z +bigint: row +bigint: column 0 7 +bigint: column 1 true +bigint: row +bigint: column 0 8 +bigint: column 1 null +bigint: done +bigint: free +== decimal first, numeric strings off +decimal: submitted +decimal: meta i,v +decimal: row +decimal: column 0 1 +decimal: column 1 1.5 +decimal: row +decimal: column 0 2 +decimal: column 1 7 +decimal: row +decimal: column 0 3 +decimal: column 1 9223372036854775807n +decimal: row +decimal: column 0 4 +decimal: column 1 2.25e-9 +decimal: row +decimal: column 0 5 +decimal: column 1 "abc" +decimal: row +decimal: column 0 6 +decimal: column 1 2020-01-02T00:00:00.000Z +decimal: row +decimal: column 0 7 +decimal: column 1 true +decimal: row +decimal: column 0 8 +decimal: column 1 null +decimal: done +decimal: free +== float first, numeric strings off +float: submitted +float: meta i,v +float: row +float: column 0 1 +float: column 1 2.25e-9 +float: row +float: column 0 2 +float: column 1 7 +float: row +float: column 0 3 +float: column 1 9223372036854775807n +float: row +float: column 0 4 +float: column 1 1.5 +float: row +float: column 0 5 +float: column 1 "abc" +float: row +float: column 0 6 +float: column 1 2020-01-02T00:00:00.000Z +float: row +float: column 0 7 +float: column 1 true +float: row +float: column 0 8 +float: column 1 null +float: done +float: free +== nvarchar first, numeric strings off +nvarchar: submitted +nvarchar: meta i,v +nvarchar: row +nvarchar: column 0 1 +nvarchar: column 1 "abc" +nvarchar: row +nvarchar: column 0 2 +nvarchar: column 1 7 +nvarchar: row +nvarchar: column 0 3 +nvarchar: column 1 9223372036854775807n +nvarchar: row +nvarchar: column 0 4 +nvarchar: column 1 1.5 +nvarchar: row +nvarchar: column 0 5 +nvarchar: column 1 2.25e-9 +nvarchar: row +nvarchar: column 0 6 +nvarchar: column 1 2020-01-02T00:00:00.000Z +nvarchar: row +nvarchar: column 0 7 +nvarchar: column 1 true +nvarchar: row +nvarchar: column 0 8 +nvarchar: column 1 null +nvarchar: done +nvarchar: free +== datetime first, numeric strings off +datetime: submitted +datetime: meta i,v +datetime: row +datetime: column 0 1 +datetime: column 1 2020-01-02T00:00:00.000Z +datetime: row +datetime: column 0 2 +datetime: column 1 7 +datetime: row +datetime: column 0 3 +datetime: column 1 9223372036854775807n +datetime: row +datetime: column 0 4 +datetime: column 1 1.5 +datetime: row +datetime: column 0 5 +datetime: column 1 2.25e-9 +datetime: row +datetime: column 0 6 +datetime: column 1 "abc" +datetime: row +datetime: column 0 7 +datetime: column 1 true +datetime: row +datetime: column 0 8 +datetime: column 1 null +datetime: done +datetime: free +== bit first, numeric strings off +bit: submitted +bit: meta i,v +bit: row +bit: column 0 1 +bit: column 1 true +bit: row +bit: column 0 2 +bit: column 1 7 +bit: row +bit: column 0 3 +bit: column 1 9223372036854775807n +bit: row +bit: column 0 4 +bit: column 1 1.5 +bit: row +bit: column 0 5 +bit: column 1 2.25e-9 +bit: row +bit: column 0 6 +bit: column 1 "abc" +bit: row +bit: column 0 7 +bit: column 1 2020-01-02T00:00:00.000Z +bit: row +bit: column 0 8 +bit: column 1 null +bit: done +bit: free +== null first, numeric strings off +null: submitted +null: meta i,v +null: row +null: column 0 1 +null: column 1 null +null: row +null: column 0 2 +null: column 1 7 +null: row +null: column 0 3 +null: column 1 9223372036854775807n +null: row +null: column 0 4 +null: column 1 1.5 +null: row +null: column 0 5 +null: column 1 2.25e-9 +null: row +null: column 0 6 +null: column 1 "abc" +null: row +null: column 0 7 +null: column 1 2020-01-02T00:00:00.000Z +null: row +null: column 0 8 +null: column 1 true +null: done +null: free +check ok diff --git a/test/contract/corpus/scripts/issue-498.txt b/test/contract/corpus/scripts/issue-498.txt new file mode 100644 index 00000000..033bd652 --- /dev/null +++ b/test/contract/corpus/scripts/issue-498.txt @@ -0,0 +1,66 @@ +# scenario: scripts/issue-498 +# status: known-bug +# script: test/contract/scripts/issue-498.js +# #498: doubles now print as String(n) does. still open: decimal and money are read as a double, +# so digits a double cannot hold are lost (c6, c8, c10), and a prepared statement binds numeric +# as a double too (ps column 1). numeric's text has no leading zero (c14 ".0000001") +-- c0 cast(0.1234567890123 as float); c1 cast(1e-10 as float); c2 cast(1.5e300 as float); c3 cast(-2.5 as float); c4 cast(0.12345678 as real); c5 cast(1.0123456789 as decimal(38,10)); c6 cast(12345678901234567890.12 as decimal(38,2)); c7 cast(0.0000001 as decimal(10,7)); c8 cast(9007199254740993 as decimal(19,0)); c9 cast(709 as decimal(10,0)); c10 cast(922337203685477.5807 as money); c11 cast(-0.0001 as money); c12 cast(1.2345 as smallmoney); c13 cast(1.0123456789 as numeric(38,10)); c14 cast(0.0000001 as numeric(10,7)); c15 cast(9223372036854775807 as bigint) +== numeric strings off +plain: submitted +plain: meta c0,c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13,c14,c15 +plain: row +plain: column 0 0.1234567890123 +plain: column 1 1e-10 +plain: column 2 1.5e+300 +plain: column 3 -2.5 +plain: column 4 0.12345678359270096 +plain: column 5 1.0123456789 +plain: column 6 12345678901234567000 +plain: column 7 1e-7 +plain: column 8 9007199254740992 +plain: column 9 709 +plain: column 10 922337203685477.6 +plain: column 11 -0.0001 +plain: column 12 1.2345 +plain: column 13 1.0123456789 +plain: column 14 1e-7 +plain: column 15 9223372036854776000 +plain: done +plain: free +== numeric strings on +ns: submitted +ns: meta c0,c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13,c14,c15 +ns: row +ns: column 0 "0.1234567890123" +ns: column 1 "1e-10" +ns: column 2 "1.5e+300" +ns: column 3 "-2.5" +ns: column 4 "0.12345678359270096" +ns: column 5 "1.0123456789" +ns: column 6 "12345678901234567000" +ns: column 7 "1e-7" +ns: column 8 "9007199254740992" +ns: column 9 "709" +ns: column 10 "922337203685477.6" +ns: column 11 "-0.0001" +ns: column 12 "1.2345" +ns: column 13 "1.0123456789" +ns: column 14 ".0000001" +ns: column 15 "9223372036854775807" +ns: done +ns: free +setup: submitted +setup: rowcount 1 +setup: cb ok rows=0 more=false +setup: done +setup: free +== prepared, numeric strings on +ps: submitted +ps: meta n,d,f +ps: row +ps: column 0 "1.0123456789" +ps: column 1 "12345678901234568" +ps: column 2 "1e-10" +ps: done +ps: free +check ok diff --git a/test/contract/native/scripts/issue-497-ns.win32.json b/test/contract/native/scripts/issue-497-ns.win32.json new file mode 100644 index 00000000..a883b1a7 --- /dev/null +++ b/test/contract/native/scripts/issue-497-ns.win32.json @@ -0,0 +1 @@ +{"scenario":"scripts/issue-497-ns","transcript":["== int first, numeric strings on","int-ns: submitted","int-ns: meta i,v","int-ns: row","int-ns: column 0 \"1\"","int-ns: column 1 \"7\"","int-ns: row","int-ns: column 0 \"2\"","int-ns: column 1 \"9223372036854775807\"","int-ns: row","int-ns: column 0 \"3\"","int-ns: column 1 \"1.50\"","int-ns: row","int-ns: column 0 \"4\"","int-ns: column 1 \"2.25e-9\"","int-ns: row","int-ns: column 0 \"5\"","int-ns: column 1 \"abc\"","int-ns: row","int-ns: column 0 \"6\"","int-ns: column 1 2020-01-02T00:00:00.000Z","int-ns: row","int-ns: column 0 \"7\"","int-ns: column 1 true","int-ns: row","int-ns: column 0 \"8\"","int-ns: column 1 null","int-ns: done","int-ns: free","== bigint first, numeric strings on","bigint-ns: submitted","bigint-ns: meta i,v","bigint-ns: row","bigint-ns: column 0 \"1\"","bigint-ns: column 1 \"9223372036854775807\"","bigint-ns: row","bigint-ns: column 0 \"2\"","bigint-ns: column 1 \"7\"","bigint-ns: row","bigint-ns: column 0 \"3\"","bigint-ns: column 1 \"1.50\"","bigint-ns: row","bigint-ns: column 0 \"4\"","bigint-ns: column 1 \"2.25e-9\"","bigint-ns: row","bigint-ns: column 0 \"5\"","bigint-ns: column 1 \"abc\"","bigint-ns: row","bigint-ns: column 0 \"6\"","bigint-ns: column 1 2020-01-02T00:00:00.000Z","bigint-ns: row","bigint-ns: column 0 \"7\"","bigint-ns: column 1 true","bigint-ns: row","bigint-ns: column 0 \"8\"","bigint-ns: column 1 null","bigint-ns: done","bigint-ns: free","== decimal first, numeric strings on","decimal-ns: submitted","decimal-ns: meta i,v","decimal-ns: row","decimal-ns: column 0 \"1\"","decimal-ns: column 1 \"1.50\"","decimal-ns: row","decimal-ns: column 0 \"2\"","decimal-ns: column 1 \"7\"","decimal-ns: row","decimal-ns: column 0 \"3\"","decimal-ns: column 1 \"9223372036854775807\"","decimal-ns: row","decimal-ns: column 0 \"4\"","decimal-ns: column 1 \"2.25e-9\"","decimal-ns: row","decimal-ns: column 0 \"5\"","decimal-ns: column 1 \"abc\"","decimal-ns: row","decimal-ns: column 0 \"6\"","decimal-ns: column 1 2020-01-02T00:00:00.000Z","decimal-ns: row","decimal-ns: column 0 \"7\"","decimal-ns: column 1 true","decimal-ns: row","decimal-ns: column 0 \"8\"","decimal-ns: column 1 null","decimal-ns: done","decimal-ns: free","== float first, numeric strings on","float-ns: submitted","float-ns: meta i,v","float-ns: row","float-ns: column 0 \"1\"","float-ns: column 1 \"2.25e-9\"","float-ns: row","float-ns: column 0 \"2\"","float-ns: column 1 \"7\"","float-ns: row","float-ns: column 0 \"3\"","float-ns: column 1 \"9223372036854775807\"","float-ns: row","float-ns: column 0 \"4\"","float-ns: column 1 \"1.50\"","float-ns: row","float-ns: column 0 \"5\"","float-ns: column 1 \"abc\"","float-ns: row","float-ns: column 0 \"6\"","float-ns: column 1 2020-01-02T00:00:00.000Z","float-ns: row","float-ns: column 0 \"7\"","float-ns: column 1 true","float-ns: row","float-ns: column 0 \"8\"","float-ns: column 1 null","float-ns: done","float-ns: free","== nvarchar first, numeric strings on","nvarchar-ns: submitted","nvarchar-ns: meta i,v","nvarchar-ns: row","nvarchar-ns: column 0 \"1\"","nvarchar-ns: column 1 \"abc\"","nvarchar-ns: row","nvarchar-ns: column 0 \"2\"","nvarchar-ns: column 1 \"7\"","nvarchar-ns: row","nvarchar-ns: column 0 \"3\"","nvarchar-ns: column 1 \"9223372036854775807\"","nvarchar-ns: row","nvarchar-ns: column 0 \"4\"","nvarchar-ns: column 1 \"1.50\"","nvarchar-ns: row","nvarchar-ns: column 0 \"5\"","nvarchar-ns: column 1 \"2.25e-9\"","nvarchar-ns: row","nvarchar-ns: column 0 \"6\"","nvarchar-ns: column 1 2020-01-02T00:00:00.000Z","nvarchar-ns: row","nvarchar-ns: column 0 \"7\"","nvarchar-ns: column 1 true","nvarchar-ns: row","nvarchar-ns: column 0 \"8\"","nvarchar-ns: column 1 null","nvarchar-ns: done","nvarchar-ns: free","== datetime first, numeric strings on","datetime-ns: submitted","datetime-ns: meta i,v","datetime-ns: row","datetime-ns: column 0 \"1\"","datetime-ns: column 1 2020-01-02T00:00:00.000Z","datetime-ns: row","datetime-ns: column 0 \"2\"","datetime-ns: column 1 \"7\"","datetime-ns: row","datetime-ns: column 0 \"3\"","datetime-ns: column 1 \"9223372036854775807\"","datetime-ns: row","datetime-ns: column 0 \"4\"","datetime-ns: column 1 \"1.50\"","datetime-ns: row","datetime-ns: column 0 \"5\"","datetime-ns: column 1 \"2.25e-9\"","datetime-ns: row","datetime-ns: column 0 \"6\"","datetime-ns: column 1 \"abc\"","datetime-ns: row","datetime-ns: column 0 \"7\"","datetime-ns: column 1 true","datetime-ns: row","datetime-ns: column 0 \"8\"","datetime-ns: column 1 null","datetime-ns: done","datetime-ns: free","== bit first, numeric strings on","bit-ns: submitted","bit-ns: meta i,v","bit-ns: row","bit-ns: column 0 \"1\"","bit-ns: column 1 true","bit-ns: row","bit-ns: column 0 \"2\"","bit-ns: column 1 \"7\"","bit-ns: row","bit-ns: column 0 \"3\"","bit-ns: column 1 \"9223372036854775807\"","bit-ns: row","bit-ns: column 0 \"4\"","bit-ns: column 1 \"1.50\"","bit-ns: row","bit-ns: column 0 \"5\"","bit-ns: column 1 \"2.25e-9\"","bit-ns: row","bit-ns: column 0 \"6\"","bit-ns: column 1 \"abc\"","bit-ns: row","bit-ns: column 0 \"7\"","bit-ns: column 1 2020-01-02T00:00:00.000Z","bit-ns: row","bit-ns: column 0 \"8\"","bit-ns: column 1 null","bit-ns: done","bit-ns: free","== null first, numeric strings on","null-ns: submitted","null-ns: meta i,v","null-ns: row","null-ns: column 0 \"1\"","null-ns: column 1 null","null-ns: row","null-ns: column 0 \"2\"","null-ns: column 1 \"7\"","null-ns: row","null-ns: column 0 \"3\"","null-ns: column 1 \"9223372036854775807\"","null-ns: row","null-ns: column 0 \"4\"","null-ns: column 1 \"1.50\"","null-ns: row","null-ns: column 0 \"5\"","null-ns: column 1 \"2.25e-9\"","null-ns: row","null-ns: column 0 \"6\"","null-ns: column 1 \"abc\"","null-ns: row","null-ns: column 0 \"7\"","null-ns: column 1 2020-01-02T00:00:00.000Z","null-ns: row","null-ns: column 0 \"8\"","null-ns: column 1 true","null-ns: done","null-ns: free","check ok"],"log":[{"ev":"call","id":0,"t":10.8,"name":"open","args":["",0]},{"ev":"return","of":0,"t":30.8,"result":[null,{"success":true}]},{"ev":"call","id":2,"t":32.7,"name":"query","args":[0,{"query_str":"select i, v from (values (1, cast(cast(7 as int) as sql_variant)), (2, cast(cast(9223372036854775807 as bigint) as sql_variant)), (3, cast(cast(1.5 as decimal(5,2)) as sql_variant)), (4, cast(cast(2.25e-9 as float) as sql_variant)), (5, cast(cast(N'abc' as nvarchar(10)) as sql_variant)), (6, cast(cast('2020-01-02' as datetime) as sql_variant)), (7, cast(cast(1 as bit) as sql_variant)), (8, cast(null as sql_variant))) t(i, v) order by i","numeric_string":true,"bigint_as_native":true,"stateChangeCallback":{"$":"function"}},[]]},{"ev":"state","of":2,"t":32.9,"change":{"handle":{"connectionId":0,"statementId":0},"oldState":"STATEMENT_CREATED","newState":"STATEMENT_BINDING"}},{"ev":"state","of":2,"t":33,"change":{"handle":{"connectionId":0,"statementId":0},"oldState":"STATEMENT_BINDING","newState":"STATEMENT_SUBMITTED"}},{"ev":"state","of":2,"t":33.6,"change":{"handle":{"connectionId":0,"statementId":0},"oldState":"STATEMENT_SUBMITTED","newState":"STATEMENT_READING"}},{"ev":"return","of":2,"t":33.6,"result":[null,{"meta":[{"name":"i","nullable":false,"type":"number","sqlType":"int","size":10},{"name":"v","nullable":true,"type":"text","sqlType":"sql_variant","size":8000}],"handle":{"connectionId":0,"statementId":0},"endOfRows":true,"endOfResults":false,"rowCount":0},true]},{"ev":"call","id":7,"t":33.9,"name":"fetchRows","args":[0,{"connectionId":0,"statementId":0},{"asArrays":true,"batchSize":50,"asObjects":false}]},{"ev":"return","of":7,"t":34.2,"result":[null,{"endOfRows":true,"endOfResults":false,"rowCount":0,"data":[["1","7"],["2","9223372036854775807"],["3","1.50"],["4","2.25e-9"],["5","abc"],["6",{"$":"date","v":1577923200000,"ns":0}],["7",true],["8",null]]}]},{"ev":"call","id":9,"t":34.5,"name":"nextResultSet","args":[0,{"connectionId":0,"statementId":0}]},{"ev":"return","of":9,"t":34.6,"result":[null,{"meta":[{"name":"i","nullable":false,"type":"number","sqlType":"int","size":10},{"name":"v","nullable":true,"type":"text","sqlType":"sql_variant","size":8000}],"handle":{"connectionId":0,"statementId":0},"endOfRows":true,"endOfResults":true,"rowCount":0}]},{"ev":"call","id":11,"t":34.9,"name":"releaseStatement","args":[0,{"connectionId":0,"statementId":0}]},{"ev":"state","of":2,"t":35,"change":{"handle":{"connectionId":0,"statementId":0},"oldState":"STATEMENT_READING","newState":"STATEMENT_CLOSED"}},{"ev":"return","of":11,"t":35,"result":[null,true]},{"ev":"call","id":14,"t":199.6,"name":"query","args":[1,{"query_str":"select i, v from (values (1, cast(cast(9223372036854775807 as bigint) as sql_variant)), (2, cast(cast(7 as int) as sql_variant)), (3, cast(cast(1.5 as decimal(5,2)) as sql_variant)), (4, cast(cast(2.25e-9 as float) as sql_variant)), (5, cast(cast(N'abc' as nvarchar(10)) as sql_variant)), (6, cast(cast('2020-01-02' as datetime) as sql_variant)), (7, cast(cast(1 as bit) as sql_variant)), (8, cast(null as sql_variant))) t(i, v) order by i","numeric_string":true,"bigint_as_native":true,"stateChangeCallback":{"$":"function"}},[]]},{"ev":"state","of":14,"t":199.7,"change":{"handle":{"connectionId":0,"statementId":1},"oldState":"STATEMENT_CREATED","newState":"STATEMENT_BINDING"}},{"ev":"state","of":14,"t":199.7,"change":{"handle":{"connectionId":0,"statementId":1},"oldState":"STATEMENT_BINDING","newState":"STATEMENT_SUBMITTED"}},{"ev":"state","of":14,"t":200.8,"change":{"handle":{"connectionId":0,"statementId":1},"oldState":"STATEMENT_SUBMITTED","newState":"STATEMENT_READING"}},{"ev":"return","of":14,"t":200.9,"result":[null,{"meta":[{"name":"i","nullable":false,"type":"number","sqlType":"int","size":10},{"name":"v","nullable":true,"type":"text","sqlType":"sql_variant","size":8000}],"handle":{"connectionId":0,"statementId":1},"endOfRows":true,"endOfResults":false,"rowCount":0},true]},{"ev":"call","id":19,"t":200.9,"name":"fetchRows","args":[1,{"connectionId":0,"statementId":1},{"asArrays":true,"batchSize":50,"asObjects":false}]},{"ev":"return","of":19,"t":201.1,"result":[null,{"endOfRows":true,"endOfResults":false,"rowCount":0,"data":[["1","9223372036854775807"],["2","7"],["3","1.50"],["4","2.25e-9"],["5","abc"],["6",{"$":"date","v":1577923200000,"ns":0}],["7",true],["8",null]]}]},{"ev":"call","id":21,"t":201.1,"name":"nextResultSet","args":[1,{"connectionId":0,"statementId":1}]},{"ev":"return","of":21,"t":201.2,"result":[null,{"meta":[{"name":"i","nullable":false,"type":"number","sqlType":"int","size":10},{"name":"v","nullable":true,"type":"text","sqlType":"sql_variant","size":8000}],"handle":{"connectionId":0,"statementId":1},"endOfRows":true,"endOfResults":true,"rowCount":0}]},{"ev":"call","id":23,"t":201.3,"name":"releaseStatement","args":[1,{"connectionId":0,"statementId":1}]},{"ev":"state","of":14,"t":201.3,"change":{"handle":{"connectionId":0,"statementId":1},"oldState":"STATEMENT_READING","newState":"STATEMENT_CLOSED"}},{"ev":"return","of":23,"t":201.3,"result":[null,true]},{"ev":"call","id":26,"t":358.3,"name":"query","args":[2,{"query_str":"select i, v from (values (1, cast(cast(1.5 as decimal(5,2)) as sql_variant)), (2, cast(cast(7 as int) as sql_variant)), (3, cast(cast(9223372036854775807 as bigint) as sql_variant)), (4, cast(cast(2.25e-9 as float) as sql_variant)), (5, cast(cast(N'abc' as nvarchar(10)) as sql_variant)), (6, cast(cast('2020-01-02' as datetime) as sql_variant)), (7, cast(cast(1 as bit) as sql_variant)), (8, cast(null as sql_variant))) t(i, v) order by i","numeric_string":true,"bigint_as_native":true,"stateChangeCallback":{"$":"function"}},[]]},{"ev":"state","of":26,"t":358.4,"change":{"handle":{"connectionId":0,"statementId":2},"oldState":"STATEMENT_CREATED","newState":"STATEMENT_BINDING"}},{"ev":"state","of":26,"t":358.4,"change":{"handle":{"connectionId":0,"statementId":2},"oldState":"STATEMENT_BINDING","newState":"STATEMENT_SUBMITTED"}},{"ev":"state","of":26,"t":359.4,"change":{"handle":{"connectionId":0,"statementId":2},"oldState":"STATEMENT_SUBMITTED","newState":"STATEMENT_READING"}},{"ev":"return","of":26,"t":359.5,"result":[null,{"meta":[{"name":"i","nullable":false,"type":"number","sqlType":"int","size":10},{"name":"v","nullable":true,"type":"text","sqlType":"sql_variant","size":8000}],"handle":{"connectionId":0,"statementId":2},"endOfRows":true,"endOfResults":false,"rowCount":0},true]},{"ev":"call","id":31,"t":359.5,"name":"fetchRows","args":[2,{"connectionId":0,"statementId":2},{"asArrays":true,"batchSize":50,"asObjects":false}]},{"ev":"return","of":31,"t":359.6,"result":[null,{"endOfRows":true,"endOfResults":false,"rowCount":0,"data":[["1","1.50"],["2","7"],["3","9223372036854775807"],["4","2.25e-9"],["5","abc"],["6",{"$":"date","v":1577923200000,"ns":0}],["7",true],["8",null]]}]},{"ev":"call","id":33,"t":359.7,"name":"nextResultSet","args":[2,{"connectionId":0,"statementId":2}]},{"ev":"return","of":33,"t":359.7,"result":[null,{"meta":[{"name":"i","nullable":false,"type":"number","sqlType":"int","size":10},{"name":"v","nullable":true,"type":"text","sqlType":"sql_variant","size":8000}],"handle":{"connectionId":0,"statementId":2},"endOfRows":true,"endOfResults":true,"rowCount":0}]},{"ev":"call","id":35,"t":359.7,"name":"releaseStatement","args":[2,{"connectionId":0,"statementId":2}]},{"ev":"state","of":26,"t":359.8,"change":{"handle":{"connectionId":0,"statementId":2},"oldState":"STATEMENT_READING","newState":"STATEMENT_CLOSED"}},{"ev":"return","of":35,"t":359.8,"result":[null,true]},{"ev":"call","id":38,"t":516.9,"name":"query","args":[3,{"query_str":"select i, v from (values (1, cast(cast(2.25e-9 as float) as sql_variant)), (2, cast(cast(7 as int) as sql_variant)), (3, cast(cast(9223372036854775807 as bigint) as sql_variant)), (4, cast(cast(1.5 as decimal(5,2)) as sql_variant)), (5, cast(cast(N'abc' as nvarchar(10)) as sql_variant)), (6, cast(cast('2020-01-02' as datetime) as sql_variant)), (7, cast(cast(1 as bit) as sql_variant)), (8, cast(null as sql_variant))) t(i, v) order by i","numeric_string":true,"bigint_as_native":true,"stateChangeCallback":{"$":"function"}},[]]},{"ev":"state","of":38,"t":517,"change":{"handle":{"connectionId":0,"statementId":3},"oldState":"STATEMENT_CREATED","newState":"STATEMENT_BINDING"}},{"ev":"state","of":38,"t":517,"change":{"handle":{"connectionId":0,"statementId":3},"oldState":"STATEMENT_BINDING","newState":"STATEMENT_SUBMITTED"}},{"ev":"state","of":38,"t":518,"change":{"handle":{"connectionId":0,"statementId":3},"oldState":"STATEMENT_SUBMITTED","newState":"STATEMENT_READING"}},{"ev":"return","of":38,"t":518,"result":[null,{"meta":[{"name":"i","nullable":false,"type":"number","sqlType":"int","size":10},{"name":"v","nullable":true,"type":"text","sqlType":"sql_variant","size":8000}],"handle":{"connectionId":0,"statementId":3},"endOfRows":true,"endOfResults":false,"rowCount":0},true]},{"ev":"call","id":43,"t":518.1,"name":"fetchRows","args":[3,{"connectionId":0,"statementId":3},{"asArrays":true,"batchSize":50,"asObjects":false}]},{"ev":"return","of":43,"t":518.2,"result":[null,{"endOfRows":true,"endOfResults":false,"rowCount":0,"data":[["1","2.25e-9"],["2","7"],["3","9223372036854775807"],["4","1.50"],["5","abc"],["6",{"$":"date","v":1577923200000,"ns":0}],["7",true],["8",null]]}]},{"ev":"call","id":45,"t":518.2,"name":"nextResultSet","args":[3,{"connectionId":0,"statementId":3}]},{"ev":"return","of":45,"t":518.3,"result":[null,{"meta":[{"name":"i","nullable":false,"type":"number","sqlType":"int","size":10},{"name":"v","nullable":true,"type":"text","sqlType":"sql_variant","size":8000}],"handle":{"connectionId":0,"statementId":3},"endOfRows":true,"endOfResults":true,"rowCount":0}]},{"ev":"call","id":47,"t":518.3,"name":"releaseStatement","args":[3,{"connectionId":0,"statementId":3}]},{"ev":"state","of":38,"t":518.3,"change":{"handle":{"connectionId":0,"statementId":3},"oldState":"STATEMENT_READING","newState":"STATEMENT_CLOSED"}},{"ev":"return","of":47,"t":518.3,"result":[null,true]},{"ev":"call","id":50,"t":674.9,"name":"query","args":[4,{"query_str":"select i, v from (values (1, cast(cast(N'abc' as nvarchar(10)) as sql_variant)), (2, cast(cast(7 as int) as sql_variant)), (3, cast(cast(9223372036854775807 as bigint) as sql_variant)), (4, cast(cast(1.5 as decimal(5,2)) as sql_variant)), (5, cast(cast(2.25e-9 as float) as sql_variant)), (6, cast(cast('2020-01-02' as datetime) as sql_variant)), (7, cast(cast(1 as bit) as sql_variant)), (8, cast(null as sql_variant))) t(i, v) order by i","numeric_string":true,"bigint_as_native":true,"stateChangeCallback":{"$":"function"}},[]]},{"ev":"state","of":50,"t":675,"change":{"handle":{"connectionId":0,"statementId":4},"oldState":"STATEMENT_CREATED","newState":"STATEMENT_BINDING"}},{"ev":"state","of":50,"t":675,"change":{"handle":{"connectionId":0,"statementId":4},"oldState":"STATEMENT_BINDING","newState":"STATEMENT_SUBMITTED"}},{"ev":"state","of":50,"t":676,"change":{"handle":{"connectionId":0,"statementId":4},"oldState":"STATEMENT_SUBMITTED","newState":"STATEMENT_READING"}},{"ev":"return","of":50,"t":676,"result":[null,{"meta":[{"name":"i","nullable":false,"type":"number","sqlType":"int","size":10},{"name":"v","nullable":true,"type":"text","sqlType":"sql_variant","size":8000}],"handle":{"connectionId":0,"statementId":4},"endOfRows":true,"endOfResults":false,"rowCount":0},true]},{"ev":"call","id":55,"t":676.1,"name":"fetchRows","args":[4,{"connectionId":0,"statementId":4},{"asArrays":true,"batchSize":50,"asObjects":false}]},{"ev":"return","of":55,"t":676.2,"result":[null,{"endOfRows":true,"endOfResults":false,"rowCount":0,"data":[["1","abc"],["2","7"],["3","9223372036854775807"],["4","1.50"],["5","2.25e-9"],["6",{"$":"date","v":1577923200000,"ns":0}],["7",true],["8",null]]}]},{"ev":"call","id":57,"t":676.2,"name":"nextResultSet","args":[4,{"connectionId":0,"statementId":4}]},{"ev":"return","of":57,"t":676.2,"result":[null,{"meta":[{"name":"i","nullable":false,"type":"number","sqlType":"int","size":10},{"name":"v","nullable":true,"type":"text","sqlType":"sql_variant","size":8000}],"handle":{"connectionId":0,"statementId":4},"endOfRows":true,"endOfResults":true,"rowCount":0}]},{"ev":"call","id":59,"t":676.3,"name":"releaseStatement","args":[4,{"connectionId":0,"statementId":4}]},{"ev":"state","of":50,"t":676.3,"change":{"handle":{"connectionId":0,"statementId":4},"oldState":"STATEMENT_READING","newState":"STATEMENT_CLOSED"}},{"ev":"return","of":59,"t":676.3,"result":[null,true]},{"ev":"call","id":62,"t":831.6,"name":"query","args":[5,{"query_str":"select i, v from (values (1, cast(cast('2020-01-02' as datetime) as sql_variant)), (2, cast(cast(7 as int) as sql_variant)), (3, cast(cast(9223372036854775807 as bigint) as sql_variant)), (4, cast(cast(1.5 as decimal(5,2)) as sql_variant)), (5, cast(cast(2.25e-9 as float) as sql_variant)), (6, cast(cast(N'abc' as nvarchar(10)) as sql_variant)), (7, cast(cast(1 as bit) as sql_variant)), (8, cast(null as sql_variant))) t(i, v) order by i","numeric_string":true,"bigint_as_native":true,"stateChangeCallback":{"$":"function"}},[]]},{"ev":"state","of":62,"t":831.8,"change":{"handle":{"connectionId":0,"statementId":5},"oldState":"STATEMENT_CREATED","newState":"STATEMENT_BINDING"}},{"ev":"state","of":62,"t":831.8,"change":{"handle":{"connectionId":0,"statementId":5},"oldState":"STATEMENT_BINDING","newState":"STATEMENT_SUBMITTED"}},{"ev":"state","of":62,"t":832.9,"change":{"handle":{"connectionId":0,"statementId":5},"oldState":"STATEMENT_SUBMITTED","newState":"STATEMENT_READING"}},{"ev":"return","of":62,"t":832.9,"result":[null,{"meta":[{"name":"i","nullable":false,"type":"number","sqlType":"int","size":10},{"name":"v","nullable":true,"type":"text","sqlType":"sql_variant","size":8000}],"handle":{"connectionId":0,"statementId":5},"endOfRows":true,"endOfResults":false,"rowCount":0},true]},{"ev":"call","id":67,"t":833,"name":"fetchRows","args":[5,{"connectionId":0,"statementId":5},{"asArrays":true,"batchSize":50,"asObjects":false}]},{"ev":"return","of":67,"t":833.1,"result":[null,{"endOfRows":true,"endOfResults":false,"rowCount":0,"data":[["1",{"$":"date","v":1577923200000,"ns":0}],["2","7"],["3","9223372036854775807"],["4","1.50"],["5","2.25e-9"],["6","abc"],["7",true],["8",null]]}]},{"ev":"call","id":69,"t":833.1,"name":"nextResultSet","args":[5,{"connectionId":0,"statementId":5}]},{"ev":"return","of":69,"t":833.2,"result":[null,{"meta":[{"name":"i","nullable":false,"type":"number","sqlType":"int","size":10},{"name":"v","nullable":true,"type":"text","sqlType":"sql_variant","size":8000}],"handle":{"connectionId":0,"statementId":5},"endOfRows":true,"endOfResults":true,"rowCount":0}]},{"ev":"call","id":71,"t":833.3,"name":"releaseStatement","args":[5,{"connectionId":0,"statementId":5}]},{"ev":"state","of":62,"t":833.3,"change":{"handle":{"connectionId":0,"statementId":5},"oldState":"STATEMENT_READING","newState":"STATEMENT_CLOSED"}},{"ev":"return","of":71,"t":833.3,"result":[null,true]},{"ev":"call","id":74,"t":987.1,"name":"query","args":[6,{"query_str":"select i, v from (values (1, cast(cast(1 as bit) as sql_variant)), (2, cast(cast(7 as int) as sql_variant)), (3, cast(cast(9223372036854775807 as bigint) as sql_variant)), (4, cast(cast(1.5 as decimal(5,2)) as sql_variant)), (5, cast(cast(2.25e-9 as float) as sql_variant)), (6, cast(cast(N'abc' as nvarchar(10)) as sql_variant)), (7, cast(cast('2020-01-02' as datetime) as sql_variant)), (8, cast(null as sql_variant))) t(i, v) order by i","numeric_string":true,"bigint_as_native":true,"stateChangeCallback":{"$":"function"}},[]]},{"ev":"state","of":74,"t":987.2,"change":{"handle":{"connectionId":0,"statementId":6},"oldState":"STATEMENT_CREATED","newState":"STATEMENT_BINDING"}},{"ev":"state","of":74,"t":987.2,"change":{"handle":{"connectionId":0,"statementId":6},"oldState":"STATEMENT_BINDING","newState":"STATEMENT_SUBMITTED"}},{"ev":"state","of":74,"t":988.3,"change":{"handle":{"connectionId":0,"statementId":6},"oldState":"STATEMENT_SUBMITTED","newState":"STATEMENT_READING"}},{"ev":"return","of":74,"t":988.3,"result":[null,{"meta":[{"name":"i","nullable":false,"type":"number","sqlType":"int","size":10},{"name":"v","nullable":true,"type":"text","sqlType":"sql_variant","size":8000}],"handle":{"connectionId":0,"statementId":6},"endOfRows":true,"endOfResults":false,"rowCount":0},true]},{"ev":"call","id":79,"t":988.4,"name":"fetchRows","args":[6,{"connectionId":0,"statementId":6},{"asArrays":true,"batchSize":50,"asObjects":false}]},{"ev":"return","of":79,"t":988.5,"result":[null,{"endOfRows":true,"endOfResults":false,"rowCount":0,"data":[["1",true],["2","7"],["3","9223372036854775807"],["4","1.50"],["5","2.25e-9"],["6","abc"],["7",{"$":"date","v":1577923200000,"ns":0}],["8",null]]}]},{"ev":"call","id":81,"t":988.5,"name":"nextResultSet","args":[6,{"connectionId":0,"statementId":6}]},{"ev":"return","of":81,"t":988.6,"result":[null,{"meta":[{"name":"i","nullable":false,"type":"number","sqlType":"int","size":10},{"name":"v","nullable":true,"type":"text","sqlType":"sql_variant","size":8000}],"handle":{"connectionId":0,"statementId":6},"endOfRows":true,"endOfResults":true,"rowCount":0}]},{"ev":"call","id":83,"t":988.6,"name":"releaseStatement","args":[6,{"connectionId":0,"statementId":6}]},{"ev":"state","of":74,"t":988.6,"change":{"handle":{"connectionId":0,"statementId":6},"oldState":"STATEMENT_READING","newState":"STATEMENT_CLOSED"}},{"ev":"return","of":83,"t":988.6,"result":[null,true]},{"ev":"call","id":86,"t":1142.5,"name":"query","args":[7,{"query_str":"select i, v from (values (1, cast(null as sql_variant)), (2, cast(cast(7 as int) as sql_variant)), (3, cast(cast(9223372036854775807 as bigint) as sql_variant)), (4, cast(cast(1.5 as decimal(5,2)) as sql_variant)), (5, cast(cast(2.25e-9 as float) as sql_variant)), (6, cast(cast(N'abc' as nvarchar(10)) as sql_variant)), (7, cast(cast('2020-01-02' as datetime) as sql_variant)), (8, cast(cast(1 as bit) as sql_variant))) t(i, v) order by i","numeric_string":true,"bigint_as_native":true,"stateChangeCallback":{"$":"function"}},[]]},{"ev":"state","of":86,"t":1142.6,"change":{"handle":{"connectionId":0,"statementId":7},"oldState":"STATEMENT_CREATED","newState":"STATEMENT_BINDING"}},{"ev":"state","of":86,"t":1142.6,"change":{"handle":{"connectionId":0,"statementId":7},"oldState":"STATEMENT_BINDING","newState":"STATEMENT_SUBMITTED"}},{"ev":"state","of":86,"t":1143.8,"change":{"handle":{"connectionId":0,"statementId":7},"oldState":"STATEMENT_SUBMITTED","newState":"STATEMENT_READING"}},{"ev":"return","of":86,"t":1143.9,"result":[null,{"meta":[{"name":"i","nullable":false,"type":"number","sqlType":"int","size":10},{"name":"v","nullable":true,"type":"text","sqlType":"sql_variant","size":8000}],"handle":{"connectionId":0,"statementId":7},"endOfRows":true,"endOfResults":false,"rowCount":0},true]},{"ev":"call","id":91,"t":1144,"name":"fetchRows","args":[7,{"connectionId":0,"statementId":7},{"asArrays":true,"batchSize":50,"asObjects":false}]},{"ev":"return","of":91,"t":1144.1,"result":[null,{"endOfRows":true,"endOfResults":false,"rowCount":0,"data":[["1",null],["2","7"],["3","9223372036854775807"],["4","1.50"],["5","2.25e-9"],["6","abc"],["7",{"$":"date","v":1577923200000,"ns":0}],["8",true]]}]},{"ev":"call","id":93,"t":1144.2,"name":"nextResultSet","args":[7,{"connectionId":0,"statementId":7}]},{"ev":"return","of":93,"t":1144.2,"result":[null,{"meta":[{"name":"i","nullable":false,"type":"number","sqlType":"int","size":10},{"name":"v","nullable":true,"type":"text","sqlType":"sql_variant","size":8000}],"handle":{"connectionId":0,"statementId":7},"endOfRows":true,"endOfResults":true,"rowCount":0}]},{"ev":"call","id":95,"t":1144.3,"name":"releaseStatement","args":[7,{"connectionId":0,"statementId":7}]},{"ev":"state","of":86,"t":1144.3,"change":{"handle":{"connectionId":0,"statementId":7},"oldState":"STATEMENT_READING","newState":"STATEMENT_CLOSED"}},{"ev":"return","of":95,"t":1144.3,"result":[null,true]},{"ev":"call","id":98,"t":1456.7,"name":"query","args":[8,{"query_str":"select 1 as n","query_timeout":0,"query_polling":false,"query_tz_adjustment":0,"numeric_string":false,"bigint_as_native":false,"stateChangeCallback":{"$":"function"}},[]]},{"ev":"state","of":98,"t":1456.8,"change":{"handle":{"connectionId":0,"statementId":8},"oldState":"STATEMENT_CREATED","newState":"STATEMENT_BINDING"}},{"ev":"state","of":98,"t":1456.9,"change":{"handle":{"connectionId":0,"statementId":8},"oldState":"STATEMENT_BINDING","newState":"STATEMENT_SUBMITTED"}},{"ev":"state","of":98,"t":1457.8,"change":{"handle":{"connectionId":0,"statementId":8},"oldState":"STATEMENT_SUBMITTED","newState":"STATEMENT_READING"}},{"ev":"return","of":98,"t":1457.8,"result":[null,{"meta":[{"name":"n","nullable":false,"type":"number","sqlType":"int","size":10}],"handle":{"connectionId":0,"statementId":8},"endOfRows":true,"endOfResults":false,"rowCount":0},true]},{"ev":"call","id":103,"t":1457.9,"name":"fetchRows","args":[8,{"connectionId":0,"statementId":8},{"asArrays":true,"batchSize":50,"asObjects":false}]},{"ev":"return","of":103,"t":1457.9,"result":[null,{"endOfRows":true,"endOfResults":false,"rowCount":0,"data":[[1]]}]},{"ev":"call","id":105,"t":1458,"name":"nextResultSet","args":[8,{"connectionId":0,"statementId":8}]},{"ev":"return","of":105,"t":1458.1,"result":[null,{"meta":[{"name":"n","nullable":false,"type":"number","sqlType":"int","size":10}],"handle":{"connectionId":0,"statementId":8},"endOfRows":true,"endOfResults":true,"rowCount":0}]},{"ev":"call","id":107,"t":1458.1,"name":"releaseStatement","args":[8,{"connectionId":0,"statementId":8}]},{"ev":"state","of":98,"t":1458.1,"change":{"handle":{"connectionId":0,"statementId":8},"oldState":"STATEMENT_READING","newState":"STATEMENT_CLOSED"}},{"ev":"return","of":107,"t":1458.1,"result":[null,true]},{"ev":"call","id":110,"t":1458.3,"name":"close","args":[]},{"ev":"return","of":110,"t":1458.4,"result":[null,true]}]} \ No newline at end of file diff --git a/test/contract/native/scripts/issue-497.win32.json b/test/contract/native/scripts/issue-497.win32.json new file mode 100644 index 00000000..9085719d --- /dev/null +++ b/test/contract/native/scripts/issue-497.win32.json @@ -0,0 +1 @@ +{"scenario":"scripts/issue-497","transcript":["== int first, numeric strings off","int: submitted","int: meta i,v","int: row","int: column 0 1","int: column 1 7","int: row","int: column 0 2","int: column 1 9223372036854775807n","int: row","int: column 0 3","int: column 1 1.5","int: row","int: column 0 4","int: column 1 2.25e-9","int: row","int: column 0 5","int: column 1 \"abc\"","int: row","int: column 0 6","int: column 1 2020-01-02T00:00:00.000Z","int: row","int: column 0 7","int: column 1 true","int: row","int: column 0 8","int: column 1 null","int: done","int: free","== bigint first, numeric strings off","bigint: submitted","bigint: meta i,v","bigint: row","bigint: column 0 1","bigint: column 1 9223372036854775807n","bigint: row","bigint: column 0 2","bigint: column 1 7","bigint: row","bigint: column 0 3","bigint: column 1 1.5","bigint: row","bigint: column 0 4","bigint: column 1 2.25e-9","bigint: row","bigint: column 0 5","bigint: column 1 \"abc\"","bigint: row","bigint: column 0 6","bigint: column 1 2020-01-02T00:00:00.000Z","bigint: row","bigint: column 0 7","bigint: column 1 true","bigint: row","bigint: column 0 8","bigint: column 1 null","bigint: done","bigint: free","== decimal first, numeric strings off","decimal: submitted","decimal: meta i,v","decimal: row","decimal: column 0 1","decimal: column 1 1.5","decimal: row","decimal: column 0 2","decimal: column 1 7","decimal: row","decimal: column 0 3","decimal: column 1 9223372036854775807n","decimal: row","decimal: column 0 4","decimal: column 1 2.25e-9","decimal: row","decimal: column 0 5","decimal: column 1 \"abc\"","decimal: row","decimal: column 0 6","decimal: column 1 2020-01-02T00:00:00.000Z","decimal: row","decimal: column 0 7","decimal: column 1 true","decimal: row","decimal: column 0 8","decimal: column 1 null","decimal: done","decimal: free","== float first, numeric strings off","float: submitted","float: meta i,v","float: row","float: column 0 1","float: column 1 2.25e-9","float: row","float: column 0 2","float: column 1 7","float: row","float: column 0 3","float: column 1 9223372036854775807n","float: row","float: column 0 4","float: column 1 1.5","float: row","float: column 0 5","float: column 1 \"abc\"","float: row","float: column 0 6","float: column 1 2020-01-02T00:00:00.000Z","float: row","float: column 0 7","float: column 1 true","float: row","float: column 0 8","float: column 1 null","float: done","float: free","== nvarchar first, numeric strings off","nvarchar: submitted","nvarchar: meta i,v","nvarchar: row","nvarchar: column 0 1","nvarchar: column 1 \"abc\"","nvarchar: row","nvarchar: column 0 2","nvarchar: column 1 7","nvarchar: row","nvarchar: column 0 3","nvarchar: column 1 9223372036854775807n","nvarchar: row","nvarchar: column 0 4","nvarchar: column 1 1.5","nvarchar: row","nvarchar: column 0 5","nvarchar: column 1 2.25e-9","nvarchar: row","nvarchar: column 0 6","nvarchar: column 1 2020-01-02T00:00:00.000Z","nvarchar: row","nvarchar: column 0 7","nvarchar: column 1 true","nvarchar: row","nvarchar: column 0 8","nvarchar: column 1 null","nvarchar: done","nvarchar: free","== datetime first, numeric strings off","datetime: submitted","datetime: meta i,v","datetime: row","datetime: column 0 1","datetime: column 1 2020-01-02T00:00:00.000Z","datetime: row","datetime: column 0 2","datetime: column 1 7","datetime: row","datetime: column 0 3","datetime: column 1 9223372036854775807n","datetime: row","datetime: column 0 4","datetime: column 1 1.5","datetime: row","datetime: column 0 5","datetime: column 1 2.25e-9","datetime: row","datetime: column 0 6","datetime: column 1 \"abc\"","datetime: row","datetime: column 0 7","datetime: column 1 true","datetime: row","datetime: column 0 8","datetime: column 1 null","datetime: done","datetime: free","== bit first, numeric strings off","bit: submitted","bit: meta i,v","bit: row","bit: column 0 1","bit: column 1 true","bit: row","bit: column 0 2","bit: column 1 7","bit: row","bit: column 0 3","bit: column 1 9223372036854775807n","bit: row","bit: column 0 4","bit: column 1 1.5","bit: row","bit: column 0 5","bit: column 1 2.25e-9","bit: row","bit: column 0 6","bit: column 1 \"abc\"","bit: row","bit: column 0 7","bit: column 1 2020-01-02T00:00:00.000Z","bit: row","bit: column 0 8","bit: column 1 null","bit: done","bit: free","== null first, numeric strings off","null: submitted","null: meta i,v","null: row","null: column 0 1","null: column 1 null","null: row","null: column 0 2","null: column 1 7","null: row","null: column 0 3","null: column 1 9223372036854775807n","null: row","null: column 0 4","null: column 1 1.5","null: row","null: column 0 5","null: column 1 2.25e-9","null: row","null: column 0 6","null: column 1 \"abc\"","null: row","null: column 0 7","null: column 1 2020-01-02T00:00:00.000Z","null: row","null: column 0 8","null: column 1 true","null: done","null: free","check ok"],"log":[{"ev":"call","id":0,"t":10.8,"name":"open","args":["",0]},{"ev":"return","of":0,"t":30.9,"result":[null,{"success":true}]},{"ev":"call","id":2,"t":32.5,"name":"query","args":[0,{"query_str":"select i, v from (values (1, cast(cast(7 as int) as sql_variant)), (2, cast(cast(9223372036854775807 as bigint) as sql_variant)), (3, cast(cast(1.5 as decimal(5,2)) as sql_variant)), (4, cast(cast(2.25e-9 as float) as sql_variant)), (5, cast(cast(N'abc' as nvarchar(10)) as sql_variant)), (6, cast(cast('2020-01-02' as datetime) as sql_variant)), (7, cast(cast(1 as bit) as sql_variant)), (8, cast(null as sql_variant))) t(i, v) order by i","numeric_string":false,"bigint_as_native":true,"stateChangeCallback":{"$":"function"}},[]]},{"ev":"state","of":2,"t":32.7,"change":{"handle":{"connectionId":0,"statementId":0},"oldState":"STATEMENT_CREATED","newState":"STATEMENT_BINDING"}},{"ev":"state","of":2,"t":32.8,"change":{"handle":{"connectionId":0,"statementId":0},"oldState":"STATEMENT_BINDING","newState":"STATEMENT_SUBMITTED"}},{"ev":"state","of":2,"t":33.3,"change":{"handle":{"connectionId":0,"statementId":0},"oldState":"STATEMENT_SUBMITTED","newState":"STATEMENT_READING"}},{"ev":"return","of":2,"t":33.4,"result":[null,{"meta":[{"name":"i","nullable":false,"type":"number","sqlType":"int","size":10},{"name":"v","nullable":true,"type":"text","sqlType":"sql_variant","size":8000}],"handle":{"connectionId":0,"statementId":0},"endOfRows":true,"endOfResults":false,"rowCount":0},true]},{"ev":"call","id":7,"t":33.6,"name":"fetchRows","args":[0,{"connectionId":0,"statementId":0},{"asArrays":true,"batchSize":50,"asObjects":false}]},{"ev":"return","of":7,"t":33.9,"result":[null,{"endOfRows":true,"endOfResults":false,"rowCount":0,"data":[[1,7],[2,{"$":"bigint","v":"9223372036854775807"}],[3,1.5],[4,2.25e-9],[5,"abc"],[6,{"$":"date","v":1577923200000,"ns":0}],[7,true],[8,null]]}]},{"ev":"call","id":9,"t":34.2,"name":"nextResultSet","args":[0,{"connectionId":0,"statementId":0}]},{"ev":"return","of":9,"t":34.3,"result":[null,{"meta":[{"name":"i","nullable":false,"type":"number","sqlType":"int","size":10},{"name":"v","nullable":true,"type":"text","sqlType":"sql_variant","size":8000}],"handle":{"connectionId":0,"statementId":0},"endOfRows":true,"endOfResults":true,"rowCount":0}]},{"ev":"call","id":11,"t":34.6,"name":"releaseStatement","args":[0,{"connectionId":0,"statementId":0}]},{"ev":"state","of":2,"t":34.6,"change":{"handle":{"connectionId":0,"statementId":0},"oldState":"STATEMENT_READING","newState":"STATEMENT_CLOSED"}},{"ev":"return","of":11,"t":34.7,"result":[null,true]},{"ev":"call","id":14,"t":186.9,"name":"query","args":[1,{"query_str":"select i, v from (values (1, cast(cast(9223372036854775807 as bigint) as sql_variant)), (2, cast(cast(7 as int) as sql_variant)), (3, cast(cast(1.5 as decimal(5,2)) as sql_variant)), (4, cast(cast(2.25e-9 as float) as sql_variant)), (5, cast(cast(N'abc' as nvarchar(10)) as sql_variant)), (6, cast(cast('2020-01-02' as datetime) as sql_variant)), (7, cast(cast(1 as bit) as sql_variant)), (8, cast(null as sql_variant))) t(i, v) order by i","numeric_string":false,"bigint_as_native":true,"stateChangeCallback":{"$":"function"}},[]]},{"ev":"state","of":14,"t":187,"change":{"handle":{"connectionId":0,"statementId":1},"oldState":"STATEMENT_CREATED","newState":"STATEMENT_BINDING"}},{"ev":"state","of":14,"t":187,"change":{"handle":{"connectionId":0,"statementId":1},"oldState":"STATEMENT_BINDING","newState":"STATEMENT_SUBMITTED"}},{"ev":"state","of":14,"t":188,"change":{"handle":{"connectionId":0,"statementId":1},"oldState":"STATEMENT_SUBMITTED","newState":"STATEMENT_READING"}},{"ev":"return","of":14,"t":188,"result":[null,{"meta":[{"name":"i","nullable":false,"type":"number","sqlType":"int","size":10},{"name":"v","nullable":true,"type":"text","sqlType":"sql_variant","size":8000}],"handle":{"connectionId":0,"statementId":1},"endOfRows":true,"endOfResults":false,"rowCount":0},true]},{"ev":"call","id":19,"t":188,"name":"fetchRows","args":[1,{"connectionId":0,"statementId":1},{"asArrays":true,"batchSize":50,"asObjects":false}]},{"ev":"return","of":19,"t":188.1,"result":[null,{"endOfRows":true,"endOfResults":false,"rowCount":0,"data":[[1,{"$":"bigint","v":"9223372036854775807"}],[2,7],[3,1.5],[4,2.25e-9],[5,"abc"],[6,{"$":"date","v":1577923200000,"ns":0}],[7,true],[8,null]]}]},{"ev":"call","id":21,"t":188.2,"name":"nextResultSet","args":[1,{"connectionId":0,"statementId":1}]},{"ev":"return","of":21,"t":188.2,"result":[null,{"meta":[{"name":"i","nullable":false,"type":"number","sqlType":"int","size":10},{"name":"v","nullable":true,"type":"text","sqlType":"sql_variant","size":8000}],"handle":{"connectionId":0,"statementId":1},"endOfRows":true,"endOfResults":true,"rowCount":0}]},{"ev":"call","id":23,"t":188.3,"name":"releaseStatement","args":[1,{"connectionId":0,"statementId":1}]},{"ev":"state","of":14,"t":188.3,"change":{"handle":{"connectionId":0,"statementId":1},"oldState":"STATEMENT_READING","newState":"STATEMENT_CLOSED"}},{"ev":"return","of":23,"t":188.3,"result":[null,true]},{"ev":"call","id":26,"t":343.7,"name":"query","args":[2,{"query_str":"select i, v from (values (1, cast(cast(1.5 as decimal(5,2)) as sql_variant)), (2, cast(cast(7 as int) as sql_variant)), (3, cast(cast(9223372036854775807 as bigint) as sql_variant)), (4, cast(cast(2.25e-9 as float) as sql_variant)), (5, cast(cast(N'abc' as nvarchar(10)) as sql_variant)), (6, cast(cast('2020-01-02' as datetime) as sql_variant)), (7, cast(cast(1 as bit) as sql_variant)), (8, cast(null as sql_variant))) t(i, v) order by i","numeric_string":false,"bigint_as_native":true,"stateChangeCallback":{"$":"function"}},[]]},{"ev":"state","of":26,"t":343.9,"change":{"handle":{"connectionId":0,"statementId":2},"oldState":"STATEMENT_CREATED","newState":"STATEMENT_BINDING"}},{"ev":"state","of":26,"t":343.9,"change":{"handle":{"connectionId":0,"statementId":2},"oldState":"STATEMENT_BINDING","newState":"STATEMENT_SUBMITTED"}},{"ev":"state","of":26,"t":344.9,"change":{"handle":{"connectionId":0,"statementId":2},"oldState":"STATEMENT_SUBMITTED","newState":"STATEMENT_READING"}},{"ev":"return","of":26,"t":344.9,"result":[null,{"meta":[{"name":"i","nullable":false,"type":"number","sqlType":"int","size":10},{"name":"v","nullable":true,"type":"text","sqlType":"sql_variant","size":8000}],"handle":{"connectionId":0,"statementId":2},"endOfRows":true,"endOfResults":false,"rowCount":0},true]},{"ev":"call","id":31,"t":344.9,"name":"fetchRows","args":[2,{"connectionId":0,"statementId":2},{"asArrays":true,"batchSize":50,"asObjects":false}]},{"ev":"return","of":31,"t":345.1,"result":[null,{"endOfRows":true,"endOfResults":false,"rowCount":0,"data":[[1,1.5],[2,7],[3,{"$":"bigint","v":"9223372036854775807"}],[4,2.25e-9],[5,"abc"],[6,{"$":"date","v":1577923200000,"ns":0}],[7,true],[8,null]]}]},{"ev":"call","id":33,"t":345.1,"name":"nextResultSet","args":[2,{"connectionId":0,"statementId":2}]},{"ev":"return","of":33,"t":345.2,"result":[null,{"meta":[{"name":"i","nullable":false,"type":"number","sqlType":"int","size":10},{"name":"v","nullable":true,"type":"text","sqlType":"sql_variant","size":8000}],"handle":{"connectionId":0,"statementId":2},"endOfRows":true,"endOfResults":true,"rowCount":0}]},{"ev":"call","id":35,"t":345.2,"name":"releaseStatement","args":[2,{"connectionId":0,"statementId":2}]},{"ev":"state","of":26,"t":345.3,"change":{"handle":{"connectionId":0,"statementId":2},"oldState":"STATEMENT_READING","newState":"STATEMENT_CLOSED"}},{"ev":"return","of":35,"t":345.3,"result":[null,true]},{"ev":"call","id":38,"t":500.5,"name":"query","args":[3,{"query_str":"select i, v from (values (1, cast(cast(2.25e-9 as float) as sql_variant)), (2, cast(cast(7 as int) as sql_variant)), (3, cast(cast(9223372036854775807 as bigint) as sql_variant)), (4, cast(cast(1.5 as decimal(5,2)) as sql_variant)), (5, cast(cast(N'abc' as nvarchar(10)) as sql_variant)), (6, cast(cast('2020-01-02' as datetime) as sql_variant)), (7, cast(cast(1 as bit) as sql_variant)), (8, cast(null as sql_variant))) t(i, v) order by i","numeric_string":false,"bigint_as_native":true,"stateChangeCallback":{"$":"function"}},[]]},{"ev":"state","of":38,"t":500.6,"change":{"handle":{"connectionId":0,"statementId":3},"oldState":"STATEMENT_CREATED","newState":"STATEMENT_BINDING"}},{"ev":"state","of":38,"t":500.6,"change":{"handle":{"connectionId":0,"statementId":3},"oldState":"STATEMENT_BINDING","newState":"STATEMENT_SUBMITTED"}},{"ev":"state","of":38,"t":501.6,"change":{"handle":{"connectionId":0,"statementId":3},"oldState":"STATEMENT_SUBMITTED","newState":"STATEMENT_READING"}},{"ev":"return","of":38,"t":501.6,"result":[null,{"meta":[{"name":"i","nullable":false,"type":"number","sqlType":"int","size":10},{"name":"v","nullable":true,"type":"text","sqlType":"sql_variant","size":8000}],"handle":{"connectionId":0,"statementId":3},"endOfRows":true,"endOfResults":false,"rowCount":0},true]},{"ev":"call","id":43,"t":501.7,"name":"fetchRows","args":[3,{"connectionId":0,"statementId":3},{"asArrays":true,"batchSize":50,"asObjects":false}]},{"ev":"return","of":43,"t":501.8,"result":[null,{"endOfRows":true,"endOfResults":false,"rowCount":0,"data":[[1,2.25e-9],[2,7],[3,{"$":"bigint","v":"9223372036854775807"}],[4,1.5],[5,"abc"],[6,{"$":"date","v":1577923200000,"ns":0}],[7,true],[8,null]]}]},{"ev":"call","id":45,"t":501.8,"name":"nextResultSet","args":[3,{"connectionId":0,"statementId":3}]},{"ev":"return","of":45,"t":501.9,"result":[null,{"meta":[{"name":"i","nullable":false,"type":"number","sqlType":"int","size":10},{"name":"v","nullable":true,"type":"text","sqlType":"sql_variant","size":8000}],"handle":{"connectionId":0,"statementId":3},"endOfRows":true,"endOfResults":true,"rowCount":0}]},{"ev":"call","id":47,"t":501.9,"name":"releaseStatement","args":[3,{"connectionId":0,"statementId":3}]},{"ev":"state","of":38,"t":502,"change":{"handle":{"connectionId":0,"statementId":3},"oldState":"STATEMENT_READING","newState":"STATEMENT_CLOSED"}},{"ev":"return","of":47,"t":502,"result":[null,true]},{"ev":"call","id":50,"t":658.3,"name":"query","args":[4,{"query_str":"select i, v from (values (1, cast(cast(N'abc' as nvarchar(10)) as sql_variant)), (2, cast(cast(7 as int) as sql_variant)), (3, cast(cast(9223372036854775807 as bigint) as sql_variant)), (4, cast(cast(1.5 as decimal(5,2)) as sql_variant)), (5, cast(cast(2.25e-9 as float) as sql_variant)), (6, cast(cast('2020-01-02' as datetime) as sql_variant)), (7, cast(cast(1 as bit) as sql_variant)), (8, cast(null as sql_variant))) t(i, v) order by i","numeric_string":false,"bigint_as_native":true,"stateChangeCallback":{"$":"function"}},[]]},{"ev":"state","of":50,"t":658.5,"change":{"handle":{"connectionId":0,"statementId":4},"oldState":"STATEMENT_CREATED","newState":"STATEMENT_BINDING"}},{"ev":"state","of":50,"t":658.5,"change":{"handle":{"connectionId":0,"statementId":4},"oldState":"STATEMENT_BINDING","newState":"STATEMENT_SUBMITTED"}},{"ev":"state","of":50,"t":659.6,"change":{"handle":{"connectionId":0,"statementId":4},"oldState":"STATEMENT_SUBMITTED","newState":"STATEMENT_READING"}},{"ev":"return","of":50,"t":659.6,"result":[null,{"meta":[{"name":"i","nullable":false,"type":"number","sqlType":"int","size":10},{"name":"v","nullable":true,"type":"text","sqlType":"sql_variant","size":8000}],"handle":{"connectionId":0,"statementId":4},"endOfRows":true,"endOfResults":false,"rowCount":0},true]},{"ev":"call","id":55,"t":659.6,"name":"fetchRows","args":[4,{"connectionId":0,"statementId":4},{"asArrays":true,"batchSize":50,"asObjects":false}]},{"ev":"return","of":55,"t":659.7,"result":[null,{"endOfRows":true,"endOfResults":false,"rowCount":0,"data":[[1,"abc"],[2,7],[3,{"$":"bigint","v":"9223372036854775807"}],[4,1.5],[5,2.25e-9],[6,{"$":"date","v":1577923200000,"ns":0}],[7,true],[8,null]]}]},{"ev":"call","id":57,"t":659.8,"name":"nextResultSet","args":[4,{"connectionId":0,"statementId":4}]},{"ev":"return","of":57,"t":659.8,"result":[null,{"meta":[{"name":"i","nullable":false,"type":"number","sqlType":"int","size":10},{"name":"v","nullable":true,"type":"text","sqlType":"sql_variant","size":8000}],"handle":{"connectionId":0,"statementId":4},"endOfRows":true,"endOfResults":true,"rowCount":0}]},{"ev":"call","id":59,"t":659.9,"name":"releaseStatement","args":[4,{"connectionId":0,"statementId":4}]},{"ev":"state","of":50,"t":659.9,"change":{"handle":{"connectionId":0,"statementId":4},"oldState":"STATEMENT_READING","newState":"STATEMENT_CLOSED"}},{"ev":"return","of":59,"t":659.9,"result":[null,true]},{"ev":"call","id":62,"t":813.9,"name":"query","args":[5,{"query_str":"select i, v from (values (1, cast(cast('2020-01-02' as datetime) as sql_variant)), (2, cast(cast(7 as int) as sql_variant)), (3, cast(cast(9223372036854775807 as bigint) as sql_variant)), (4, cast(cast(1.5 as decimal(5,2)) as sql_variant)), (5, cast(cast(2.25e-9 as float) as sql_variant)), (6, cast(cast(N'abc' as nvarchar(10)) as sql_variant)), (7, cast(cast(1 as bit) as sql_variant)), (8, cast(null as sql_variant))) t(i, v) order by i","numeric_string":false,"bigint_as_native":true,"stateChangeCallback":{"$":"function"}},[]]},{"ev":"state","of":62,"t":814,"change":{"handle":{"connectionId":0,"statementId":5},"oldState":"STATEMENT_CREATED","newState":"STATEMENT_BINDING"}},{"ev":"state","of":62,"t":814,"change":{"handle":{"connectionId":0,"statementId":5},"oldState":"STATEMENT_BINDING","newState":"STATEMENT_SUBMITTED"}},{"ev":"state","of":62,"t":815.1,"change":{"handle":{"connectionId":0,"statementId":5},"oldState":"STATEMENT_SUBMITTED","newState":"STATEMENT_READING"}},{"ev":"return","of":62,"t":815.1,"result":[null,{"meta":[{"name":"i","nullable":false,"type":"number","sqlType":"int","size":10},{"name":"v","nullable":true,"type":"text","sqlType":"sql_variant","size":8000}],"handle":{"connectionId":0,"statementId":5},"endOfRows":true,"endOfResults":false,"rowCount":0},true]},{"ev":"call","id":67,"t":815.1,"name":"fetchRows","args":[5,{"connectionId":0,"statementId":5},{"asArrays":true,"batchSize":50,"asObjects":false}]},{"ev":"return","of":67,"t":815.2,"result":[null,{"endOfRows":true,"endOfResults":false,"rowCount":0,"data":[[1,{"$":"date","v":1577923200000,"ns":0}],[2,7],[3,{"$":"bigint","v":"9223372036854775807"}],[4,1.5],[5,2.25e-9],[6,"abc"],[7,true],[8,null]]}]},{"ev":"call","id":69,"t":815.3,"name":"nextResultSet","args":[5,{"connectionId":0,"statementId":5}]},{"ev":"return","of":69,"t":815.3,"result":[null,{"meta":[{"name":"i","nullable":false,"type":"number","sqlType":"int","size":10},{"name":"v","nullable":true,"type":"text","sqlType":"sql_variant","size":8000}],"handle":{"connectionId":0,"statementId":5},"endOfRows":true,"endOfResults":true,"rowCount":0}]},{"ev":"call","id":71,"t":815.3,"name":"releaseStatement","args":[5,{"connectionId":0,"statementId":5}]},{"ev":"state","of":62,"t":815.4,"change":{"handle":{"connectionId":0,"statementId":5},"oldState":"STATEMENT_READING","newState":"STATEMENT_CLOSED"}},{"ev":"return","of":71,"t":815.4,"result":[null,true]},{"ev":"call","id":74,"t":970.3,"name":"query","args":[6,{"query_str":"select i, v from (values (1, cast(cast(1 as bit) as sql_variant)), (2, cast(cast(7 as int) as sql_variant)), (3, cast(cast(9223372036854775807 as bigint) as sql_variant)), (4, cast(cast(1.5 as decimal(5,2)) as sql_variant)), (5, cast(cast(2.25e-9 as float) as sql_variant)), (6, cast(cast(N'abc' as nvarchar(10)) as sql_variant)), (7, cast(cast('2020-01-02' as datetime) as sql_variant)), (8, cast(null as sql_variant))) t(i, v) order by i","numeric_string":false,"bigint_as_native":true,"stateChangeCallback":{"$":"function"}},[]]},{"ev":"state","of":74,"t":970.4,"change":{"handle":{"connectionId":0,"statementId":6},"oldState":"STATEMENT_CREATED","newState":"STATEMENT_BINDING"}},{"ev":"state","of":74,"t":970.4,"change":{"handle":{"connectionId":0,"statementId":6},"oldState":"STATEMENT_BINDING","newState":"STATEMENT_SUBMITTED"}},{"ev":"state","of":74,"t":971.4,"change":{"handle":{"connectionId":0,"statementId":6},"oldState":"STATEMENT_SUBMITTED","newState":"STATEMENT_READING"}},{"ev":"return","of":74,"t":971.5,"result":[null,{"meta":[{"name":"i","nullable":false,"type":"number","sqlType":"int","size":10},{"name":"v","nullable":true,"type":"text","sqlType":"sql_variant","size":8000}],"handle":{"connectionId":0,"statementId":6},"endOfRows":true,"endOfResults":false,"rowCount":0},true]},{"ev":"call","id":79,"t":971.5,"name":"fetchRows","args":[6,{"connectionId":0,"statementId":6},{"asArrays":true,"batchSize":50,"asObjects":false}]},{"ev":"return","of":79,"t":971.6,"result":[null,{"endOfRows":true,"endOfResults":false,"rowCount":0,"data":[[1,true],[2,7],[3,{"$":"bigint","v":"9223372036854775807"}],[4,1.5],[5,2.25e-9],[6,"abc"],[7,{"$":"date","v":1577923200000,"ns":0}],[8,null]]}]},{"ev":"call","id":81,"t":971.6,"name":"nextResultSet","args":[6,{"connectionId":0,"statementId":6}]},{"ev":"return","of":81,"t":971.7,"result":[null,{"meta":[{"name":"i","nullable":false,"type":"number","sqlType":"int","size":10},{"name":"v","nullable":true,"type":"text","sqlType":"sql_variant","size":8000}],"handle":{"connectionId":0,"statementId":6},"endOfRows":true,"endOfResults":true,"rowCount":0}]},{"ev":"call","id":83,"t":971.7,"name":"releaseStatement","args":[6,{"connectionId":0,"statementId":6}]},{"ev":"state","of":74,"t":971.8,"change":{"handle":{"connectionId":0,"statementId":6},"oldState":"STATEMENT_READING","newState":"STATEMENT_CLOSED"}},{"ev":"return","of":83,"t":971.8,"result":[null,true]},{"ev":"call","id":86,"t":1126.5,"name":"query","args":[7,{"query_str":"select i, v from (values (1, cast(null as sql_variant)), (2, cast(cast(7 as int) as sql_variant)), (3, cast(cast(9223372036854775807 as bigint) as sql_variant)), (4, cast(cast(1.5 as decimal(5,2)) as sql_variant)), (5, cast(cast(2.25e-9 as float) as sql_variant)), (6, cast(cast(N'abc' as nvarchar(10)) as sql_variant)), (7, cast(cast('2020-01-02' as datetime) as sql_variant)), (8, cast(cast(1 as bit) as sql_variant))) t(i, v) order by i","numeric_string":false,"bigint_as_native":true,"stateChangeCallback":{"$":"function"}},[]]},{"ev":"state","of":86,"t":1126.7,"change":{"handle":{"connectionId":0,"statementId":7},"oldState":"STATEMENT_CREATED","newState":"STATEMENT_BINDING"}},{"ev":"state","of":86,"t":1126.7,"change":{"handle":{"connectionId":0,"statementId":7},"oldState":"STATEMENT_BINDING","newState":"STATEMENT_SUBMITTED"}},{"ev":"state","of":86,"t":1127.6,"change":{"handle":{"connectionId":0,"statementId":7},"oldState":"STATEMENT_SUBMITTED","newState":"STATEMENT_READING"}},{"ev":"return","of":86,"t":1127.7,"result":[null,{"meta":[{"name":"i","nullable":false,"type":"number","sqlType":"int","size":10},{"name":"v","nullable":true,"type":"text","sqlType":"sql_variant","size":8000}],"handle":{"connectionId":0,"statementId":7},"endOfRows":true,"endOfResults":false,"rowCount":0},true]},{"ev":"call","id":91,"t":1127.7,"name":"fetchRows","args":[7,{"connectionId":0,"statementId":7},{"asArrays":true,"batchSize":50,"asObjects":false}]},{"ev":"return","of":91,"t":1127.9,"result":[null,{"endOfRows":true,"endOfResults":false,"rowCount":0,"data":[[1,null],[2,7],[3,{"$":"bigint","v":"9223372036854775807"}],[4,1.5],[5,2.25e-9],[6,"abc"],[7,{"$":"date","v":1577923200000,"ns":0}],[8,true]]}]},{"ev":"call","id":93,"t":1127.9,"name":"nextResultSet","args":[7,{"connectionId":0,"statementId":7}]},{"ev":"return","of":93,"t":1128,"result":[null,{"meta":[{"name":"i","nullable":false,"type":"number","sqlType":"int","size":10},{"name":"v","nullable":true,"type":"text","sqlType":"sql_variant","size":8000}],"handle":{"connectionId":0,"statementId":7},"endOfRows":true,"endOfResults":true,"rowCount":0}]},{"ev":"call","id":95,"t":1128,"name":"releaseStatement","args":[7,{"connectionId":0,"statementId":7}]},{"ev":"state","of":86,"t":1128,"change":{"handle":{"connectionId":0,"statementId":7},"oldState":"STATEMENT_READING","newState":"STATEMENT_CLOSED"}},{"ev":"return","of":95,"t":1128,"result":[null,true]},{"ev":"call","id":98,"t":1441.5,"name":"query","args":[8,{"query_str":"select 1 as n","query_timeout":0,"query_polling":false,"query_tz_adjustment":0,"numeric_string":false,"bigint_as_native":false,"stateChangeCallback":{"$":"function"}},[]]},{"ev":"state","of":98,"t":1441.6,"change":{"handle":{"connectionId":0,"statementId":8},"oldState":"STATEMENT_CREATED","newState":"STATEMENT_BINDING"}},{"ev":"state","of":98,"t":1441.6,"change":{"handle":{"connectionId":0,"statementId":8},"oldState":"STATEMENT_BINDING","newState":"STATEMENT_SUBMITTED"}},{"ev":"state","of":98,"t":1442.6,"change":{"handle":{"connectionId":0,"statementId":8},"oldState":"STATEMENT_SUBMITTED","newState":"STATEMENT_READING"}},{"ev":"return","of":98,"t":1442.6,"result":[null,{"meta":[{"name":"n","nullable":false,"type":"number","sqlType":"int","size":10}],"handle":{"connectionId":0,"statementId":8},"endOfRows":true,"endOfResults":false,"rowCount":0},true]},{"ev":"call","id":103,"t":1442.7,"name":"fetchRows","args":[8,{"connectionId":0,"statementId":8},{"asArrays":true,"batchSize":50,"asObjects":false}]},{"ev":"return","of":103,"t":1442.7,"result":[null,{"endOfRows":true,"endOfResults":false,"rowCount":0,"data":[[1]]}]},{"ev":"call","id":105,"t":1442.8,"name":"nextResultSet","args":[8,{"connectionId":0,"statementId":8}]},{"ev":"return","of":105,"t":1442.9,"result":[null,{"meta":[{"name":"n","nullable":false,"type":"number","sqlType":"int","size":10}],"handle":{"connectionId":0,"statementId":8},"endOfRows":true,"endOfResults":true,"rowCount":0}]},{"ev":"call","id":107,"t":1442.9,"name":"releaseStatement","args":[8,{"connectionId":0,"statementId":8}]},{"ev":"state","of":98,"t":1442.9,"change":{"handle":{"connectionId":0,"statementId":8},"oldState":"STATEMENT_READING","newState":"STATEMENT_CLOSED"}},{"ev":"return","of":107,"t":1442.9,"result":[null,true]},{"ev":"call","id":110,"t":1443.1,"name":"close","args":[]},{"ev":"return","of":110,"t":1443.2,"result":[null,true]}]} \ No newline at end of file diff --git a/test/contract/native/scripts/issue-498.win32.json b/test/contract/native/scripts/issue-498.win32.json new file mode 100644 index 00000000..7109918c --- /dev/null +++ b/test/contract/native/scripts/issue-498.win32.json @@ -0,0 +1 @@ +{"scenario":"scripts/issue-498","transcript":["-- c0 cast(0.1234567890123 as float); c1 cast(1e-10 as float); c2 cast(1.5e300 as float); c3 cast(-2.5 as float); c4 cast(0.12345678 as real); c5 cast(1.0123456789 as decimal(38,10)); c6 cast(12345678901234567890.12 as decimal(38,2)); c7 cast(0.0000001 as decimal(10,7)); c8 cast(9007199254740993 as decimal(19,0)); c9 cast(709 as decimal(10,0)); c10 cast(922337203685477.5807 as money); c11 cast(-0.0001 as money); c12 cast(1.2345 as smallmoney); c13 cast(1.0123456789 as numeric(38,10)); c14 cast(0.0000001 as numeric(10,7)); c15 cast(9223372036854775807 as bigint)","== numeric strings off","plain: submitted","plain: meta c0,c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13,c14,c15","plain: row","plain: column 0 0.1234567890123","plain: column 1 1e-10","plain: column 2 1.5e+300","plain: column 3 -2.5","plain: column 4 0.12345678359270096","plain: column 5 1.0123456789","plain: column 6 12345678901234567000","plain: column 7 1e-7","plain: column 8 9007199254740992","plain: column 9 709","plain: column 10 922337203685477.6","plain: column 11 -0.0001","plain: column 12 1.2345","plain: column 13 1.0123456789","plain: column 14 1e-7","plain: column 15 9223372036854776000","plain: done","plain: free","== numeric strings on","ns: submitted","ns: meta c0,c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13,c14,c15","ns: row","ns: column 0 \"0.1234567890123\"","ns: column 1 \"1e-10\"","ns: column 2 \"1.5e+300\"","ns: column 3 \"-2.5\"","ns: column 4 \"0.12345678359270096\"","ns: column 5 \"1.0123456789\"","ns: column 6 \"12345678901234567000\"","ns: column 7 \"1e-7\"","ns: column 8 \"9007199254740992\"","ns: column 9 \"709\"","ns: column 10 \"922337203685477.6\"","ns: column 11 \"-0.0001\"","ns: column 12 \"1.2345\"","ns: column 13 \"1.0123456789\"","ns: column 14 \".0000001\"","ns: column 15 \"9223372036854775807\"","ns: done","ns: free","setup: submitted","setup: rowcount 1","setup: cb ok rows=0 more=false","setup: done","setup: free","== prepared, numeric strings on","ps: submitted","ps: meta n,d,f","ps: row","ps: column 0 \"1.0123456789\"","ps: column 1 \"12345678901234568\"","ps: column 2 \"1e-10\"","ps: done","ps: free","check ok"],"log":[{"ev":"call","id":0,"t":10.7,"name":"open","args":["",0]},{"ev":"return","of":0,"t":30,"result":[null,{"success":true}]},{"ev":"call","id":2,"t":31.6,"name":"query","args":[0,{"query_str":"select cast(0.1234567890123 as float) as c0, cast(1e-10 as float) as c1, cast(1.5e300 as float) as c2, cast(-2.5 as float) as c3, cast(0.12345678 as real) as c4, cast(1.0123456789 as decimal(38,10)) as c5, cast(12345678901234567890.12 as decimal(38,2)) as c6, cast(0.0000001 as decimal(10,7)) as c7, cast(9007199254740993 as decimal(19,0)) as c8, cast(709 as decimal(10,0)) as c9, cast(922337203685477.5807 as money) as c10, cast(-0.0001 as money) as c11, cast(1.2345 as smallmoney) as c12, cast(1.0123456789 as numeric(38,10)) as c13, cast(0.0000001 as numeric(10,7)) as c14, cast(9223372036854775807 as bigint) as c15","numeric_string":false,"bigint_as_native":false,"stateChangeCallback":{"$":"function"}},[]]},{"ev":"state","of":2,"t":31.8,"change":{"handle":{"connectionId":0,"statementId":0},"oldState":"STATEMENT_CREATED","newState":"STATEMENT_BINDING"}},{"ev":"state","of":2,"t":32,"change":{"handle":{"connectionId":0,"statementId":0},"oldState":"STATEMENT_BINDING","newState":"STATEMENT_SUBMITTED"}},{"ev":"state","of":2,"t":32.6,"change":{"handle":{"connectionId":0,"statementId":0},"oldState":"STATEMENT_SUBMITTED","newState":"STATEMENT_READING"}},{"ev":"return","of":2,"t":32.8,"result":[null,{"meta":[{"name":"c0","nullable":true,"type":"number","sqlType":"float","size":53},{"name":"c1","nullable":true,"type":"number","sqlType":"float","size":53},{"name":"c2","nullable":true,"type":"number","sqlType":"float","size":53},{"name":"c3","nullable":true,"type":"number","sqlType":"float","size":53},{"name":"c4","nullable":true,"type":"number","sqlType":"real","size":24},{"name":"c5","nullable":true,"type":"number","sqlType":"decimal","size":38},{"name":"c6","nullable":true,"type":"number","sqlType":"decimal","size":38},{"name":"c7","nullable":true,"type":"number","sqlType":"decimal","size":10},{"name":"c8","nullable":true,"type":"number","sqlType":"decimal","size":19},{"name":"c9","nullable":true,"type":"number","sqlType":"decimal","size":10},{"name":"c10","nullable":true,"type":"number","sqlType":"money","size":19},{"name":"c11","nullable":true,"type":"number","sqlType":"money","size":19},{"name":"c12","nullable":true,"type":"number","sqlType":"smallmoney","size":10},{"name":"c13","nullable":true,"type":"number","sqlType":"numeric","size":38},{"name":"c14","nullable":true,"type":"number","sqlType":"numeric","size":10},{"name":"c15","nullable":true,"type":"number","sqlType":"bigint","size":19}],"handle":{"connectionId":0,"statementId":0},"endOfRows":true,"endOfResults":false,"rowCount":0},true]},{"ev":"call","id":7,"t":33,"name":"fetchRows","args":[0,{"connectionId":0,"statementId":0},{"asArrays":true,"batchSize":50,"asObjects":false}]},{"ev":"return","of":7,"t":33.2,"result":[null,{"endOfRows":true,"endOfResults":false,"rowCount":0,"data":[[0.1234567890123,1e-10,1.5e+300,-2.5,0.12345678359270096,1.0123456789,12345678901234567000,1e-7,9007199254740992,709,922337203685477.6,-0.0001,1.2345,1.0123456789,1e-7,9223372036854776000]]}]},{"ev":"call","id":9,"t":33.5,"name":"nextResultSet","args":[0,{"connectionId":0,"statementId":0}]},{"ev":"return","of":9,"t":33.6,"result":[null,{"meta":[{"name":"c0","nullable":true,"type":"number","sqlType":"float","size":53},{"name":"c1","nullable":true,"type":"number","sqlType":"float","size":53},{"name":"c2","nullable":true,"type":"number","sqlType":"float","size":53},{"name":"c3","nullable":true,"type":"number","sqlType":"float","size":53},{"name":"c4","nullable":true,"type":"number","sqlType":"real","size":24},{"name":"c5","nullable":true,"type":"number","sqlType":"decimal","size":38},{"name":"c6","nullable":true,"type":"number","sqlType":"decimal","size":38},{"name":"c7","nullable":true,"type":"number","sqlType":"decimal","size":10},{"name":"c8","nullable":true,"type":"number","sqlType":"decimal","size":19},{"name":"c9","nullable":true,"type":"number","sqlType":"decimal","size":10},{"name":"c10","nullable":true,"type":"number","sqlType":"money","size":19},{"name":"c11","nullable":true,"type":"number","sqlType":"money","size":19},{"name":"c12","nullable":true,"type":"number","sqlType":"smallmoney","size":10},{"name":"c13","nullable":true,"type":"number","sqlType":"numeric","size":38},{"name":"c14","nullable":true,"type":"number","sqlType":"numeric","size":10},{"name":"c15","nullable":true,"type":"number","sqlType":"bigint","size":19}],"handle":{"connectionId":0,"statementId":0},"endOfRows":true,"endOfResults":true,"rowCount":0}]},{"ev":"call","id":11,"t":33.9,"name":"releaseStatement","args":[0,{"connectionId":0,"statementId":0}]},{"ev":"state","of":2,"t":34,"change":{"handle":{"connectionId":0,"statementId":0},"oldState":"STATEMENT_READING","newState":"STATEMENT_CLOSED"}},{"ev":"return","of":11,"t":34,"result":[null,true]},{"ev":"call","id":14,"t":187.7,"name":"query","args":[1,{"query_str":"select cast(0.1234567890123 as float) as c0, cast(1e-10 as float) as c1, cast(1.5e300 as float) as c2, cast(-2.5 as float) as c3, cast(0.12345678 as real) as c4, cast(1.0123456789 as decimal(38,10)) as c5, cast(12345678901234567890.12 as decimal(38,2)) as c6, cast(0.0000001 as decimal(10,7)) as c7, cast(9007199254740993 as decimal(19,0)) as c8, cast(709 as decimal(10,0)) as c9, cast(922337203685477.5807 as money) as c10, cast(-0.0001 as money) as c11, cast(1.2345 as smallmoney) as c12, cast(1.0123456789 as numeric(38,10)) as c13, cast(0.0000001 as numeric(10,7)) as c14, cast(9223372036854775807 as bigint) as c15","numeric_string":true,"bigint_as_native":false,"stateChangeCallback":{"$":"function"}},[]]},{"ev":"state","of":14,"t":187.8,"change":{"handle":{"connectionId":0,"statementId":1},"oldState":"STATEMENT_CREATED","newState":"STATEMENT_BINDING"}},{"ev":"state","of":14,"t":187.8,"change":{"handle":{"connectionId":0,"statementId":1},"oldState":"STATEMENT_BINDING","newState":"STATEMENT_SUBMITTED"}},{"ev":"state","of":14,"t":189,"change":{"handle":{"connectionId":0,"statementId":1},"oldState":"STATEMENT_SUBMITTED","newState":"STATEMENT_READING"}},{"ev":"return","of":14,"t":189.1,"result":[null,{"meta":[{"name":"c0","nullable":true,"type":"number","sqlType":"float","size":53},{"name":"c1","nullable":true,"type":"number","sqlType":"float","size":53},{"name":"c2","nullable":true,"type":"number","sqlType":"float","size":53},{"name":"c3","nullable":true,"type":"number","sqlType":"float","size":53},{"name":"c4","nullable":true,"type":"number","sqlType":"real","size":24},{"name":"c5","nullable":true,"type":"number","sqlType":"decimal","size":38},{"name":"c6","nullable":true,"type":"number","sqlType":"decimal","size":38},{"name":"c7","nullable":true,"type":"number","sqlType":"decimal","size":10},{"name":"c8","nullable":true,"type":"number","sqlType":"decimal","size":19},{"name":"c9","nullable":true,"type":"number","sqlType":"decimal","size":10},{"name":"c10","nullable":true,"type":"number","sqlType":"money","size":19},{"name":"c11","nullable":true,"type":"number","sqlType":"money","size":19},{"name":"c12","nullable":true,"type":"number","sqlType":"smallmoney","size":10},{"name":"c13","nullable":true,"type":"number","sqlType":"numeric","size":38},{"name":"c14","nullable":true,"type":"number","sqlType":"numeric","size":10},{"name":"c15","nullable":true,"type":"number","sqlType":"bigint","size":19}],"handle":{"connectionId":0,"statementId":1},"endOfRows":true,"endOfResults":false,"rowCount":0},true]},{"ev":"call","id":19,"t":189.1,"name":"fetchRows","args":[1,{"connectionId":0,"statementId":1},{"asArrays":true,"batchSize":50,"asObjects":false}]},{"ev":"return","of":19,"t":189.2,"result":[null,{"endOfRows":true,"endOfResults":false,"rowCount":0,"data":[["0.1234567890123","1e-10","1.5e+300","-2.5","0.12345678359270096","1.0123456789","12345678901234567000","1e-7","9007199254740992","709","922337203685477.6","-0.0001","1.2345","1.0123456789",".0000001","9223372036854775807"]]}]},{"ev":"call","id":21,"t":189.3,"name":"nextResultSet","args":[1,{"connectionId":0,"statementId":1}]},{"ev":"return","of":21,"t":189.4,"result":[null,{"meta":[{"name":"c0","nullable":true,"type":"number","sqlType":"float","size":53},{"name":"c1","nullable":true,"type":"number","sqlType":"float","size":53},{"name":"c2","nullable":true,"type":"number","sqlType":"float","size":53},{"name":"c3","nullable":true,"type":"number","sqlType":"float","size":53},{"name":"c4","nullable":true,"type":"number","sqlType":"real","size":24},{"name":"c5","nullable":true,"type":"number","sqlType":"decimal","size":38},{"name":"c6","nullable":true,"type":"number","sqlType":"decimal","size":38},{"name":"c7","nullable":true,"type":"number","sqlType":"decimal","size":10},{"name":"c8","nullable":true,"type":"number","sqlType":"decimal","size":19},{"name":"c9","nullable":true,"type":"number","sqlType":"decimal","size":10},{"name":"c10","nullable":true,"type":"number","sqlType":"money","size":19},{"name":"c11","nullable":true,"type":"number","sqlType":"money","size":19},{"name":"c12","nullable":true,"type":"number","sqlType":"smallmoney","size":10},{"name":"c13","nullable":true,"type":"number","sqlType":"numeric","size":38},{"name":"c14","nullable":true,"type":"number","sqlType":"numeric","size":10},{"name":"c15","nullable":true,"type":"number","sqlType":"bigint","size":19}],"handle":{"connectionId":0,"statementId":1},"endOfRows":true,"endOfResults":true,"rowCount":0}]},{"ev":"call","id":23,"t":189.4,"name":"releaseStatement","args":[1,{"connectionId":0,"statementId":1}]},{"ev":"state","of":14,"t":189.5,"change":{"handle":{"connectionId":0,"statementId":1},"oldState":"STATEMENT_READING","newState":"STATEMENT_CLOSED"}},{"ev":"return","of":23,"t":189.5,"result":[null,true]},{"ev":"call","id":26,"t":344,"name":"query","args":[2,{"query_str":"create table #p (n numeric(38,10), d decimal(38,2), f float); insert #p values (1.0123456789, 12345678901234567.89, 1e-10)","query_timeout":0,"query_polling":false,"query_tz_adjustment":0,"numeric_string":false,"bigint_as_native":false,"stateChangeCallback":{"$":"function"}},[]]},{"ev":"state","of":26,"t":344.2,"change":{"handle":{"connectionId":0,"statementId":2},"oldState":"STATEMENT_CREATED","newState":"STATEMENT_BINDING"}},{"ev":"state","of":26,"t":344.2,"change":{"handle":{"connectionId":0,"statementId":2},"oldState":"STATEMENT_BINDING","newState":"STATEMENT_SUBMITTED"}},{"ev":"state","of":26,"t":346.2,"change":{"handle":{"connectionId":0,"statementId":2},"oldState":"STATEMENT_SUBMITTED","newState":"STATEMENT_READING"}},{"ev":"return","of":26,"t":346.2,"result":[null,{"meta":[],"handle":{"connectionId":0,"statementId":2},"endOfRows":true,"endOfResults":false,"rowCount":1},true]},{"ev":"call","id":31,"t":346.2,"name":"nextResultSet","args":[2,{"connectionId":0,"statementId":2}]},{"ev":"return","of":31,"t":346.3,"result":[null,{"meta":[],"handle":{"connectionId":0,"statementId":2},"endOfRows":true,"endOfResults":true,"rowCount":1}]},{"ev":"call","id":33,"t":346.4,"name":"releaseStatement","args":[2,{"connectionId":0,"statementId":2}]},{"ev":"state","of":26,"t":346.4,"change":{"handle":{"connectionId":0,"statementId":2},"oldState":"STATEMENT_READING","newState":"STATEMENT_CLOSED"}},{"ev":"return","of":33,"t":346.4,"result":[null,true]},{"ev":"call","id":36,"t":499.5,"name":"prepare","args":[3,{"query_str":"select n, d, f from #p where 1 = ?","numeric_string":true,"bigint_as_native":false,"stateChangeCallback":{"$":"function"}}]},{"ev":"state","of":36,"t":501,"change":{"handle":{"connectionId":0,"statementId":3},"oldState":"STATEMENT_CREATED","newState":"STATEMENT_PREPARED"}},{"ev":"return","of":36,"t":501,"result":[null,{"meta":[{"name":"n","nullable":true,"type":"number","sqlType":"numeric","size":38},{"name":"d","nullable":true,"type":"number","sqlType":"decimal","size":38},{"name":"f","nullable":true,"type":"number","sqlType":"float","size":53}],"handle":{"connectionId":0,"statementId":3},"endOfRows":true,"endOfResults":false,"rowCount":0}]},{"ev":"call","id":39,"t":501.2,"name":"bindQuery","args":[3,[1]]},{"ev":"state","of":36,"t":501.3,"change":{"handle":{"connectionId":0,"statementId":3},"oldState":"STATEMENT_PREPARED","newState":"STATEMENT_SUBMITTED"}},{"ev":"return","of":39,"t":504.6,"result":[null,{"meta":[{"name":"n","nullable":true,"type":"number","sqlType":"numeric","size":38},{"name":"d","nullable":true,"type":"number","sqlType":"decimal","size":38},{"name":"f","nullable":true,"type":"number","sqlType":"float","size":53}],"handle":{"connectionId":0,"statementId":3},"endOfRows":false,"endOfResults":false,"rowCount":0}]},{"ev":"call","id":42,"t":504.6,"name":"fetchRows","args":[3,{"connectionId":0,"statementId":3},{"asArrays":true,"batchSize":50,"asObjects":false}]},{"ev":"return","of":42,"t":505.3,"result":[null,{"endOfRows":false,"endOfResults":false,"rowCount":1,"data":[["1.0123456789","12345678901234568","1e-10"]]}]},{"ev":"call","id":44,"t":505.4,"name":"fetchRows","args":[3,{"connectionId":0,"statementId":3},{"asArrays":true,"batchSize":50,"asObjects":false}]},{"ev":"return","of":44,"t":505.4,"result":[null,{"endOfRows":true,"endOfResults":false,"rowCount":0,"data":[]}]},{"ev":"call","id":46,"t":505.4,"name":"nextResultSet","args":[3,{"connectionId":0,"statementId":3}]},{"ev":"return","of":46,"t":505.5,"result":[null,{"meta":[{"name":"n","nullable":true,"type":"number","sqlType":"numeric","size":38},{"name":"d","nullable":true,"type":"number","sqlType":"decimal","size":38},{"name":"f","nullable":true,"type":"number","sqlType":"float","size":53}],"handle":{"connectionId":0,"statementId":3},"endOfRows":true,"endOfResults":true,"rowCount":0}]},{"ev":"call","id":48,"t":505.6,"name":"releaseStatement","args":[3,{"connectionId":0,"statementId":3}]},{"ev":"state","of":36,"t":505.6,"change":{"handle":{"connectionId":0,"statementId":3},"oldState":"STATEMENT_SUBMITTED","newState":"STATEMENT_CLOSED"}},{"ev":"return","of":48,"t":506.1,"result":[null,true]},{"ev":"call","id":51,"t":669.6,"name":"query","args":[4,{"query_str":"select 1 as n","query_timeout":0,"query_polling":false,"query_tz_adjustment":0,"numeric_string":false,"bigint_as_native":false,"stateChangeCallback":{"$":"function"}},[]]},{"ev":"state","of":51,"t":669.8,"change":{"handle":{"connectionId":0,"statementId":4},"oldState":"STATEMENT_CREATED","newState":"STATEMENT_BINDING"}},{"ev":"state","of":51,"t":669.8,"change":{"handle":{"connectionId":0,"statementId":4},"oldState":"STATEMENT_BINDING","newState":"STATEMENT_SUBMITTED"}},{"ev":"state","of":51,"t":670.7,"change":{"handle":{"connectionId":0,"statementId":4},"oldState":"STATEMENT_SUBMITTED","newState":"STATEMENT_READING"}},{"ev":"return","of":51,"t":670.7,"result":[null,{"meta":[{"name":"n","nullable":false,"type":"number","sqlType":"int","size":10}],"handle":{"connectionId":0,"statementId":4},"endOfRows":true,"endOfResults":false,"rowCount":0},true]},{"ev":"call","id":56,"t":670.8,"name":"fetchRows","args":[4,{"connectionId":0,"statementId":4},{"asArrays":true,"batchSize":50,"asObjects":false}]},{"ev":"return","of":56,"t":670.8,"result":[null,{"endOfRows":true,"endOfResults":false,"rowCount":0,"data":[[1]]}]},{"ev":"call","id":58,"t":670.9,"name":"nextResultSet","args":[4,{"connectionId":0,"statementId":4}]},{"ev":"return","of":58,"t":671,"result":[null,{"meta":[{"name":"n","nullable":false,"type":"number","sqlType":"int","size":10}],"handle":{"connectionId":0,"statementId":4},"endOfRows":true,"endOfResults":true,"rowCount":0}]},{"ev":"call","id":60,"t":671,"name":"releaseStatement","args":[4,{"connectionId":0,"statementId":4}]},{"ev":"state","of":51,"t":671,"change":{"handle":{"connectionId":0,"statementId":4},"oldState":"STATEMENT_READING","newState":"STATEMENT_CLOSED"}},{"ev":"return","of":60,"t":671,"result":[null,true]},{"ev":"call","id":63,"t":671.2,"name":"close","args":[]},{"ev":"return","of":63,"t":671.3,"result":[null,true]}]} \ No newline at end of file diff --git a/test/contract/recorder.js b/test/contract/recorder.js index 8e655ef8..f72b298b 100644 --- a/test/contract/recorder.js +++ b/test/contract/recorder.js @@ -44,6 +44,7 @@ const formatValue = v => { if (v === null || v === undefined) return String(v) if (Buffer.isBuffer(v)) return `0x${v.toString('hex')}` if (v instanceof Date) return v.toISOString() + if (typeof v === 'bigint') return `${v}n` return JSON.stringify(v) } diff --git a/test/contract/repro/i497.js b/test/contract/repro/i497.js new file mode 100644 index 00000000..2888fe37 --- /dev/null +++ b/test/contract/repro/i497.js @@ -0,0 +1,36 @@ +'use strict' +// #497: sql_variant rows read as the first row's base type. +// node i497.js wrong-data cases (numeric strings off and on) +// node i497.js crash the case that killed the process (0xC0000005) +const { sql, cs, version } = require('./common') +const variantColumn = (cols, ...values) => + `select ${cols} from (values ` + + values.map((x, i) => `(${i + 1}, cast(${x} as sql_variant))`).join(', ') + + ') t(i, v) order by i' +const cases = { + 'int, decimal': variantColumn('v', 'cast(7 as int)', 'cast(1.5 as decimal(5,2))'), + 'int, nvarchar': variantColumn('v', 'cast(7 as int)', "cast(N'abc' as nvarchar(10))"), + 'datetime, int': variantColumn('v', "cast('2020-01-02' as datetime)", 'cast(7 as int)'), + 'NULL, int, nvarchar, numeric': variantColumn('v', 'null', '1', "N'abc'", '1.5'), + 'float, bigint': variantColumn('v', 'cast(2.25e-9 as float)', 'cast(9223372036854775807 as bigint)'), + 'bit, int': variantColumn('v', 'cast(1 as bit)', 'cast(7 as int)') +} +const crashes = { + 'mix of five': variantColumn('v', '1', "N'abc'", '1.5', 'cast(9223372036854775807 as bigint)', '2.25e-9'), + 'i, v int nvarchar': variantColumn('i, v', 'cast(7 as int)', "cast(N'abc' as nvarchar(10))"), + 'int nvarchar int': variantColumn('v', 'cast(7 as int)', "cast(N'abc' as nvarchar(10))", 'cast(8 as int)') +} +const run = (conn, query, numericString) => new Promise(resolve => { + conn.queryRaw({ query_str: query, numeric_string: numericString, bigint_as_native: true }, + (err, res) => resolve(err ? `error ${err.sqlstate} ${err.message}` : res.rows.map(r => r[r.length - 1]))) +}) +sql.open(cs, async (err, conn) => { + if (err) throw err + const which = process.argv[2] === 'crash' ? crashes : cases + for (const ns of [false, true]) { + for (const [name, query] of Object.entries(which)) { + console.log(version, `ns=${ns}`, name, await run(conn, query, ns)) + } + } + conn.close(() => {}) +}) diff --git a/test/contract/repro/i498.js b/test/contract/repro/i498.js new file mode 100644 index 00000000..66c2e538 --- /dev/null +++ b/test/contract/repro/i498.js @@ -0,0 +1,36 @@ +'use strict' +// #498: numeric_string prints float, real, decimal and money with %f. +const { sql, cs, version } = require('./common') +const query = `select + cast(0.1234567890123 as float) as f1, + cast(1e-10 as float) as f2, + cast(1.5e300 as float) as f3, + cast(0.12345678 as real) as r1, + cast(1.0123456789 as decimal(38,10)) as d1, + cast(12345678901234567890.12 as decimal(38,2)) as d2, + cast(0.0000001 as decimal(10,7)) as d3, + cast(9007199254740993 as decimal(19,0)) as d4, + cast(709 as decimal(10,0)) as d5, + cast(922337203685477.5807 as money) as m1, + cast(-0.0001 as money) as m2, + cast(1.2345 as smallmoney) as sm1, + cast(1.0123456789 as numeric(38,10)) as n1` +const show = res => res.meta.map((m, i) => `${m.name}=${JSON.stringify(res.rows[0][i])}`).join(' ') +sql.open(cs, async (err, conn) => { + if (err) throw err + for (const ns of [false, true]) { + const res = await new Promise((resolve, reject) => + conn.queryRaw({ query_str: query, numeric_string: ns }, (e, r) => e ? reject(e) : resolve(r))) + console.log(version, `ns=${ns}`, show(res)) + } + await new Promise((resolve, reject) => conn.query( + 'create table #p (n1 numeric(38,10), d2 numeric(38,2)); insert #p values (1.0123456789, 12345678901234567.89)', + e => e ? reject(e) : resolve())) + const ps = await new Promise((resolve, reject) => + conn.prepare({ query_str: 'select n1, d2 from #p where 1 = ?', numeric_string: true }, + (e, p) => e ? reject(e) : resolve(p))) + const pres = await new Promise((resolve, reject) => + ps.preparedQuery([1], (e, r) => e ? reject(e) : resolve(r))) + console.log(version, 'prepared ns=true', JSON.stringify(pres)) + ps.free(() => conn.close(() => {})) +}) diff --git a/test/contract/run-one.js b/test/contract/run-one.js index 0093d685..b8b43949 100644 --- a/test/contract/run-one.js +++ b/test/contract/run-one.js @@ -23,7 +23,8 @@ const nativeFile = process.env.MSSQL_CONTRACT_NATIVE let tap = null if (nativeFile) { const { utilModule } = require(path.join(root, 'lib/util')) - tap = require('./native-tap').install(new utilModule.Native().cppDriver, { keepData: !!scenario.columns }) + // a script may log column values on any query, so its rows are kept whole + tap = require('./native-tap').install(new utilModule.Native().cppDriver, { keepData: !!(scenario.columns || scenario.script) }) } runScenario(require(root), process.env.MSSQL_CONTRACT_CS, scenario) diff --git a/test/contract/scripts/issue-497-ns.js b/test/contract/scripts/issue-497-ns.js new file mode 100644 index 00000000..62b82fe9 --- /dev/null +++ b/test/contract/scripts/issue-497-ns.js @@ -0,0 +1,4 @@ +'use strict' + +// #497 with numeric strings on: see issue-497.js +module.exports = require('./issue-497').run(true) diff --git a/test/contract/scripts/issue-497.js b/test/contract/scripts/issue-497.js new file mode 100644 index 00000000..90750dc4 --- /dev/null +++ b/test/contract/scripts/issue-497.js @@ -0,0 +1,38 @@ +'use strict' + +// #497: a sql_variant column's values were all read as the first row's base type, so later +// values came back truncated (1.5 as 1), as another type, as an error, or crashed the +// process when a failed cell was followed by another. each case is one variant column +// starting with one base type and followed by all the others, read next to a key column +// (select i, v: the shape that crashed). a NULL in the last row is read too. + +const VALUES = { + int: 'cast(7 as int)', + bigint: 'cast(9223372036854775807 as bigint)', + decimal: 'cast(1.5 as decimal(5,2))', + float: 'cast(2.25e-9 as float)', + nvarchar: "cast(N'abc' as nvarchar(10))", + datetime: "cast('2020-01-02' as datetime)", + bit: 'cast(1 as bit)', + null: 'null' +} + +const column = first => { + const values = [VALUES[first], ...Object.entries(VALUES).filter(([k]) => k !== first).map(([, v]) => v)] + return 'select i, v from (values ' + + values.map((x, i) => `(${i + 1}, cast(${x} as sql_variant))`).join(', ') + + ') t(i, v) order by i' +} + +// numeric strings off here, on in issue-497-ns: both in one transcript pass its 400 lines +const run = numericString => async t => { + for (const first of Object.keys(VALUES)) { + const label = `${first}${numericString ? '-ns' : ''}` + t.section(`${first} first, numeric strings ${numericString ? 'on' : 'off'}`) + t.query(label, { query_str: column(first), numeric_string: numericString, bigint_as_native: true }, null, { columns: true }) + await t.settled(label) + } +} + +module.exports = run(false) +module.exports.run = run diff --git a/test/contract/scripts/issue-498.js b/test/contract/scripts/issue-498.js new file mode 100644 index 00000000..9e3bdf84 --- /dev/null +++ b/test/contract/scripts/issue-498.js @@ -0,0 +1,49 @@ +'use strict' + +// #498: under numeric strings, float, real, decimal and money were printed with %f (six +// decimal places, no exponent): 1e-10 came back as "0.000000". each value is read with +// numeric strings off and on; the strings should keep the value. then the same through a +// prepared statement. + +const VALUES = [ + 'cast(0.1234567890123 as float)', + 'cast(1e-10 as float)', + 'cast(1.5e300 as float)', + 'cast(-2.5 as float)', + 'cast(0.12345678 as real)', + 'cast(1.0123456789 as decimal(38,10))', + 'cast(12345678901234567890.12 as decimal(38,2))', + 'cast(0.0000001 as decimal(10,7))', + 'cast(9007199254740993 as decimal(19,0))', + 'cast(709 as decimal(10,0))', + 'cast(922337203685477.5807 as money)', + 'cast(-0.0001 as money)', + 'cast(1.2345 as smallmoney)', + 'cast(1.0123456789 as numeric(38,10))', + 'cast(0.0000001 as numeric(10,7))', + 'cast(9223372036854775807 as bigint)' +] +const SELECT = 'select ' + VALUES.map((v, i) => `${v} as c${i}`).join(', ') + +module.exports = async t => { + t.note(VALUES.map((v, i) => `c${i} ${v}`).join('; ')) + for (const numericString of [false, true]) { + const label = numericString ? 'ns' : 'plain' + t.section(`numeric strings ${numericString ? 'on' : 'off'}`) + t.query(label, { query_str: SELECT, numeric_string: numericString }, null, { columns: true }) + await t.settled(label) + } + + // a prepared statement binds these columns as double, numeric included + t.query('setup', 'create table #p (n numeric(38,10), d decimal(38,2), f float); ' + + 'insert #p values (1.0123456789, 12345678901234567.89, 1e-10)', null, { callback: true }) + await t.settled('setup') + const ps = await new Promise((resolve, reject) => { + t.conn.prepare({ query_str: 'select n, d, f from #p where 1 = ?', numeric_string: true }, + (err, p) => err ? reject(err) : resolve(p)) + }) + t.section('prepared, numeric strings on') + t.watch('ps', ps.preparedQuery([1]), { columns: true }) + await t.next('ps', 'done') + await new Promise(resolve => ps.free(resolve)) +} diff --git a/test/params-complete-refactored.test.js b/test/params-complete-refactored.test.js index caf64b6e..adca3e58 100644 --- a/test/params-complete-refactored.test.js +++ b/test/params-complete-refactored.test.js @@ -866,6 +866,49 @@ describe('Parameter Tests', function () { assert(smalldt.getMonth() === date.getMonth()) assert(smalldt.getDay() === date.getDay()) }) + + // #497: each row of a variant column is read by its own base type, not the first row's + const variantColumn = (...values) => + 'select i, v from (values ' + + values.map((x, i) => `(${i + 1}, cast(${x} as sql_variant))`).join(', ') + + ') t(i, v) order by i' + + const variantValues = async (query, numericString) => { + const res = await env.theConnection.promises.query({ + query_str: query, + numeric_string: numericString, + bigint_as_native: true + }) + return res.first.map(r => r.v) + } + + it('should read each row of a mixed sql_variant column by its own type', async function () { + const query = variantColumn('cast(7 as int)', 'cast(1.5 as decimal(5,2))', "cast(N'abc' as nvarchar(10))", + 'cast(9223372036854775807 as bigint)', 'cast(2.25e-9 as float)', "cast('2020-01-02' as datetime)", + 'cast(1 as bit)', 'null') + const values = await variantValues(query, false) + assert.deepStrictEqual(values.slice(0, 5), [7, 1.5, 'abc', 9223372036854775807n, 2.25e-9]) + assert.strictEqual(values[5].toISOString(), '2020-01-02T00:00:00.000Z') + assert.deepStrictEqual(values.slice(6), [true, null]) + }) + + it('should read a sql_variant column whose first row is null', async function () { + const values = await variantValues(variantColumn('null', '1', "N'abc'", '1.5'), false) + assert.deepStrictEqual(values, [null, 1, 'abc', 1.5]) + }) + + it('should read a datetime-first sql_variant column', async function () { + const values = await variantValues(variantColumn("cast('2020-01-02' as datetime)", 'cast(7 as int)'), false) + assert.strictEqual(values[0].toISOString(), '2020-01-02T00:00:00.000Z') + assert.strictEqual(values[1], 7) + }) + + it('should read a mixed sql_variant column with numeric strings', async function () { + const query = variantColumn('cast(7 as int)', "cast(N'abc' as nvarchar(10))", 'cast(2.25e-9 as float)', + 'cast(9223372036854775807 as bigint)', 'cast(1 as bit)') + const values = await variantValues(query, true) + assert.deepStrictEqual(values, ['7', 'abc', '2.25e-9', '9223372036854775807', true]) + }) }) // ======================================== @@ -927,6 +970,25 @@ describe('Parameter Tests', function () { assert.deepStrictEqual(result.first[0].number, num) }) + + // #498: a float under numeric strings is the text String(n) gives, not %f + it('should return float and real as strings that keep the value', async function () { + const result = await env.theConnection.promises.query({ + query_str: 'select cast(1e-10 as float) as f1, cast(0.1234567890123 as float) as f2, ' + + 'cast(1.5e300 as float) as f3, cast(-2.5 as float) as f4, cast(0.5 as real) as r1', + numeric_string: true + }) + assert.deepStrictEqual(result.first[0], { f1: '1e-10', f2: '0.1234567890123', f3: '1.5e+300', f4: '-2.5', r1: '0.5' }) + }) + + it('should return decimal and money as strings without %f padding', async function () { + const result = await env.theConnection.promises.query({ + query_str: 'select cast(1.0123456789 as decimal(38,10)) as d1, cast(0.0000001 as decimal(10,7)) as d2, ' + + 'cast(-0.0001 as money) as m1, cast(1.2345 as smallmoney) as m2', + numeric_string: true + }) + assert.deepStrictEqual(result.first[0], { d1: '1.0123456789', d2: '1e-7', m1: '-0.0001', m2: '1.2345' }) + }) }) // ========================================