alasql 4.19.1 → 4.20.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.
@@ -1,7 +1,7 @@
1
- //! AlaSQL v4.19.0 build: develop-98e852ad | © 2014-2025 Andrey Gershun & Mathias Wulff | License: MIT
1
+ //! AlaSQL v4.19.1 build: develop-cfae681d | © 2014-2025 Andrey Gershun & Mathias Wulff | License: MIT
2
2
  /*
3
3
  @module alasql
4
- @version 4.19.0
4
+ @version 4.19.1
5
5
 
6
6
  AlaSQL - JavaScript SQL database
7
7
  © 2014-2025 Andrey Gershun & Mathias Wulff
package/dist/alasql.d.ts CHANGED
@@ -85,13 +85,7 @@ declare module 'alasql' {
85
85
  }
86
86
 
87
87
  export type ExpressionNode =
88
- | Op
89
- | Column
90
- | ParamValue
91
- | NumValue
92
- | StringValue
93
- | LogicValue
94
- | UniOp;
88
+ Op | Column | ParamValue | NumValue | StringValue | LogicValue | UniOp;
95
89
 
96
90
  export interface ExpressionWrapper extends AlaSQLExpression {
97
91
  expression: ExpressionNode;
package/dist/alasql.fs.js CHANGED
@@ -1,7 +1,7 @@
1
- //! AlaSQL v4.19.0 build: develop-98e852ad | © 2014-2025 Andrey Gershun & Mathias Wulff | License: MIT
1
+ //! AlaSQL v4.19.1 build: develop-cfae681d | © 2014-2025 Andrey Gershun & Mathias Wulff | License: MIT
2
2
  /*
3
3
  @module alasql
4
- @version 4.19.0
4
+ @version 4.19.1
5
5
 
6
6
  AlaSQL - JavaScript SQL database
7
7
  © 2014-2025 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.19.0';
145
- alasql.build = 'develop-98e852ad';
144
+ alasql.version = '4.19.1';
145
+ alasql.build = 'develop-cfae681d';
146
146
 
147
147
  /**
148
148
  Debug flag
@@ -8601,7 +8601,11 @@ yy.Select = class Select {
8601
8601
  return referencesExternal(subquery.where) || referencesExternal(subquery.columns);
8602
8602
  };
8603
8603
 
8604
- query.queriesfn = this.queries.map(function (q, idx) {
8604
+ // Compile each subquery. Nested scalar subqueries such as
8605
+ // SELECT (SELECT (SELECT 1 AS c) AS b) AS a share one statement-level
8606
+ // queries list (see #1025), so every compiled subquery must be able to
8607
+ // resolve queriesidx against the same queriesfn array at runtime.
8608
+ query.queriesfn = this.queries.map(function (q) {
8605
8609
  var nq = q.compile(query.database.databaseid);
8606
8610
  nq.query.modifier = 'RECORDSET';
8607
8611
 
@@ -8609,8 +8613,8 @@ yy.Select = class Select {
8609
8613
  nq.query.isCorrelated = isCorrelated(q, query);
8610
8614
 
8611
8615
  // If the nested query has its own queries, ensure they're compiled too
8612
- // This handles nested subqueries properly
8613
- if (q.queries && q.queries.length > 0) {
8616
+ // (e.g. IN/ALL/ANY subqueries that captured a nested queries list)
8617
+ if (q.queries && q.queries.length > 0 && !nq.query.queriesfn) {
8614
8618
  nq.query.queriesfn = q.queries.map(function (qq) {
8615
8619
  var nnq = qq.compile(query.database.databaseid);
8616
8620
  nnq.query.modifier = 'RECORDSET';
@@ -8620,15 +8624,20 @@ yy.Select = class Select {
8620
8624
  return nq;
8621
8625
  });
8622
8626
 
8623
- // Subquery indices (queriesidx) are assigned against the statement-level
8624
- // queries list, so a subquery that references another subquery
8625
- // (e.g. a scalar subquery nested inside a subquery's WHERE clause)
8626
- // needs access to the same compiled list
8627
- query.queriesfn.forEach(function (nq) {
8628
- if (!nq.query.queriesfn) {
8629
- nq.query.queriesfn = query.queriesfn;
8630
- }
8631
- });
8627
+ // Share compiled subquery functions down the tree. Without this,
8628
+ // multi-level scalar subqueries fail with
8629
+ // "Cannot read properties of undefined (reading '0')" when the
8630
+ // inner select expression evaluates this.queriesfn[queriesidx-1].
8631
+ (function shareQueriesfn(queriesfn) {
8632
+ if (!queriesfn) return;
8633
+ queriesfn.forEach(function (nq) {
8634
+ if (!nq.query.queriesfn) {
8635
+ nq.query.queriesfn = queriesfn;
8636
+ } else if (nq.query.queriesfn !== queriesfn) {
8637
+ shareQueriesfn(nq.query.queriesfn);
8638
+ }
8639
+ });
8640
+ })(query.queriesfn);
8632
8641
  }
8633
8642
  };
8634
8643
 
@@ -15455,40 +15464,61 @@ function mapColumnsToNames(data, sourceColumns, targetColumns) {
15455
15464
 
15456
15465
  yy.WithSelect.prototype.execute = function (databaseid, params, cb) {
15457
15466
  var self = this;
15458
- // Create temporary tables
15459
15467
  var savedTables = [];
15460
- self.withs.forEach(function (w) {
15468
+
15469
+ // Restore tables shadowed by the temporary CTE tables
15470
+ function restoreTables() {
15471
+ self.withs.forEach(function (w, idx) {
15472
+ if (savedTables[idx]) alasql.databases[databaseid].tables[w.name] = savedTables[idx];
15473
+ else delete alasql.databases[databaseid].tables[w.name];
15474
+ });
15475
+ }
15476
+
15477
+ // Create temporary tables one after another. Each non-recursive CTE is
15478
+ // executed with a callback, so sources that load data asynchronously
15479
+ // (like CSV() or XLSX() reading a file) are fully loaded before the
15480
+ // next CTE or the main select reads the temporary table.
15481
+ function executeWith(idx) {
15482
+ if (idx >= self.withs.length) {
15483
+ return self.select.execute(databaseid, params, function (data, err) {
15484
+ restoreTables();
15485
+ if (cb) data = cb(data, err);
15486
+ return data;
15487
+ });
15488
+ }
15489
+
15490
+ var w = self.withs[idx];
15461
15491
  savedTables.push(alasql.databases[databaseid].tables[w.name]);
15462
15492
 
15463
15493
  if (w.recursive) {
15464
15494
  // Execute recursive CTE
15465
15495
  executeRecursiveCTE(w, databaseid, params);
15466
- } else {
15467
- // Non-recursive CTE - original behavior
15468
- var tb = (alasql.databases[databaseid].tables[w.name] = new Table({
15469
- tableid: w.name,
15470
- }));
15471
- tb.data = w.select.execute(databaseid, params);
15496
+ return executeWith(idx + 1);
15497
+ }
15498
+
15499
+ // Non-recursive CTE
15500
+ var tb = (alasql.databases[databaseid].tables[w.name] = new Table({
15501
+ tableid: w.name,
15502
+ }));
15503
+ // The statement returns its own result, so keep the result of the rest
15504
+ // of the chain (available right away when all sources are synchronous)
15505
+ var res;
15506
+ w.select.execute(databaseid, params, function (data, err) {
15507
+ if (err) {
15508
+ restoreTables();
15509
+ if (cb) return cb(null, err);
15510
+ throw err;
15511
+ }
15512
+ tb.data = data;
15472
15513
  if (w.columns) {
15473
15514
  tb.data = renameColumns(tb.data, w.columns);
15474
15515
  }
15475
- }
15476
- });
15477
-
15478
- var res = 1;
15479
- res = this.select.execute(databaseid, params, function (data) {
15480
- // Clear temporary tables
15481
- // setTimeout(function(){
15482
- self.withs.forEach(function (w, idx) {
15483
- if (savedTables[idx]) alasql.databases[databaseid].tables[w.name] = savedTables[idx];
15484
- else delete alasql.databases[databaseid].tables[w.name];
15516
+ res = executeWith(idx + 1);
15485
15517
  });
15486
- // },0);
15518
+ return res;
15519
+ }
15487
15520
 
15488
- if (cb) data = cb(data);
15489
- return data;
15490
- });
15491
- return res;
15521
+ return executeWith(0);
15492
15522
  };
15493
15523
 
15494
15524
  /*
package/dist/alasql.js CHANGED
@@ -1,7 +1,7 @@
1
- //! AlaSQL v4.19.0 build: develop-98e852ad | © 2014-2025 Andrey Gershun & Mathias Wulff | License: MIT
1
+ //! AlaSQL v4.19.1 build: develop-cfae681d | © 2014-2025 Andrey Gershun & Mathias Wulff | License: MIT
2
2
  /*
3
3
  @module alasql
4
- @version 4.19.0
4
+ @version 4.19.1
5
5
 
6
6
  AlaSQL - JavaScript SQL database
7
7
  © 2014-2025 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.19.0';
145
- alasql.build = 'develop-98e852ad';
144
+ alasql.version = '4.19.1';
145
+ alasql.build = 'develop-cfae681d';
146
146
 
147
147
  /**
148
148
  Debug flag
@@ -8601,7 +8601,11 @@ yy.Select = class Select {
8601
8601
  return referencesExternal(subquery.where) || referencesExternal(subquery.columns);
8602
8602
  };
8603
8603
 
8604
- query.queriesfn = this.queries.map(function (q, idx) {
8604
+ // Compile each subquery. Nested scalar subqueries such as
8605
+ // SELECT (SELECT (SELECT 1 AS c) AS b) AS a share one statement-level
8606
+ // queries list (see #1025), so every compiled subquery must be able to
8607
+ // resolve queriesidx against the same queriesfn array at runtime.
8608
+ query.queriesfn = this.queries.map(function (q) {
8605
8609
  var nq = q.compile(query.database.databaseid);
8606
8610
  nq.query.modifier = 'RECORDSET';
8607
8611
 
@@ -8609,8 +8613,8 @@ yy.Select = class Select {
8609
8613
  nq.query.isCorrelated = isCorrelated(q, query);
8610
8614
 
8611
8615
  // If the nested query has its own queries, ensure they're compiled too
8612
- // This handles nested subqueries properly
8613
- if (q.queries && q.queries.length > 0) {
8616
+ // (e.g. IN/ALL/ANY subqueries that captured a nested queries list)
8617
+ if (q.queries && q.queries.length > 0 && !nq.query.queriesfn) {
8614
8618
  nq.query.queriesfn = q.queries.map(function (qq) {
8615
8619
  var nnq = qq.compile(query.database.databaseid);
8616
8620
  nnq.query.modifier = 'RECORDSET';
@@ -8620,15 +8624,20 @@ yy.Select = class Select {
8620
8624
  return nq;
8621
8625
  });
8622
8626
 
8623
- // Subquery indices (queriesidx) are assigned against the statement-level
8624
- // queries list, so a subquery that references another subquery
8625
- // (e.g. a scalar subquery nested inside a subquery's WHERE clause)
8626
- // needs access to the same compiled list
8627
- query.queriesfn.forEach(function (nq) {
8628
- if (!nq.query.queriesfn) {
8629
- nq.query.queriesfn = query.queriesfn;
8630
- }
8631
- });
8627
+ // Share compiled subquery functions down the tree. Without this,
8628
+ // multi-level scalar subqueries fail with
8629
+ // "Cannot read properties of undefined (reading '0')" when the
8630
+ // inner select expression evaluates this.queriesfn[queriesidx-1].
8631
+ (function shareQueriesfn(queriesfn) {
8632
+ if (!queriesfn) return;
8633
+ queriesfn.forEach(function (nq) {
8634
+ if (!nq.query.queriesfn) {
8635
+ nq.query.queriesfn = queriesfn;
8636
+ } else if (nq.query.queriesfn !== queriesfn) {
8637
+ shareQueriesfn(nq.query.queriesfn);
8638
+ }
8639
+ });
8640
+ })(query.queriesfn);
8632
8641
  }
8633
8642
  };
8634
8643
 
@@ -15455,40 +15464,61 @@ function mapColumnsToNames(data, sourceColumns, targetColumns) {
15455
15464
 
15456
15465
  yy.WithSelect.prototype.execute = function (databaseid, params, cb) {
15457
15466
  var self = this;
15458
- // Create temporary tables
15459
15467
  var savedTables = [];
15460
- self.withs.forEach(function (w) {
15468
+
15469
+ // Restore tables shadowed by the temporary CTE tables
15470
+ function restoreTables() {
15471
+ self.withs.forEach(function (w, idx) {
15472
+ if (savedTables[idx]) alasql.databases[databaseid].tables[w.name] = savedTables[idx];
15473
+ else delete alasql.databases[databaseid].tables[w.name];
15474
+ });
15475
+ }
15476
+
15477
+ // Create temporary tables one after another. Each non-recursive CTE is
15478
+ // executed with a callback, so sources that load data asynchronously
15479
+ // (like CSV() or XLSX() reading a file) are fully loaded before the
15480
+ // next CTE or the main select reads the temporary table.
15481
+ function executeWith(idx) {
15482
+ if (idx >= self.withs.length) {
15483
+ return self.select.execute(databaseid, params, function (data, err) {
15484
+ restoreTables();
15485
+ if (cb) data = cb(data, err);
15486
+ return data;
15487
+ });
15488
+ }
15489
+
15490
+ var w = self.withs[idx];
15461
15491
  savedTables.push(alasql.databases[databaseid].tables[w.name]);
15462
15492
 
15463
15493
  if (w.recursive) {
15464
15494
  // Execute recursive CTE
15465
15495
  executeRecursiveCTE(w, databaseid, params);
15466
- } else {
15467
- // Non-recursive CTE - original behavior
15468
- var tb = (alasql.databases[databaseid].tables[w.name] = new Table({
15469
- tableid: w.name,
15470
- }));
15471
- tb.data = w.select.execute(databaseid, params);
15496
+ return executeWith(idx + 1);
15497
+ }
15498
+
15499
+ // Non-recursive CTE
15500
+ var tb = (alasql.databases[databaseid].tables[w.name] = new Table({
15501
+ tableid: w.name,
15502
+ }));
15503
+ // The statement returns its own result, so keep the result of the rest
15504
+ // of the chain (available right away when all sources are synchronous)
15505
+ var res;
15506
+ w.select.execute(databaseid, params, function (data, err) {
15507
+ if (err) {
15508
+ restoreTables();
15509
+ if (cb) return cb(null, err);
15510
+ throw err;
15511
+ }
15512
+ tb.data = data;
15472
15513
  if (w.columns) {
15473
15514
  tb.data = renameColumns(tb.data, w.columns);
15474
15515
  }
15475
- }
15476
- });
15477
-
15478
- var res = 1;
15479
- res = this.select.execute(databaseid, params, function (data) {
15480
- // Clear temporary tables
15481
- // setTimeout(function(){
15482
- self.withs.forEach(function (w, idx) {
15483
- if (savedTables[idx]) alasql.databases[databaseid].tables[w.name] = savedTables[idx];
15484
- else delete alasql.databases[databaseid].tables[w.name];
15516
+ res = executeWith(idx + 1);
15485
15517
  });
15486
- // },0);
15518
+ return res;
15519
+ }
15487
15520
 
15488
- if (cb) data = cb(data);
15489
- return data;
15490
- });
15491
- return res;
15521
+ return executeWith(0);
15492
15522
  };
15493
15523
 
15494
15524
  /*