alasql 4.6.4 → 4.6.5
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/dist/alasql-worker.js +2 -2
- package/dist/alasql.fs.js +193 -77
- package/dist/alasql.js +193 -77
- package/dist/alasql.min.js +122 -122
- package/package.json +1 -1
package/dist/alasql-worker.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
//! AlaSQL v4.6.
|
|
1
|
+
//! AlaSQL v4.6.4 build: develop-ea35f7aa | © 2014-2024 Andrey Gershun & Mathias Wulff | License: MIT
|
|
2
2
|
/*
|
|
3
3
|
@module alasql
|
|
4
|
-
@version 4.6.
|
|
4
|
+
@version 4.6.4
|
|
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.
|
|
1
|
+
//! AlaSQL v4.6.4 build: develop-ea35f7aa | © 2014-2024 Andrey Gershun & Mathias Wulff | License: MIT
|
|
2
2
|
/*
|
|
3
3
|
@module alasql
|
|
4
|
-
@version 4.6.
|
|
4
|
+
@version 4.6.4
|
|
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.
|
|
145
|
-
alasql.build = 'develop-
|
|
144
|
+
alasql.version = '4.6.4';
|
|
145
|
+
alasql.build = 'develop-ea35f7aa';
|
|
146
146
|
|
|
147
147
|
/**
|
|
148
148
|
Debug flag
|
|
@@ -9473,104 +9473,220 @@ yy.Select.prototype.compilePivot = function (query) {
|
|
|
9473
9473
|
});
|
|
9474
9474
|
}
|
|
9475
9475
|
|
|
9476
|
-
// Function for PIVOT post production
|
|
9476
|
+
// Function for PIVOT post production (returned by compilePivot)
|
|
9477
9477
|
return function () {
|
|
9478
|
-
var query = this;
|
|
9479
|
-
|
|
9480
|
-
|
|
9481
|
-
|
|
9482
|
-
|
|
9483
|
-
|
|
9484
|
-
|
|
9485
|
-
|
|
9478
|
+
var query = this; // Keep reference to the query object
|
|
9479
|
+
|
|
9480
|
+
// Exit if no data to pivot
|
|
9481
|
+
if (!query.data || query.data.length === 0) {
|
|
9482
|
+
query.columns = []; // Reset columns if no data
|
|
9483
|
+
return;
|
|
9484
|
+
}
|
|
9485
|
+
|
|
9486
|
+
// --- Determine grouping columns robustly ---
|
|
9487
|
+
var firstRowKeys = Object.keys(query.data[0]);
|
|
9488
|
+
var cols = firstRowKeys.filter(function (key) {
|
|
9489
|
+
return key !== columnid && key !== exprcolid;
|
|
9490
|
+
});
|
|
9491
|
+
// -----------------------------------------
|
|
9492
|
+
|
|
9493
|
+
var newcols = []; // Stores the new column headers (e.g., 'MON', 'TUE')
|
|
9494
|
+
var gnewcols = {}; // Tracks unique new columns encountered
|
|
9495
|
+
var gr = {}; // Stores the grouped & pivoted results (key: gx, value: g)
|
|
9496
|
+
var ga = {}; // Stores counts for AVG calculation (key: gx, value: {day: count})
|
|
9497
|
+
var data = []; // The final pivoted data array
|
|
9486
9498
|
|
|
9487
|
-
var newcols = [];
|
|
9488
|
-
var gnewcols = {};
|
|
9489
|
-
var gr = {};
|
|
9490
|
-
var ga = {};
|
|
9491
|
-
var data = [];
|
|
9492
9499
|
query.data.forEach(function (d) {
|
|
9493
|
-
if
|
|
9494
|
-
|
|
9495
|
-
|
|
9496
|
-
|
|
9497
|
-
})
|
|
9498
|
-
.join('`');
|
|
9499
|
-
var g = gr[gx];
|
|
9500
|
-
if (!g) {
|
|
9501
|
-
g = {};
|
|
9502
|
-
gr[gx] = g;
|
|
9503
|
-
data.push(g);
|
|
9504
|
-
cols.forEach(function (colid) {
|
|
9505
|
-
g[colid] = d[colid];
|
|
9506
|
-
});
|
|
9507
|
-
}
|
|
9500
|
+
// Skip row if the pivot column value is not in the IN list (if provided)
|
|
9501
|
+
if (inlist && inlist.indexOf(d[columnid]) === -1) {
|
|
9502
|
+
return;
|
|
9503
|
+
}
|
|
9508
9504
|
|
|
9509
|
-
|
|
9510
|
-
|
|
9511
|
-
|
|
9505
|
+
var gx = cols
|
|
9506
|
+
.map(function (colid) {
|
|
9507
|
+
return d[colid] === undefined || d[colid] === null ? '' : d[colid];
|
|
9508
|
+
})
|
|
9509
|
+
.join('`');
|
|
9512
9510
|
|
|
9513
|
-
|
|
9514
|
-
|
|
9515
|
-
|
|
9516
|
-
|
|
9517
|
-
|
|
9511
|
+
var g = gr[gx];
|
|
9512
|
+
if (!g) {
|
|
9513
|
+
g = {};
|
|
9514
|
+
gr[gx] = g;
|
|
9515
|
+
data.push(g);
|
|
9516
|
+
cols.forEach(function (colid) {
|
|
9517
|
+
g[colid] = d[colid];
|
|
9518
|
+
});
|
|
9519
|
+
}
|
|
9518
9520
|
|
|
9519
|
-
|
|
9520
|
-
|
|
9521
|
-
|
|
9521
|
+
if (!ga[gx]) {
|
|
9522
|
+
ga[gx] = {};
|
|
9523
|
+
}
|
|
9524
|
+
|
|
9525
|
+
var pivotColValue = d[columnid];
|
|
9526
|
+
var aggValue = d[exprcolid];
|
|
9527
|
+
|
|
9528
|
+
// Increment count only for non-null/undefined values when calculating AVG
|
|
9529
|
+
if (ga[gx][pivotColValue]) {
|
|
9530
|
+
if (aggValue !== null && typeof aggValue !== 'undefined') {
|
|
9531
|
+
ga[gx][pivotColValue]++;
|
|
9522
9532
|
}
|
|
9533
|
+
} else {
|
|
9534
|
+
ga[gx][pivotColValue] = aggValue !== null && typeof aggValue !== 'undefined' ? 1 : 0;
|
|
9535
|
+
}
|
|
9536
|
+
|
|
9537
|
+
if (!gnewcols[pivotColValue]) {
|
|
9538
|
+
gnewcols[pivotColValue] = true;
|
|
9539
|
+
newcols.push(pivotColValue);
|
|
9540
|
+
}
|
|
9523
9541
|
|
|
9524
|
-
|
|
9525
|
-
|
|
9526
|
-
|
|
9527
|
-
|
|
9528
|
-
|
|
9529
|
-
|
|
9530
|
-
|
|
9531
|
-
|
|
9532
|
-
|
|
9533
|
-
}
|
|
9534
|
-
|
|
9535
|
-
|
|
9536
|
-
|
|
9537
|
-
|
|
9538
|
-
|
|
9539
|
-
|
|
9540
|
-
|
|
9541
|
-
|
|
9542
|
-
|
|
9542
|
+
// Apply the specified aggregation
|
|
9543
|
+
if (aggr == 'SUM' || aggr == 'AVG' || aggr == 'TOTAL') {
|
|
9544
|
+
if (aggValue !== null && typeof aggValue !== 'undefined') {
|
|
9545
|
+
g[pivotColValue] =
|
|
9546
|
+
typeof g[pivotColValue] === 'undefined' || g[pivotColValue] === null
|
|
9547
|
+
? Number(aggValue)
|
|
9548
|
+
: g[pivotColValue] + Number(aggValue);
|
|
9549
|
+
} else if (typeof g[pivotColValue] === 'undefined') {
|
|
9550
|
+
g[pivotColValue] = null;
|
|
9551
|
+
}
|
|
9552
|
+
} else if (aggr == 'COUNT') {
|
|
9553
|
+
if (exprcolid === '*' || (aggValue !== null && typeof aggValue !== 'undefined')) {
|
|
9554
|
+
g[pivotColValue] = (g[pivotColValue] || 0) + 1;
|
|
9555
|
+
} else if (typeof g[pivotColValue] === 'undefined') {
|
|
9556
|
+
g[pivotColValue] = 0;
|
|
9557
|
+
}
|
|
9558
|
+
} else if (aggr == 'MIN') {
|
|
9559
|
+
if (aggValue !== null && typeof aggValue !== 'undefined') {
|
|
9560
|
+
if (
|
|
9561
|
+
typeof g[pivotColValue] === 'undefined' ||
|
|
9562
|
+
g[pivotColValue] === null ||
|
|
9563
|
+
aggValue < g[pivotColValue]
|
|
9564
|
+
) {
|
|
9565
|
+
g[pivotColValue] = aggValue;
|
|
9566
|
+
}
|
|
9567
|
+
} else if (typeof g[pivotColValue] === 'undefined') {
|
|
9568
|
+
g[pivotColValue] = null;
|
|
9569
|
+
}
|
|
9570
|
+
} else if (aggr == 'MAX') {
|
|
9571
|
+
if (aggValue !== null && typeof aggValue !== 'undefined') {
|
|
9572
|
+
if (
|
|
9573
|
+
typeof g[pivotColValue] === 'undefined' ||
|
|
9574
|
+
g[pivotColValue] === null ||
|
|
9575
|
+
aggValue > g[pivotColValue]
|
|
9576
|
+
) {
|
|
9577
|
+
g[pivotColValue] = aggValue;
|
|
9578
|
+
}
|
|
9579
|
+
} else if (typeof g[pivotColValue] === 'undefined') {
|
|
9580
|
+
g[pivotColValue] = null;
|
|
9581
|
+
}
|
|
9582
|
+
} else if (aggr == 'FIRST') {
|
|
9583
|
+
if (typeof g[pivotColValue] === 'undefined') {
|
|
9584
|
+
g[pivotColValue] = aggValue;
|
|
9585
|
+
}
|
|
9586
|
+
} else if (aggr == 'LAST') {
|
|
9587
|
+
g[pivotColValue] = aggValue;
|
|
9588
|
+
} else if (alasql.aggr[aggr]) {
|
|
9589
|
+
if (typeof g[pivotColValue] === 'undefined') {
|
|
9590
|
+
g[pivotColValue] = alasql.aggr[aggr](aggValue, undefined, 1);
|
|
9543
9591
|
} else {
|
|
9544
|
-
|
|
9592
|
+
g[pivotColValue] = alasql.aggr[aggr](aggValue, g[pivotColValue], 2);
|
|
9545
9593
|
}
|
|
9594
|
+
} else {
|
|
9595
|
+
throw new Error('Unknown aggregator in PIVOT clause: ' + aggr);
|
|
9546
9596
|
}
|
|
9547
9597
|
});
|
|
9548
9598
|
|
|
9599
|
+
// Finalize AVG calculation
|
|
9549
9600
|
if (aggr == 'AVG') {
|
|
9550
9601
|
for (var gx in gr) {
|
|
9551
9602
|
var d = gr[gx];
|
|
9552
|
-
for (var
|
|
9553
|
-
if (
|
|
9554
|
-
|
|
9603
|
+
for (var pivotColValue in ga[gx]) {
|
|
9604
|
+
if (d.hasOwnProperty(pivotColValue) && d[pivotColValue] !== null) {
|
|
9605
|
+
var count = ga[gx][pivotColValue];
|
|
9606
|
+
if (count > 0) {
|
|
9607
|
+
d[pivotColValue] = d[pivotColValue] / count;
|
|
9608
|
+
} else {
|
|
9609
|
+
d[pivotColValue] = null;
|
|
9610
|
+
}
|
|
9555
9611
|
}
|
|
9556
9612
|
}
|
|
9557
9613
|
}
|
|
9558
9614
|
}
|
|
9559
9615
|
|
|
9560
|
-
// columns
|
|
9616
|
+
// --- Rebuild query.columns ---
|
|
9561
9617
|
query.data = data;
|
|
9562
9618
|
|
|
9563
|
-
if (inlist)
|
|
9619
|
+
if (inlist) {
|
|
9620
|
+
newcols = inlist;
|
|
9621
|
+
} else {
|
|
9622
|
+
newcols.sort();
|
|
9623
|
+
}
|
|
9564
9624
|
|
|
9565
|
-
|
|
9566
|
-
|
|
9567
|
-
|
|
9625
|
+
// Find original column definition - might be basic if SELECT * was used
|
|
9626
|
+
let aggColDef = query.columns.find(col => col.columnid === exprcolid);
|
|
9627
|
+
// If SELECT * was used, aggColDef might be missing, find it from the table definition if possible
|
|
9628
|
+
if (!aggColDef && query.sources && query.sources.length > 0) {
|
|
9629
|
+
let sourceTableId = query.sources[0].tableid;
|
|
9630
|
+
let sourceDbId = query.sources[0].databaseid;
|
|
9631
|
+
if (
|
|
9632
|
+
sourceTableId &&
|
|
9633
|
+
sourceDbId &&
|
|
9634
|
+
alasql.databases[sourceDbId]?.tables?.[sourceTableId]?.xcolumns
|
|
9635
|
+
) {
|
|
9636
|
+
aggColDef = alasql.databases[sourceDbId].tables[sourceTableId].xcolumns[exprcolid];
|
|
9637
|
+
}
|
|
9638
|
+
}
|
|
9639
|
+
// Provide a fallback if still not found
|
|
9640
|
+
aggColDef = aggColDef || { columnid: exprcolid, dbtypeid: 'OBJECT' };
|
|
9641
|
+
|
|
9642
|
+
// Keep only the grouping columns initially
|
|
9568
9643
|
query.columns = query.columns.filter(function (col) {
|
|
9569
|
-
return
|
|
9644
|
+
return cols.includes(col.columnid);
|
|
9570
9645
|
});
|
|
9571
|
-
|
|
9572
|
-
|
|
9573
|
-
|
|
9646
|
+
|
|
9647
|
+
// Add the new pivoted columns
|
|
9648
|
+
newcols.forEach(function (newColId) {
|
|
9649
|
+
var nc = cloneDeep(aggColDef);
|
|
9650
|
+
nc.columnid = newColId;
|
|
9651
|
+
|
|
9652
|
+
// ---- Final Refined Type Logic ----
|
|
9653
|
+
const originalType = (aggColDef.dbtypeid || 'OBJECT').toUpperCase();
|
|
9654
|
+
const integerTypes = [
|
|
9655
|
+
'INT',
|
|
9656
|
+
'INTEGER',
|
|
9657
|
+
'SMALLINT',
|
|
9658
|
+
'BIGINT',
|
|
9659
|
+
'SERIAL',
|
|
9660
|
+
'SMALLSERIAL',
|
|
9661
|
+
'BIGSERIAL',
|
|
9662
|
+
];
|
|
9663
|
+
const numericTypes = [...integerTypes, 'NUMBER', 'FLOAT', 'DECIMAL', 'NUMERIC', 'MONEY'];
|
|
9664
|
+
|
|
9665
|
+
if (aggr === 'COUNT') {
|
|
9666
|
+
nc.dbtypeid = 'INT';
|
|
9667
|
+
} else if (aggr === 'AVG') {
|
|
9668
|
+
// Keep INT type if original was INT-like, otherwise use FLOAT
|
|
9669
|
+
if (integerTypes.includes(originalType)) {
|
|
9670
|
+
nc.dbtypeid = aggColDef.dbtypeid; // Preserve original INT-like type
|
|
9671
|
+
} else {
|
|
9672
|
+
nc.dbtypeid = 'FLOAT';
|
|
9673
|
+
}
|
|
9674
|
+
} else if (aggr === 'SUM' || aggr === 'TOTAL') {
|
|
9675
|
+
// Preserve numeric types, default to FLOAT otherwise
|
|
9676
|
+
if (numericTypes.includes(originalType)) {
|
|
9677
|
+
nc.dbtypeid = aggColDef.dbtypeid;
|
|
9678
|
+
} else {
|
|
9679
|
+
nc.dbtypeid = 'FLOAT'; // Default for non-numeric or unknown sums
|
|
9680
|
+
}
|
|
9681
|
+
} else if (aggr === 'MIN' || aggr === 'MAX' || aggr === 'FIRST' || aggr === 'LAST') {
|
|
9682
|
+
// Preserve original type as comparisons work across types
|
|
9683
|
+
nc.dbtypeid = aggColDef.dbtypeid;
|
|
9684
|
+
}
|
|
9685
|
+
// For custom aggregators (AGGR, REDUCE), inherit type from clone, ensure fallback
|
|
9686
|
+
else if (!nc.dbtypeid) {
|
|
9687
|
+
nc.dbtypeid = 'OBJECT';
|
|
9688
|
+
}
|
|
9689
|
+
|
|
9574
9690
|
query.columns.push(nc);
|
|
9575
9691
|
});
|
|
9576
9692
|
};
|
|
@@ -16783,7 +16899,7 @@ function XLSXLSX(X, filename, opts, cb, idx, query) {
|
|
|
16783
16899
|
}
|
|
16784
16900
|
},
|
|
16785
16901
|
function (err) {
|
|
16786
|
-
if(query && query.cb) {
|
|
16902
|
+
if (query && query.cb) {
|
|
16787
16903
|
query.cb(null, err);
|
|
16788
16904
|
return;
|
|
16789
16905
|
}
|
package/dist/alasql.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
//! AlaSQL v4.6.
|
|
1
|
+
//! AlaSQL v4.6.4 build: develop-ea35f7aa | © 2014-2024 Andrey Gershun & Mathias Wulff | License: MIT
|
|
2
2
|
/*
|
|
3
3
|
@module alasql
|
|
4
|
-
@version 4.6.
|
|
4
|
+
@version 4.6.4
|
|
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.
|
|
145
|
-
alasql.build = 'develop-
|
|
144
|
+
alasql.version = '4.6.4';
|
|
145
|
+
alasql.build = 'develop-ea35f7aa';
|
|
146
146
|
|
|
147
147
|
/**
|
|
148
148
|
Debug flag
|
|
@@ -9473,104 +9473,220 @@ yy.Select.prototype.compilePivot = function (query) {
|
|
|
9473
9473
|
});
|
|
9474
9474
|
}
|
|
9475
9475
|
|
|
9476
|
-
// Function for PIVOT post production
|
|
9476
|
+
// Function for PIVOT post production (returned by compilePivot)
|
|
9477
9477
|
return function () {
|
|
9478
|
-
var query = this;
|
|
9479
|
-
|
|
9480
|
-
|
|
9481
|
-
|
|
9482
|
-
|
|
9483
|
-
|
|
9484
|
-
|
|
9485
|
-
|
|
9478
|
+
var query = this; // Keep reference to the query object
|
|
9479
|
+
|
|
9480
|
+
// Exit if no data to pivot
|
|
9481
|
+
if (!query.data || query.data.length === 0) {
|
|
9482
|
+
query.columns = []; // Reset columns if no data
|
|
9483
|
+
return;
|
|
9484
|
+
}
|
|
9485
|
+
|
|
9486
|
+
// --- Determine grouping columns robustly ---
|
|
9487
|
+
var firstRowKeys = Object.keys(query.data[0]);
|
|
9488
|
+
var cols = firstRowKeys.filter(function (key) {
|
|
9489
|
+
return key !== columnid && key !== exprcolid;
|
|
9490
|
+
});
|
|
9491
|
+
// -----------------------------------------
|
|
9492
|
+
|
|
9493
|
+
var newcols = []; // Stores the new column headers (e.g., 'MON', 'TUE')
|
|
9494
|
+
var gnewcols = {}; // Tracks unique new columns encountered
|
|
9495
|
+
var gr = {}; // Stores the grouped & pivoted results (key: gx, value: g)
|
|
9496
|
+
var ga = {}; // Stores counts for AVG calculation (key: gx, value: {day: count})
|
|
9497
|
+
var data = []; // The final pivoted data array
|
|
9486
9498
|
|
|
9487
|
-
var newcols = [];
|
|
9488
|
-
var gnewcols = {};
|
|
9489
|
-
var gr = {};
|
|
9490
|
-
var ga = {};
|
|
9491
|
-
var data = [];
|
|
9492
9499
|
query.data.forEach(function (d) {
|
|
9493
|
-
if
|
|
9494
|
-
|
|
9495
|
-
|
|
9496
|
-
|
|
9497
|
-
})
|
|
9498
|
-
.join('`');
|
|
9499
|
-
var g = gr[gx];
|
|
9500
|
-
if (!g) {
|
|
9501
|
-
g = {};
|
|
9502
|
-
gr[gx] = g;
|
|
9503
|
-
data.push(g);
|
|
9504
|
-
cols.forEach(function (colid) {
|
|
9505
|
-
g[colid] = d[colid];
|
|
9506
|
-
});
|
|
9507
|
-
}
|
|
9500
|
+
// Skip row if the pivot column value is not in the IN list (if provided)
|
|
9501
|
+
if (inlist && inlist.indexOf(d[columnid]) === -1) {
|
|
9502
|
+
return;
|
|
9503
|
+
}
|
|
9508
9504
|
|
|
9509
|
-
|
|
9510
|
-
|
|
9511
|
-
|
|
9505
|
+
var gx = cols
|
|
9506
|
+
.map(function (colid) {
|
|
9507
|
+
return d[colid] === undefined || d[colid] === null ? '' : d[colid];
|
|
9508
|
+
})
|
|
9509
|
+
.join('`');
|
|
9512
9510
|
|
|
9513
|
-
|
|
9514
|
-
|
|
9515
|
-
|
|
9516
|
-
|
|
9517
|
-
|
|
9511
|
+
var g = gr[gx];
|
|
9512
|
+
if (!g) {
|
|
9513
|
+
g = {};
|
|
9514
|
+
gr[gx] = g;
|
|
9515
|
+
data.push(g);
|
|
9516
|
+
cols.forEach(function (colid) {
|
|
9517
|
+
g[colid] = d[colid];
|
|
9518
|
+
});
|
|
9519
|
+
}
|
|
9518
9520
|
|
|
9519
|
-
|
|
9520
|
-
|
|
9521
|
-
|
|
9521
|
+
if (!ga[gx]) {
|
|
9522
|
+
ga[gx] = {};
|
|
9523
|
+
}
|
|
9524
|
+
|
|
9525
|
+
var pivotColValue = d[columnid];
|
|
9526
|
+
var aggValue = d[exprcolid];
|
|
9527
|
+
|
|
9528
|
+
// Increment count only for non-null/undefined values when calculating AVG
|
|
9529
|
+
if (ga[gx][pivotColValue]) {
|
|
9530
|
+
if (aggValue !== null && typeof aggValue !== 'undefined') {
|
|
9531
|
+
ga[gx][pivotColValue]++;
|
|
9522
9532
|
}
|
|
9533
|
+
} else {
|
|
9534
|
+
ga[gx][pivotColValue] = aggValue !== null && typeof aggValue !== 'undefined' ? 1 : 0;
|
|
9535
|
+
}
|
|
9536
|
+
|
|
9537
|
+
if (!gnewcols[pivotColValue]) {
|
|
9538
|
+
gnewcols[pivotColValue] = true;
|
|
9539
|
+
newcols.push(pivotColValue);
|
|
9540
|
+
}
|
|
9523
9541
|
|
|
9524
|
-
|
|
9525
|
-
|
|
9526
|
-
|
|
9527
|
-
|
|
9528
|
-
|
|
9529
|
-
|
|
9530
|
-
|
|
9531
|
-
|
|
9532
|
-
|
|
9533
|
-
}
|
|
9534
|
-
|
|
9535
|
-
|
|
9536
|
-
|
|
9537
|
-
|
|
9538
|
-
|
|
9539
|
-
|
|
9540
|
-
|
|
9541
|
-
|
|
9542
|
-
|
|
9542
|
+
// Apply the specified aggregation
|
|
9543
|
+
if (aggr == 'SUM' || aggr == 'AVG' || aggr == 'TOTAL') {
|
|
9544
|
+
if (aggValue !== null && typeof aggValue !== 'undefined') {
|
|
9545
|
+
g[pivotColValue] =
|
|
9546
|
+
typeof g[pivotColValue] === 'undefined' || g[pivotColValue] === null
|
|
9547
|
+
? Number(aggValue)
|
|
9548
|
+
: g[pivotColValue] + Number(aggValue);
|
|
9549
|
+
} else if (typeof g[pivotColValue] === 'undefined') {
|
|
9550
|
+
g[pivotColValue] = null;
|
|
9551
|
+
}
|
|
9552
|
+
} else if (aggr == 'COUNT') {
|
|
9553
|
+
if (exprcolid === '*' || (aggValue !== null && typeof aggValue !== 'undefined')) {
|
|
9554
|
+
g[pivotColValue] = (g[pivotColValue] || 0) + 1;
|
|
9555
|
+
} else if (typeof g[pivotColValue] === 'undefined') {
|
|
9556
|
+
g[pivotColValue] = 0;
|
|
9557
|
+
}
|
|
9558
|
+
} else if (aggr == 'MIN') {
|
|
9559
|
+
if (aggValue !== null && typeof aggValue !== 'undefined') {
|
|
9560
|
+
if (
|
|
9561
|
+
typeof g[pivotColValue] === 'undefined' ||
|
|
9562
|
+
g[pivotColValue] === null ||
|
|
9563
|
+
aggValue < g[pivotColValue]
|
|
9564
|
+
) {
|
|
9565
|
+
g[pivotColValue] = aggValue;
|
|
9566
|
+
}
|
|
9567
|
+
} else if (typeof g[pivotColValue] === 'undefined') {
|
|
9568
|
+
g[pivotColValue] = null;
|
|
9569
|
+
}
|
|
9570
|
+
} else if (aggr == 'MAX') {
|
|
9571
|
+
if (aggValue !== null && typeof aggValue !== 'undefined') {
|
|
9572
|
+
if (
|
|
9573
|
+
typeof g[pivotColValue] === 'undefined' ||
|
|
9574
|
+
g[pivotColValue] === null ||
|
|
9575
|
+
aggValue > g[pivotColValue]
|
|
9576
|
+
) {
|
|
9577
|
+
g[pivotColValue] = aggValue;
|
|
9578
|
+
}
|
|
9579
|
+
} else if (typeof g[pivotColValue] === 'undefined') {
|
|
9580
|
+
g[pivotColValue] = null;
|
|
9581
|
+
}
|
|
9582
|
+
} else if (aggr == 'FIRST') {
|
|
9583
|
+
if (typeof g[pivotColValue] === 'undefined') {
|
|
9584
|
+
g[pivotColValue] = aggValue;
|
|
9585
|
+
}
|
|
9586
|
+
} else if (aggr == 'LAST') {
|
|
9587
|
+
g[pivotColValue] = aggValue;
|
|
9588
|
+
} else if (alasql.aggr[aggr]) {
|
|
9589
|
+
if (typeof g[pivotColValue] === 'undefined') {
|
|
9590
|
+
g[pivotColValue] = alasql.aggr[aggr](aggValue, undefined, 1);
|
|
9543
9591
|
} else {
|
|
9544
|
-
|
|
9592
|
+
g[pivotColValue] = alasql.aggr[aggr](aggValue, g[pivotColValue], 2);
|
|
9545
9593
|
}
|
|
9594
|
+
} else {
|
|
9595
|
+
throw new Error('Unknown aggregator in PIVOT clause: ' + aggr);
|
|
9546
9596
|
}
|
|
9547
9597
|
});
|
|
9548
9598
|
|
|
9599
|
+
// Finalize AVG calculation
|
|
9549
9600
|
if (aggr == 'AVG') {
|
|
9550
9601
|
for (var gx in gr) {
|
|
9551
9602
|
var d = gr[gx];
|
|
9552
|
-
for (var
|
|
9553
|
-
if (
|
|
9554
|
-
|
|
9603
|
+
for (var pivotColValue in ga[gx]) {
|
|
9604
|
+
if (d.hasOwnProperty(pivotColValue) && d[pivotColValue] !== null) {
|
|
9605
|
+
var count = ga[gx][pivotColValue];
|
|
9606
|
+
if (count > 0) {
|
|
9607
|
+
d[pivotColValue] = d[pivotColValue] / count;
|
|
9608
|
+
} else {
|
|
9609
|
+
d[pivotColValue] = null;
|
|
9610
|
+
}
|
|
9555
9611
|
}
|
|
9556
9612
|
}
|
|
9557
9613
|
}
|
|
9558
9614
|
}
|
|
9559
9615
|
|
|
9560
|
-
// columns
|
|
9616
|
+
// --- Rebuild query.columns ---
|
|
9561
9617
|
query.data = data;
|
|
9562
9618
|
|
|
9563
|
-
if (inlist)
|
|
9619
|
+
if (inlist) {
|
|
9620
|
+
newcols = inlist;
|
|
9621
|
+
} else {
|
|
9622
|
+
newcols.sort();
|
|
9623
|
+
}
|
|
9564
9624
|
|
|
9565
|
-
|
|
9566
|
-
|
|
9567
|
-
|
|
9625
|
+
// Find original column definition - might be basic if SELECT * was used
|
|
9626
|
+
let aggColDef = query.columns.find(col => col.columnid === exprcolid);
|
|
9627
|
+
// If SELECT * was used, aggColDef might be missing, find it from the table definition if possible
|
|
9628
|
+
if (!aggColDef && query.sources && query.sources.length > 0) {
|
|
9629
|
+
let sourceTableId = query.sources[0].tableid;
|
|
9630
|
+
let sourceDbId = query.sources[0].databaseid;
|
|
9631
|
+
if (
|
|
9632
|
+
sourceTableId &&
|
|
9633
|
+
sourceDbId &&
|
|
9634
|
+
alasql.databases[sourceDbId]?.tables?.[sourceTableId]?.xcolumns
|
|
9635
|
+
) {
|
|
9636
|
+
aggColDef = alasql.databases[sourceDbId].tables[sourceTableId].xcolumns[exprcolid];
|
|
9637
|
+
}
|
|
9638
|
+
}
|
|
9639
|
+
// Provide a fallback if still not found
|
|
9640
|
+
aggColDef = aggColDef || { columnid: exprcolid, dbtypeid: 'OBJECT' };
|
|
9641
|
+
|
|
9642
|
+
// Keep only the grouping columns initially
|
|
9568
9643
|
query.columns = query.columns.filter(function (col) {
|
|
9569
|
-
return
|
|
9644
|
+
return cols.includes(col.columnid);
|
|
9570
9645
|
});
|
|
9571
|
-
|
|
9572
|
-
|
|
9573
|
-
|
|
9646
|
+
|
|
9647
|
+
// Add the new pivoted columns
|
|
9648
|
+
newcols.forEach(function (newColId) {
|
|
9649
|
+
var nc = cloneDeep(aggColDef);
|
|
9650
|
+
nc.columnid = newColId;
|
|
9651
|
+
|
|
9652
|
+
// ---- Final Refined Type Logic ----
|
|
9653
|
+
const originalType = (aggColDef.dbtypeid || 'OBJECT').toUpperCase();
|
|
9654
|
+
const integerTypes = [
|
|
9655
|
+
'INT',
|
|
9656
|
+
'INTEGER',
|
|
9657
|
+
'SMALLINT',
|
|
9658
|
+
'BIGINT',
|
|
9659
|
+
'SERIAL',
|
|
9660
|
+
'SMALLSERIAL',
|
|
9661
|
+
'BIGSERIAL',
|
|
9662
|
+
];
|
|
9663
|
+
const numericTypes = [...integerTypes, 'NUMBER', 'FLOAT', 'DECIMAL', 'NUMERIC', 'MONEY'];
|
|
9664
|
+
|
|
9665
|
+
if (aggr === 'COUNT') {
|
|
9666
|
+
nc.dbtypeid = 'INT';
|
|
9667
|
+
} else if (aggr === 'AVG') {
|
|
9668
|
+
// Keep INT type if original was INT-like, otherwise use FLOAT
|
|
9669
|
+
if (integerTypes.includes(originalType)) {
|
|
9670
|
+
nc.dbtypeid = aggColDef.dbtypeid; // Preserve original INT-like type
|
|
9671
|
+
} else {
|
|
9672
|
+
nc.dbtypeid = 'FLOAT';
|
|
9673
|
+
}
|
|
9674
|
+
} else if (aggr === 'SUM' || aggr === 'TOTAL') {
|
|
9675
|
+
// Preserve numeric types, default to FLOAT otherwise
|
|
9676
|
+
if (numericTypes.includes(originalType)) {
|
|
9677
|
+
nc.dbtypeid = aggColDef.dbtypeid;
|
|
9678
|
+
} else {
|
|
9679
|
+
nc.dbtypeid = 'FLOAT'; // Default for non-numeric or unknown sums
|
|
9680
|
+
}
|
|
9681
|
+
} else if (aggr === 'MIN' || aggr === 'MAX' || aggr === 'FIRST' || aggr === 'LAST') {
|
|
9682
|
+
// Preserve original type as comparisons work across types
|
|
9683
|
+
nc.dbtypeid = aggColDef.dbtypeid;
|
|
9684
|
+
}
|
|
9685
|
+
// For custom aggregators (AGGR, REDUCE), inherit type from clone, ensure fallback
|
|
9686
|
+
else if (!nc.dbtypeid) {
|
|
9687
|
+
nc.dbtypeid = 'OBJECT';
|
|
9688
|
+
}
|
|
9689
|
+
|
|
9574
9690
|
query.columns.push(nc);
|
|
9575
9691
|
});
|
|
9576
9692
|
};
|
|
@@ -16783,7 +16899,7 @@ function XLSXLSX(X, filename, opts, cb, idx, query) {
|
|
|
16783
16899
|
}
|
|
16784
16900
|
},
|
|
16785
16901
|
function (err) {
|
|
16786
|
-
if(query && query.cb) {
|
|
16902
|
+
if (query && query.cb) {
|
|
16787
16903
|
query.cb(null, err);
|
|
16788
16904
|
return;
|
|
16789
16905
|
}
|