From 6773b835fb8826284d8d3aa028a73c40ba7133fa Mon Sep 17 00:00:00 2001 From: mike-git374 <217764531+mike-git374@users.noreply.github.com> Date: Thu, 26 Feb 2026 09:59:26 -0700 Subject: [PATCH 1/8] sqlite: bind undefined to null --- src/node_sqlite.cc | 2 ++ test/parallel/test-sqlite-data-types.js | 20 +++++++++++++++++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/node_sqlite.cc b/src/node_sqlite.cc index fb229e19fd6aef..47b7128cfc89d8 100644 --- a/src/node_sqlite.cc +++ b/src/node_sqlite.cc @@ -2293,6 +2293,8 @@ bool StatementSync::BindValue(const Local& value, const int index) { buf.data(), static_cast(buf.length()), SQLITE_TRANSIENT); + } else if (value->IsUndefined()) { + r = sqlite3_bind_null(statement_, index); } else if (value->IsBigInt()) { bool lossless; int64_t as_int = value.As()->Int64Value(&lossless); diff --git a/test/parallel/test-sqlite-data-types.js b/test/parallel/test-sqlite-data-types.js index 26af15a777d234..628976f1fa4337 100644 --- a/test/parallel/test-sqlite-data-types.js +++ b/test/parallel/test-sqlite-data-types.js @@ -46,6 +46,10 @@ suite('data binding and mapping', () => { stmt.run(4, 99n, 0xf, '', new Uint8Array()), { changes: 1, lastInsertRowid: 4 }, ); + t.assert.deepStrictEqual( + stmt.run(5, undefined, undefined, undefined, undefined), + { changes: 1, lastInsertRowid: 5 }, + ); const query = db.prepare('SELECT * FROM types WHERE key = ?'); t.assert.deepStrictEqual(query.get(1), { @@ -80,6 +84,21 @@ suite('data binding and mapping', () => { text: '', buf: new Uint8Array(), }); + t.assert.deepStrictEqual(query.get(5), { + __proto__: null, + key: 5, + int: null, + double: null, + text: null, + buf: null, + }); + + const insertNamedParams = db.prepare('INSERT INTO types (key, int, double, text, buf) VALUES ($key, $int, $double, $text, $buf)'); + const params = { key: 6, int: undefined, double: undefined, text: undefined, buf: undefined }; + t.assert.deepStrictEqual(insertNamedParams.run(params), { changes: 1, lastInsertRowid: 6 }); + t.assert.deepStrictEqual(insertNamedParams.run({ key: 7 }), { changes: 1, lastInsertRowid: 7 }); + t.assert.deepStrictEqual(query.get(6), { __proto__: null, key: 6, int: null, double: null, text: null, buf: null }); + t.assert.deepStrictEqual(query.get(7), { __proto__: null, key: 7, int: null, double: null, text: null, buf: null }); }); test('large strings are bound correctly', (t) => { @@ -126,7 +145,6 @@ suite('data binding and mapping', () => { t.assert.strictEqual(setup, undefined); [ - undefined, () => {}, Symbol(), /foo/, From 8d8df526a16d0cf65354e0687a851c66c5916b36 Mon Sep 17 00:00:00 2001 From: mike-git374 <217764531+mike-git374@users.noreply.github.com> Date: Thu, 26 Feb 2026 10:46:49 -0700 Subject: [PATCH 2/8] test shorten --- test/parallel/test-sqlite-data-types.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/parallel/test-sqlite-data-types.js b/test/parallel/test-sqlite-data-types.js index 628976f1fa4337..a2ec11ce70adfb 100644 --- a/test/parallel/test-sqlite-data-types.js +++ b/test/parallel/test-sqlite-data-types.js @@ -93,7 +93,7 @@ suite('data binding and mapping', () => { buf: null, }); - const insertNamedParams = db.prepare('INSERT INTO types (key, int, double, text, buf) VALUES ($key, $int, $double, $text, $buf)'); + const insertNamedParams = db.prepare(`INSERT INTO types VALUES ($key, $int, $double, $text, $buf)`); const params = { key: 6, int: undefined, double: undefined, text: undefined, buf: undefined }; t.assert.deepStrictEqual(insertNamedParams.run(params), { changes: 1, lastInsertRowid: 6 }); t.assert.deepStrictEqual(insertNamedParams.run({ key: 7 }), { changes: 1, lastInsertRowid: 7 }); From 5c6c0b5aa705dbae91f9fa928af980e233aaabfc Mon Sep 17 00:00:00 2001 From: mike-git374 <217764531+mike-git374@users.noreply.github.com> Date: Thu, 26 Feb 2026 10:47:25 -0700 Subject: [PATCH 3/8] test quote --- test/parallel/test-sqlite-data-types.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/parallel/test-sqlite-data-types.js b/test/parallel/test-sqlite-data-types.js index a2ec11ce70adfb..b066ff0c5c3834 100644 --- a/test/parallel/test-sqlite-data-types.js +++ b/test/parallel/test-sqlite-data-types.js @@ -93,7 +93,7 @@ suite('data binding and mapping', () => { buf: null, }); - const insertNamedParams = db.prepare(`INSERT INTO types VALUES ($key, $int, $double, $text, $buf)`); + const insertNamedParams = db.prepare('INSERT INTO types VALUES ($key, $int, $double, $text, $buf)'); const params = { key: 6, int: undefined, double: undefined, text: undefined, buf: undefined }; t.assert.deepStrictEqual(insertNamedParams.run(params), { changes: 1, lastInsertRowid: 6 }); t.assert.deepStrictEqual(insertNamedParams.run({ key: 7 }), { changes: 1, lastInsertRowid: 7 }); From fd6106738851c757a75ee5736c7855c58e917855 Mon Sep 17 00:00:00 2001 From: mike-git374 <217764531+mike-git374@users.noreply.github.com> Date: Thu, 26 Feb 2026 15:24:06 -0700 Subject: [PATCH 4/8] test shorten --- test/parallel/test-sqlite-data-types.js | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/test/parallel/test-sqlite-data-types.js b/test/parallel/test-sqlite-data-types.js index b066ff0c5c3834..45d64a926d251b 100644 --- a/test/parallel/test-sqlite-data-types.js +++ b/test/parallel/test-sqlite-data-types.js @@ -93,12 +93,13 @@ suite('data binding and mapping', () => { buf: null, }); - const insertNamedParams = db.prepare('INSERT INTO types VALUES ($key, $int, $double, $text, $buf)'); - const params = { key: 6, int: undefined, double: undefined, text: undefined, buf: undefined }; - t.assert.deepStrictEqual(insertNamedParams.run(params), { changes: 1, lastInsertRowid: 6 }); - t.assert.deepStrictEqual(insertNamedParams.run({ key: 7 }), { changes: 1, lastInsertRowid: 7 }); - t.assert.deepStrictEqual(query.get(6), { __proto__: null, key: 6, int: null, double: null, text: null, buf: null }); - t.assert.deepStrictEqual(query.get(7), { __proto__: null, key: 7, int: null, double: null, text: null, buf: null }); + const insertNamed = db.prepare('INSERT INTO types VALUES ($key, $int, $double, $text, $buf)'); + const params = { int: undefined, double: undefined, text: undefined, buf: undefined }; + const nulls = { int: null, double: null, text: null, buf: null }; + t.assert.deepStrictEqual(insertNamed.run({ key: 6, ...params }), { changes: 1, lastInsertRowid: 6 }); + t.assert.deepStrictEqual(insertNamed.run({ key: 7 }), { changes: 1, lastInsertRowid: 7 }); + t.assert.deepStrictEqual(query.get(6), { __proto__: null, key: 6, ...nulls }); + t.assert.deepStrictEqual(query.get(7), { __proto__: null, key: 7, ...nulls }); }); test('large strings are bound correctly', (t) => { From a845bcee4fe6a412d47f95f4c5bc1e4df0d530d2 Mon Sep 17 00:00:00 2001 From: mike-git374 <217764531+mike-git374@users.noreply.github.com> Date: Fri, 27 Feb 2026 11:07:58 -0700 Subject: [PATCH 5/8] test consolidate --- test/parallel/test-sqlite-data-types.js | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/test/parallel/test-sqlite-data-types.js b/test/parallel/test-sqlite-data-types.js index 45d64a926d251b..49d6decc74b7d5 100644 --- a/test/parallel/test-sqlite-data-types.js +++ b/test/parallel/test-sqlite-data-types.js @@ -46,10 +46,6 @@ suite('data binding and mapping', () => { stmt.run(4, 99n, 0xf, '', new Uint8Array()), { changes: 1, lastInsertRowid: 4 }, ); - t.assert.deepStrictEqual( - stmt.run(5, undefined, undefined, undefined, undefined), - { changes: 1, lastInsertRowid: 5 }, - ); const query = db.prepare('SELECT * FROM types WHERE key = ?'); t.assert.deepStrictEqual(query.get(1), { @@ -84,20 +80,16 @@ suite('data binding and mapping', () => { text: '', buf: new Uint8Array(), }); - t.assert.deepStrictEqual(query.get(5), { - __proto__: null, - key: 5, - int: null, - double: null, - text: null, - buf: null, - }); - const insertNamed = db.prepare('INSERT INTO types VALUES ($key, $int, $double, $text, $buf)'); - const params = { int: undefined, double: undefined, text: undefined, buf: undefined }; const nulls = { int: null, double: null, text: null, buf: null }; - t.assert.deepStrictEqual(insertNamed.run({ key: 6, ...params }), { changes: 1, lastInsertRowid: 6 }); + const undefArray = [ undefined, undefined, undefined, undefined ]; + const undefObj = { int: undefined, double: undefined, text: undefined, buf: undefined }; + const insertAnon = db.prepare('INSERT INTO types VALUES (?, ?, ?, ?, ?)'); + const insertNamed = db.prepare('INSERT INTO types VALUES ($key, $int, $double, $text, $buf)'); + t.assert.deepStrictEqual(insertAnon.run(5, ...undefArray), { changes: 1, lastInsertRowid: 5 }); + t.assert.deepStrictEqual(insertNamed.run({ key: 6, ...undefObj }), { changes: 1, lastInsertRowid: 6 }); t.assert.deepStrictEqual(insertNamed.run({ key: 7 }), { changes: 1, lastInsertRowid: 7 }); + t.assert.deepStrictEqual(query.get(5), { __proto__: null, key: 5, ...nulls }); t.assert.deepStrictEqual(query.get(6), { __proto__: null, key: 6, ...nulls }); t.assert.deepStrictEqual(query.get(7), { __proto__: null, key: 7, ...nulls }); }); From 262ccecc44a714db944b5b4de49ff4dacdc989dd Mon Sep 17 00:00:00 2001 From: mike-git374 <217764531+mike-git374@users.noreply.github.com> Date: Fri, 6 Mar 2026 13:23:20 -0700 Subject: [PATCH 6/8] combine null and undefined --- src/node_sqlite.cc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/node_sqlite.cc b/src/node_sqlite.cc index 47b7128cfc89d8..f2b503d1eeeee0 100644 --- a/src/node_sqlite.cc +++ b/src/node_sqlite.cc @@ -2284,7 +2284,7 @@ bool StatementSync::BindValue(const Local& value, const int index) { SQLITE_TRANSIENT, SQLITE_UTF8); } - } else if (value->IsNull()) { + } else if (value->IsNull() || value->IsUndefined()) { r = sqlite3_bind_null(statement_, index); } else if (value->IsArrayBufferView()) { ArrayBufferViewContents buf(value); @@ -2293,8 +2293,6 @@ bool StatementSync::BindValue(const Local& value, const int index) { buf.data(), static_cast(buf.length()), SQLITE_TRANSIENT); - } else if (value->IsUndefined()) { - r = sqlite3_bind_null(statement_, index); } else if (value->IsBigInt()) { bool lossless; int64_t as_int = value.As()->Int64Value(&lossless); From 37f3bf431e3f52edfe7b76fdd2040060ea712ed6 Mon Sep 17 00:00:00 2001 From: mike-git374 <217764531+mike-git374@users.noreply.github.com> Date: Fri, 6 Mar 2026 13:33:36 -0700 Subject: [PATCH 7/8] line <= 80 chars --- test/parallel/test-sqlite-data-types.js | 28 +++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/test/parallel/test-sqlite-data-types.js b/test/parallel/test-sqlite-data-types.js index 49d6decc74b7d5..4365e1020ee677 100644 --- a/test/parallel/test-sqlite-data-types.js +++ b/test/parallel/test-sqlite-data-types.js @@ -83,15 +83,31 @@ suite('data binding and mapping', () => { const nulls = { int: null, double: null, text: null, buf: null }; const undefArray = [ undefined, undefined, undefined, undefined ]; - const undefObj = { int: undefined, double: undefined, text: undefined, buf: undefined }; + const undefObj = { + int: undefined, + double: undefined, + text: undefined, + buf: undefined, + }; const insertAnon = db.prepare('INSERT INTO types VALUES (?, ?, ?, ?, ?)'); - const insertNamed = db.prepare('INSERT INTO types VALUES ($key, $int, $double, $text, $buf)'); - t.assert.deepStrictEqual(insertAnon.run(5, ...undefArray), { changes: 1, lastInsertRowid: 5 }); - t.assert.deepStrictEqual(insertNamed.run({ key: 6, ...undefObj }), { changes: 1, lastInsertRowid: 6 }); - t.assert.deepStrictEqual(insertNamed.run({ key: 7 }), { changes: 1, lastInsertRowid: 7 }); - t.assert.deepStrictEqual(query.get(5), { __proto__: null, key: 5, ...nulls }); + const insertNamed = db.prepare( + 'INSERT INTO types VALUES ($key, $int, $double, $text, $buf)' + ); + t.assert.deepStrictEqual( + insertAnon.run(6, ...undefArray), + { lastInsertRowid: 6, changes: 1 }, + ); + t.assert.deepStrictEqual( + insertNamed.run({ key: 7, ...undefObj }), + { lastInsertRowid: 7, changes: 1 }, + ); + t.assert.deepStrictEqual( + insertNamed.run({ key: 8 }), + { lastInsertRowid: 8, changes: 1 }, + ); t.assert.deepStrictEqual(query.get(6), { __proto__: null, key: 6, ...nulls }); t.assert.deepStrictEqual(query.get(7), { __proto__: null, key: 7, ...nulls }); + t.assert.deepStrictEqual(query.get(8), { __proto__: null, key: 8, ...nulls }); }); test('large strings are bound correctly', (t) => { From 4cfb4949a026754621092b84ff8f210518a152f2 Mon Sep 17 00:00:00 2001 From: mike-git374 <217764531+mike-git374@users.noreply.github.com> Date: Fri, 6 Mar 2026 13:39:32 -0700 Subject: [PATCH 8/8] test reduce --- test/parallel/test-sqlite-data-types.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/parallel/test-sqlite-data-types.js b/test/parallel/test-sqlite-data-types.js index 4365e1020ee677..3c944bf80df7d6 100644 --- a/test/parallel/test-sqlite-data-types.js +++ b/test/parallel/test-sqlite-data-types.js @@ -82,7 +82,6 @@ suite('data binding and mapping', () => { }); const nulls = { int: null, double: null, text: null, buf: null }; - const undefArray = [ undefined, undefined, undefined, undefined ]; const undefObj = { int: undefined, double: undefined, @@ -94,7 +93,7 @@ suite('data binding and mapping', () => { 'INSERT INTO types VALUES ($key, $int, $double, $text, $buf)' ); t.assert.deepStrictEqual( - insertAnon.run(6, ...undefArray), + insertAnon.run(6, undefined, undefined, undefined, undefined), { lastInsertRowid: 6, changes: 1 }, ); t.assert.deepStrictEqual(