diff --git a/src/node_sqlite.cc b/src/node_sqlite.cc index fb229e19fd6aef..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); diff --git a/test/parallel/test-sqlite-data-types.js b/test/parallel/test-sqlite-data-types.js index 26af15a777d234..3c944bf80df7d6 100644 --- a/test/parallel/test-sqlite-data-types.js +++ b/test/parallel/test-sqlite-data-types.js @@ -80,6 +80,33 @@ suite('data binding and mapping', () => { text: '', buf: new Uint8Array(), }); + + const nulls = { int: null, double: null, text: null, buf: null }; + 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(6, undefined, undefined, undefined, undefined), + { 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) => { @@ -126,7 +153,6 @@ suite('data binding and mapping', () => { t.assert.strictEqual(setup, undefined); [ - undefined, () => {}, Symbol(), /foo/,