From 576180d7956b8be56f6e4f9abd322f73116f19ee Mon Sep 17 00:00:00 2001 From: yuexihuachen <2578038405@qq.com> Date: Fri, 30 Oct 2026 21:20:22 +0800 Subject: [PATCH 1/2] Fix CSV export of missing properties (#369) --- src/830into.js | 3 +++ test/test-csv-missing-properties.js | 21 +++++++++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 test/test-csv-missing-properties.js diff --git a/src/830into.js b/src/830into.js index 93428a74bc..ec427f304c 100755 --- a/src/830into.js +++ b/src/830into.js @@ -257,6 +257,9 @@ alasql.into.CSV = function (filename, opts, data, columns, cb) { columns .map(function (col) { var s = d[col.columnid]; + if (s === undefined) { + s = ''; + } // escape the character wherever it appears in the field if (opt.quote !== '') { s = (s + '').replace(new RegExp('\\' + opt.quote, 'g'), opt.quote + opt.quote); diff --git a/test/test-csv-missing-properties.js b/test/test-csv-missing-properties.js new file mode 100644 index 0000000000..31e1088658 --- /dev/null +++ b/test/test-csv-missing-properties.js @@ -0,0 +1,21 @@ +if (typeof exports === 'object') { + var assert = require('assert'); + var alasql = require('..'); +} + +describe('Test 369 - CSV export with missing properties', function () { + it('A) Export missing properties as empty fields', function () { + var data = [ + {a: 1, b: 2, c: 3, d: 4}, + {a: 5, b: 6}, + ]; + var res = alasql('SELECT * INTO CSV({headers:true, utf8Bom:false}) FROM ?', [data]); + assert.deepStrictEqual(res, '"a";"b";"c";"d"\r\n1;2;3;4\r\n5;6;;\r\n'); + }); + + it('B) Preserve an explicit undefined string', function () { + var data = [{a: 'undefined'}]; + var res = alasql('SELECT * INTO CSV({headers:true, utf8Bom:false}) FROM ?', [data]); + assert.deepStrictEqual(res, '"a"\r\n"undefined"\r\n'); + }); +}); From 18f0d8f5b67e33dc5c8d6d4602257f3c723e35b9 Mon Sep 17 00:00:00 2001 From: yuexihuachen <2578038405@qq.com> Date: Sun, 1 Nov 2026 09:04:05 +0800 Subject: [PATCH 2/2] Handle null CSV values as empty fields --- src/830into.js | 3 ++- test/test-csv-missing-properties.js | 6 ++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/830into.js b/src/830into.js index ec427f304c..1c0362ba3c 100755 --- a/src/830into.js +++ b/src/830into.js @@ -257,7 +257,8 @@ alasql.into.CSV = function (filename, opts, data, columns, cb) { columns .map(function (col) { var s = d[col.columnid]; - if (s === undefined) { + // Missing properties and null values both represent empty CSV fields. + if (s == null) { s = ''; } // escape the character wherever it appears in the field diff --git a/test/test-csv-missing-properties.js b/test/test-csv-missing-properties.js index 31e1088658..d2707c2c21 100644 --- a/test/test-csv-missing-properties.js +++ b/test/test-csv-missing-properties.js @@ -18,4 +18,10 @@ describe('Test 369 - CSV export with missing properties', function () { var res = alasql('SELECT * INTO CSV({headers:true, utf8Bom:false}) FROM ?', [data]); assert.deepStrictEqual(res, '"a"\r\n"undefined"\r\n'); }); + + it('C) Export null as empty but preserve an explicit null string', function () { + var data = [{a: null, b: 'null'}]; + var res = alasql('SELECT * INTO CSV({headers:true, utf8Bom:false}) FROM ?', [data]); + assert.deepStrictEqual(res, '"a";"b"\r\n;"null"\r\n'); + }); });