alasql 4.7.0 → 4.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
- - _AlaSQL is an unfunded open source project installed 500k+ times each month. [Please donate your time](https://github.com/AlaSQL/alasql/issues?q=is%3Aopen+label%3A%22Help+wanted%22+sort%3Aupdated-desc). We appreciate any and all contributions we can get._
1
+ - _AlaSQL is an unfunded open source project installed 650k+ times each month. [Please donate your time](https://github.com/AlaSQL/alasql/issues?q=is%3Aopen+label%3A%22Help+wanted%22+sort%3Aupdated-desc). We appreciate any and all contributions we can get._
2
2
 
3
- - _Have a question? [Ask the AlaSQL bot](https://chat.openai.com/g/g-XcBL24WTe-alasql-bot) or post on [Stack Overflow](http://stackoverflow.com/questions/ask?tags=AlaSQL)._
3
+ - _Have a question? [Ask The AlaSQL Bot](https://chatgpt.com/g/g-XcBL24WTe-alasql-bot) or post on [Stack Overflow](http://stackoverflow.com/questions/ask?tags=AlaSQL)._
4
4
 
5
5
  [![CI-test](https://github.com/alasql/alasql/workflows/CI%20build%20&%20test/badge.svg)](https://github.com/alasql/alasql/actions)
6
6
  [![NPM downloads](http://img.shields.io/npm/dm/alasql.svg?style=flat&label=npm%20downloads)](https://npm-stat.com/charts.html?package=alasql)
package/bin/alasql-cli.js CHANGED
@@ -10,7 +10,6 @@
10
10
  let alasql = require('../dist/alasql.fs.js');
11
11
  let path = require('path');
12
12
  let fs = require('fs');
13
- let stdin = process.openStdin();
14
13
  let yargs = require('yargs')
15
14
  .strict()
16
15
  .usage(
@@ -58,44 +57,73 @@ let yargs = require('yargs')
58
57
  .epilog('\nMore information about the library: www.alasql.org');
59
58
 
60
59
  let argv = yargs.argv;
61
- let sql = '';
62
- let params = [];
63
- let pipedData = '';
64
- stdin.on('data', function (chunk) {
65
- pipedData += chunk;
66
- });
67
60
 
68
- if (argv.v) {
69
- console.log(alasql.version);
70
- process.exit(0);
61
+ // Regex patterns for detecting functions
62
+ const re = {
63
+ txt: /txt\s*\(\s*\)/i,
64
+ };
65
+
66
+ // Helper function to check if SQL contains txt() and stdin is piped
67
+ function isPipeData(sql) {
68
+ return sql && !process.stdin.isTTY && re.txt.test(sql);
71
69
  }
72
70
 
73
- if (argv.f) {
74
- if (!fs.existsSync(argv.f)) {
71
+ // Helper function to setup stdin handling
72
+ function pipeIsSQL() {
73
+ const stdin = process.openStdin();
74
+ let pipedData = '';
75
+ stdin.on('data', function (chunk) {
76
+ pipedData += chunk;
77
+ });
78
+ stdin.on('end', function () {
79
+ execute(pipedData, argv._);
80
+ });
81
+ return stdin;
82
+ }
83
+
84
+ // Helper function to load and validate SQL file
85
+ function loadSqlFile(filePath) {
86
+ if (!fs.existsSync(filePath)) {
75
87
  console.error('Error: file not found');
76
88
  process.exit(1);
77
89
  }
78
-
79
- if (isDirectory(argv.f)) {
90
+ if (isDirectory(filePath)) {
80
91
  console.error('Error: file expected but directory found');
81
92
  process.exit(1);
82
93
  }
94
+ return fs.readFileSync(filePath, 'utf8').toString();
95
+ }
96
+
97
+ // Main execution logic
98
+ function main() {
99
+ let sql = '';
100
+ let pipeIsData = false;
101
+
102
+ if (argv.f) {
103
+ sql = loadSqlFile(argv.f);
104
+ pipeIsData = isPipeData(sql);
105
+ } else {
106
+ sql = argv._.shift() || '';
107
+ pipeIsData = isPipeData(sql);
108
+ }
83
109
 
84
- sql = fs.readFileSync(argv.f, 'utf8').toString();
85
- execute(sql, argv._);
86
- } else {
87
- sql = argv._.shift() || '';
110
+ // Setup stdin handling only if not using txt() pipe
111
+ if (!pipeIsData) {
112
+ pipeIsSQL();
113
+ }
88
114
 
89
- // if data is not piped
90
- if (Boolean(process.stdin.isTTY)) {
115
+ // Execute immediately if we have SQL or are using txt() pipe
116
+ if (sql || pipeIsData) {
91
117
  execute(sql, argv._);
92
118
  }
93
119
  }
94
120
 
95
- // if data is piped
96
- stdin.on('end', function () {
97
- execute(pipedData, argv._);
98
- });
121
+ if (argv.v) {
122
+ console.log(alasql.version);
123
+ process.exit(0);
124
+ }
125
+
126
+ main();
99
127
 
100
128
  /**
101
129
  * Execute SQL query
@@ -1,7 +1,7 @@
1
- //! AlaSQL v4.6.6 build: develop-272b12b3 | © 2014-2024 Andrey Gershun & Mathias Wulff | License: MIT
1
+ //! AlaSQL v4.8.0 build: develop-af967432 | © 2014-2024 Andrey Gershun & Mathias Wulff | License: MIT
2
2
  /*
3
3
  @module alasql
4
- @version 4.6.6
4
+ @version 4.8.0
5
5
 
6
6
  AlaSQL - JavaScript SQL database
7
7
  © 2014-2024 Andrey Gershun & Mathias Wulff
package/dist/alasql.fs.js CHANGED
@@ -1,7 +1,7 @@
1
- //! AlaSQL v4.6.6 build: develop-272b12b3 | © 2014-2024 Andrey Gershun & Mathias Wulff | License: MIT
1
+ //! AlaSQL v4.8.0 build: develop-af967432 | © 2014-2024 Andrey Gershun & Mathias Wulff | License: MIT
2
2
  /*
3
3
  @module alasql
4
- @version 4.6.6
4
+ @version 4.8.0
5
5
 
6
6
  AlaSQL - JavaScript SQL database
7
7
  © 2014-2024 Andrey Gershun & Mathias Wulff
@@ -141,8 +141,8 @@ SOFTWARE.
141
141
  Current version of alasql
142
142
  @constant {string}
143
143
  */
144
- alasql.version = '4.6.6';
145
- alasql.build = 'develop-272b12b3';
144
+ alasql.version = '4.8.0';
145
+ alasql.build = 'develop-af967432';
146
146
 
147
147
  /**
148
148
  Debug flag
@@ -244,7 +244,7 @@ case 1:
244
244
 
245
245
  break;
246
246
  case 2:
247
- this.$ = doubleq($$[$0].substr(1,$$[$0].length-2));
247
+ this.$ = doubleq($$[$0].substr(1,$$[$0].length-2));
248
248
  break;
249
249
  case 3:
250
250
  this.$ = $$[$0].toLowerCase()
@@ -3487,7 +3487,7 @@ let loadFile = (utils.loadFile = function (path, asy, success, error) {
3487
3487
  fs = require('fs');
3488
3488
 
3489
3489
  // If path is empty, than read data from stdin (for Node)
3490
- if (typeof path === 'undefined') {
3490
+ if ([null, undefined].includes(path)) {
3491
3491
  var buff = '';
3492
3492
  process.stdin.setEncoding('utf8');
3493
3493
  process.stdin.on('readable', function () {
@@ -8443,9 +8443,9 @@ yy.Select.prototype.compileGroup = function (query) {
8443
8443
  if (col.aggregatorid === 'SUM') {
8444
8444
  if ('funcid' in col.expression) {
8445
8445
  let colexp1 = colExpIfFunIdExists(col.expression);
8446
- return `'${colas}':(${colexp1})|| typeof ${colexp1} == 'number' ? ${colexp} : null,`;
8446
+ return `'${colas}':(__alasql_tmp = ${colexp}, (__alasql_tmp instanceof Date) ? undefined : ((__alasql_tmp || typeof __alasql_tmp == 'number') ? __alasql_tmp : undefined)),`;
8447
8447
  }
8448
- return `'${colas}':(${colexp})|| typeof ${colexp} == 'number' ? ${colexp} : null,`;
8448
+ return `'${colas}':(__alasql_tmp = ${colexp}, (__alasql_tmp instanceof Date) ? undefined : ((__alasql_tmp || typeof __alasql_tmp == 'number') ? __alasql_tmp : undefined)),`;
8449
8449
  } else if (col.aggregatorid === 'TOTAL') {
8450
8450
  if ('funcid' in col.expression) {
8451
8451
  let colexp1 = colExpIfFunIdExists(col.expression);
@@ -8462,19 +8462,16 @@ yy.Select.prototype.compileGroup = function (query) {
8462
8462
  if ('funcid' in col.expression) {
8463
8463
  let colexp1 = colExpIfFunIdExists(col.expression);
8464
8464
 
8465
- return `'${colas}': (typeof ${colexp1} == 'number' || typeof ${colexp1} == 'bigint' ? ${colexp} : typeof ${colexp1} == 'object' ?
8466
- typeof Number(${colexp1}) == 'number' && ${colexp1}!== null? ${colexp} : null : null),`;
8465
+ return `'${colas}': (__alasql_tmp = ${colexp}, typeof __alasql_tmp == 'number' || typeof __alasql_tmp == 'bigint' || (typeof __alasql_tmp == 'object' && (typeof Number(__alasql_tmp) == 'number' || __alasql_tmp instanceof Date)) ? __alasql_tmp : undefined),`;
8467
8466
  }
8468
- return `'${colas}': (typeof ${colexp} == 'number' || typeof ${colexp} == 'bigint' ? ${colexp} : typeof ${colexp} == 'object' ?
8469
- typeof Number(${colexp}) == 'number' && ${colexp}!== null? ${colexp} : null : null),`;
8467
+ return `'${colas}': (__alasql_tmp = ${colexp}, typeof __alasql_tmp == 'number' || typeof __alasql_tmp == 'bigint' || (typeof __alasql_tmp == 'object' && (typeof Number(__alasql_tmp) == 'number' || __alasql_tmp instanceof Date)) ? __alasql_tmp : undefined),`;
8470
8468
  } else if (col.aggregatorid === 'MAX') {
8471
8469
  if ('funcid' in col.expression) {
8472
8470
  let colexp1 = colExpIfFunIdExists(col.expression);
8473
- return `'${colas}' : (typeof ${colexp1} == 'number' || typeof ${colexp1} == 'bigint' ? ${colexp} : typeof ${colexp1} == 'object' ?
8474
- typeof Number(${colexp1}) == 'number' ? ${colexp} : null : null),`;
8471
+ return `'${colas}': (__alasql_tmp = ${colexp}, typeof __alasql_tmp == 'number' || typeof __alasql_tmp == 'bigint' || (typeof __alasql_tmp == 'object' && (typeof Number(__alasql_tmp) == 'number' || __alasql_tmp instanceof Date)) ? __alasql_tmp : undefined),`;
8475
8472
  }
8476
8473
  return `'${colas}' : (typeof ${colexp} == 'number' || typeof ${colexp} == 'bigint' ? ${colexp} : typeof ${colexp} == 'object' ?
8477
- typeof Number(${colexp}) == 'number' ? ${colexp} : null : null),`;
8474
+ typeof Number(${colexp}) == 'number' ? ${colexp} : undefined : undefined),`;
8478
8475
  } else if (col.aggregatorid === 'ARRAY') {
8479
8476
  return `'${colas}':[${colexp}],`;
8480
8477
  } else if (col.aggregatorid === 'COUNT') {
@@ -8487,7 +8484,7 @@ yy.Select.prototype.compileGroup = function (query) {
8487
8484
  query.removeKeys.push(`_SUM_${colas}`);
8488
8485
  query.removeKeys.push(`_COUNT_${colas}`);
8489
8486
 
8490
- return `'${colas}':${colexp},'_SUM_${colas}':(${colexp})||0,'_COUNT_${colas}':(typeof ${colexp} == "undefined" || ${colexp} === null) ? 0 : 1,`;
8487
+ return `'${colas}':(function() { var t = ${colexp}; return (t instanceof Date) ? undefined : t; })(),'_SUM_${colas}':(function() { var t = ${colexp}; return (t instanceof Date) ? undefined : (t || 0); })(),'_COUNT_${colas}':(typeof ${colexp} == "undefined" || ${colexp} === null) ? 0 : 1,`;
8491
8488
  } else if (col.aggregatorid === 'AGGR') {
8492
8489
  aft += `,g['${colas}']=${col.expression.toJS('g', -1)}`;
8493
8490
  return '';
@@ -8531,17 +8528,20 @@ yy.Select.prototype.compileGroup = function (query) {
8531
8528
  const __colexp1 = ${colexp1};
8532
8529
 
8533
8530
  if (__g_colas == null && ${colexp1} == null) {
8534
- g['${colas}'] = null;
8531
+ g['${colas}'] = undefined;
8535
8532
  } else if (typeof __g_colas === 'bigint' || typeof __colexp1 === 'bigint') {
8536
8533
  g['${colas}'] = BigInt(__g_colas) + BigInt(__colexp);
8537
8534
  } else if ((typeof __g_colas !== 'object' && typeof __g_colas !== 'number' && __typeof_colexp1 !== 'object' && __typeof_colexp1 !== 'number') ||
8538
- (__g_colas == null || (typeof __g_colas !== 'number' && typeof __g_colas !== 'object')) && (${colexp1} == null || (__typeof_colexp1 !== 'number' && __typeof_colexp1 !== 'object'))) {
8539
- g['${colas}'] = null;
8535
+ (__g_colas == null || (typeof __g_colas !== 'number' && typeof __g_colas !== 'object')) && (${colexp1} == null || (__typeof_colexp1 !== 'number' && __typeof_colexp1 !== 'object'))) {
8536
+ g['${colas}'] = undefined;
8540
8537
  } else if ((typeof __g_colas !== 'object' && typeof __g_colas !== 'number' && __typeof_colexp1 == 'number') ||
8541
8538
  (__g_colas == null && __typeof_colexp1 == 'number')) {
8542
8539
  g['${colas}'] = ${colexp};
8543
8540
  } else if (typeof __g_colas == 'number' && ${colexp1} == null) {
8544
8541
  g['${colas}'] = __g_colas;
8542
+ } else if (__g_colas instanceof Date || __colexp1 instanceof Date) {
8543
+ // Date objects cause string concatenation with +=, return undefined instead
8544
+ g['${colas}'] = undefined;
8545
8545
  } else {
8546
8546
  g['${colas}'] += ${colexp} || 0;
8547
8547
  }
@@ -8559,23 +8559,26 @@ yy.Select.prototype.compileGroup = function (query) {
8559
8559
  const __colexp = ${colexp};
8560
8560
 
8561
8561
  if (__g_colas == null && ${colexp} == null) {
8562
- g['${colas}'] = null;
8562
+ g['${colas}'] = undefined;
8563
8563
  } else if (typeof __g_colas === 'bigint' || typeof __colexp === 'bigint') {
8564
8564
  g['${colas}'] = BigInt(__g_colas) + BigInt(__colexp);
8565
8565
  } else if ((typeof __g_colas !== 'object' && typeof __g_colas !== 'number' && __typeof_colexp !== 'object' && __typeof_colexp !== 'number') ||
8566
8566
  (__g_colas == null || (typeof __g_colas !== 'number' && typeof __g_colas !== 'object')) && (${colexp} == null || (__typeof_colexp !== 'number' && __typeof_colexp !== 'object'))) {
8567
- g['${colas}'] = null;
8568
- } else if (typeof __g_colas !== 'object' && typeof __g_colas !== 'number' && __typeof_colexp == 'number') {
8569
- g['${colas}'] = ${colexp};
8570
- } else if (typeof __g_colas == 'number' && ${colexp} == null) {
8571
- g['${colas}'] = __g_colas;
8572
- } else if (__g_colas == null && __typeof_colexp == 'number') {
8573
- g['${colas}'] = ${colexp};
8574
- } else {
8575
- g['${colas}'] += ${colexp} || 0;
8576
- }
8567
+ g['${colas}'] = undefined;
8568
+ } else if (typeof __g_colas !== 'object' && typeof __g_colas !== 'number' && __typeof_colexp == 'number') {
8569
+ g['${colas}'] = ${colexp};
8570
+ } else if (typeof __g_colas == 'number' && ${colexp} == null) {
8571
+ g['${colas}'] = __g_colas;
8572
+ } else if (__g_colas == null && __typeof_colexp == 'number') {
8573
+ g['${colas}'] = ${colexp};
8574
+ } else if (__g_colas instanceof Date || __colexp instanceof Date) {
8575
+ // Date objects cause string concatenation with +=, return undefined instead
8576
+ g['${colas}'] = undefined;
8577
+ } else {
8578
+ g['${colas}'] += ${colexp} || 0;
8577
8579
  }
8578
- ` +
8580
+ }
8581
+ ` +
8579
8582
  post
8580
8583
  );
8581
8584
  } else if (col.aggregatorid === 'TOTAL') {
@@ -8714,19 +8717,19 @@ yy.Select.prototype.compileGroup = function (query) {
8714
8717
  }
8715
8718
  return (
8716
8719
  pre +
8717
- `if((g['${colas}'] == null && ${colexp}!== null) ? y = ${colexp} :
8718
- (g['${colas}']!== null && ${colexp} == null) ? y = g['${colas}'] :
8719
- ((y=${colexp}) > g['${colas}'])) {
8720
- if(typeof y == 'number' || typeof y == 'bigint') {
8721
- g['${colas}'] = y;
8722
- } else if(typeof y == 'object' && y instanceof Date) {
8723
- g['${colas}'] = y;
8724
- } else if(typeof y == 'object' && typeof Number(y) == 'number') {
8725
- g['${colas}'] = Number(y);
8720
+ `if ((g['${colas}'] == null && ${colexp} !== null) ? y = ${colexp} :
8721
+ (g['${colas}'] !== null && ${colexp} == null) ? y = g['${colas}'] :
8722
+ ((y = ${colexp}) > g['${colas}'])) {
8723
+ if (typeof y == 'number' || typeof y == 'bigint') {
8724
+ g['${colas}'] = y;
8725
+ } else if (typeof y == 'object' && y instanceof Date) {
8726
+ g['${colas}'] = y;
8727
+ } else if (typeof y == 'object' && typeof Number(y) == 'number') {
8728
+ g['${colas}'] = Number(y);
8726
8729
  }
8727
- } else if(g['${colas}']!== null && typeof g['${colas}'] == 'object' && y instanceof Date) {
8730
+ } else if (g['${colas}'] !== null && typeof g['${colas}'] == 'object' && y instanceof Date) {
8728
8731
  g['${colas}'] = g['${colas}'];
8729
- } else if(g['${colas}']!== null && typeof g['${colas}'] == 'object') {
8732
+ } else if (g['${colas}'] !== null && typeof g['${colas}'] == 'object') {
8730
8733
  g['${colas}'] = Number(g['${colas}']);
8731
8734
  }` +
8732
8735
  post
@@ -8739,7 +8742,11 @@ yy.Select.prototype.compileGroup = function (query) {
8739
8742
  return `${pre}
8740
8743
  y= (${colexp});
8741
8744
  g['_COUNT_${colas}'] += (typeof y == "undefined" || y === null) ? 0 : 1;
8742
- if (typeof g['_SUM_${colas}'] === 'bigint' || typeof y === 'bigint') {
8745
+ if (y instanceof Date || (g['_SUM_${colas}'] && g['_SUM_${colas}'] instanceof Date)) {
8746
+ // AVG on Date objects doesn't make semantic sense - return undefined
8747
+ g['_SUM_${colas}'] = undefined;
8748
+ g['${colas}'] = undefined;
8749
+ } else if (typeof g['_SUM_${colas}'] === 'bigint' || typeof y === 'bigint') {
8743
8750
  g['_SUM_${colas}'] = BigInt(g['_SUM_${colas}']);
8744
8751
  g['_SUM_${colas}'] += BigInt(y || 0);
8745
8752
  g['${colas}'] = BigInt(g['_SUM_${colas}']) / BigInt(g['_COUNT_${colas}']);
@@ -11270,9 +11277,21 @@ stdlib.RANDOM = function (r) {
11270
11277
  };
11271
11278
  stdlib.ROUND = function (s, d) {
11272
11279
  if (arguments.length == 2) {
11273
- return 'Math.round((' + s + ')*Math.pow(10,(' + d + ')))/Math.pow(10,(' + d + '))';
11280
+ return (
11281
+ '(__alasql_tmp = (' +
11282
+ s +
11283
+ '), (__alasql_tmp == null || (typeof __alasql_tmp === "string" && __alasql_tmp.trim() === "")) ? undefined : ((__alasql_tmp = Number(__alasql_tmp)), isNaN(__alasql_tmp) ? undefined : Math.round(__alasql_tmp*Math.pow(10,(' +
11284
+ d +
11285
+ ')))/Math.pow(10,(' +
11286
+ d +
11287
+ '))))'
11288
+ );
11274
11289
  } else {
11275
- return 'Math.round(' + s + ')';
11290
+ return (
11291
+ '(__alasql_tmp = (' +
11292
+ s +
11293
+ '), (__alasql_tmp == null || (typeof __alasql_tmp === "string" && __alasql_tmp.trim() === "")) ? undefined : ((__alasql_tmp = Number(__alasql_tmp)), isNaN(__alasql_tmp) ? undefined : Math.round(__alasql_tmp)))'
11294
+ );
11276
11295
  }
11277
11296
  };
11278
11297
  stdlib.CEIL = stdlib.CEILING = function (s) {
@@ -16549,7 +16568,7 @@ alasql.from.JSON = function (filename, opts, cb, idx, query) {
16549
16568
  var res;
16550
16569
 
16551
16570
  filename = alasql.utils.autoExtFilename(filename, 'json', opts);
16552
- alasql.utils.loadFile(filename, !!cb, function (data) {
16571
+ (alasql.utils.loadFile(filename, !!cb, function (data) {
16553
16572
 
16554
16573
  // res = [{a:1}];
16555
16574
  res = JSON.parse(data);
@@ -16559,12 +16578,12 @@ alasql.from.JSON = function (filename, opts, cb, idx, query) {
16559
16578
  }),
16560
16579
  err => {
16561
16580
  const error = err instanceof Error ? err : new Error(err);
16562
- if(query && query.cb) {
16581
+ if (query && query.cb) {
16563
16582
  query.cb(null, error);
16564
16583
  return;
16565
16584
  }
16566
16585
  throw error;
16567
- };
16586
+ });
16568
16587
  return res;
16569
16588
  };
16570
16589
 
@@ -16593,7 +16612,7 @@ const jsonl = ext => {
16593
16612
  },
16594
16613
  err => {
16595
16614
  const error = err instanceof Error ? err : new Error(err);
16596
- if(query && query.cb) {
16615
+ if (query && query.cb) {
16597
16616
  query.cb(null, error);
16598
16617
  return;
16599
16618
  }
@@ -16669,7 +16688,7 @@ alasql.from.CSV = function (contents, opts, cb, idx, query) {
16669
16688
  return EOF;
16670
16689
  }
16671
16690
  if (eol) {
16672
- return (eol = false), EOL;
16691
+ return ((eol = false), EOL);
16673
16692
  }
16674
16693
  var j = I;
16675
16694
  if (text.charCodeAt(j) === quoteCode) {
package/dist/alasql.js CHANGED
@@ -1,7 +1,7 @@
1
- //! AlaSQL v4.6.6 build: develop-272b12b3 | © 2014-2024 Andrey Gershun & Mathias Wulff | License: MIT
1
+ //! AlaSQL v4.8.0 build: develop-af967432 | © 2014-2024 Andrey Gershun & Mathias Wulff | License: MIT
2
2
  /*
3
3
  @module alasql
4
- @version 4.6.6
4
+ @version 4.8.0
5
5
 
6
6
  AlaSQL - JavaScript SQL database
7
7
  © 2014-2024 Andrey Gershun & Mathias Wulff
@@ -141,8 +141,8 @@ SOFTWARE.
141
141
  Current version of alasql
142
142
  @constant {string}
143
143
  */
144
- alasql.version = '4.6.6';
145
- alasql.build = 'develop-272b12b3';
144
+ alasql.version = '4.8.0';
145
+ alasql.build = 'develop-af967432';
146
146
 
147
147
  /**
148
148
  Debug flag
@@ -244,7 +244,7 @@ case 1:
244
244
 
245
245
  break;
246
246
  case 2:
247
- this.$ = doubleq($$[$0].substr(1,$$[$0].length-2));
247
+ this.$ = doubleq($$[$0].substr(1,$$[$0].length-2));
248
248
  break;
249
249
  case 3:
250
250
  this.$ = $$[$0].toLowerCase()
@@ -3487,7 +3487,7 @@ let loadFile = (utils.loadFile = function (path, asy, success, error) {
3487
3487
  fs = require('fs');
3488
3488
 
3489
3489
  // If path is empty, than read data from stdin (for Node)
3490
- if (typeof path === 'undefined') {
3490
+ if ([null, undefined].includes(path)) {
3491
3491
  var buff = '';
3492
3492
  process.stdin.setEncoding('utf8');
3493
3493
  process.stdin.on('readable', function () {
@@ -8443,9 +8443,9 @@ yy.Select.prototype.compileGroup = function (query) {
8443
8443
  if (col.aggregatorid === 'SUM') {
8444
8444
  if ('funcid' in col.expression) {
8445
8445
  let colexp1 = colExpIfFunIdExists(col.expression);
8446
- return `'${colas}':(${colexp1})|| typeof ${colexp1} == 'number' ? ${colexp} : null,`;
8446
+ return `'${colas}':(__alasql_tmp = ${colexp}, (__alasql_tmp instanceof Date) ? undefined : ((__alasql_tmp || typeof __alasql_tmp == 'number') ? __alasql_tmp : undefined)),`;
8447
8447
  }
8448
- return `'${colas}':(${colexp})|| typeof ${colexp} == 'number' ? ${colexp} : null,`;
8448
+ return `'${colas}':(__alasql_tmp = ${colexp}, (__alasql_tmp instanceof Date) ? undefined : ((__alasql_tmp || typeof __alasql_tmp == 'number') ? __alasql_tmp : undefined)),`;
8449
8449
  } else if (col.aggregatorid === 'TOTAL') {
8450
8450
  if ('funcid' in col.expression) {
8451
8451
  let colexp1 = colExpIfFunIdExists(col.expression);
@@ -8462,19 +8462,16 @@ yy.Select.prototype.compileGroup = function (query) {
8462
8462
  if ('funcid' in col.expression) {
8463
8463
  let colexp1 = colExpIfFunIdExists(col.expression);
8464
8464
 
8465
- return `'${colas}': (typeof ${colexp1} == 'number' || typeof ${colexp1} == 'bigint' ? ${colexp} : typeof ${colexp1} == 'object' ?
8466
- typeof Number(${colexp1}) == 'number' && ${colexp1}!== null? ${colexp} : null : null),`;
8465
+ return `'${colas}': (__alasql_tmp = ${colexp}, typeof __alasql_tmp == 'number' || typeof __alasql_tmp == 'bigint' || (typeof __alasql_tmp == 'object' && (typeof Number(__alasql_tmp) == 'number' || __alasql_tmp instanceof Date)) ? __alasql_tmp : undefined),`;
8467
8466
  }
8468
- return `'${colas}': (typeof ${colexp} == 'number' || typeof ${colexp} == 'bigint' ? ${colexp} : typeof ${colexp} == 'object' ?
8469
- typeof Number(${colexp}) == 'number' && ${colexp}!== null? ${colexp} : null : null),`;
8467
+ return `'${colas}': (__alasql_tmp = ${colexp}, typeof __alasql_tmp == 'number' || typeof __alasql_tmp == 'bigint' || (typeof __alasql_tmp == 'object' && (typeof Number(__alasql_tmp) == 'number' || __alasql_tmp instanceof Date)) ? __alasql_tmp : undefined),`;
8470
8468
  } else if (col.aggregatorid === 'MAX') {
8471
8469
  if ('funcid' in col.expression) {
8472
8470
  let colexp1 = colExpIfFunIdExists(col.expression);
8473
- return `'${colas}' : (typeof ${colexp1} == 'number' || typeof ${colexp1} == 'bigint' ? ${colexp} : typeof ${colexp1} == 'object' ?
8474
- typeof Number(${colexp1}) == 'number' ? ${colexp} : null : null),`;
8471
+ return `'${colas}': (__alasql_tmp = ${colexp}, typeof __alasql_tmp == 'number' || typeof __alasql_tmp == 'bigint' || (typeof __alasql_tmp == 'object' && (typeof Number(__alasql_tmp) == 'number' || __alasql_tmp instanceof Date)) ? __alasql_tmp : undefined),`;
8475
8472
  }
8476
8473
  return `'${colas}' : (typeof ${colexp} == 'number' || typeof ${colexp} == 'bigint' ? ${colexp} : typeof ${colexp} == 'object' ?
8477
- typeof Number(${colexp}) == 'number' ? ${colexp} : null : null),`;
8474
+ typeof Number(${colexp}) == 'number' ? ${colexp} : undefined : undefined),`;
8478
8475
  } else if (col.aggregatorid === 'ARRAY') {
8479
8476
  return `'${colas}':[${colexp}],`;
8480
8477
  } else if (col.aggregatorid === 'COUNT') {
@@ -8487,7 +8484,7 @@ yy.Select.prototype.compileGroup = function (query) {
8487
8484
  query.removeKeys.push(`_SUM_${colas}`);
8488
8485
  query.removeKeys.push(`_COUNT_${colas}`);
8489
8486
 
8490
- return `'${colas}':${colexp},'_SUM_${colas}':(${colexp})||0,'_COUNT_${colas}':(typeof ${colexp} == "undefined" || ${colexp} === null) ? 0 : 1,`;
8487
+ return `'${colas}':(function() { var t = ${colexp}; return (t instanceof Date) ? undefined : t; })(),'_SUM_${colas}':(function() { var t = ${colexp}; return (t instanceof Date) ? undefined : (t || 0); })(),'_COUNT_${colas}':(typeof ${colexp} == "undefined" || ${colexp} === null) ? 0 : 1,`;
8491
8488
  } else if (col.aggregatorid === 'AGGR') {
8492
8489
  aft += `,g['${colas}']=${col.expression.toJS('g', -1)}`;
8493
8490
  return '';
@@ -8531,17 +8528,20 @@ yy.Select.prototype.compileGroup = function (query) {
8531
8528
  const __colexp1 = ${colexp1};
8532
8529
 
8533
8530
  if (__g_colas == null && ${colexp1} == null) {
8534
- g['${colas}'] = null;
8531
+ g['${colas}'] = undefined;
8535
8532
  } else if (typeof __g_colas === 'bigint' || typeof __colexp1 === 'bigint') {
8536
8533
  g['${colas}'] = BigInt(__g_colas) + BigInt(__colexp);
8537
8534
  } else if ((typeof __g_colas !== 'object' && typeof __g_colas !== 'number' && __typeof_colexp1 !== 'object' && __typeof_colexp1 !== 'number') ||
8538
- (__g_colas == null || (typeof __g_colas !== 'number' && typeof __g_colas !== 'object')) && (${colexp1} == null || (__typeof_colexp1 !== 'number' && __typeof_colexp1 !== 'object'))) {
8539
- g['${colas}'] = null;
8535
+ (__g_colas == null || (typeof __g_colas !== 'number' && typeof __g_colas !== 'object')) && (${colexp1} == null || (__typeof_colexp1 !== 'number' && __typeof_colexp1 !== 'object'))) {
8536
+ g['${colas}'] = undefined;
8540
8537
  } else if ((typeof __g_colas !== 'object' && typeof __g_colas !== 'number' && __typeof_colexp1 == 'number') ||
8541
8538
  (__g_colas == null && __typeof_colexp1 == 'number')) {
8542
8539
  g['${colas}'] = ${colexp};
8543
8540
  } else if (typeof __g_colas == 'number' && ${colexp1} == null) {
8544
8541
  g['${colas}'] = __g_colas;
8542
+ } else if (__g_colas instanceof Date || __colexp1 instanceof Date) {
8543
+ // Date objects cause string concatenation with +=, return undefined instead
8544
+ g['${colas}'] = undefined;
8545
8545
  } else {
8546
8546
  g['${colas}'] += ${colexp} || 0;
8547
8547
  }
@@ -8559,23 +8559,26 @@ yy.Select.prototype.compileGroup = function (query) {
8559
8559
  const __colexp = ${colexp};
8560
8560
 
8561
8561
  if (__g_colas == null && ${colexp} == null) {
8562
- g['${colas}'] = null;
8562
+ g['${colas}'] = undefined;
8563
8563
  } else if (typeof __g_colas === 'bigint' || typeof __colexp === 'bigint') {
8564
8564
  g['${colas}'] = BigInt(__g_colas) + BigInt(__colexp);
8565
8565
  } else if ((typeof __g_colas !== 'object' && typeof __g_colas !== 'number' && __typeof_colexp !== 'object' && __typeof_colexp !== 'number') ||
8566
8566
  (__g_colas == null || (typeof __g_colas !== 'number' && typeof __g_colas !== 'object')) && (${colexp} == null || (__typeof_colexp !== 'number' && __typeof_colexp !== 'object'))) {
8567
- g['${colas}'] = null;
8568
- } else if (typeof __g_colas !== 'object' && typeof __g_colas !== 'number' && __typeof_colexp == 'number') {
8569
- g['${colas}'] = ${colexp};
8570
- } else if (typeof __g_colas == 'number' && ${colexp} == null) {
8571
- g['${colas}'] = __g_colas;
8572
- } else if (__g_colas == null && __typeof_colexp == 'number') {
8573
- g['${colas}'] = ${colexp};
8574
- } else {
8575
- g['${colas}'] += ${colexp} || 0;
8576
- }
8567
+ g['${colas}'] = undefined;
8568
+ } else if (typeof __g_colas !== 'object' && typeof __g_colas !== 'number' && __typeof_colexp == 'number') {
8569
+ g['${colas}'] = ${colexp};
8570
+ } else if (typeof __g_colas == 'number' && ${colexp} == null) {
8571
+ g['${colas}'] = __g_colas;
8572
+ } else if (__g_colas == null && __typeof_colexp == 'number') {
8573
+ g['${colas}'] = ${colexp};
8574
+ } else if (__g_colas instanceof Date || __colexp instanceof Date) {
8575
+ // Date objects cause string concatenation with +=, return undefined instead
8576
+ g['${colas}'] = undefined;
8577
+ } else {
8578
+ g['${colas}'] += ${colexp} || 0;
8577
8579
  }
8578
- ` +
8580
+ }
8581
+ ` +
8579
8582
  post
8580
8583
  );
8581
8584
  } else if (col.aggregatorid === 'TOTAL') {
@@ -8714,19 +8717,19 @@ yy.Select.prototype.compileGroup = function (query) {
8714
8717
  }
8715
8718
  return (
8716
8719
  pre +
8717
- `if((g['${colas}'] == null && ${colexp}!== null) ? y = ${colexp} :
8718
- (g['${colas}']!== null && ${colexp} == null) ? y = g['${colas}'] :
8719
- ((y=${colexp}) > g['${colas}'])) {
8720
- if(typeof y == 'number' || typeof y == 'bigint') {
8721
- g['${colas}'] = y;
8722
- } else if(typeof y == 'object' && y instanceof Date) {
8723
- g['${colas}'] = y;
8724
- } else if(typeof y == 'object' && typeof Number(y) == 'number') {
8725
- g['${colas}'] = Number(y);
8720
+ `if ((g['${colas}'] == null && ${colexp} !== null) ? y = ${colexp} :
8721
+ (g['${colas}'] !== null && ${colexp} == null) ? y = g['${colas}'] :
8722
+ ((y = ${colexp}) > g['${colas}'])) {
8723
+ if (typeof y == 'number' || typeof y == 'bigint') {
8724
+ g['${colas}'] = y;
8725
+ } else if (typeof y == 'object' && y instanceof Date) {
8726
+ g['${colas}'] = y;
8727
+ } else if (typeof y == 'object' && typeof Number(y) == 'number') {
8728
+ g['${colas}'] = Number(y);
8726
8729
  }
8727
- } else if(g['${colas}']!== null && typeof g['${colas}'] == 'object' && y instanceof Date) {
8730
+ } else if (g['${colas}'] !== null && typeof g['${colas}'] == 'object' && y instanceof Date) {
8728
8731
  g['${colas}'] = g['${colas}'];
8729
- } else if(g['${colas}']!== null && typeof g['${colas}'] == 'object') {
8732
+ } else if (g['${colas}'] !== null && typeof g['${colas}'] == 'object') {
8730
8733
  g['${colas}'] = Number(g['${colas}']);
8731
8734
  }` +
8732
8735
  post
@@ -8739,7 +8742,11 @@ yy.Select.prototype.compileGroup = function (query) {
8739
8742
  return `${pre}
8740
8743
  y= (${colexp});
8741
8744
  g['_COUNT_${colas}'] += (typeof y == "undefined" || y === null) ? 0 : 1;
8742
- if (typeof g['_SUM_${colas}'] === 'bigint' || typeof y === 'bigint') {
8745
+ if (y instanceof Date || (g['_SUM_${colas}'] && g['_SUM_${colas}'] instanceof Date)) {
8746
+ // AVG on Date objects doesn't make semantic sense - return undefined
8747
+ g['_SUM_${colas}'] = undefined;
8748
+ g['${colas}'] = undefined;
8749
+ } else if (typeof g['_SUM_${colas}'] === 'bigint' || typeof y === 'bigint') {
8743
8750
  g['_SUM_${colas}'] = BigInt(g['_SUM_${colas}']);
8744
8751
  g['_SUM_${colas}'] += BigInt(y || 0);
8745
8752
  g['${colas}'] = BigInt(g['_SUM_${colas}']) / BigInt(g['_COUNT_${colas}']);
@@ -11270,9 +11277,21 @@ stdlib.RANDOM = function (r) {
11270
11277
  };
11271
11278
  stdlib.ROUND = function (s, d) {
11272
11279
  if (arguments.length == 2) {
11273
- return 'Math.round((' + s + ')*Math.pow(10,(' + d + ')))/Math.pow(10,(' + d + '))';
11280
+ return (
11281
+ '(__alasql_tmp = (' +
11282
+ s +
11283
+ '), (__alasql_tmp == null || (typeof __alasql_tmp === "string" && __alasql_tmp.trim() === "")) ? undefined : ((__alasql_tmp = Number(__alasql_tmp)), isNaN(__alasql_tmp) ? undefined : Math.round(__alasql_tmp*Math.pow(10,(' +
11284
+ d +
11285
+ ')))/Math.pow(10,(' +
11286
+ d +
11287
+ '))))'
11288
+ );
11274
11289
  } else {
11275
- return 'Math.round(' + s + ')';
11290
+ return (
11291
+ '(__alasql_tmp = (' +
11292
+ s +
11293
+ '), (__alasql_tmp == null || (typeof __alasql_tmp === "string" && __alasql_tmp.trim() === "")) ? undefined : ((__alasql_tmp = Number(__alasql_tmp)), isNaN(__alasql_tmp) ? undefined : Math.round(__alasql_tmp)))'
11294
+ );
11276
11295
  }
11277
11296
  };
11278
11297
  stdlib.CEIL = stdlib.CEILING = function (s) {
@@ -16549,7 +16568,7 @@ alasql.from.JSON = function (filename, opts, cb, idx, query) {
16549
16568
  var res;
16550
16569
 
16551
16570
  filename = alasql.utils.autoExtFilename(filename, 'json', opts);
16552
- alasql.utils.loadFile(filename, !!cb, function (data) {
16571
+ (alasql.utils.loadFile(filename, !!cb, function (data) {
16553
16572
 
16554
16573
  // res = [{a:1}];
16555
16574
  res = JSON.parse(data);
@@ -16559,12 +16578,12 @@ alasql.from.JSON = function (filename, opts, cb, idx, query) {
16559
16578
  }),
16560
16579
  err => {
16561
16580
  const error = err instanceof Error ? err : new Error(err);
16562
- if(query && query.cb) {
16581
+ if (query && query.cb) {
16563
16582
  query.cb(null, error);
16564
16583
  return;
16565
16584
  }
16566
16585
  throw error;
16567
- };
16586
+ });
16568
16587
  return res;
16569
16588
  };
16570
16589
 
@@ -16593,7 +16612,7 @@ const jsonl = ext => {
16593
16612
  },
16594
16613
  err => {
16595
16614
  const error = err instanceof Error ? err : new Error(err);
16596
- if(query && query.cb) {
16615
+ if (query && query.cb) {
16597
16616
  query.cb(null, error);
16598
16617
  return;
16599
16618
  }
@@ -16669,7 +16688,7 @@ alasql.from.CSV = function (contents, opts, cb, idx, query) {
16669
16688
  return EOF;
16670
16689
  }
16671
16690
  if (eol) {
16672
- return (eol = false), EOL;
16691
+ return ((eol = false), EOL);
16673
16692
  }
16674
16693
  var j = I;
16675
16694
  if (text.charCodeAt(j) === quoteCode) {