@uwdata/mosaic-sql 0.7.0 → 0.8.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/dist/mosaic-sql.js +217 -25
- package/dist/mosaic-sql.min.js +1 -1
- package/package.json +3 -3
- package/src/Query.js +109 -0
- package/src/aggregates.js +51 -5
- package/src/desc.js +2 -2
- package/src/expression.js +14 -3
- package/src/load/load.js +1 -1
- package/src/load/sql-from.js +7 -0
- package/src/ref.js +4 -4
- package/src/scales.js +1 -1
- package/src/windows.js +43 -1
package/dist/mosaic-sql.js
CHANGED
|
@@ -3,13 +3,11 @@ var Ref = class {
|
|
|
3
3
|
/**
|
|
4
4
|
* Create a new Ref instance.
|
|
5
5
|
* @param {string|Ref|null} table The table name.
|
|
6
|
-
* @param {string|null} column The column name.
|
|
6
|
+
* @param {string|null} [column] The column name.
|
|
7
7
|
*/
|
|
8
8
|
constructor(table, column2) {
|
|
9
|
-
if (table)
|
|
10
|
-
|
|
11
|
-
if (column2)
|
|
12
|
-
this.column = column2;
|
|
9
|
+
if (table) this.table = String(table);
|
|
10
|
+
if (column2) this.column = column2;
|
|
13
11
|
}
|
|
14
12
|
/**
|
|
15
13
|
* Get the list of referenced columns. Either a single element array
|
|
@@ -48,7 +46,7 @@ function asRelation(value) {
|
|
|
48
46
|
function relation(name) {
|
|
49
47
|
return new Ref(name);
|
|
50
48
|
}
|
|
51
|
-
function column(table, column2) {
|
|
49
|
+
function column(table, column2 = null) {
|
|
52
50
|
if (arguments.length === 1) {
|
|
53
51
|
column2 = table;
|
|
54
52
|
table = null;
|
|
@@ -76,8 +74,7 @@ function literalToSQL(value) {
|
|
|
76
74
|
return "NULL";
|
|
77
75
|
} else if (value instanceof Date) {
|
|
78
76
|
const ts = +value;
|
|
79
|
-
if (Number.isNaN(ts))
|
|
80
|
-
return "NULL";
|
|
77
|
+
if (Number.isNaN(ts)) return "NULL";
|
|
81
78
|
const y2 = value.getUTCFullYear();
|
|
82
79
|
const m = value.getUTCMonth();
|
|
83
80
|
const d = value.getUTCDate();
|
|
@@ -98,7 +95,7 @@ function isSQLExpression(value) {
|
|
|
98
95
|
var SQLExpression = class {
|
|
99
96
|
/**
|
|
100
97
|
* Create a new SQL expression instance.
|
|
101
|
-
* @param {(string|SQLExpression|Ref)[]} parts The parts of the expression.
|
|
98
|
+
* @param {(string | ParamLike | SQLExpression | import('./ref.js').Ref)[]} parts The parts of the expression.
|
|
102
99
|
* @param {string[]} [columns=[]] The column dependencies
|
|
103
100
|
* @param {object} [props] Additional properties for this expression.
|
|
104
101
|
*/
|
|
@@ -290,6 +287,16 @@ var isInfinite = functionCall("ISINF");
|
|
|
290
287
|
|
|
291
288
|
// src/windows.js
|
|
292
289
|
var WindowFunction = class _WindowFunction extends SQLExpression {
|
|
290
|
+
/**
|
|
291
|
+
* Create a new WindowFunction instance.
|
|
292
|
+
* @param {string} op The window operation indicator.
|
|
293
|
+
* @param {*} func The window function expression.
|
|
294
|
+
* @param {*} [type] The SQL data type to cast to.
|
|
295
|
+
* @param {string} [name] The window definition name.
|
|
296
|
+
* @param {*} [group] Grouping (partition by) expressions.
|
|
297
|
+
* @param {*} [order] Sorting (order by) expressions.
|
|
298
|
+
* @param {*} [frame] The window frame definition.
|
|
299
|
+
*/
|
|
293
300
|
constructor(op, func, type, name, group = "", order = "", frame = "") {
|
|
294
301
|
let expr;
|
|
295
302
|
const noWindowParams = !(group || order || frame);
|
|
@@ -304,7 +311,14 @@ var WindowFunction = class _WindowFunction extends SQLExpression {
|
|
|
304
311
|
expr = sql`(${expr})::${type}`;
|
|
305
312
|
}
|
|
306
313
|
const { _expr, _deps } = expr;
|
|
307
|
-
super(_expr, _deps
|
|
314
|
+
super(_expr, _deps);
|
|
315
|
+
this.window = op;
|
|
316
|
+
this.func = func;
|
|
317
|
+
this.type = type;
|
|
318
|
+
this.name = name;
|
|
319
|
+
this.group = group;
|
|
320
|
+
this.order = order;
|
|
321
|
+
this.frame = frame;
|
|
308
322
|
}
|
|
309
323
|
get basis() {
|
|
310
324
|
return this.column;
|
|
@@ -313,10 +327,20 @@ var WindowFunction = class _WindowFunction extends SQLExpression {
|
|
|
313
327
|
const { func } = this;
|
|
314
328
|
return func.label ?? func.toString();
|
|
315
329
|
}
|
|
330
|
+
/**
|
|
331
|
+
* Return an updated window function over a named window definition.
|
|
332
|
+
* @param {string} name The window definition name.
|
|
333
|
+
* @returns {WindowFunction} A new window function.
|
|
334
|
+
*/
|
|
316
335
|
over(name) {
|
|
317
336
|
const { window: op, func, type, group, order, frame } = this;
|
|
318
337
|
return new _WindowFunction(op, func, type, name, group, order, frame);
|
|
319
338
|
}
|
|
339
|
+
/**
|
|
340
|
+
* Return an updated window function with the given partitioning.
|
|
341
|
+
* @param {*} expr The grouping (partition by) criteria for the window function.
|
|
342
|
+
* @returns {WindowFunction} A new window function.
|
|
343
|
+
*/
|
|
320
344
|
partitionby(...expr) {
|
|
321
345
|
const exprs = expr.flat().filter((x2) => x2).map(asColumn);
|
|
322
346
|
const group = sql(
|
|
@@ -326,6 +350,11 @@ var WindowFunction = class _WindowFunction extends SQLExpression {
|
|
|
326
350
|
const { window: op, func, type, name, order, frame } = this;
|
|
327
351
|
return new _WindowFunction(op, func, type, name, group, order, frame);
|
|
328
352
|
}
|
|
353
|
+
/**
|
|
354
|
+
* Return an updated window function with the given ordering.
|
|
355
|
+
* @param {*} expr The sorting (order by) criteria for the window function.
|
|
356
|
+
* @returns {WindowFunction} A new window function.
|
|
357
|
+
*/
|
|
329
358
|
orderby(...expr) {
|
|
330
359
|
const exprs = expr.flat().filter((x2) => x2).map(asColumn);
|
|
331
360
|
const order = sql(
|
|
@@ -335,11 +364,21 @@ var WindowFunction = class _WindowFunction extends SQLExpression {
|
|
|
335
364
|
const { window: op, func, type, name, group, frame } = this;
|
|
336
365
|
return new _WindowFunction(op, func, type, name, group, order, frame);
|
|
337
366
|
}
|
|
367
|
+
/**
|
|
368
|
+
* Return an updated window function with the given rows frame.
|
|
369
|
+
* @param {(number|null)[] | import('./expression.js').ParamLike} expr The row-based window frame.
|
|
370
|
+
* @returns {WindowFunction} A new window function.
|
|
371
|
+
*/
|
|
338
372
|
rows(expr) {
|
|
339
373
|
const frame = windowFrame("ROWS", expr);
|
|
340
374
|
const { window: op, func, type, name, group, order } = this;
|
|
341
375
|
return new _WindowFunction(op, func, type, name, group, order, frame);
|
|
342
376
|
}
|
|
377
|
+
/**
|
|
378
|
+
* Return an updated window function with the given range frame.
|
|
379
|
+
* @param {(number|null)[] | import('./expression.js').ParamLike} expr The range-based window frame.
|
|
380
|
+
* @returns {WindowFunction} A new window function.
|
|
381
|
+
*/
|
|
343
382
|
range(expr) {
|
|
344
383
|
const frame = windowFrame("RANGE", expr);
|
|
345
384
|
const { window: op, func, type, name, group, order } = this;
|
|
@@ -383,11 +422,24 @@ function agg(strings, ...exprs) {
|
|
|
383
422
|
return sql(strings, ...exprs).annotate({ aggregate: true });
|
|
384
423
|
}
|
|
385
424
|
var AggregateFunction = class _AggregateFunction extends SQLExpression {
|
|
425
|
+
/**
|
|
426
|
+
* Create a new AggregateFunction instance.
|
|
427
|
+
* @param {*} op The aggregate operation.
|
|
428
|
+
* @param {*} [args] The aggregate function arguments.
|
|
429
|
+
* @param {*} [type] The SQL data type to cast to.
|
|
430
|
+
* @param {boolean} [isDistinct] Flag indicating if this is a distinct value aggregate.
|
|
431
|
+
* @param {*} [filter] Filtering expression to apply prior to aggregation.
|
|
432
|
+
*/
|
|
386
433
|
constructor(op, args, type, isDistinct2, filter) {
|
|
387
434
|
args = (args || []).map(asColumn);
|
|
388
435
|
const { strings, exprs } = aggExpr(op, args, type, isDistinct2, filter);
|
|
389
436
|
const { spans, cols } = parseSQL(strings, exprs);
|
|
390
|
-
super(spans, cols
|
|
437
|
+
super(spans, cols);
|
|
438
|
+
this.aggregate = op;
|
|
439
|
+
this.args = args;
|
|
440
|
+
this.type = type;
|
|
441
|
+
this.isDistinct = isDistinct2;
|
|
442
|
+
this.filter = filter;
|
|
391
443
|
}
|
|
392
444
|
get basis() {
|
|
393
445
|
return this.column;
|
|
@@ -398,30 +450,63 @@ var AggregateFunction = class _AggregateFunction extends SQLExpression {
|
|
|
398
450
|
const tail = args.length ? `(${dist}${args.map(unquoted).join(", ")})` : "";
|
|
399
451
|
return `${op.toLowerCase()}${tail}`;
|
|
400
452
|
}
|
|
453
|
+
/**
|
|
454
|
+
* Return a new derived aggregate function over distinct values.
|
|
455
|
+
* @returns {AggregateFunction} A new aggregate function.
|
|
456
|
+
*/
|
|
401
457
|
distinct() {
|
|
402
458
|
const { aggregate: op, args, type, filter } = this;
|
|
403
459
|
return new _AggregateFunction(op, args, type, true, filter);
|
|
404
460
|
}
|
|
461
|
+
/**
|
|
462
|
+
* Return a new derived aggregate function that filters values.
|
|
463
|
+
* @param {*} filter The filter expresion.
|
|
464
|
+
* @returns {AggregateFunction} A new aggregate function.
|
|
465
|
+
*/
|
|
405
466
|
where(filter) {
|
|
406
467
|
const { aggregate: op, args, type, isDistinct: isDistinct2 } = this;
|
|
407
468
|
return new _AggregateFunction(op, args, type, isDistinct2, filter);
|
|
408
469
|
}
|
|
470
|
+
/**
|
|
471
|
+
* Return a new window function over this aggregate.
|
|
472
|
+
* @returns {WindowFunction} A new aggregate function.
|
|
473
|
+
*/
|
|
409
474
|
window() {
|
|
410
475
|
const { aggregate: op, args, type, isDistinct: isDistinct2 } = this;
|
|
411
476
|
const func = new _AggregateFunction(op, args, null, isDistinct2);
|
|
412
477
|
return new WindowFunction(op, func, type);
|
|
413
478
|
}
|
|
479
|
+
/**
|
|
480
|
+
* Return a window function over this aggregate with the given partitioning.
|
|
481
|
+
* @param {*} expr The grouping (partition by) criteria for the window function.
|
|
482
|
+
* @returns {WindowFunction} A new window function.
|
|
483
|
+
*/
|
|
414
484
|
partitionby(...expr) {
|
|
415
485
|
return this.window().partitionby(...expr);
|
|
416
486
|
}
|
|
487
|
+
/**
|
|
488
|
+
* Return a window function over this aggregate with the given ordering.
|
|
489
|
+
* @param {*} expr The sorting (order by) criteria for the window function.
|
|
490
|
+
* @returns {WindowFunction} A new window function.
|
|
491
|
+
*/
|
|
417
492
|
orderby(...expr) {
|
|
418
493
|
return this.window().orderby(...expr);
|
|
419
494
|
}
|
|
420
|
-
|
|
421
|
-
|
|
495
|
+
/**
|
|
496
|
+
* Return a window function over this aggregate with the given row frame.
|
|
497
|
+
* @param {(number|null)[] | import('./expression.js').ParamLike} frame The row-based window frame.
|
|
498
|
+
* @returns {WindowFunction} A new window function.
|
|
499
|
+
*/
|
|
500
|
+
rows(frame) {
|
|
501
|
+
return this.window().rows(frame);
|
|
422
502
|
}
|
|
423
|
-
|
|
424
|
-
|
|
503
|
+
/**
|
|
504
|
+
* Return a window function over this aggregate with the given range frame.
|
|
505
|
+
* @param {(number|null)[] | import('./expression.js').ParamLike} frame The range-based window frame.
|
|
506
|
+
* @returns {WindowFunction} A new window function.
|
|
507
|
+
*/
|
|
508
|
+
range(frame) {
|
|
509
|
+
return this.window().range(frame);
|
|
425
510
|
}
|
|
426
511
|
};
|
|
427
512
|
function aggExpr(op, args, type, isDistinct2, filter) {
|
|
@@ -573,12 +658,22 @@ var Query = class _Query {
|
|
|
573
658
|
qualify: [],
|
|
574
659
|
orderby: []
|
|
575
660
|
};
|
|
661
|
+
this.cteFor = null;
|
|
576
662
|
}
|
|
577
663
|
clone() {
|
|
578
664
|
const q = new _Query();
|
|
579
665
|
q.query = { ...this.query };
|
|
580
666
|
return q;
|
|
581
667
|
}
|
|
668
|
+
/**
|
|
669
|
+
* Retrieve current WITH common table expressions (CTEs).
|
|
670
|
+
* @returns {any[]}
|
|
671
|
+
*/
|
|
672
|
+
/**
|
|
673
|
+
* Add WITH common table expressions (CTEs).
|
|
674
|
+
* @param {...any} expr Expressions to add.
|
|
675
|
+
* @returns {this}
|
|
676
|
+
*/
|
|
582
677
|
with(...expr) {
|
|
583
678
|
const { query } = this;
|
|
584
679
|
if (expr.length === 0) {
|
|
@@ -604,6 +699,15 @@ var Query = class _Query {
|
|
|
604
699
|
return this;
|
|
605
700
|
}
|
|
606
701
|
}
|
|
702
|
+
/**
|
|
703
|
+
* Retrieve current SELECT expressions.
|
|
704
|
+
* @returns {any[]}
|
|
705
|
+
*/
|
|
706
|
+
/**
|
|
707
|
+
* Add SELECT expressions.
|
|
708
|
+
* @param {...any} expr Expressions to add.
|
|
709
|
+
* @returns {this}
|
|
710
|
+
*/
|
|
607
711
|
select(...expr) {
|
|
608
712
|
const { query } = this;
|
|
609
713
|
if (expr.length === 0) {
|
|
@@ -636,6 +740,15 @@ var Query = class _Query {
|
|
|
636
740
|
this.query.distinct = !!value;
|
|
637
741
|
return this;
|
|
638
742
|
}
|
|
743
|
+
/**
|
|
744
|
+
* Retrieve current from expressions.
|
|
745
|
+
* @returns {any[]}
|
|
746
|
+
*/
|
|
747
|
+
/**
|
|
748
|
+
* Provide table from expressions.
|
|
749
|
+
* @param {...any} expr
|
|
750
|
+
* @returns {this}
|
|
751
|
+
*/
|
|
639
752
|
from(...expr) {
|
|
640
753
|
const { query } = this;
|
|
641
754
|
if (expr.length === 0) {
|
|
@@ -666,6 +779,16 @@ var Query = class _Query {
|
|
|
666
779
|
this.query.from = [];
|
|
667
780
|
return this.from(...expr);
|
|
668
781
|
}
|
|
782
|
+
/**
|
|
783
|
+
* Retrieve current SAMPLE settings.
|
|
784
|
+
* @returns {any[]}
|
|
785
|
+
*/
|
|
786
|
+
/**
|
|
787
|
+
* Set SAMPLE settings.
|
|
788
|
+
* @param {number|object} value The percentage or number of rows to sample.
|
|
789
|
+
* @param {string} [method] The sampling method to use.
|
|
790
|
+
* @returns {this}
|
|
791
|
+
*/
|
|
669
792
|
sample(value, method) {
|
|
670
793
|
const { query } = this;
|
|
671
794
|
if (arguments.length === 0) {
|
|
@@ -679,6 +802,15 @@ var Query = class _Query {
|
|
|
679
802
|
return this;
|
|
680
803
|
}
|
|
681
804
|
}
|
|
805
|
+
/**
|
|
806
|
+
* Retrieve current WHERE expressions.
|
|
807
|
+
* @returns {any[]}
|
|
808
|
+
*/
|
|
809
|
+
/**
|
|
810
|
+
* Add WHERE expressions.
|
|
811
|
+
* @param {...any} expr Expressions to add.
|
|
812
|
+
* @returns {this}
|
|
813
|
+
*/
|
|
682
814
|
where(...expr) {
|
|
683
815
|
const { query } = this;
|
|
684
816
|
if (expr.length === 0) {
|
|
@@ -694,6 +826,15 @@ var Query = class _Query {
|
|
|
694
826
|
this.query.where = [];
|
|
695
827
|
return this.where(...expr);
|
|
696
828
|
}
|
|
829
|
+
/**
|
|
830
|
+
* Retrieve current GROUP BY expressions.
|
|
831
|
+
* @returns {any[]}
|
|
832
|
+
*/
|
|
833
|
+
/**
|
|
834
|
+
* Add GROUP BY expressions.
|
|
835
|
+
* @param {...any} expr Expressions to add.
|
|
836
|
+
* @returns {this}
|
|
837
|
+
*/
|
|
697
838
|
groupby(...expr) {
|
|
698
839
|
const { query } = this;
|
|
699
840
|
if (expr.length === 0) {
|
|
@@ -709,6 +850,15 @@ var Query = class _Query {
|
|
|
709
850
|
this.query.groupby = [];
|
|
710
851
|
return this.groupby(...expr);
|
|
711
852
|
}
|
|
853
|
+
/**
|
|
854
|
+
* Retrieve current HAVING expressions.
|
|
855
|
+
* @returns {any[]}
|
|
856
|
+
*/
|
|
857
|
+
/**
|
|
858
|
+
* Add HAVING expressions.
|
|
859
|
+
* @param {...any} expr Expressions to add.
|
|
860
|
+
* @returns {this}
|
|
861
|
+
*/
|
|
712
862
|
having(...expr) {
|
|
713
863
|
const { query } = this;
|
|
714
864
|
if (expr.length === 0) {
|
|
@@ -720,6 +870,15 @@ var Query = class _Query {
|
|
|
720
870
|
return this;
|
|
721
871
|
}
|
|
722
872
|
}
|
|
873
|
+
/**
|
|
874
|
+
* Retrieve current WINDOW definitions.
|
|
875
|
+
* @returns {any[]}
|
|
876
|
+
*/
|
|
877
|
+
/**
|
|
878
|
+
* Add WINDOW definitions.
|
|
879
|
+
* @param {...any} expr Expressions to add.
|
|
880
|
+
* @returns {this}
|
|
881
|
+
*/
|
|
723
882
|
window(...expr) {
|
|
724
883
|
const { query } = this;
|
|
725
884
|
if (expr.length === 0) {
|
|
@@ -738,6 +897,15 @@ var Query = class _Query {
|
|
|
738
897
|
return this;
|
|
739
898
|
}
|
|
740
899
|
}
|
|
900
|
+
/**
|
|
901
|
+
* Retrieve current QUALIFY expressions.
|
|
902
|
+
* @returns {any[]}
|
|
903
|
+
*/
|
|
904
|
+
/**
|
|
905
|
+
* Add QUALIFY expressions.
|
|
906
|
+
* @param {...any} expr Expressions to add.
|
|
907
|
+
* @returns {this}
|
|
908
|
+
*/
|
|
741
909
|
qualify(...expr) {
|
|
742
910
|
const { query } = this;
|
|
743
911
|
if (expr.length === 0) {
|
|
@@ -749,6 +917,15 @@ var Query = class _Query {
|
|
|
749
917
|
return this;
|
|
750
918
|
}
|
|
751
919
|
}
|
|
920
|
+
/**
|
|
921
|
+
* Retrieve current ORDER BY expressions.
|
|
922
|
+
* @returns {any[]}
|
|
923
|
+
*/
|
|
924
|
+
/**
|
|
925
|
+
* Add ORDER BY expressions.
|
|
926
|
+
* @param {...any} expr Expressions to add.
|
|
927
|
+
* @returns {this}
|
|
928
|
+
*/
|
|
752
929
|
orderby(...expr) {
|
|
753
930
|
const { query } = this;
|
|
754
931
|
if (expr.length === 0) {
|
|
@@ -760,6 +937,15 @@ var Query = class _Query {
|
|
|
760
937
|
return this;
|
|
761
938
|
}
|
|
762
939
|
}
|
|
940
|
+
/**
|
|
941
|
+
* Retrieve current LIMIT value.
|
|
942
|
+
* @returns {number|null}
|
|
943
|
+
*/
|
|
944
|
+
/**
|
|
945
|
+
* Set the query result LIMIT.
|
|
946
|
+
* @param {number} value The limit value.
|
|
947
|
+
* @returns {this}
|
|
948
|
+
*/
|
|
763
949
|
limit(value) {
|
|
764
950
|
const { query } = this;
|
|
765
951
|
if (arguments.length === 0) {
|
|
@@ -769,6 +955,15 @@ var Query = class _Query {
|
|
|
769
955
|
return this;
|
|
770
956
|
}
|
|
771
957
|
}
|
|
958
|
+
/**
|
|
959
|
+
* Retrieve current OFFSET value.
|
|
960
|
+
* @returns {number|null}
|
|
961
|
+
*/
|
|
962
|
+
/**
|
|
963
|
+
* Set the query result OFFSET.
|
|
964
|
+
* @param {number} value The offset value.
|
|
965
|
+
* @returns {this}
|
|
966
|
+
*/
|
|
772
967
|
offset(value) {
|
|
773
968
|
const { query } = this;
|
|
774
969
|
if (arguments.length === 0) {
|
|
@@ -827,8 +1022,7 @@ var Query = class _Query {
|
|
|
827
1022
|
}
|
|
828
1023
|
if (where.length) {
|
|
829
1024
|
const clauses = where.map(String).filter((x2) => x2).join(" AND ");
|
|
830
|
-
if (clauses)
|
|
831
|
-
sql2.push(`WHERE ${clauses}`);
|
|
1025
|
+
if (clauses) sql2.push(`WHERE ${clauses}`);
|
|
832
1026
|
}
|
|
833
1027
|
if (sample) {
|
|
834
1028
|
const { rows, perc, method, seed } = sample;
|
|
@@ -841,8 +1035,7 @@ var Query = class _Query {
|
|
|
841
1035
|
}
|
|
842
1036
|
if (having.length) {
|
|
843
1037
|
const clauses = having.map(String).filter((x2) => x2).join(" AND ");
|
|
844
|
-
if (clauses)
|
|
845
|
-
sql2.push(`HAVING ${clauses}`);
|
|
1038
|
+
if (clauses) sql2.push(`HAVING ${clauses}`);
|
|
846
1039
|
}
|
|
847
1040
|
if (window.length) {
|
|
848
1041
|
const windows = window.map(({ as, expr }) => `"${as}" AS (${expr})`);
|
|
@@ -850,8 +1043,7 @@ var Query = class _Query {
|
|
|
850
1043
|
}
|
|
851
1044
|
if (qualify.length) {
|
|
852
1045
|
const clauses = qualify.map(String).filter((x2) => x2).join(" AND ");
|
|
853
|
-
if (clauses)
|
|
854
|
-
sql2.push(`QUALIFY ${clauses}`);
|
|
1046
|
+
if (clauses) sql2.push(`QUALIFY ${clauses}`);
|
|
855
1047
|
}
|
|
856
1048
|
if (orderby.length) {
|
|
857
1049
|
sql2.push(`ORDER BY ${orderby.join(", ")}`);
|
|
@@ -870,6 +1062,7 @@ var SetOperation = class _SetOperation {
|
|
|
870
1062
|
this.op = op;
|
|
871
1063
|
this.queries = queries.map((q) => q.clone());
|
|
872
1064
|
this.query = { orderby: [] };
|
|
1065
|
+
this.cteFor = null;
|
|
873
1066
|
}
|
|
874
1067
|
clone() {
|
|
875
1068
|
const q = new _SetOperation(this.op, this.queries);
|
|
@@ -907,8 +1100,7 @@ var SetOperation = class _SetOperation {
|
|
|
907
1100
|
}
|
|
908
1101
|
get subqueries() {
|
|
909
1102
|
const { queries, cteFor } = this;
|
|
910
|
-
if (cteFor)
|
|
911
|
-
queries.forEach((q) => q.cteFor = cteFor);
|
|
1103
|
+
if (cteFor) queries.forEach((q) => q.cteFor = cteFor);
|
|
912
1104
|
return queries;
|
|
913
1105
|
}
|
|
914
1106
|
toString() {
|
|
@@ -949,7 +1141,7 @@ function scaleLinear() {
|
|
|
949
1141
|
sqlInvert: identity
|
|
950
1142
|
};
|
|
951
1143
|
}
|
|
952
|
-
function scaleLog({ base } = {}) {
|
|
1144
|
+
function scaleLog({ base = null } = {}) {
|
|
953
1145
|
if (base == null || base === Math.E) {
|
|
954
1146
|
return {
|
|
955
1147
|
apply: Math.log,
|
|
@@ -1080,7 +1272,7 @@ function loadSpatial(tableName, fileName, options = {}) {
|
|
|
1080
1272
|
const { options: opt, ...rest } = options;
|
|
1081
1273
|
if (opt) {
|
|
1082
1274
|
const open = Array.isArray(opt) ? opt.join(", ") : typeof opt === "string" ? opt : Object.entries(opt).map(([key, value]) => `${key}=${value}`).join(", ");
|
|
1083
|
-
rest
|
|
1275
|
+
Object.assign(rest, { open_options: open.toUpperCase() });
|
|
1084
1276
|
}
|
|
1085
1277
|
return load("st_read", tableName, fileName, rest);
|
|
1086
1278
|
}
|
package/dist/mosaic-sql.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var S=class{constructor(t,e){t&&(this.table=String(t)),e&&(this.column=e)}get columns(){return this.column?[this.column]:[]}toString(){let{table:t,column:e}=this;if(e){let n=e.startsWith("*")?e:`"${e}"`;return`${t?`${V(t)}.`:""}${n}`}else return t?V(t):"NULL"}};function V(r){return r.split(".").map(e=>`"${e}"`).join(".")}function k(r,t){return r instanceof S&&r.column===t}function u(r){return typeof r=="string"?K(r):r}function O(r){return typeof r=="string"?H(r):r}function H(r){return new S(r)}function K(r,t){return arguments.length===1&&(t=r,r=null),new S(r,t)}function ut(r){return new S(r,"*")}function lt(r){return typeof r=="string"?`"${r}"`:$(r)}function $(r){switch(typeof r){case"boolean":return r?"TRUE":"FALSE";case"string":return`'${r}'`;case"number":return Number.isFinite(r)?String(r):"NULL";default:if(r==null)return"NULL";if(r instanceof Date){let t=+r;if(Number.isNaN(t))return"NULL";let e=r.getUTCFullYear(),n=r.getUTCMonth(),o=r.getUTCDate();return t===Date.UTC(e,n,o)?`MAKE_DATE(${e}, ${n+1}, ${o})`:`EPOCH_MS(${t})`}else return r instanceof RegExp?`'${r.source}'`:String(r)}}var T=r=>typeof r?.addEventListener=="function";function _(r){return r instanceof N}var N=class{constructor(t,e,n){this._expr=Array.isArray(t)?t:[t],this._deps=e||[],this.annotate(n);let o=this._expr.filter(s=>T(s));o.length>0?(this._params=Array.from(new Set(o)),this._params.forEach(s=>{s.addEventListener("value",()=>pt(this,this.map?.get("value")))})):this.addEventListener=void 0}get value(){return this}get columns(){let{_params:t,_deps:e}=this;if(t){let n=new Set(t.flatMap(o=>{let s=o.value?.columns;return Array.isArray(s)?s:[]}));if(n.size){let o=new Set(e);return n.forEach(s=>o.add(s)),Array.from(o)}}return e}get column(){return this._deps.length?this._deps[0]:this.columns[0]}annotate(...t){return Object.assign(this,...t)}toString(){return this._expr.map(t=>T(t)&&!_(t)?$(t.value):t).join("")}addEventListener(t,e){let n=this.map||(this.map=new Map);(n.get(t)||(n.set(t,new Set),n.get(t))).add(e)}};function pt(r,t){if(t?.size)return Promise.allSettled(Array.from(t,e=>e(r)))}function W(r,t){let e=[r[0]],n=new Set,o=t.length;for(let s=0,i=0;s<o;){let a=t[s];T(a)?e[++i]=a:(Array.isArray(a?.columns)&&a.columns.forEach(d=>n.add(d)),e[i]+=typeof a=="string"?a:$(a));let p=r[++s];T(e[i])?e[++i]=p:e[i]+=p}return{spans:e,cols:Array.from(n)}}function c(r,...t){let{spans:e,cols:n}=W(r,t);return new N(e,n)}function ft(r){let t=u(r);return c`${t} DESC NULLS LAST`.annotate({label:t?.label,desc:!0})}var ht=r=>({value:r,toString:()=>$(r)});function D(r){r(this.op,this),this.children?.forEach(t=>t.visit(r))}function z(r,t){let e=t.filter(o=>o!=null).map(u),n=e.map((o,s)=>s?` ${r} `:"");return e.length===1?n.push(""):e.length>1&&(n[0]="(",n.push(")")),c(n,...e).annotate({op:r,children:e,visit:D})}var mt=(...r)=>z("AND",r.flat()),gt=(...r)=>z("OR",r.flat()),dt=r=>t=>c`(${r} ${u(t)})`.annotate({op:r,a:t,visit:D}),xt=dt("NOT"),J=r=>t=>c`(${u(t)} ${r})`.annotate({op:r,a:t,visit:D}),$t=J("IS NULL"),Et=J("IS NOT NULL"),w=r=>(t,e)=>c`(${u(t)} ${r} ${u(e)})`.annotate({op:r,a:t,b:e,visit:D}),yt=w("="),St=w("<>"),Nt=w("<"),wt=w(">"),At=w("<="),Tt=w(">="),Rt=w("IS DISTINCT FROM"),qt=w("IS NOT DISTINCT FROM");function Z(r,t,e,n){t=u(t);let o=r.startsWith("NOT ")?"NOT ":"";return(e?n?c`${o}(${e[0]} <= ${t} AND ${t} < ${e[1]})`:c`(${t} ${r} ${e[0]} AND ${e[1]})`:c``).annotate({op:r,visit:D,field:t,range:e})}var bt=(r,t,e)=>Z("BETWEEN",r,t,e),It=(r,t,e)=>Z("NOT BETWEEN",r,t,e);function R(r,t){return Array.from({length:r},()=>t)}function m(r,t){return(...e)=>{let n=e.map(u),o=t?`::${t}`:"";return(n.length?c([`${r}(`,...R(n.length-1,", "),`)${o}`],...n):c`${r}()${o}`).annotate({func:r,args:n})}}var Lt=m("REGEXP_MATCHES"),Ot=m("CONTAINS"),Dt=m("PREFIX"),Ct=m("SUFFIX"),Mt=m("LOWER"),_t=m("UPPER"),Pt=m("LENGTH"),Ft=m("ISNAN"),Gt=m("ISFINITE"),Ut=m("ISINF");var C=class r extends N{constructor(t,e,n,o,s="",i="",a=""){let p;if(o&&!(s||i||a))p=o?c`${e} OVER "${o}"`:c`${e} OVER ()`;else{let b=s&&i?" ":"",I=(s||i)&&a?" ":"";p=c`${e} OVER (${o?`"${o}" `:""}${s}${b}${i}${I}${a})`}n&&(p=c`(${p})::${n}`);let{_expr:y,_deps:A}=p;super(y,A,{window:t,func:e,type:n,name:o,group:s,order:i,frame:a})}get basis(){return this.column}get label(){let{func:t}=this;return t.label??t.toString()}over(t){let{window:e,func:n,type:o,group:s,order:i,frame:a}=this;return new r(e,n,o,t,s,i,a)}partitionby(...t){let e=t.flat().filter(y=>y).map(u),n=c(["PARTITION BY ",R(e.length-1,", "),""],...e),{window:o,func:s,type:i,name:a,order:p,frame:d}=this;return new r(o,s,i,a,n,p,d)}orderby(...t){let e=t.flat().filter(y=>y).map(u),n=c(["ORDER BY ",R(e.length-1,", "),""],...e),{window:o,func:s,type:i,name:a,group:p,frame:d}=this;return new r(o,s,i,a,p,n,d)}rows(t){let e=tt("ROWS",t),{window:n,func:o,type:s,name:i,group:a,order:p}=this;return new r(n,o,s,i,a,p,e)}range(t){let e=tt("RANGE",t),{window:n,func:o,type:s,name:i,group:a,order:p}=this;return new r(n,o,s,i,a,p,e)}};function tt(r,t){if(T(t)){let e=c`${t}`;return e.toString=()=>`${r} ${et(t.value)}`,e}return`${r} ${et(t)}`}function et(r){let[t,e]=r,n=t===0?"CURRENT ROW":Number.isFinite(t)?`${Math.abs(t)} PRECEDING`:"UNBOUNDED PRECEDING",o=e===0?"CURRENT ROW":Number.isFinite(e)?`${Math.abs(e)} FOLLOWING`:"UNBOUNDED FOLLOWING";return`BETWEEN ${n} AND ${o}`}function E(r,t){return(...e)=>{let n=m(r)(...e);return new C(r,n,t)}}var jt=E("ROW_NUMBER","INTEGER"),Wt=E("RANK","INTEGER"),Yt=E("DENSE_RANK","INTEGER"),Bt=E("PERCENT_RANK"),Xt=E("CUME_DIST"),vt=E("NTILE"),Qt=E("LAG"),Vt=E("LEAD"),kt=E("FIRST_VALUE"),Ht=E("LAST_VALUE"),Kt=E("NTH_VALUE");function zt(r,...t){return c(r,...t).annotate({aggregate:!0})}var Y=class r extends N{constructor(t,e,n,o,s){e=(e||[]).map(u);let{strings:i,exprs:a}=Jt(t,e,n,o,s),{spans:p,cols:d}=W(i,a);super(p,d,{aggregate:t,args:e,type:n,isDistinct:o,filter:s})}get basis(){return this.column}get label(){let{aggregate:t,args:e,isDistinct:n}=this,o=n?"DISTINCT"+(e.length?" ":""):"",s=e.length?`(${o}${e.map(Zt).join(", ")})`:"";return`${t.toLowerCase()}${s}`}distinct(){let{aggregate:t,args:e,type:n,filter:o}=this;return new r(t,e,n,!0,o)}where(t){let{aggregate:e,args:n,type:o,isDistinct:s}=this;return new r(e,n,o,s,t)}window(){let{aggregate:t,args:e,type:n,isDistinct:o}=this,s=new r(t,e,null,o);return new C(t,s,n)}partitionby(...t){return this.window().partitionby(...t)}orderby(...t){return this.window().orderby(...t)}rows(t,e){return this.window().rows(t,e)}range(t,e){return this.window().range(t,e)}};function Jt(r,t,e,n,o){let s=`)${e?`::${e}`:""}`,i=[`${r}(${n?"DISTINCT ":""}`],a=[];return t.length?(i=i.concat([...R(t.length-1,", "),`${s}${o?" FILTER (WHERE ":""}`,...o?[")"]:[]]),a=[...t,...o?[o]:[]]):i[0]+="*"+s,{exprs:a,strings:i}}function Zt(r){let t=$(r);return t&&t.startsWith('"')&&t.endsWith('"')?t.slice(1,-1):t}function l(r,t){return(...e)=>new Y(r,e,t)}var te=l("COUNT","INTEGER"),ee=l("AVG"),re=l("AVG"),ne=l("MAD"),oe=l("MAX"),se=l("MIN"),ie=l("SUM","DOUBLE"),ce=l("PRODUCT"),ae=l("MEDIAN"),ue=l("QUANTILE"),le=l("MODE"),pe=l("VARIANCE"),fe=l("STDDEV"),he=l("SKEWNESS"),me=l("KURTOSIS"),ge=l("ENTROPY"),de=l("VAR_POP"),xe=l("STDDEV_POP"),$e=l("CORR"),Ee=l("COVAR_POP"),ye=l("REGR_INTERCEPT"),Se=l("REGR_SLOPE"),Ne=l("REGR_COUNT"),we=l("REGR_R2"),Ae=l("REGR_SYY"),Te=l("REGR_SXX"),Re=l("REGR_SXY"),qe=l("REGR_AVGX"),be=l("REGR_AVGY"),Ie=l("FIRST"),Le=l("LAST"),Oe=l("ARG_MIN"),De=l("ARG_MAX"),Ce=l("STRING_AGG"),Me=l("ARRAY_AGG");function B(r,t){let e=u(r),n=c`CAST(${e} AS ${t})`;return Object.defineProperty(n,"label",{enumerable:!0,get(){return r.label}}),Object.defineProperty(n,"aggregate",{enumerable:!0,get(){return r.aggregate||!1}}),n}var _e=r=>B(r,"DOUBLE"),Pe=r=>B(r,"INTEGER");var X=r=>c`epoch_ms(${u(r)})`,Fe=r=>{let t=u(r);return c`MAKE_DATE(2012, MONTH(${t}), 1)`.annotate({label:"month"})},Ge=r=>{let t=u(r);return c`MAKE_DATE(2012, MONTH(${t}), DAY(${t}))`.annotate({label:"date"})},Ue=r=>{let t=u(r);return c`MAKE_DATE(2012, 1, DAY(${t}))`.annotate({label:"date"})};var je=m("ST_AsGeoJSON"),rt=m("ST_X"),nt=m("ST_Y"),v=m("ST_CENTROID"),We=r=>rt(v(r)),Ye=r=>nt(v(r));var F=class r{static select(...t){return new r().select(...t)}static from(...t){return new r().from(...t)}static with(...t){return new r().with(...t)}static union(...t){return new q("UNION",t.flat())}static unionAll(...t){return new q("UNION ALL",t.flat())}static intersect(...t){return new q("INTERSECT",t.flat())}static except(...t){return new q("EXCEPT",t.flat())}static describe(t){let e=t.clone(),{clone:n,toString:o}=e;return Object.assign(e,{describe:!0,clone:()=>r.describe(n.call(e)),toString:()=>`DESCRIBE ${o.call(e)}`})}constructor(){this.query={with:[],select:[],from:[],where:[],groupby:[],having:[],window:[],qualify:[],orderby:[]}}clone(){let t=new r;return t.query={...this.query},t}with(...t){let{query:e}=this;if(t.length===0)return e.with;{let n=[],o=(s,i)=>{let a=i.clone();a.cteFor=this,n.push({as:s,query:a})};return t.flat().forEach(s=>{if(s!=null)if(s.as&&s.query)o(s.as,s.query);else for(let i in s)o(i,s[i])}),e.with=e.with.concat(n),this}}select(...t){let{query:e}=this;if(t.length===0)return e.select;{let n=[];for(let o of t.flat())if(o!=null)if(typeof o=="string")n.push({as:o,expr:u(o)});else if(o instanceof S)n.push({as:o.column,expr:o});else if(Array.isArray(o))n.push({as:o[0],expr:o[1]});else for(let s in o)n.push({as:P(s),expr:u(o[s])});return e.select=e.select.concat(n),this}}$select(...t){return this.query.select=[],this.select(...t)}distinct(t=!0){return this.query.distinct=!!t,this}from(...t){let{query:e}=this;if(t.length===0)return e.from;{let n=[];return t.flat().forEach(o=>{if(o!=null)if(typeof o=="string")n.push({as:o,from:O(o)});else if(o instanceof S)n.push({as:o.table,from:o});else if(M(o)||_(o))n.push({from:o});else if(Array.isArray(o))n.push({as:P(o[0]),from:O(o[1])});else for(let s in o)n.push({as:P(s),from:O(o[s])})}),e.from=e.from.concat(n),this}}$from(...t){return this.query.from=[],this.from(...t)}sample(t,e){let{query:n}=this;if(arguments.length===0)return n.sample;{let o=t;return typeof t=="number"&&(o=t>0&&t<1?{perc:100*t,method:e}:{rows:Math.round(t),method:e}),n.sample=o,this}}where(...t){let{query:e}=this;return t.length===0?e.where:(e.where=e.where.concat(t.flat().filter(n=>n)),this)}$where(...t){return this.query.where=[],this.where(...t)}groupby(...t){let{query:e}=this;return t.length===0?e.groupby:(e.groupby=e.groupby.concat(t.flat().filter(n=>n).map(u)),this)}$groupby(...t){return this.query.groupby=[],this.groupby(...t)}having(...t){let{query:e}=this;return t.length===0?e.having:(e.having=e.having.concat(t.flat().filter(n=>n)),this)}window(...t){let{query:e}=this;if(t.length===0)return e.window;{let n=[];return t.flat().forEach(o=>{if(o!=null)for(let s in o)n.push({as:P(s),expr:o[s]})}),e.window=e.window.concat(n),this}}qualify(...t){let{query:e}=this;return t.length===0?e.qualify:(e.qualify=e.qualify.concat(t.flat().filter(n=>n)),this)}orderby(...t){let{query:e}=this;return t.length===0?e.orderby:(e.orderby=e.orderby.concat(t.flat().filter(n=>n).map(u)),this)}limit(t){let{query:e}=this;return arguments.length===0?e.limit:(e.limit=Number.isFinite(t)?t:void 0,this)}offset(t){let{query:e}=this;return arguments.length===0?e.offset:(e.offset=Number.isFinite(t)?t:void 0,this)}get subqueries(){let{query:t,cteFor:e}=this,o=(e?.query||t).with?.reduce((i,{as:a,query:p})=>(i[a]=p,i),{}),s=[];return t.from.forEach(({from:i})=>{if(M(i))s.push(i);else if(o[i.table]){let a=o[i.table];s.push(a)}}),s}toString(){let{with:t,select:e,distinct:n,from:o,sample:s,where:i,groupby:a,having:p,window:d,qualify:y,orderby:A,limit:b,offset:I}=this.query,g=[];if(t.length){let f=t.map(({as:h,query:x})=>`"${h}" AS (${x})`);g.push(`WITH ${f.join(", ")}`)}let it=e.map(({as:f,expr:h})=>k(h,f)&&!h.table?`${h}`:`${h} AS "${f}"`);if(g.push(`SELECT${n?" DISTINCT":""} ${it.join(", ")}`),o.length){let f=o.map(({as:h,from:x})=>{let L=M(x)?`(${x})`:`${x}`;return!h||h===x.table?L:`${L} AS "${h}"`});g.push(`FROM ${f.join(", ")}`)}if(i.length){let f=i.map(String).filter(h=>h).join(" AND ");f&&g.push(`WHERE ${f}`)}if(s){let{rows:f,perc:h,method:x,seed:L}=s,ct=f?`${f} ROWS`:`${h} PERCENT`,at=x?` (${x}${L!=null?`, ${L}`:""})`:"";g.push(`USING SAMPLE ${ct}${at}`)}if(a.length&&g.push(`GROUP BY ${a.join(", ")}`),p.length){let f=p.map(String).filter(h=>h).join(" AND ");f&&g.push(`HAVING ${f}`)}if(d.length){let f=d.map(({as:h,expr:x})=>`"${h}" AS (${x})`);g.push(`WINDOW ${f.join(", ")}`)}if(y.length){let f=y.map(String).filter(h=>h).join(" AND ");f&&g.push(`QUALIFY ${f}`)}return A.length&&g.push(`ORDER BY ${A.join(", ")}`),Number.isFinite(b)&&g.push(`LIMIT ${b}`),Number.isFinite(I)&&g.push(`OFFSET ${I}`),g.join(" ")}},q=class r{constructor(t,e){this.op=t,this.queries=e.map(n=>n.clone()),this.query={orderby:[]}}clone(){let t=new r(this.op,this.queries);return t.query={...this.query},t}orderby(...t){let{query:e}=this;return t.length===0?e.orderby:(e.orderby=e.orderby.concat(t.flat().filter(n=>n).map(u)),this)}limit(t){let{query:e}=this;return arguments.length===0?e.limit:(e.limit=Number.isFinite(t)?t:void 0,this)}offset(t){let{query:e}=this;return arguments.length===0?e.offset:(e.offset=Number.isFinite(t)?t:void 0,this)}get subqueries(){let{queries:t,cteFor:e}=this;return e&&t.forEach(n=>n.cteFor=e),t}toString(){let{op:t,queries:e,query:{orderby:n,limit:o,offset:s}}=this,i=[e.join(` ${t} `)];return n.length&&i.push(`ORDER BY ${n.join(", ")}`),Number.isFinite(o)&&i.push(`LIMIT ${o}`),Number.isFinite(s)&&i.push(`OFFSET ${s}`),i.join(" ")}};function M(r){return r instanceof F||r instanceof q}function Be(r){return M(r)&&r.describe}function P(r){return Xe(r)?r.slice(1,-1):r}function Xe(r){return r[0]==='"'&&r[r.length-1]==='"'}var G=r=>r;function ve(){return{apply:G,invert:G,sqlApply:u,sqlInvert:G}}function Qe({base:r}={}){if(r==null||r===Math.E)return{apply:Math.log,invert:Math.exp,sqlApply:t=>c`LN(${u(t)})`,sqlInvert:t=>c`EXP(${t})`};if(r===10)return{apply:Math.log10,invert:t=>Math.pow(10,t),sqlApply:t=>c`LOG(${u(t)})`,sqlInvert:t=>c`POW(10, ${t})`};{let t=+r;return{apply:e=>Math.log(e)/Math.log(t),invert:e=>Math.pow(t,e),sqlApply:e=>c`LN(${u(e)}) / LN(${t})`,sqlInvert:e=>c`POW(${t}, ${e})`}}}function Ve({constant:r=1}={}){let t=+r;return{apply:e=>Math.sign(e)*Math.log1p(Math.abs(e)),invert:e=>Math.sign(e)*Math.exp(Math.abs(e)-t),sqlApply:e=>(e=u(e),c`SIGN(${e}) * LN(${t} + ABS(${e}))`),sqlInvert:e=>c`SIGN(${e}) * (EXP(ABS(${e})) - ${t})`}}function ke(){return{apply:r=>Math.sign(r)*Math.sqrt(Math.abs(r)),invert:r=>Math.sign(r)*r*r,sqlApply:r=>(r=u(r),c`SIGN(${r}) * SQRT(ABS(${r}))`),sqlInvert:r=>c`SIGN(${r}) * (${r}) ** 2`}}function He({exponent:r=1}={}){let t=+r;return{apply:e=>Math.sign(e)*Math.pow(Math.abs(e),t),invert:e=>Math.sign(e)*Math.pow(Math.abs(e),1/t),sqlApply:e=>(e=u(e),c`SIGN(${e}) * POW(ABS(${e}), ${t})`),sqlInvert:e=>c`SIGN(${e}) * POW(ABS(${e}), 1/${t})`}}function ot(){return{apply:r=>+r,invert:r=>new Date(r),sqlApply:r=>r instanceof Date?+r:X(u(r)),sqlInvert:G}}var Ke={linear:ve,log:Qe,symlog:Ve,sqrt:ke,pow:He,time:ot,utc:ot};function ze(r){let t=Ke[r.type];return t?{...r,...t(r)}:null}function U(r,t,{replace:e=!1,temp:n=!0,view:o=!1}={}){return"CREATE"+(e?" OR REPLACE ":" ")+(n?"TEMP ":"")+(o?"VIEW":"TABLE")+(e?" ":" IF NOT EXISTS ")+r+" AS "+t}function Je(r){return`INSTALL ${r}; LOAD ${r}`}function st(r,{columns:t=Object.keys(r?.[0]||{})}={}){let e=[];if(Array.isArray(t)?(e=t,t=e.reduce((o,s)=>(o[s]=s,o),{})):t&&(e=Object.keys(t)),!e.length)throw new Error("Can not create table from empty column set.");let n=[];for(let o of r){let s=e.map(i=>`${$(o[i])} AS "${t[i]}"`);n.push(`(SELECT ${s.join(", ")})`)}return n.join(" UNION ALL ")}function j(r,t,e,n={},o={}){let{select:s=["*"],where:i,view:a,temp:p,replace:d,...y}=n,A=or({...o,...y}),b=`${r}('${e}'${A?", "+A:""})`,I=i?` WHERE ${i}`:"",g=`SELECT ${s.join(", ")} FROM ${b}${I}`;return U(t,g,{view:a,temp:p,replace:d})}function Ze(r,t,e){return j("read_csv",r,t,e,{auto_detect:!0,sample_size:-1})}function tr(r,t,e){return j("read_json",r,t,e,{auto_detect:!0,json_format:"auto"})}function er(r,t,e){return j("read_parquet",r,t,e)}function rr(r,t,e={}){let{options:n,...o}=e;if(n){let s=Array.isArray(n)?n.join(", "):typeof n=="string"?n:Object.entries(n).map(([i,a])=>`${i}=${a}`).join(", ");o.open_options=s.toUpperCase()}return j("st_read",r,t,o)}function nr(r,t,e={}){let{select:n=["*"],...o}=e,s=st(t),i=n.length===1&&n[0]==="*"?s:`SELECT ${n} FROM ${s}`;return U(r,i,o)}function or(r){return Object.entries(r).map(([t,e])=>`${t}=${Q(e)}`).join(", ")}function Q(r){switch(typeof r){case"boolean":return String(r);case"string":return`'${r}'`;case"undefined":case"object":return r==null?"NULL":Array.isArray(r)?"["+r.map(t=>Q(t)).join(", ")+"]":"{"+Object.entries(r).map(([t,e])=>`'${t}': ${Q(e)}`).join(", ")+"}";default:return r}}export{F as Query,S as Ref,zt as agg,ut as all,mt as and,De as argmax,Oe as argmin,Me as arrayAgg,u as asColumn,O as asRelation,ee as avg,B as cast,_e as castDouble,Pe as castInteger,v as centroid,We as centroidX,Ye as centroidY,K as column,Ot as contains,$e as corr,te as count,Ee as covarPop,U as create,Xt as cume_dist,Ue as dateDay,Fe as dateMonth,Ge as dateMonthDay,Yt as dense_rank,ft as desc,ge as entropy,X as epoch_ms,yt as eq,Ie as first,kt as first_value,je as geojson,wt as gt,Tt as gte,bt as isBetween,Be as isDescribeQuery,Rt as isDistinct,Gt as isFinite,Ut as isInfinite,Ft as isNaN,It as isNotBetween,qt as isNotDistinct,Et as isNotNull,$t as isNull,T as isParamLike,M as isQuery,_ as isSQLExpression,me as kurtosis,Qt as lag,Le as last,Ht as last_value,Vt as lead,Pt as length,ht as literal,$ as literalToSQL,Ze as loadCSV,Je as loadExtension,tr as loadJSON,nr as loadObjects,er as loadParquet,rr as loadSpatial,Mt as lower,Nt as lt,At as lte,ne as mad,oe as max,re as mean,ae as median,se as min,le as mode,St as neq,xt as not,Kt as nth_value,vt as ntile,gt as or,Bt as percent_rank,Dt as prefix,ce as product,ue as quantile,Wt as rank,Lt as regexp_matches,qe as regrAvgX,be as regrAvgY,Ne as regrCount,ye as regrIntercept,we as regrR2,Te as regrSXX,Re as regrSXY,Ae as regrSYY,Se as regrSlope,H as relation,jt as row_number,ze as scaleTransform,he as skewness,c as sql,fe as stddev,xe as stddevPop,Ce as stringAgg,Ct as suffix,ie as sum,lt as toSQL,_t as upper,de as varPop,pe as variance,rt as x,nt as y};
|
|
1
|
+
var S=class{constructor(t,e){t&&(this.table=String(t)),e&&(this.column=e)}get columns(){return this.column?[this.column]:[]}toString(){let{table:t,column:e}=this;if(e){let n=e.startsWith("*")?e:`"${e}"`;return`${t?`${V(t)}.`:""}${n}`}else return t?V(t):"NULL"}};function V(r){return r.split(".").map(e=>`"${e}"`).join(".")}function k(r,t){return r instanceof S&&r.column===t}function u(r){return typeof r=="string"?K(r):r}function O(r){return typeof r=="string"?H(r):r}function H(r){return new S(r)}function K(r,t=null){return arguments.length===1&&(t=r,r=null),new S(r,t)}function ut(r){return new S(r,"*")}function lt(r){return typeof r=="string"?`"${r}"`:$(r)}function $(r){switch(typeof r){case"boolean":return r?"TRUE":"FALSE";case"string":return`'${r}'`;case"number":return Number.isFinite(r)?String(r):"NULL";default:if(r==null)return"NULL";if(r instanceof Date){let t=+r;if(Number.isNaN(t))return"NULL";let e=r.getUTCFullYear(),n=r.getUTCMonth(),o=r.getUTCDate();return t===Date.UTC(e,n,o)?`MAKE_DATE(${e}, ${n+1}, ${o})`:`EPOCH_MS(${t})`}else return r instanceof RegExp?`'${r.source}'`:String(r)}}var T=r=>typeof r?.addEventListener=="function";function _(r){return r instanceof N}var N=class{constructor(t,e,n){this._expr=Array.isArray(t)?t:[t],this._deps=e||[],this.annotate(n);let o=this._expr.filter(s=>T(s));o.length>0?(this._params=Array.from(new Set(o)),this._params.forEach(s=>{s.addEventListener("value",()=>pt(this,this.map?.get("value")))})):this.addEventListener=void 0}get value(){return this}get columns(){let{_params:t,_deps:e}=this;if(t){let n=new Set(t.flatMap(o=>{let s=o.value?.columns;return Array.isArray(s)?s:[]}));if(n.size){let o=new Set(e);return n.forEach(s=>o.add(s)),Array.from(o)}}return e}get column(){return this._deps.length?this._deps[0]:this.columns[0]}annotate(...t){return Object.assign(this,...t)}toString(){return this._expr.map(t=>T(t)&&!_(t)?$(t.value):t).join("")}addEventListener(t,e){let n=this.map||(this.map=new Map);(n.get(t)||(n.set(t,new Set),n.get(t))).add(e)}};function pt(r,t){if(t?.size)return Promise.allSettled(Array.from(t,e=>e(r)))}function W(r,t){let e=[r[0]],n=new Set,o=t.length;for(let s=0,i=0;s<o;){let a=t[s];T(a)?e[++i]=a:(Array.isArray(a?.columns)&&a.columns.forEach(d=>n.add(d)),e[i]+=typeof a=="string"?a:$(a));let p=r[++s];T(e[i])?e[++i]=p:e[i]+=p}return{spans:e,cols:Array.from(n)}}function c(r,...t){let{spans:e,cols:n}=W(r,t);return new N(e,n)}function ft(r){let t=u(r);return c`${t} DESC NULLS LAST`.annotate({label:t?.label,desc:!0})}var ht=r=>({value:r,toString:()=>$(r)});function D(r){r(this.op,this),this.children?.forEach(t=>t.visit(r))}function z(r,t){let e=t.filter(o=>o!=null).map(u),n=e.map((o,s)=>s?` ${r} `:"");return e.length===1?n.push(""):e.length>1&&(n[0]="(",n.push(")")),c(n,...e).annotate({op:r,children:e,visit:D})}var mt=(...r)=>z("AND",r.flat()),gt=(...r)=>z("OR",r.flat()),dt=r=>t=>c`(${r} ${u(t)})`.annotate({op:r,a:t,visit:D}),xt=dt("NOT"),J=r=>t=>c`(${u(t)} ${r})`.annotate({op:r,a:t,visit:D}),$t=J("IS NULL"),Et=J("IS NOT NULL"),w=r=>(t,e)=>c`(${u(t)} ${r} ${u(e)})`.annotate({op:r,a:t,b:e,visit:D}),yt=w("="),St=w("<>"),Nt=w("<"),wt=w(">"),At=w("<="),Tt=w(">="),Rt=w("IS DISTINCT FROM"),qt=w("IS NOT DISTINCT FROM");function Z(r,t,e,n){t=u(t);let o=r.startsWith("NOT ")?"NOT ":"";return(e?n?c`${o}(${e[0]} <= ${t} AND ${t} < ${e[1]})`:c`(${t} ${r} ${e[0]} AND ${e[1]})`:c``).annotate({op:r,visit:D,field:t,range:e})}var bt=(r,t,e)=>Z("BETWEEN",r,t,e),It=(r,t,e)=>Z("NOT BETWEEN",r,t,e);function R(r,t){return Array.from({length:r},()=>t)}function m(r,t){return(...e)=>{let n=e.map(u),o=t?`::${t}`:"";return(n.length?c([`${r}(`,...R(n.length-1,", "),`)${o}`],...n):c`${r}()${o}`).annotate({func:r,args:n})}}var Lt=m("REGEXP_MATCHES"),Ot=m("CONTAINS"),Dt=m("PREFIX"),Ct=m("SUFFIX"),Mt=m("LOWER"),_t=m("UPPER"),Pt=m("LENGTH"),Ft=m("ISNAN"),Gt=m("ISFINITE"),jt=m("ISINF");var C=class r extends N{constructor(t,e,n,o,s="",i="",a=""){let p;if(o&&!(s||i||a))p=o?c`${e} OVER "${o}"`:c`${e} OVER ()`;else{let b=s&&i?" ":"",I=(s||i)&&a?" ":"";p=c`${e} OVER (${o?`"${o}" `:""}${s}${b}${i}${I}${a})`}n&&(p=c`(${p})::${n}`);let{_expr:y,_deps:A}=p;super(y,A),this.window=t,this.func=e,this.type=n,this.name=o,this.group=s,this.order=i,this.frame=a}get basis(){return this.column}get label(){let{func:t}=this;return t.label??t.toString()}over(t){let{window:e,func:n,type:o,group:s,order:i,frame:a}=this;return new r(e,n,o,t,s,i,a)}partitionby(...t){let e=t.flat().filter(y=>y).map(u),n=c(["PARTITION BY ",R(e.length-1,", "),""],...e),{window:o,func:s,type:i,name:a,order:p,frame:d}=this;return new r(o,s,i,a,n,p,d)}orderby(...t){let e=t.flat().filter(y=>y).map(u),n=c(["ORDER BY ",R(e.length-1,", "),""],...e),{window:o,func:s,type:i,name:a,group:p,frame:d}=this;return new r(o,s,i,a,p,n,d)}rows(t){let e=tt("ROWS",t),{window:n,func:o,type:s,name:i,group:a,order:p}=this;return new r(n,o,s,i,a,p,e)}range(t){let e=tt("RANGE",t),{window:n,func:o,type:s,name:i,group:a,order:p}=this;return new r(n,o,s,i,a,p,e)}};function tt(r,t){if(T(t)){let e=c`${t}`;return e.toString=()=>`${r} ${et(t.value)}`,e}return`${r} ${et(t)}`}function et(r){let[t,e]=r,n=t===0?"CURRENT ROW":Number.isFinite(t)?`${Math.abs(t)} PRECEDING`:"UNBOUNDED PRECEDING",o=e===0?"CURRENT ROW":Number.isFinite(e)?`${Math.abs(e)} FOLLOWING`:"UNBOUNDED FOLLOWING";return`BETWEEN ${n} AND ${o}`}function E(r,t){return(...e)=>{let n=m(r)(...e);return new C(r,n,t)}}var Ut=E("ROW_NUMBER","INTEGER"),Wt=E("RANK","INTEGER"),Yt=E("DENSE_RANK","INTEGER"),Bt=E("PERCENT_RANK"),Xt=E("CUME_DIST"),vt=E("NTILE"),Qt=E("LAG"),Vt=E("LEAD"),kt=E("FIRST_VALUE"),Ht=E("LAST_VALUE"),Kt=E("NTH_VALUE");function zt(r,...t){return c(r,...t).annotate({aggregate:!0})}var Y=class r extends N{constructor(t,e,n,o,s){e=(e||[]).map(u);let{strings:i,exprs:a}=Jt(t,e,n,o,s),{spans:p,cols:d}=W(i,a);super(p,d),this.aggregate=t,this.args=e,this.type=n,this.isDistinct=o,this.filter=s}get basis(){return this.column}get label(){let{aggregate:t,args:e,isDistinct:n}=this,o=n?"DISTINCT"+(e.length?" ":""):"",s=e.length?`(${o}${e.map(Zt).join(", ")})`:"";return`${t.toLowerCase()}${s}`}distinct(){let{aggregate:t,args:e,type:n,filter:o}=this;return new r(t,e,n,!0,o)}where(t){let{aggregate:e,args:n,type:o,isDistinct:s}=this;return new r(e,n,o,s,t)}window(){let{aggregate:t,args:e,type:n,isDistinct:o}=this,s=new r(t,e,null,o);return new C(t,s,n)}partitionby(...t){return this.window().partitionby(...t)}orderby(...t){return this.window().orderby(...t)}rows(t){return this.window().rows(t)}range(t){return this.window().range(t)}};function Jt(r,t,e,n,o){let s=`)${e?`::${e}`:""}`,i=[`${r}(${n?"DISTINCT ":""}`],a=[];return t.length?(i=i.concat([...R(t.length-1,", "),`${s}${o?" FILTER (WHERE ":""}`,...o?[")"]:[]]),a=[...t,...o?[o]:[]]):i[0]+="*"+s,{exprs:a,strings:i}}function Zt(r){let t=$(r);return t&&t.startsWith('"')&&t.endsWith('"')?t.slice(1,-1):t}function l(r,t){return(...e)=>new Y(r,e,t)}var te=l("COUNT","INTEGER"),ee=l("AVG"),re=l("AVG"),ne=l("MAD"),oe=l("MAX"),se=l("MIN"),ie=l("SUM","DOUBLE"),ce=l("PRODUCT"),ae=l("MEDIAN"),ue=l("QUANTILE"),le=l("MODE"),pe=l("VARIANCE"),fe=l("STDDEV"),he=l("SKEWNESS"),me=l("KURTOSIS"),ge=l("ENTROPY"),de=l("VAR_POP"),xe=l("STDDEV_POP"),$e=l("CORR"),Ee=l("COVAR_POP"),ye=l("REGR_INTERCEPT"),Se=l("REGR_SLOPE"),Ne=l("REGR_COUNT"),we=l("REGR_R2"),Ae=l("REGR_SYY"),Te=l("REGR_SXX"),Re=l("REGR_SXY"),qe=l("REGR_AVGX"),be=l("REGR_AVGY"),Ie=l("FIRST"),Le=l("LAST"),Oe=l("ARG_MIN"),De=l("ARG_MAX"),Ce=l("STRING_AGG"),Me=l("ARRAY_AGG");function B(r,t){let e=u(r),n=c`CAST(${e} AS ${t})`;return Object.defineProperty(n,"label",{enumerable:!0,get(){return r.label}}),Object.defineProperty(n,"aggregate",{enumerable:!0,get(){return r.aggregate||!1}}),n}var _e=r=>B(r,"DOUBLE"),Pe=r=>B(r,"INTEGER");var X=r=>c`epoch_ms(${u(r)})`,Fe=r=>{let t=u(r);return c`MAKE_DATE(2012, MONTH(${t}), 1)`.annotate({label:"month"})},Ge=r=>{let t=u(r);return c`MAKE_DATE(2012, MONTH(${t}), DAY(${t}))`.annotate({label:"date"})},je=r=>{let t=u(r);return c`MAKE_DATE(2012, 1, DAY(${t}))`.annotate({label:"date"})};var Ue=m("ST_AsGeoJSON"),rt=m("ST_X"),nt=m("ST_Y"),v=m("ST_CENTROID"),We=r=>rt(v(r)),Ye=r=>nt(v(r));var F=class r{static select(...t){return new r().select(...t)}static from(...t){return new r().from(...t)}static with(...t){return new r().with(...t)}static union(...t){return new q("UNION",t.flat())}static unionAll(...t){return new q("UNION ALL",t.flat())}static intersect(...t){return new q("INTERSECT",t.flat())}static except(...t){return new q("EXCEPT",t.flat())}static describe(t){let e=t.clone(),{clone:n,toString:o}=e;return Object.assign(e,{describe:!0,clone:()=>r.describe(n.call(e)),toString:()=>`DESCRIBE ${o.call(e)}`})}constructor(){this.query={with:[],select:[],from:[],where:[],groupby:[],having:[],window:[],qualify:[],orderby:[]},this.cteFor=null}clone(){let t=new r;return t.query={...this.query},t}with(...t){let{query:e}=this;if(t.length===0)return e.with;{let n=[],o=(s,i)=>{let a=i.clone();a.cteFor=this,n.push({as:s,query:a})};return t.flat().forEach(s=>{if(s!=null)if(s.as&&s.query)o(s.as,s.query);else for(let i in s)o(i,s[i])}),e.with=e.with.concat(n),this}}select(...t){let{query:e}=this;if(t.length===0)return e.select;{let n=[];for(let o of t.flat())if(o!=null)if(typeof o=="string")n.push({as:o,expr:u(o)});else if(o instanceof S)n.push({as:o.column,expr:o});else if(Array.isArray(o))n.push({as:o[0],expr:o[1]});else for(let s in o)n.push({as:P(s),expr:u(o[s])});return e.select=e.select.concat(n),this}}$select(...t){return this.query.select=[],this.select(...t)}distinct(t=!0){return this.query.distinct=!!t,this}from(...t){let{query:e}=this;if(t.length===0)return e.from;{let n=[];return t.flat().forEach(o=>{if(o!=null)if(typeof o=="string")n.push({as:o,from:O(o)});else if(o instanceof S)n.push({as:o.table,from:o});else if(M(o)||_(o))n.push({from:o});else if(Array.isArray(o))n.push({as:P(o[0]),from:O(o[1])});else for(let s in o)n.push({as:P(s),from:O(o[s])})}),e.from=e.from.concat(n),this}}$from(...t){return this.query.from=[],this.from(...t)}sample(t,e){let{query:n}=this;if(arguments.length===0)return n.sample;{let o=t;return typeof t=="number"&&(o=t>0&&t<1?{perc:100*t,method:e}:{rows:Math.round(t),method:e}),n.sample=o,this}}where(...t){let{query:e}=this;return t.length===0?e.where:(e.where=e.where.concat(t.flat().filter(n=>n)),this)}$where(...t){return this.query.where=[],this.where(...t)}groupby(...t){let{query:e}=this;return t.length===0?e.groupby:(e.groupby=e.groupby.concat(t.flat().filter(n=>n).map(u)),this)}$groupby(...t){return this.query.groupby=[],this.groupby(...t)}having(...t){let{query:e}=this;return t.length===0?e.having:(e.having=e.having.concat(t.flat().filter(n=>n)),this)}window(...t){let{query:e}=this;if(t.length===0)return e.window;{let n=[];return t.flat().forEach(o=>{if(o!=null)for(let s in o)n.push({as:P(s),expr:o[s]})}),e.window=e.window.concat(n),this}}qualify(...t){let{query:e}=this;return t.length===0?e.qualify:(e.qualify=e.qualify.concat(t.flat().filter(n=>n)),this)}orderby(...t){let{query:e}=this;return t.length===0?e.orderby:(e.orderby=e.orderby.concat(t.flat().filter(n=>n).map(u)),this)}limit(t){let{query:e}=this;return arguments.length===0?e.limit:(e.limit=Number.isFinite(t)?t:void 0,this)}offset(t){let{query:e}=this;return arguments.length===0?e.offset:(e.offset=Number.isFinite(t)?t:void 0,this)}get subqueries(){let{query:t,cteFor:e}=this,o=(e?.query||t).with?.reduce((i,{as:a,query:p})=>(i[a]=p,i),{}),s=[];return t.from.forEach(({from:i})=>{if(M(i))s.push(i);else if(o[i.table]){let a=o[i.table];s.push(a)}}),s}toString(){let{with:t,select:e,distinct:n,from:o,sample:s,where:i,groupby:a,having:p,window:d,qualify:y,orderby:A,limit:b,offset:I}=this.query,g=[];if(t.length){let f=t.map(({as:h,query:x})=>`"${h}" AS (${x})`);g.push(`WITH ${f.join(", ")}`)}let it=e.map(({as:f,expr:h})=>k(h,f)&&!h.table?`${h}`:`${h} AS "${f}"`);if(g.push(`SELECT${n?" DISTINCT":""} ${it.join(", ")}`),o.length){let f=o.map(({as:h,from:x})=>{let L=M(x)?`(${x})`:`${x}`;return!h||h===x.table?L:`${L} AS "${h}"`});g.push(`FROM ${f.join(", ")}`)}if(i.length){let f=i.map(String).filter(h=>h).join(" AND ");f&&g.push(`WHERE ${f}`)}if(s){let{rows:f,perc:h,method:x,seed:L}=s,ct=f?`${f} ROWS`:`${h} PERCENT`,at=x?` (${x}${L!=null?`, ${L}`:""})`:"";g.push(`USING SAMPLE ${ct}${at}`)}if(a.length&&g.push(`GROUP BY ${a.join(", ")}`),p.length){let f=p.map(String).filter(h=>h).join(" AND ");f&&g.push(`HAVING ${f}`)}if(d.length){let f=d.map(({as:h,expr:x})=>`"${h}" AS (${x})`);g.push(`WINDOW ${f.join(", ")}`)}if(y.length){let f=y.map(String).filter(h=>h).join(" AND ");f&&g.push(`QUALIFY ${f}`)}return A.length&&g.push(`ORDER BY ${A.join(", ")}`),Number.isFinite(b)&&g.push(`LIMIT ${b}`),Number.isFinite(I)&&g.push(`OFFSET ${I}`),g.join(" ")}},q=class r{constructor(t,e){this.op=t,this.queries=e.map(n=>n.clone()),this.query={orderby:[]},this.cteFor=null}clone(){let t=new r(this.op,this.queries);return t.query={...this.query},t}orderby(...t){let{query:e}=this;return t.length===0?e.orderby:(e.orderby=e.orderby.concat(t.flat().filter(n=>n).map(u)),this)}limit(t){let{query:e}=this;return arguments.length===0?e.limit:(e.limit=Number.isFinite(t)?t:void 0,this)}offset(t){let{query:e}=this;return arguments.length===0?e.offset:(e.offset=Number.isFinite(t)?t:void 0,this)}get subqueries(){let{queries:t,cteFor:e}=this;return e&&t.forEach(n=>n.cteFor=e),t}toString(){let{op:t,queries:e,query:{orderby:n,limit:o,offset:s}}=this,i=[e.join(` ${t} `)];return n.length&&i.push(`ORDER BY ${n.join(", ")}`),Number.isFinite(o)&&i.push(`LIMIT ${o}`),Number.isFinite(s)&&i.push(`OFFSET ${s}`),i.join(" ")}};function M(r){return r instanceof F||r instanceof q}function Be(r){return M(r)&&r.describe}function P(r){return Xe(r)?r.slice(1,-1):r}function Xe(r){return r[0]==='"'&&r[r.length-1]==='"'}var G=r=>r;function ve(){return{apply:G,invert:G,sqlApply:u,sqlInvert:G}}function Qe({base:r=null}={}){if(r==null||r===Math.E)return{apply:Math.log,invert:Math.exp,sqlApply:t=>c`LN(${u(t)})`,sqlInvert:t=>c`EXP(${t})`};if(r===10)return{apply:Math.log10,invert:t=>Math.pow(10,t),sqlApply:t=>c`LOG(${u(t)})`,sqlInvert:t=>c`POW(10, ${t})`};{let t=+r;return{apply:e=>Math.log(e)/Math.log(t),invert:e=>Math.pow(t,e),sqlApply:e=>c`LN(${u(e)}) / LN(${t})`,sqlInvert:e=>c`POW(${t}, ${e})`}}}function Ve({constant:r=1}={}){let t=+r;return{apply:e=>Math.sign(e)*Math.log1p(Math.abs(e)),invert:e=>Math.sign(e)*Math.exp(Math.abs(e)-t),sqlApply:e=>(e=u(e),c`SIGN(${e}) * LN(${t} + ABS(${e}))`),sqlInvert:e=>c`SIGN(${e}) * (EXP(ABS(${e})) - ${t})`}}function ke(){return{apply:r=>Math.sign(r)*Math.sqrt(Math.abs(r)),invert:r=>Math.sign(r)*r*r,sqlApply:r=>(r=u(r),c`SIGN(${r}) * SQRT(ABS(${r}))`),sqlInvert:r=>c`SIGN(${r}) * (${r}) ** 2`}}function He({exponent:r=1}={}){let t=+r;return{apply:e=>Math.sign(e)*Math.pow(Math.abs(e),t),invert:e=>Math.sign(e)*Math.pow(Math.abs(e),1/t),sqlApply:e=>(e=u(e),c`SIGN(${e}) * POW(ABS(${e}), ${t})`),sqlInvert:e=>c`SIGN(${e}) * POW(ABS(${e}), 1/${t})`}}function ot(){return{apply:r=>+r,invert:r=>new Date(r),sqlApply:r=>r instanceof Date?+r:X(u(r)),sqlInvert:G}}var Ke={linear:ve,log:Qe,symlog:Ve,sqrt:ke,pow:He,time:ot,utc:ot};function ze(r){let t=Ke[r.type];return t?{...r,...t(r)}:null}function j(r,t,{replace:e=!1,temp:n=!0,view:o=!1}={}){return"CREATE"+(e?" OR REPLACE ":" ")+(n?"TEMP ":"")+(o?"VIEW":"TABLE")+(e?" ":" IF NOT EXISTS ")+r+" AS "+t}function Je(r){return`INSTALL ${r}; LOAD ${r}`}function st(r,{columns:t=Object.keys(r?.[0]||{})}={}){let e=[];if(Array.isArray(t)?(e=t,t=e.reduce((o,s)=>(o[s]=s,o),{})):t&&(e=Object.keys(t)),!e.length)throw new Error("Can not create table from empty column set.");let n=[];for(let o of r){let s=e.map(i=>`${$(o[i])} AS "${t[i]}"`);n.push(`(SELECT ${s.join(", ")})`)}return n.join(" UNION ALL ")}function U(r,t,e,n={},o={}){let{select:s=["*"],where:i,view:a,temp:p,replace:d,...y}=n,A=or({...o,...y}),b=`${r}('${e}'${A?", "+A:""})`,I=i?` WHERE ${i}`:"",g=`SELECT ${s.join(", ")} FROM ${b}${I}`;return j(t,g,{view:a,temp:p,replace:d})}function Ze(r,t,e){return U("read_csv",r,t,e,{auto_detect:!0,sample_size:-1})}function tr(r,t,e){return U("read_json",r,t,e,{auto_detect:!0,json_format:"auto"})}function er(r,t,e){return U("read_parquet",r,t,e)}function rr(r,t,e={}){let{options:n,...o}=e;if(n){let s=Array.isArray(n)?n.join(", "):typeof n=="string"?n:Object.entries(n).map(([i,a])=>`${i}=${a}`).join(", ");Object.assign(o,{open_options:s.toUpperCase()})}return U("st_read",r,t,o)}function nr(r,t,e={}){let{select:n=["*"],...o}=e,s=st(t),i=n.length===1&&n[0]==="*"?s:`SELECT ${n} FROM ${s}`;return j(r,i,o)}function or(r){return Object.entries(r).map(([t,e])=>`${t}=${Q(e)}`).join(", ")}function Q(r){switch(typeof r){case"boolean":return String(r);case"string":return`'${r}'`;case"undefined":case"object":return r==null?"NULL":Array.isArray(r)?"["+r.map(t=>Q(t)).join(", ")+"]":"{"+Object.entries(r).map(([t,e])=>`'${t}': ${Q(e)}`).join(", ")+"}";default:return r}}export{F as Query,S as Ref,zt as agg,ut as all,mt as and,De as argmax,Oe as argmin,Me as arrayAgg,u as asColumn,O as asRelation,ee as avg,B as cast,_e as castDouble,Pe as castInteger,v as centroid,We as centroidX,Ye as centroidY,K as column,Ot as contains,$e as corr,te as count,Ee as covarPop,j as create,Xt as cume_dist,je as dateDay,Fe as dateMonth,Ge as dateMonthDay,Yt as dense_rank,ft as desc,ge as entropy,X as epoch_ms,yt as eq,Ie as first,kt as first_value,Ue as geojson,wt as gt,Tt as gte,bt as isBetween,Be as isDescribeQuery,Rt as isDistinct,Gt as isFinite,jt as isInfinite,Ft as isNaN,It as isNotBetween,qt as isNotDistinct,Et as isNotNull,$t as isNull,T as isParamLike,M as isQuery,_ as isSQLExpression,me as kurtosis,Qt as lag,Le as last,Ht as last_value,Vt as lead,Pt as length,ht as literal,$ as literalToSQL,Ze as loadCSV,Je as loadExtension,tr as loadJSON,nr as loadObjects,er as loadParquet,rr as loadSpatial,Mt as lower,Nt as lt,At as lte,ne as mad,oe as max,re as mean,ae as median,se as min,le as mode,St as neq,xt as not,Kt as nth_value,vt as ntile,gt as or,Bt as percent_rank,Dt as prefix,ce as product,ue as quantile,Wt as rank,Lt as regexp_matches,qe as regrAvgX,be as regrAvgY,Ne as regrCount,ye as regrIntercept,we as regrR2,Te as regrSXX,Re as regrSXY,Ae as regrSYY,Se as regrSlope,H as relation,Ut as row_number,ze as scaleTransform,he as skewness,c as sql,fe as stddev,xe as stddevPop,Ce as stringAgg,Ct as suffix,ie as sum,lt as toSQL,_t as upper,de as varPop,pe as variance,rt as x,nt as y};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uwdata/mosaic-sql",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "SQL query construction and analysis.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"sql",
|
|
@@ -21,9 +21,9 @@
|
|
|
21
21
|
"scripts": {
|
|
22
22
|
"prebuild": "rimraf dist && mkdir dist",
|
|
23
23
|
"build": "node ../../esbuild.js mosaic-sql",
|
|
24
|
-
"lint": "eslint src test
|
|
24
|
+
"lint": "eslint src test",
|
|
25
25
|
"test": "mocha 'test/**/*-test.js'",
|
|
26
26
|
"prepublishOnly": "npm run test && npm run lint && npm run build"
|
|
27
27
|
},
|
|
28
|
-
"gitHead": "
|
|
28
|
+
"gitHead": "a24b4c9f7dfa1c38c6af96ec17e075326c1af9b0"
|
|
29
29
|
}
|
package/src/Query.js
CHANGED
|
@@ -53,6 +53,7 @@ export class Query {
|
|
|
53
53
|
qualify: [],
|
|
54
54
|
orderby: []
|
|
55
55
|
};
|
|
56
|
+
this.cteFor = null;
|
|
56
57
|
}
|
|
57
58
|
|
|
58
59
|
clone() {
|
|
@@ -61,9 +62,18 @@ export class Query {
|
|
|
61
62
|
return q;
|
|
62
63
|
}
|
|
63
64
|
|
|
65
|
+
/**
|
|
66
|
+
* Retrieve current WITH common table expressions (CTEs).
|
|
67
|
+
* @returns {any[]}
|
|
68
|
+
*//**
|
|
69
|
+
* Add WITH common table expressions (CTEs).
|
|
70
|
+
* @param {...any} expr Expressions to add.
|
|
71
|
+
* @returns {this}
|
|
72
|
+
*/
|
|
64
73
|
with(...expr) {
|
|
65
74
|
const { query } = this;
|
|
66
75
|
if (expr.length === 0) {
|
|
76
|
+
// @ts-ignore
|
|
67
77
|
return query.with;
|
|
68
78
|
} else {
|
|
69
79
|
const list = [];
|
|
@@ -88,9 +98,18 @@ export class Query {
|
|
|
88
98
|
}
|
|
89
99
|
}
|
|
90
100
|
|
|
101
|
+
/**
|
|
102
|
+
* Retrieve current SELECT expressions.
|
|
103
|
+
* @returns {any[]}
|
|
104
|
+
*//**
|
|
105
|
+
* Add SELECT expressions.
|
|
106
|
+
* @param {...any} expr Expressions to add.
|
|
107
|
+
* @returns {this}
|
|
108
|
+
*/
|
|
91
109
|
select(...expr) {
|
|
92
110
|
const { query } = this;
|
|
93
111
|
if (expr.length === 0) {
|
|
112
|
+
// @ts-ignore
|
|
94
113
|
return query.select;
|
|
95
114
|
} else {
|
|
96
115
|
const list = [];
|
|
@@ -124,9 +143,18 @@ export class Query {
|
|
|
124
143
|
return this;
|
|
125
144
|
}
|
|
126
145
|
|
|
146
|
+
/**
|
|
147
|
+
* Retrieve current from expressions.
|
|
148
|
+
* @returns {any[]}
|
|
149
|
+
*//**
|
|
150
|
+
* Provide table from expressions.
|
|
151
|
+
* @param {...any} expr
|
|
152
|
+
* @returns {this}
|
|
153
|
+
*/
|
|
127
154
|
from(...expr) {
|
|
128
155
|
const { query } = this;
|
|
129
156
|
if (expr.length === 0) {
|
|
157
|
+
// @ts-ignore
|
|
130
158
|
return query.from;
|
|
131
159
|
} else {
|
|
132
160
|
const list = [];
|
|
@@ -157,9 +185,19 @@ export class Query {
|
|
|
157
185
|
return this.from(...expr);
|
|
158
186
|
}
|
|
159
187
|
|
|
188
|
+
/**
|
|
189
|
+
* Retrieve current SAMPLE settings.
|
|
190
|
+
* @returns {any[]}
|
|
191
|
+
*//**
|
|
192
|
+
* Set SAMPLE settings.
|
|
193
|
+
* @param {number|object} value The percentage or number of rows to sample.
|
|
194
|
+
* @param {string} [method] The sampling method to use.
|
|
195
|
+
* @returns {this}
|
|
196
|
+
*/
|
|
160
197
|
sample(value, method) {
|
|
161
198
|
const { query } = this;
|
|
162
199
|
if (arguments.length === 0) {
|
|
200
|
+
// @ts-ignore
|
|
163
201
|
return query.sample;
|
|
164
202
|
} else {
|
|
165
203
|
let spec = value;
|
|
@@ -173,9 +211,18 @@ export class Query {
|
|
|
173
211
|
}
|
|
174
212
|
}
|
|
175
213
|
|
|
214
|
+
/**
|
|
215
|
+
* Retrieve current WHERE expressions.
|
|
216
|
+
* @returns {any[]}
|
|
217
|
+
*//**
|
|
218
|
+
* Add WHERE expressions.
|
|
219
|
+
* @param {...any} expr Expressions to add.
|
|
220
|
+
* @returns {this}
|
|
221
|
+
*/
|
|
176
222
|
where(...expr) {
|
|
177
223
|
const { query } = this;
|
|
178
224
|
if (expr.length === 0) {
|
|
225
|
+
// @ts-ignore
|
|
179
226
|
return query.where;
|
|
180
227
|
} else {
|
|
181
228
|
query.where = query.where.concat(
|
|
@@ -190,9 +237,18 @@ export class Query {
|
|
|
190
237
|
return this.where(...expr);
|
|
191
238
|
}
|
|
192
239
|
|
|
240
|
+
/**
|
|
241
|
+
* Retrieve current GROUP BY expressions.
|
|
242
|
+
* @returns {any[]}
|
|
243
|
+
*//**
|
|
244
|
+
* Add GROUP BY expressions.
|
|
245
|
+
* @param {...any} expr Expressions to add.
|
|
246
|
+
* @returns {this}
|
|
247
|
+
*/
|
|
193
248
|
groupby(...expr) {
|
|
194
249
|
const { query } = this;
|
|
195
250
|
if (expr.length === 0) {
|
|
251
|
+
// @ts-ignore
|
|
196
252
|
return query.groupby;
|
|
197
253
|
} else {
|
|
198
254
|
query.groupby = query.groupby.concat(
|
|
@@ -207,9 +263,18 @@ export class Query {
|
|
|
207
263
|
return this.groupby(...expr);
|
|
208
264
|
}
|
|
209
265
|
|
|
266
|
+
/**
|
|
267
|
+
* Retrieve current HAVING expressions.
|
|
268
|
+
* @returns {any[]}
|
|
269
|
+
*//**
|
|
270
|
+
* Add HAVING expressions.
|
|
271
|
+
* @param {...any} expr Expressions to add.
|
|
272
|
+
* @returns {this}
|
|
273
|
+
*/
|
|
210
274
|
having(...expr) {
|
|
211
275
|
const { query } = this;
|
|
212
276
|
if (expr.length === 0) {
|
|
277
|
+
// @ts-ignore
|
|
213
278
|
return query.having;
|
|
214
279
|
} else {
|
|
215
280
|
query.having = query.having.concat(
|
|
@@ -219,9 +284,18 @@ export class Query {
|
|
|
219
284
|
}
|
|
220
285
|
}
|
|
221
286
|
|
|
287
|
+
/**
|
|
288
|
+
* Retrieve current WINDOW definitions.
|
|
289
|
+
* @returns {any[]}
|
|
290
|
+
*//**
|
|
291
|
+
* Add WINDOW definitions.
|
|
292
|
+
* @param {...any} expr Expressions to add.
|
|
293
|
+
* @returns {this}
|
|
294
|
+
*/
|
|
222
295
|
window(...expr) {
|
|
223
296
|
const { query } = this;
|
|
224
297
|
if (expr.length === 0) {
|
|
298
|
+
// @ts-ignore
|
|
225
299
|
return query.window;
|
|
226
300
|
} else {
|
|
227
301
|
const list = [];
|
|
@@ -239,9 +313,18 @@ export class Query {
|
|
|
239
313
|
}
|
|
240
314
|
}
|
|
241
315
|
|
|
316
|
+
/**
|
|
317
|
+
* Retrieve current QUALIFY expressions.
|
|
318
|
+
* @returns {any[]}
|
|
319
|
+
*//**
|
|
320
|
+
* Add QUALIFY expressions.
|
|
321
|
+
* @param {...any} expr Expressions to add.
|
|
322
|
+
* @returns {this}
|
|
323
|
+
*/
|
|
242
324
|
qualify(...expr) {
|
|
243
325
|
const { query } = this;
|
|
244
326
|
if (expr.length === 0) {
|
|
327
|
+
// @ts-ignore
|
|
245
328
|
return query.qualify;
|
|
246
329
|
} else {
|
|
247
330
|
query.qualify = query.qualify.concat(
|
|
@@ -251,9 +334,18 @@ export class Query {
|
|
|
251
334
|
}
|
|
252
335
|
}
|
|
253
336
|
|
|
337
|
+
/**
|
|
338
|
+
* Retrieve current ORDER BY expressions.
|
|
339
|
+
* @returns {any[]}
|
|
340
|
+
*//**
|
|
341
|
+
* Add ORDER BY expressions.
|
|
342
|
+
* @param {...any} expr Expressions to add.
|
|
343
|
+
* @returns {this}
|
|
344
|
+
*/
|
|
254
345
|
orderby(...expr) {
|
|
255
346
|
const { query } = this;
|
|
256
347
|
if (expr.length === 0) {
|
|
348
|
+
// @ts-ignore
|
|
257
349
|
return query.orderby;
|
|
258
350
|
} else {
|
|
259
351
|
query.orderby = query.orderby.concat(
|
|
@@ -263,6 +355,14 @@ export class Query {
|
|
|
263
355
|
}
|
|
264
356
|
}
|
|
265
357
|
|
|
358
|
+
/**
|
|
359
|
+
* Retrieve current LIMIT value.
|
|
360
|
+
* @returns {number|null}
|
|
361
|
+
*//**
|
|
362
|
+
* Set the query result LIMIT.
|
|
363
|
+
* @param {number} value The limit value.
|
|
364
|
+
* @returns {this}
|
|
365
|
+
*/
|
|
266
366
|
limit(value) {
|
|
267
367
|
const { query } = this;
|
|
268
368
|
if (arguments.length === 0) {
|
|
@@ -273,6 +373,14 @@ export class Query {
|
|
|
273
373
|
}
|
|
274
374
|
}
|
|
275
375
|
|
|
376
|
+
/**
|
|
377
|
+
* Retrieve current OFFSET value.
|
|
378
|
+
* @returns {number|null}
|
|
379
|
+
*//**
|
|
380
|
+
* Set the query result OFFSET.
|
|
381
|
+
* @param {number} value The offset value.
|
|
382
|
+
* @returns {this}
|
|
383
|
+
*/
|
|
276
384
|
offset(value) {
|
|
277
385
|
const { query } = this;
|
|
278
386
|
if (arguments.length === 0) {
|
|
@@ -391,6 +499,7 @@ export class SetOperation {
|
|
|
391
499
|
this.op = op;
|
|
392
500
|
this.queries = queries.map(q => q.clone());
|
|
393
501
|
this.query = { orderby: [] };
|
|
502
|
+
this.cteFor = null;
|
|
394
503
|
}
|
|
395
504
|
|
|
396
505
|
clone() {
|
package/src/aggregates.js
CHANGED
|
@@ -19,11 +19,24 @@ export function agg(strings, ...exprs) {
|
|
|
19
19
|
* rather than instantiate this class.
|
|
20
20
|
*/
|
|
21
21
|
export class AggregateFunction extends SQLExpression {
|
|
22
|
+
/**
|
|
23
|
+
* Create a new AggregateFunction instance.
|
|
24
|
+
* @param {*} op The aggregate operation.
|
|
25
|
+
* @param {*} [args] The aggregate function arguments.
|
|
26
|
+
* @param {*} [type] The SQL data type to cast to.
|
|
27
|
+
* @param {boolean} [isDistinct] Flag indicating if this is a distinct value aggregate.
|
|
28
|
+
* @param {*} [filter] Filtering expression to apply prior to aggregation.
|
|
29
|
+
*/
|
|
22
30
|
constructor(op, args, type, isDistinct, filter) {
|
|
23
31
|
args = (args || []).map(asColumn);
|
|
24
32
|
const { strings, exprs } = aggExpr(op, args, type, isDistinct, filter);
|
|
25
33
|
const { spans, cols } = parseSQL(strings, exprs);
|
|
26
|
-
super(spans, cols
|
|
34
|
+
super(spans, cols);
|
|
35
|
+
this.aggregate = op;
|
|
36
|
+
this.args = args;
|
|
37
|
+
this.type = type;
|
|
38
|
+
this.isDistinct = isDistinct;
|
|
39
|
+
this.filter = filter;
|
|
27
40
|
}
|
|
28
41
|
|
|
29
42
|
get basis() {
|
|
@@ -37,36 +50,69 @@ export class AggregateFunction extends SQLExpression {
|
|
|
37
50
|
return `${op.toLowerCase()}${tail}`;
|
|
38
51
|
}
|
|
39
52
|
|
|
53
|
+
/**
|
|
54
|
+
* Return a new derived aggregate function over distinct values.
|
|
55
|
+
* @returns {AggregateFunction} A new aggregate function.
|
|
56
|
+
*/
|
|
40
57
|
distinct() {
|
|
41
58
|
const { aggregate: op, args, type, filter } = this;
|
|
42
59
|
return new AggregateFunction(op, args, type, true, filter);
|
|
43
60
|
}
|
|
44
61
|
|
|
62
|
+
/**
|
|
63
|
+
* Return a new derived aggregate function that filters values.
|
|
64
|
+
* @param {*} filter The filter expresion.
|
|
65
|
+
* @returns {AggregateFunction} A new aggregate function.
|
|
66
|
+
*/
|
|
45
67
|
where(filter) {
|
|
46
68
|
const { aggregate: op, args, type, isDistinct } = this;
|
|
47
69
|
return new AggregateFunction(op, args, type, isDistinct, filter);
|
|
48
70
|
}
|
|
49
71
|
|
|
72
|
+
/**
|
|
73
|
+
* Return a new window function over this aggregate.
|
|
74
|
+
* @returns {WindowFunction} A new aggregate function.
|
|
75
|
+
*/
|
|
50
76
|
window() {
|
|
51
77
|
const { aggregate: op, args, type, isDistinct } = this;
|
|
52
78
|
const func = new AggregateFunction(op, args, null, isDistinct);
|
|
53
79
|
return new WindowFunction(op, func, type);
|
|
54
80
|
}
|
|
55
81
|
|
|
82
|
+
/**
|
|
83
|
+
* Return a window function over this aggregate with the given partitioning.
|
|
84
|
+
* @param {*} expr The grouping (partition by) criteria for the window function.
|
|
85
|
+
* @returns {WindowFunction} A new window function.
|
|
86
|
+
*/
|
|
56
87
|
partitionby(...expr) {
|
|
57
88
|
return this.window().partitionby(...expr);
|
|
58
89
|
}
|
|
59
90
|
|
|
91
|
+
/**
|
|
92
|
+
* Return a window function over this aggregate with the given ordering.
|
|
93
|
+
* @param {*} expr The sorting (order by) criteria for the window function.
|
|
94
|
+
* @returns {WindowFunction} A new window function.
|
|
95
|
+
*/
|
|
60
96
|
orderby(...expr) {
|
|
61
97
|
return this.window().orderby(...expr);
|
|
62
98
|
}
|
|
63
99
|
|
|
64
|
-
|
|
65
|
-
|
|
100
|
+
/**
|
|
101
|
+
* Return a window function over this aggregate with the given row frame.
|
|
102
|
+
* @param {(number|null)[] | import('./expression.js').ParamLike} frame The row-based window frame.
|
|
103
|
+
* @returns {WindowFunction} A new window function.
|
|
104
|
+
*/
|
|
105
|
+
rows(frame) {
|
|
106
|
+
return this.window().rows(frame);
|
|
66
107
|
}
|
|
67
108
|
|
|
68
|
-
|
|
69
|
-
|
|
109
|
+
/**
|
|
110
|
+
* Return a window function over this aggregate with the given range frame.
|
|
111
|
+
* @param {(number|null)[] | import('./expression.js').ParamLike} frame The range-based window frame.
|
|
112
|
+
* @returns {WindowFunction} A new window function.
|
|
113
|
+
*/
|
|
114
|
+
range(frame) {
|
|
115
|
+
return this.window().range(frame);
|
|
70
116
|
}
|
|
71
117
|
}
|
|
72
118
|
|
package/src/desc.js
CHANGED
|
@@ -4,8 +4,8 @@ import { asColumn } from './ref.js';
|
|
|
4
4
|
/**
|
|
5
5
|
* Annotate an expression to indicate descending sort order.
|
|
6
6
|
* Null values are ordered last.
|
|
7
|
-
* @param {SQLExpression|string} expr A SQL expression or column name string.
|
|
8
|
-
* @returns {SQLExpression} An expression with descending order.
|
|
7
|
+
* @param {import('./expression.js').SQLExpression|string} expr A SQL expression or column name string.
|
|
8
|
+
* @returns {import('./expression.js').SQLExpression} An expression with descending order.
|
|
9
9
|
*/
|
|
10
10
|
export function desc(expr) {
|
|
11
11
|
const e = asColumn(expr);
|
package/src/expression.js
CHANGED
|
@@ -1,16 +1,25 @@
|
|
|
1
1
|
import { literalToSQL } from './to-sql.js';
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* @typedef {{
|
|
5
|
+
* value: any;
|
|
6
|
+
* addEventListener(type: string, callback: Function): any;
|
|
7
|
+
* column?: string,
|
|
8
|
+
* columns?: string[]
|
|
9
|
+
* }} ParamLike
|
|
10
|
+
*/
|
|
11
|
+
|
|
3
12
|
/**
|
|
4
13
|
* Test if a value is parameter-like. Parameters have addEventListener methods.
|
|
5
14
|
* @param {*} value The value to test.
|
|
6
|
-
* @returns True if the value is param-like, false otherwise.
|
|
15
|
+
* @returns {value is ParamLike} True if the value is param-like, false otherwise.
|
|
7
16
|
*/
|
|
8
17
|
export const isParamLike = value => typeof value?.addEventListener === 'function';
|
|
9
18
|
|
|
10
19
|
/**
|
|
11
20
|
* Test if a value is a SQL expression instance.
|
|
12
21
|
* @param {*} value The value to test.
|
|
13
|
-
* @returns {
|
|
22
|
+
* @returns {value is SQLExpression} True if value is a SQL expression, false otherwise.
|
|
14
23
|
*/
|
|
15
24
|
export function isSQLExpression(value) {
|
|
16
25
|
return value instanceof SQLExpression;
|
|
@@ -24,7 +33,7 @@ export class SQLExpression {
|
|
|
24
33
|
|
|
25
34
|
/**
|
|
26
35
|
* Create a new SQL expression instance.
|
|
27
|
-
* @param {(string|SQLExpression|Ref)[]} parts The parts of the expression.
|
|
36
|
+
* @param {(string | ParamLike | SQLExpression | import('./ref.js').Ref)[]} parts The parts of the expression.
|
|
28
37
|
* @param {string[]} [columns=[]] The column dependencies
|
|
29
38
|
* @param {object} [props] Additional properties for this expression.
|
|
30
39
|
*/
|
|
@@ -35,6 +44,8 @@ export class SQLExpression {
|
|
|
35
44
|
|
|
36
45
|
const params = this._expr.filter(part => isParamLike(part));
|
|
37
46
|
if (params.length > 0) {
|
|
47
|
+
/** @type {ParamLike[]} */
|
|
48
|
+
// @ts-ignore
|
|
38
49
|
this._params = Array.from(new Set(params));
|
|
39
50
|
this._params.forEach(param => {
|
|
40
51
|
param.addEventListener('value', () => update(this, this.map?.get('value')));
|
package/src/load/load.js
CHANGED
|
@@ -38,7 +38,7 @@ export function loadSpatial(tableName, fileName, options = {}) {
|
|
|
38
38
|
: Object.entries(opt)
|
|
39
39
|
.map(([key, value]) => `${key}=${value}`)
|
|
40
40
|
.join(', ');
|
|
41
|
-
rest
|
|
41
|
+
Object.assign(rest, { open_options: open.toUpperCase() });
|
|
42
42
|
}
|
|
43
43
|
// TODO: handle box_2d for spatial_filter_box option
|
|
44
44
|
// TODO: handle wkb_blob for spatial_filter option
|
package/src/load/sql-from.js
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import { literalToSQL } from '../to-sql.js';
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Create a SQL query that embeds the given data for loading.
|
|
5
|
+
* @param {*} data The dataset
|
|
6
|
+
* @param {object} [options] Loading options
|
|
7
|
+
* @param {string[]|object} [options.columns] The columns to include
|
|
8
|
+
* @returns {string} SQL query string to load data
|
|
9
|
+
*/
|
|
3
10
|
export function sqlFrom(data, {
|
|
4
11
|
columns = Object.keys(data?.[0] || {})
|
|
5
12
|
} = {}) {
|
package/src/ref.js
CHANGED
|
@@ -5,7 +5,7 @@ export class Ref {
|
|
|
5
5
|
/**
|
|
6
6
|
* Create a new Ref instance.
|
|
7
7
|
* @param {string|Ref|null} table The table name.
|
|
8
|
-
* @param {string|null} column The column name.
|
|
8
|
+
* @param {string|null} [column] The column name.
|
|
9
9
|
*/
|
|
10
10
|
constructor(table, column) {
|
|
11
11
|
if (table) this.table = String(table);
|
|
@@ -87,11 +87,11 @@ export function relation(name) {
|
|
|
87
87
|
|
|
88
88
|
/**
|
|
89
89
|
* Create a column reference.
|
|
90
|
-
* @param {string}
|
|
91
|
-
* @param {string} column The column name.
|
|
90
|
+
* @param {string} table The table name (optional).
|
|
91
|
+
* @param {string} [column] The column name.
|
|
92
92
|
* @returns {Ref} The generated column reference.
|
|
93
93
|
*/
|
|
94
|
-
export function column(table, column) {
|
|
94
|
+
export function column(table, column = null) {
|
|
95
95
|
if (arguments.length === 1) {
|
|
96
96
|
column = table;
|
|
97
97
|
table = null;
|
package/src/scales.js
CHANGED
package/src/windows.js
CHANGED
|
@@ -9,6 +9,16 @@ import { repeat } from './repeat.js';
|
|
|
9
9
|
* rather than instantiate this class.
|
|
10
10
|
*/
|
|
11
11
|
export class WindowFunction extends SQLExpression {
|
|
12
|
+
/**
|
|
13
|
+
* Create a new WindowFunction instance.
|
|
14
|
+
* @param {string} op The window operation indicator.
|
|
15
|
+
* @param {*} func The window function expression.
|
|
16
|
+
* @param {*} [type] The SQL data type to cast to.
|
|
17
|
+
* @param {string} [name] The window definition name.
|
|
18
|
+
* @param {*} [group] Grouping (partition by) expressions.
|
|
19
|
+
* @param {*} [order] Sorting (order by) expressions.
|
|
20
|
+
* @param {*} [frame] The window frame definition.
|
|
21
|
+
*/
|
|
12
22
|
constructor(op, func, type, name, group = '', order = '', frame = '') {
|
|
13
23
|
// build and parse expression
|
|
14
24
|
let expr;
|
|
@@ -24,7 +34,14 @@ export class WindowFunction extends SQLExpression {
|
|
|
24
34
|
expr = sql`(${expr})::${type}`;
|
|
25
35
|
}
|
|
26
36
|
const { _expr, _deps } = expr;
|
|
27
|
-
super(_expr, _deps
|
|
37
|
+
super(_expr, _deps);
|
|
38
|
+
this.window = op;
|
|
39
|
+
this.func = func;
|
|
40
|
+
this.type = type;
|
|
41
|
+
this.name = name;
|
|
42
|
+
this.group = group;
|
|
43
|
+
this.order = order;
|
|
44
|
+
this.frame = frame;
|
|
28
45
|
}
|
|
29
46
|
|
|
30
47
|
get basis() {
|
|
@@ -36,11 +53,21 @@ export class WindowFunction extends SQLExpression {
|
|
|
36
53
|
return func.label ?? func.toString();
|
|
37
54
|
}
|
|
38
55
|
|
|
56
|
+
/**
|
|
57
|
+
* Return an updated window function over a named window definition.
|
|
58
|
+
* @param {string} name The window definition name.
|
|
59
|
+
* @returns {WindowFunction} A new window function.
|
|
60
|
+
*/
|
|
39
61
|
over(name) {
|
|
40
62
|
const { window: op, func, type, group, order, frame } = this;
|
|
41
63
|
return new WindowFunction(op, func, type, name, group, order, frame);
|
|
42
64
|
}
|
|
43
65
|
|
|
66
|
+
/**
|
|
67
|
+
* Return an updated window function with the given partitioning.
|
|
68
|
+
* @param {*} expr The grouping (partition by) criteria for the window function.
|
|
69
|
+
* @returns {WindowFunction} A new window function.
|
|
70
|
+
*/
|
|
44
71
|
partitionby(...expr) {
|
|
45
72
|
const exprs = expr.flat().filter(x => x).map(asColumn);
|
|
46
73
|
const group = sql(
|
|
@@ -51,6 +78,11 @@ export class WindowFunction extends SQLExpression {
|
|
|
51
78
|
return new WindowFunction(op, func, type, name, group, order, frame);
|
|
52
79
|
}
|
|
53
80
|
|
|
81
|
+
/**
|
|
82
|
+
* Return an updated window function with the given ordering.
|
|
83
|
+
* @param {*} expr The sorting (order by) criteria for the window function.
|
|
84
|
+
* @returns {WindowFunction} A new window function.
|
|
85
|
+
*/
|
|
54
86
|
orderby(...expr) {
|
|
55
87
|
const exprs = expr.flat().filter(x => x).map(asColumn);
|
|
56
88
|
const order = sql(
|
|
@@ -61,12 +93,22 @@ export class WindowFunction extends SQLExpression {
|
|
|
61
93
|
return new WindowFunction(op, func, type, name, group, order, frame);
|
|
62
94
|
}
|
|
63
95
|
|
|
96
|
+
/**
|
|
97
|
+
* Return an updated window function with the given rows frame.
|
|
98
|
+
* @param {(number|null)[] | import('./expression.js').ParamLike} expr The row-based window frame.
|
|
99
|
+
* @returns {WindowFunction} A new window function.
|
|
100
|
+
*/
|
|
64
101
|
rows(expr) {
|
|
65
102
|
const frame = windowFrame('ROWS', expr);
|
|
66
103
|
const { window: op, func, type, name, group, order } = this;
|
|
67
104
|
return new WindowFunction(op, func, type, name, group, order, frame);
|
|
68
105
|
}
|
|
69
106
|
|
|
107
|
+
/**
|
|
108
|
+
* Return an updated window function with the given range frame.
|
|
109
|
+
* @param {(number|null)[] | import('./expression.js').ParamLike} expr The range-based window frame.
|
|
110
|
+
* @returns {WindowFunction} A new window function.
|
|
111
|
+
*/
|
|
70
112
|
range(expr) {
|
|
71
113
|
const frame = windowFrame('RANGE', expr);
|
|
72
114
|
const { window: op, func, type, name, group, order } = this;
|