From de047c6be7741e195040d829b831f2c92a0565d9 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 19 Nov 2025 10:03:57 +0000 Subject: [PATCH 1/9] Initial plan From d1b867dad5242f34e7d4c4a73056f9c7909bd20e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 19 Nov 2025 10:07:23 +0000 Subject: [PATCH 2/9] Add test for NULL values in INTO SQL() - confirms issue exists Co-authored-by: mathiasrw <1063454+mathiasrw@users.noreply.github.com> --- test/test042_null_issue.js | 73 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 test/test042_null_issue.js diff --git a/test/test042_null_issue.js b/test/test042_null_issue.js new file mode 100644 index 0000000000..7986a80a8b --- /dev/null +++ b/test/test042_null_issue.js @@ -0,0 +1,73 @@ +if (typeof exports === 'object') { + var assert = require('assert'); + var alasql = require('..'); +} + +describe('Test 042 - NULL values in INTO SQL()', function () { + it('1. Should output NULL for null values', function (done) { + var data = [ + {a: 1, b: 'test', c: null, d: 3}, + {a: 2, b: null, c: 4, d: null}, + {a: null, b: 'value', c: null, d: null}, + ]; + var res = alasql('SELECT * INTO SQL({tableid:"test_table"}) FROM ?', [data]); + + console.log('Generated SQL:'); + console.log(res); + + // Check that NULL appears in the output instead of empty values + assert(res.indexOf('NULL') > -1, 'Output should contain NULL keyword'); + + // Check that we don't have consecutive commas (,,) which indicate missing values + assert(res.indexOf(',,') === -1, 'Output should not contain consecutive commas (,,)'); + + // Verify specific patterns for NULL values + // First row: c should be NULL + assert(res.indexOf('(1,\'test\',NULL,3)') > -1, 'First row should have NULL for c'); + + // Second row: b and d should be NULL + assert(res.indexOf('(2,NULL,4,NULL)') > -1, 'Second row should have NULL for b and d'); + + // Third row: a, c, and d should be NULL + assert(res.indexOf('(NULL,\'value\',NULL,NULL)') > -1, 'Third row should have NULL for a, c, and d'); + + done(); + }); + + it('2. Should handle undefined values as NULL', function (done) { + var data = [ + {a: 1, b: 'test'}, + {a: 2, b: undefined, c: 4}, + ]; + var res = alasql('SELECT * INTO SQL({tableid:"test_table"}) FROM ?', [data]); + + console.log('Generated SQL with undefined:'); + console.log(res); + + // Check that NULL appears in the output + assert(res.indexOf('NULL') > -1, 'Output should contain NULL keyword for undefined values'); + + // Check that we don't have consecutive commas + assert(res.indexOf(',,') === -1, 'Output should not contain consecutive commas (,,)'); + + done(); + }); + + it('3. Should handle mixed NULL, undefined, and empty strings', function (done) { + var data = [ + {a: 1, b: '', c: null, d: undefined}, + ]; + var res = alasql('SELECT * INTO SQL({tableid:"test_table"}) FROM ?', [data]); + + console.log('Generated SQL with mixed values:'); + console.log(res); + + // Empty string should remain as empty string + assert(res.indexOf("''") > -1, 'Empty string should be preserved as \'\''); + + // null and undefined should become NULL + assert(res.indexOf('NULL') > -1, 'null and undefined should become NULL'); + + done(); + }); +}); From cc04534d3466a95ba0c5ec99d4efabae048640a7 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 19 Nov 2025 10:09:11 +0000 Subject: [PATCH 3/9] Fix NULL values in INTO SQL() - handle null and undefined properly Co-authored-by: mathiasrw <1063454+mathiasrw@users.noreply.github.com> --- src/830into.js | 40 +++++++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/src/830into.js b/src/830into.js index 221ae3d42e..11e931f255 100755 --- a/src/830into.js +++ b/src/830into.js @@ -36,25 +36,31 @@ alasql.into.SQL = function (filename, opts, data, columns, cb) { }) .join(','); s += ') VALUES ('; - s += columns.map(function (col) { - var val = data[i][col.columnid]; - if (col.typeid) { - if ( - col.typeid === 'STRING' || - col.typeid === 'VARCHAR' || - col.typeid === 'NVARCHAR' || - col.typeid === 'CHAR' || - col.typeid === 'NCHAR' - ) { - val = "'" + escapeqq(val) + "'"; + s += columns + .map(function (col) { + var val = data[i][col.columnid]; + // Handle null and undefined values + if (val === null || val === undefined) { + return 'NULL'; } - } else { - if (typeof val == 'string') { - val = "'" + escapeqq(val) + "'"; + if (col.typeid) { + if ( + col.typeid === 'STRING' || + col.typeid === 'VARCHAR' || + col.typeid === 'NVARCHAR' || + col.typeid === 'CHAR' || + col.typeid === 'NCHAR' + ) { + val = "'" + escapeqq(val) + "'"; + } + } else { + if (typeof val == 'string') { + val = "'" + escapeqq(val) + "'"; + } } - } - return val; - }); + return val; + }) + .join(','); s += ');\n'; } // if(filename === '') { From 35acc644c43f486db81411b2db4f471abd25eb40 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 19 Nov 2025 13:58:12 +0000 Subject: [PATCH 4/9] Fix code formatting for test042_null_issue.js Co-authored-by: mathiasrw <1063454+mathiasrw@users.noreply.github.com> --- test/test042_null_issue.js | 47 +++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/test/test042_null_issue.js b/test/test042_null_issue.js index 7986a80a8b..a46d4f0569 100644 --- a/test/test042_null_issue.js +++ b/test/test042_null_issue.js @@ -11,63 +11,64 @@ describe('Test 042 - NULL values in INTO SQL()', function () { {a: null, b: 'value', c: null, d: null}, ]; var res = alasql('SELECT * INTO SQL({tableid:"test_table"}) FROM ?', [data]); - + console.log('Generated SQL:'); console.log(res); - + // Check that NULL appears in the output instead of empty values assert(res.indexOf('NULL') > -1, 'Output should contain NULL keyword'); - + // Check that we don't have consecutive commas (,,) which indicate missing values assert(res.indexOf(',,') === -1, 'Output should not contain consecutive commas (,,)'); - + // Verify specific patterns for NULL values // First row: c should be NULL - assert(res.indexOf('(1,\'test\',NULL,3)') > -1, 'First row should have NULL for c'); - + assert(res.indexOf("(1,'test',NULL,3)") > -1, 'First row should have NULL for c'); + // Second row: b and d should be NULL assert(res.indexOf('(2,NULL,4,NULL)') > -1, 'Second row should have NULL for b and d'); - + // Third row: a, c, and d should be NULL - assert(res.indexOf('(NULL,\'value\',NULL,NULL)') > -1, 'Third row should have NULL for a, c, and d'); - + assert( + res.indexOf("(NULL,'value',NULL,NULL)") > -1, + 'Third row should have NULL for a, c, and d' + ); + done(); }); - + it('2. Should handle undefined values as NULL', function (done) { var data = [ {a: 1, b: 'test'}, {a: 2, b: undefined, c: 4}, ]; var res = alasql('SELECT * INTO SQL({tableid:"test_table"}) FROM ?', [data]); - + console.log('Generated SQL with undefined:'); console.log(res); - + // Check that NULL appears in the output assert(res.indexOf('NULL') > -1, 'Output should contain NULL keyword for undefined values'); - + // Check that we don't have consecutive commas assert(res.indexOf(',,') === -1, 'Output should not contain consecutive commas (,,)'); - + done(); }); - + it('3. Should handle mixed NULL, undefined, and empty strings', function (done) { - var data = [ - {a: 1, b: '', c: null, d: undefined}, - ]; + var data = [{a: 1, b: '', c: null, d: undefined}]; var res = alasql('SELECT * INTO SQL({tableid:"test_table"}) FROM ?', [data]); - + console.log('Generated SQL with mixed values:'); console.log(res); - + // Empty string should remain as empty string - assert(res.indexOf("''") > -1, 'Empty string should be preserved as \'\''); - + assert(res.indexOf("''") > -1, "Empty string should be preserved as ''"); + // null and undefined should become NULL assert(res.indexOf('NULL') > -1, 'null and undefined should become NULL'); - + done(); }); }); From ec64f1c95c5741868033205df76fe4bfaee84254 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 20 Nov 2025 03:05:21 +0000 Subject: [PATCH 5/9] Refactor tests: remove console.log, use deepEqual, arrow functions Co-authored-by: mathiasrw <1063454+mathiasrw@users.noreply.github.com> --- src/830into.js | 16 +++++------ test/test042_null_issue.js | 57 ++++++++++---------------------------- 2 files changed, 22 insertions(+), 51 deletions(-) diff --git a/src/830into.js b/src/830into.js index 11e931f255..66e8af3545 100755 --- a/src/830into.js +++ b/src/830into.js @@ -44,14 +44,14 @@ alasql.into.SQL = function (filename, opts, data, columns, cb) { return 'NULL'; } if (col.typeid) { - if ( - col.typeid === 'STRING' || - col.typeid === 'VARCHAR' || - col.typeid === 'NVARCHAR' || - col.typeid === 'CHAR' || - col.typeid === 'NCHAR' - ) { - val = "'" + escapeqq(val) + "'"; + switch (col.typeid) { + case 'STRING': + case 'VARCHAR': + case 'NVARCHAR': + case 'CHAR': + case 'NCHAR': + val = "'" + escapeqq(val) + "'"; + break; } } else { if (typeof val == 'string') { diff --git a/test/test042_null_issue.js b/test/test042_null_issue.js index a46d4f0569..62fffc973b 100644 --- a/test/test042_null_issue.js +++ b/test/test042_null_issue.js @@ -4,7 +4,7 @@ if (typeof exports === 'object') { } describe('Test 042 - NULL values in INTO SQL()', function () { - it('1. Should output NULL for null values', function (done) { + it('1. Should output NULL for null values', () => { var data = [ {a: 1, b: 'test', c: null, d: 3}, {a: 2, b: null, c: 4, d: null}, @@ -12,63 +12,34 @@ describe('Test 042 - NULL values in INTO SQL()', function () { ]; var res = alasql('SELECT * INTO SQL({tableid:"test_table"}) FROM ?', [data]); - console.log('Generated SQL:'); - console.log(res); + var expected = + "INSERT INTO test_table(a,b,c,d) VALUES (1,'test',NULL,3);\n" + + 'INSERT INTO test_table(a,b,c,d) VALUES (2,NULL,4,NULL);\n' + + "INSERT INTO test_table(a,b,c,d) VALUES (NULL,'value',NULL,NULL);\n"; - // Check that NULL appears in the output instead of empty values - assert(res.indexOf('NULL') > -1, 'Output should contain NULL keyword'); - - // Check that we don't have consecutive commas (,,) which indicate missing values - assert(res.indexOf(',,') === -1, 'Output should not contain consecutive commas (,,)'); - - // Verify specific patterns for NULL values - // First row: c should be NULL - assert(res.indexOf("(1,'test',NULL,3)") > -1, 'First row should have NULL for c'); - - // Second row: b and d should be NULL - assert(res.indexOf('(2,NULL,4,NULL)') > -1, 'Second row should have NULL for b and d'); - - // Third row: a, c, and d should be NULL - assert( - res.indexOf("(NULL,'value',NULL,NULL)") > -1, - 'Third row should have NULL for a, c, and d' - ); - - done(); + assert.deepEqual(res, expected); }); - it('2. Should handle undefined values as NULL', function (done) { + it('2. Should handle undefined values as NULL', () => { var data = [ {a: 1, b: 'test'}, {a: 2, b: undefined, c: 4}, ]; var res = alasql('SELECT * INTO SQL({tableid:"test_table"}) FROM ?', [data]); - console.log('Generated SQL with undefined:'); - console.log(res); + var expected = + "INSERT INTO test_table(a,b) VALUES (1,'test');\n" + + 'INSERT INTO test_table(a,b) VALUES (2,NULL);\n'; - // Check that NULL appears in the output - assert(res.indexOf('NULL') > -1, 'Output should contain NULL keyword for undefined values'); - - // Check that we don't have consecutive commas - assert(res.indexOf(',,') === -1, 'Output should not contain consecutive commas (,,)'); - - done(); + assert.deepEqual(res, expected); }); - it('3. Should handle mixed NULL, undefined, and empty strings', function (done) { + it('3. Should handle mixed NULL, undefined, and empty strings', () => { var data = [{a: 1, b: '', c: null, d: undefined}]; var res = alasql('SELECT * INTO SQL({tableid:"test_table"}) FROM ?', [data]); - console.log('Generated SQL with mixed values:'); - console.log(res); - - // Empty string should remain as empty string - assert(res.indexOf("''") > -1, "Empty string should be preserved as ''"); - - // null and undefined should become NULL - assert(res.indexOf('NULL') > -1, 'null and undefined should become NULL'); + var expected = "INSERT INTO test_table(a,b,c,d) VALUES (1,'',NULL,NULL);\n"; - done(); + assert.deepEqual(res, expected); }); }); From 210b87a8fbb359851841420a9eed95a5d9d0b2c4 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 20 Nov 2025 05:22:39 +0000 Subject: [PATCH 6/9] Refactor switch statement to include default case Co-authored-by: mathiasrw <1063454+mathiasrw@users.noreply.github.com> --- src/830into.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/830into.js b/src/830into.js index 66e8af3545..89a30bab4a 100755 --- a/src/830into.js +++ b/src/830into.js @@ -52,6 +52,10 @@ alasql.into.SQL = function (filename, opts, data, columns, cb) { case 'NCHAR': val = "'" + escapeqq(val) + "'"; break; + default: + if (typeof val == 'string') { + val = "'" + escapeqq(val) + "'"; + } } } else { if (typeof val == 'string') { From 85a079af5300f8cc341bf8b3126558bce3cd479f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 20 Nov 2025 05:22:47 +0000 Subject: [PATCH 7/9] Refactor: simplify if-else to use else-if for cleaner code Co-authored-by: mathiasrw <1063454+mathiasrw@users.noreply.github.com> --- src/830into.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/830into.js b/src/830into.js index 89a30bab4a..d688447708 100755 --- a/src/830into.js +++ b/src/830into.js @@ -57,10 +57,8 @@ alasql.into.SQL = function (filename, opts, data, columns, cb) { val = "'" + escapeqq(val) + "'"; } } - } else { - if (typeof val == 'string') { - val = "'" + escapeqq(val) + "'"; - } + } else if (typeof val == 'string') { + val = "'" + escapeqq(val) + "'"; } return val; }) From 616a97ef8f1f19342d69504d958de07b37e41db2 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 20 Nov 2025 08:43:47 +0000 Subject: [PATCH 8/9] Refactor: eliminate code repetition by consolidating escape logic Co-authored-by: mathiasrw <1063454+mathiasrw@users.noreply.github.com> --- src/830into.js | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/src/830into.js b/src/830into.js index d688447708..c009255a69 100755 --- a/src/830into.js +++ b/src/830into.js @@ -43,21 +43,16 @@ alasql.into.SQL = function (filename, opts, data, columns, cb) { if (val === null || val === undefined) { return 'NULL'; } - if (col.typeid) { - switch (col.typeid) { - case 'STRING': - case 'VARCHAR': - case 'NVARCHAR': - case 'CHAR': - case 'NCHAR': - val = "'" + escapeqq(val) + "'"; - break; - default: - if (typeof val == 'string') { - val = "'" + escapeqq(val) + "'"; - } - } - } else if (typeof val == 'string') { + // Check if value should be escaped as a string + var shouldEscape = + (col.typeid && + (col.typeid === 'STRING' || + col.typeid === 'VARCHAR' || + col.typeid === 'NVARCHAR' || + col.typeid === 'CHAR' || + col.typeid === 'NCHAR')) || + typeof val == 'string'; + if (shouldEscape) { val = "'" + escapeqq(val) + "'"; } return val; From ba35f5e29ef70b0e4ad337378d95a1324c5a6eb3 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 20 Nov 2025 09:07:11 +0000 Subject: [PATCH 9/9] Rename test file to test42.js and update test name to "Test 42" Co-authored-by: mathiasrw <1063454+mathiasrw@users.noreply.github.com> --- test/{test042_null_issue.js => test42.js} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename test/{test042_null_issue.js => test42.js} (95%) diff --git a/test/test042_null_issue.js b/test/test42.js similarity index 95% rename from test/test042_null_issue.js rename to test/test42.js index 62fffc973b..ddb7552142 100644 --- a/test/test042_null_issue.js +++ b/test/test42.js @@ -3,7 +3,7 @@ if (typeof exports === 'object') { var alasql = require('..'); } -describe('Test 042 - NULL values in INTO SQL()', function () { +describe('Test 42 - NULL values in INTO SQL()', function () { it('1. Should output NULL for null values', () => { var data = [ {a: 1, b: 'test', c: null, d: 3},