@uwdata/mosaic-sql 0.12.2 → 0.14.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.
Files changed (82) hide show
  1. package/README.md +1 -1
  2. package/dist/types/ast/aggregate.d.ts +5 -4
  3. package/dist/types/ast/case.d.ts +6 -7
  4. package/dist/types/ast/column-param.d.ts +7 -7
  5. package/dist/types/ast/column-ref.d.ts +7 -6
  6. package/dist/types/ast/param.d.ts +5 -4
  7. package/dist/types/ast/query.d.ts +94 -42
  8. package/dist/types/ast/window.d.ts +15 -12
  9. package/dist/types/ast/with.d.ts +11 -1
  10. package/dist/types/functions/aggregate.d.ts +93 -86
  11. package/dist/types/functions/case.d.ts +6 -8
  12. package/dist/types/functions/column.d.ts +5 -3
  13. package/dist/types/functions/cte.d.ts +13 -0
  14. package/dist/types/functions/datetime.d.ts +12 -11
  15. package/dist/types/functions/numeric.d.ts +48 -46
  16. package/dist/types/functions/operators.d.ts +80 -78
  17. package/dist/types/functions/order-by.d.ts +5 -4
  18. package/dist/types/functions/spatial.d.ts +14 -13
  19. package/dist/types/functions/sql-template-tag.d.ts +4 -5
  20. package/dist/types/functions/string.d.ts +22 -20
  21. package/dist/types/functions/util.d.ts +8 -0
  22. package/dist/types/functions/window.d.ts +18 -16
  23. package/dist/types/index.d.ts +5 -1
  24. package/dist/types/transforms/bin-1d.d.ts +3 -2
  25. package/dist/types/transforms/bin-2d.d.ts +6 -5
  26. package/dist/types/transforms/bin-date.d.ts +44 -0
  27. package/dist/types/transforms/bin-histogram.d.ts +51 -0
  28. package/dist/types/transforms/bin-linear-1d.d.ts +6 -4
  29. package/dist/types/transforms/bin-linear-2d.d.ts +6 -5
  30. package/dist/types/transforms/line-density.d.ts +5 -4
  31. package/dist/types/transforms/m4.d.ts +7 -4
  32. package/dist/types/transforms/util/bin-step.d.ts +61 -0
  33. package/dist/types/transforms/util/time-interval.d.ts +13 -0
  34. package/dist/types/types.d.ts +4 -1
  35. package/dist/types/util/ast.d.ts +6 -5
  36. package/dist/types/util/function.d.ts +6 -4
  37. package/dist/types/util/type-check.d.ts +6 -2
  38. package/dist/types/visit/visitors.d.ts +3 -2
  39. package/dist/types/visit/walk.d.ts +7 -4
  40. package/package.json +9 -9
  41. package/src/ast/aggregate.js +5 -2
  42. package/src/ast/case.js +6 -5
  43. package/src/ast/column-param.js +7 -5
  44. package/src/ast/column-ref.js +6 -3
  45. package/src/ast/literal.js +1 -1
  46. package/src/ast/param.js +5 -2
  47. package/src/ast/query.js +120 -47
  48. package/src/ast/window.js +10 -6
  49. package/src/ast/with.js +16 -2
  50. package/src/functions/aggregate.js +63 -51
  51. package/src/functions/case.js +7 -7
  52. package/src/functions/column.js +6 -2
  53. package/src/functions/cte.js +16 -0
  54. package/src/functions/datetime.js +9 -6
  55. package/src/functions/numeric.js +35 -31
  56. package/src/functions/operators.js +53 -50
  57. package/src/functions/order-by.js +5 -2
  58. package/src/functions/spatial.js +10 -7
  59. package/src/functions/sql-template-tag.js +5 -5
  60. package/src/functions/string.js +16 -13
  61. package/src/functions/util.js +14 -0
  62. package/src/functions/window.js +13 -10
  63. package/src/index.js +5 -1
  64. package/src/transforms/bin-1d.js +4 -1
  65. package/src/transforms/bin-2d.js +7 -4
  66. package/src/transforms/bin-date.js +37 -0
  67. package/src/transforms/bin-histogram.js +52 -0
  68. package/src/transforms/bin-linear-1d.js +7 -3
  69. package/src/transforms/bin-linear-2d.js +12 -8
  70. package/src/transforms/line-density.js +7 -3
  71. package/src/transforms/m4.js +19 -6
  72. package/src/transforms/util/bin-step.js +79 -0
  73. package/src/transforms/util/time-interval.js +97 -0
  74. package/src/types.ts +17 -1
  75. package/src/util/ast.js +6 -3
  76. package/src/util/function.js +6 -2
  77. package/src/util/type-check.js +5 -1
  78. package/src/visit/visitors.js +6 -2
  79. package/src/visit/walk.js +8 -3
  80. package/vitest.config.ts +3 -0
  81. package/dist/mosaic-sql.js +0 -2610
  82. package/dist/mosaic-sql.min.js +0 -1
package/src/ast/query.js CHANGED
@@ -1,3 +1,7 @@
1
+ /**
2
+ * @import { FilterExpr, FromExpr, GroupByExpr, OrderByExpr, SelectExpr, WithExpr } from '../types.js'
3
+ * @import { SampleMethod } from './sample.js'
4
+ */
1
5
  import { DESCRIBE_QUERY, SELECT_QUERY, SET_OPERATION } from '../constants.js';
2
6
  import { asNode, asTableRef, asVerbatim } from '../util/ast.js';
3
7
  import { exprList } from '../util/function.js';
@@ -40,9 +44,18 @@ export function isDescribeQuery(value) {
40
44
  }
41
45
 
42
46
  export class Query extends ExprNode {
47
+ /**
48
+ * Create a new WITH clause with the given CTE queries.
49
+ * @param {...WithExpr} expr The WITH CTE queries.
50
+ * @returns {WithClause}
51
+ */
52
+ static with(...expr) {
53
+ return new WithClause(...expr);
54
+ }
55
+
43
56
  /**
44
57
  * Create a new select query with the given SELECT expressions.
45
- * @param {...import('../types.js').SelectExpr} expr The SELECT expressions.
58
+ * @param {...SelectExpr} expr The SELECT expressions.
46
59
  * @returns {SelectQuery}
47
60
  */
48
61
  static select(...expr) {
@@ -51,22 +64,13 @@ export class Query extends ExprNode {
51
64
 
52
65
  /**
53
66
  * Create a new select query with the given FROM expressions.
54
- * @param {...import('../types.js').FromExpr} expr The FROM expressions.
67
+ * @param {...FromExpr} expr The FROM expressions.
55
68
  * @returns {SelectQuery}
56
69
  */
57
70
  static from(...expr) {
58
71
  return new SelectQuery().from(...expr);
59
72
  }
60
73
 
61
- /**
62
- * Create a new select query with the given WITH CTE queries.
63
- * @param {...import('../types.js').WithExpr} expr The WITH CTE queries.
64
- * @returns {SelectQuery}
65
- */
66
- static with(...expr) {
67
- return new SelectQuery().with(...expr);
68
- }
69
-
70
74
  /**
71
75
  * Create a new UNION set operation over the given queries.
72
76
  * @param {...Query} queries The queries.
@@ -117,6 +121,8 @@ export class Query extends ExprNode {
117
121
  */
118
122
  constructor(type) {
119
123
  super(type);
124
+ /** @type {WithClauseNode[]} */
125
+ this._with = [];
120
126
  /** @type {ExprNode[]} */
121
127
  this._orderby = [];
122
128
  /** @type {number} */
@@ -143,9 +149,30 @@ export class Query extends ExprNode {
143
149
  return this;
144
150
  }
145
151
 
152
+ /**
153
+ * Add WITH common table expressions (CTEs).
154
+ * @param {...WithExpr} expr Expressions to add.
155
+ * @returns {this}
156
+ */
157
+ with(...expr) {
158
+ /** @type {WithClauseNode[]} */
159
+ const list = [];
160
+ const add = (name, q) => {
161
+ const query = q.clone();
162
+ query.cteFor = this;
163
+ list.push(new WithClauseNode(name, query));
164
+ };
165
+ expr.flat().forEach(e => {
166
+ if (e instanceof WithClauseNode) list.push(e);
167
+ else if (e != null) for (const name in e) add(name, e[name]);
168
+ });
169
+ this._with = this._with.concat(list);
170
+ return this;
171
+ }
172
+
146
173
  /**
147
174
  * Add ORDER BY expressions.
148
- * @param {...import('../types.js').OrderByExpr} expr Expressions to add.
175
+ * @param {...OrderByExpr} expr Expressions to add.
149
176
  * @returns
150
177
  */
151
178
  orderby(...expr) {
@@ -180,8 +207,6 @@ export class SelectQuery extends Query {
180
207
  */
181
208
  constructor() {
182
209
  super(SELECT_QUERY);
183
- /** @type {WithClauseNode[]} */
184
- this._with = [];
185
210
  /** @type {SelectClauseNode[]} */
186
211
  this._select = [];
187
212
  /** @type {FromClauseNode[]} */
@@ -232,29 +257,9 @@ export class SelectQuery extends Query {
232
257
  return Object.assign(new SelectQuery(), this);
233
258
  }
234
259
 
235
- /**
236
- * Add WITH common table expressions (CTEs).
237
- * @param {...import('../types.js').WithExpr} expr Expressions to add.
238
- * @returns {this}
239
- */
240
- with(...expr) {
241
- /** @type {WithClauseNode[]} */
242
- const list = [];
243
- const add = (name, q) => {
244
- const query = q.clone();
245
- query.cteFor = this;
246
- list.push(new WithClauseNode(name, query));
247
- };
248
- expr.flat().forEach(e => {
249
- if (e != null) for (const name in e) add(name, e[name]);
250
- });
251
- this._with = this._with.concat(list);
252
- return this;
253
- }
254
-
255
260
  /**
256
261
  * Add SELECT expressions.
257
- * @param {...import('../types.js').SelectExpr} expr Expressions to add.
262
+ * @param {...SelectExpr} expr Expressions to add.
258
263
  * @returns {this}
259
264
  */
260
265
  select(...expr) {
@@ -280,7 +285,7 @@ export class SelectQuery extends Query {
280
285
 
281
286
  /**
282
287
  * Set SELECT expressions, replacing any prior expressions.
283
- * @param {...import('../types.js').SelectExpr} expr Expressions to add.
288
+ * @param {...SelectExpr} expr Expressions to add.
284
289
  * @returns {this}
285
290
  */
286
291
  setSelect(...expr) {
@@ -300,7 +305,7 @@ export class SelectQuery extends Query {
300
305
 
301
306
  /**
302
307
  * Add table FROM expressions.
303
- * @param {...import('../types.js').FromExpr} expr Expressions to add.
308
+ * @param {...FromExpr} expr Expressions to add.
304
309
  * @returns {this}
305
310
  */
306
311
  from(...expr) {
@@ -320,7 +325,7 @@ export class SelectQuery extends Query {
320
325
 
321
326
  /**
322
327
  * Set FROM expressions, replacing any prior expressions.
323
- * @param {...import('../types.js').FromExpr} expr Expressions to add.
328
+ * @param {...FromExpr} expr Expressions to add.
324
329
  * @returns {this}
325
330
  */
326
331
  setFrom(...expr) {
@@ -332,7 +337,7 @@ export class SelectQuery extends Query {
332
337
  * Set SAMPLE settings.
333
338
  * @param {number | SampleClauseNode} value Either a sample clause node
334
339
  * or the sample size as either a row count or percentage.
335
- * @param {import('./sample.js').SampleMethod} [method] The sampling method
340
+ * @param {SampleMethod} [method] The sampling method
336
341
  * to use.
337
342
  * @param {number} [seed] The random seed.
338
343
  * @returns {this}
@@ -352,7 +357,7 @@ export class SelectQuery extends Query {
352
357
 
353
358
  /**
354
359
  * Add WHERE expressions.
355
- * @param {...import('../types.js').FilterExpr} expr Expressions to add.
360
+ * @param {...FilterExpr} expr Expressions to add.
356
361
  * @returns {this}
357
362
  */
358
363
  where(...expr) {
@@ -362,7 +367,7 @@ export class SelectQuery extends Query {
362
367
 
363
368
  /**
364
369
  * Set WHERE expressions, replacing any prior expressions.
365
- * @param {...import('../types.js').FilterExpr} expr Expressions to add.
370
+ * @param {...FilterExpr} expr Expressions to add.
366
371
  * @returns {this}
367
372
  */
368
373
  setWhere(...expr) {
@@ -372,7 +377,7 @@ export class SelectQuery extends Query {
372
377
 
373
378
  /**
374
379
  * Add GROUP BY expressions.
375
- * @param {...import('../types.js').GroupByExpr} expr Expressions to add.
380
+ * @param {...GroupByExpr} expr Expressions to add.
376
381
  * @returns {this}
377
382
  */
378
383
  groupby(...expr) {
@@ -382,7 +387,7 @@ export class SelectQuery extends Query {
382
387
 
383
388
  /**
384
389
  * Set GROUP BY expressions, replacing any prior expressions.
385
- * @param {...import('../types.js').GroupByExpr} expr Expressions to add.
390
+ * @param {...GroupByExpr} expr Expressions to add.
386
391
  * @returns {this}
387
392
  */
388
393
  setGroupby(...expr) {
@@ -392,7 +397,7 @@ export class SelectQuery extends Query {
392
397
 
393
398
  /**
394
399
  * Add HAVING expressions.
395
- * @param {...import('../types.js').FilterExpr} expr Expressions to add.
400
+ * @param {...FilterExpr} expr Expressions to add.
396
401
  * @returns {this}
397
402
  */
398
403
  having(...expr) {
@@ -418,7 +423,7 @@ export class SelectQuery extends Query {
418
423
 
419
424
  /**
420
425
  * Add QUALIFY expressions.
421
- * @param {...import('../types.js').FilterExpr} expr Expressions to add.
426
+ * @param {...FilterExpr} expr Expressions to add.
422
427
  * @returns {this}
423
428
  */
424
429
  qualify(...expr) {
@@ -559,10 +564,14 @@ export class SetOperation extends Query {
559
564
  * @returns {string}
560
565
  */
561
566
  toString() {
562
- const { op, queries, _orderby, _limit, _offset } = this;
567
+ const { op, queries, _with, _orderby, _limit, _offset } = this;
568
+ const sql = [];
569
+
570
+ // WITH
571
+ if (_with.length) sql.push(`WITH ${_with.join(', ')}`);
563
572
 
564
573
  // SUBQUERIES
565
- const sql = [ queries.join(` ${op} `) ];
574
+ sql.push(queries.join(` ${op} `));
566
575
 
567
576
  // ORDER BY
568
577
  if (_orderby.length) sql.push(`ORDER BY ${_orderby.join(', ')}`);
@@ -576,3 +585,67 @@ export class SetOperation extends Query {
576
585
  return sql.join(' ');
577
586
  }
578
587
  }
588
+
589
+ class WithClause {
590
+ /**
591
+ * Instantiate a new WITH clause instance.
592
+ * @param {...WithExpr} expr The WITH CTE queries.
593
+ */
594
+ constructor(...expr) {
595
+ this._with = expr;
596
+ }
597
+
598
+ /**
599
+ * Create a new select query with the given SELECT expressions.
600
+ * @param {...SelectExpr} expr The SELECT expressions.
601
+ * @returns {SelectQuery}
602
+ */
603
+ select(...expr) {
604
+ return Query.select(...expr).with(...this._with);
605
+ }
606
+
607
+ /**
608
+ * Create a new select query with the given FROM expressions.
609
+ * @param {...FromExpr} expr The FROM expressions.
610
+ * @returns {SelectQuery}
611
+ */
612
+ from(...expr) {
613
+ return Query.from(...expr).with(...this._with);
614
+ }
615
+
616
+ /**
617
+ * Create a new UNION set operation over the given queries.
618
+ * @param {...Query} queries The queries.
619
+ * @returns {SetOperation}
620
+ */
621
+ union(...queries) {
622
+ return Query.union(...queries).with(...this._with);
623
+ }
624
+
625
+ /**
626
+ * Create a new UNION ALL set operation over the given queries.
627
+ * @param {...Query} queries The queries.
628
+ * @returns {SetOperation}
629
+ */
630
+ unionAll(...queries) {
631
+ return Query.unionAll(...queries).with(...this._with);
632
+ }
633
+
634
+ /**
635
+ * Create a new INTERSECT set operation over the given queries.
636
+ * @param {...Query} queries The queries.
637
+ * @returns {SetOperation}
638
+ */
639
+ intersect(...queries) {
640
+ return Query.intersect(...queries).with(...this._with);
641
+ }
642
+
643
+ /**
644
+ * Create a new EXCEPT set operation over the given queries.
645
+ * @param {...Query} queries The queries.
646
+ * @returns {SetOperation}
647
+ */
648
+ except(...queries) {
649
+ return Query.except(...queries).with(...this._with);
650
+ }
651
+ }
package/src/ast/window.js CHANGED
@@ -1,3 +1,7 @@
1
+ /**
2
+ * @import { ExprVarArgs, WindowFunctionName } from '../types.js'
3
+ * @import { ParamLike } from '../types.js'
4
+ */
1
5
  import { WINDOW, WINDOW_CLAUSE, WINDOW_DEF, WINDOW_FRAME } from '../constants.js';
2
6
  import { exprList } from '../util/function.js';
3
7
  import { quoteIdentifier } from '../util/string.js';
@@ -8,7 +12,7 @@ import { ExprNode, isNode, SQLNode } from './node.js';
8
12
  import { ParamNode } from './param.js';
9
13
 
10
14
  /**
11
- * @typedef {[any, any] | import('../types.js').ParamLike} FrameExtent
15
+ * @typedef {[any, any] | ParamLike} FrameExtent
12
16
  */
13
17
 
14
18
  export class WindowClauseNode extends SQLNode {
@@ -69,7 +73,7 @@ export class WindowNode extends ExprNode {
69
73
 
70
74
  /**
71
75
  * Return an updated window with the given partitions.
72
- * @param {...import('../types.js').ExprVarArgs} expr The partition by criteria.
76
+ * @param {...ExprVarArgs} expr The partition by criteria.
73
77
  * @returns {WindowNode} A new window node.
74
78
  */
75
79
  partitionby(...expr) {
@@ -78,7 +82,7 @@ export class WindowNode extends ExprNode {
78
82
 
79
83
  /**
80
84
  * Return an updated window with the given ordering.
81
- * @param {...import('../types.js').ExprVarArgs} expr The order by criteria.
85
+ * @param {...ExprVarArgs} expr The order by criteria.
82
86
  * @returns {WindowNode} A new window node.
83
87
  */
84
88
  orderby(...expr) {
@@ -115,7 +119,7 @@ export class WindowNode extends ExprNode {
115
119
  export class WindowFunctionNode extends FunctionNode {
116
120
  /**
117
121
  * Instantiate a window function call node.
118
- * @param {import('../types.js').WindowFunctionName} name The function name.
122
+ * @param {WindowFunctionName} name The function name.
119
123
  * @param {ExprNode[]} [args=[]] The function arguments.
120
124
  */
121
125
  constructor(name, args) {
@@ -170,7 +174,7 @@ export class WindowDefNode extends SQLNode {
170
174
 
171
175
  /**
172
176
  * Return an updated window definition with the given partitions.
173
- * @param {...import('../types.js').ExprVarArgs} expr The partition by criteria.
177
+ * @param {...ExprVarArgs} expr The partition by criteria.
174
178
  * @returns {WindowDefNode} A new window definition node.
175
179
  */
176
180
  partitionby(...expr) {
@@ -179,7 +183,7 @@ export class WindowDefNode extends SQLNode {
179
183
 
180
184
  /**
181
185
  * Return an updated window definition with the given ordering.
182
- * @param {...import('../types.js').ExprVarArgs} expr The order by criteria.
186
+ * @param {...ExprVarArgs} expr The order by criteria.
183
187
  * @returns {WindowDefNode} A new window definition node.
184
188
  */
185
189
  orderby(...expr) {
package/src/ast/with.js CHANGED
@@ -7,8 +7,12 @@ export class WithClauseNode extends SQLNode {
7
7
  * Instantiate a with clause node for a common table expression (CTE).
8
8
  * @param {string} name The common table expression (CTE) name.
9
9
  * @param {Query} query The common table expression (CTE) query.
10
+ * @param {boolean | null} [materialized] The common table expression (CTE)
11
+ * materialization flag. If `true`, forces materialization of the CTE.
12
+ * If `false`, materialization is not performed. Otherwise (for example, if
13
+ * `undefined` or `null`), materialization is decided by the database.
10
14
  */
11
- constructor(name, query) {
15
+ constructor(name, query, materialized = undefined) {
12
16
  super(WITH_CLAUSE);
13
17
  /**
14
18
  * The common table expression (CTE) name.
@@ -22,9 +26,19 @@ export class WithClauseNode extends SQLNode {
22
26
  * @readonly
23
27
  */
24
28
  this.query = query;
29
+ /**
30
+ * The common table expression (CTE) materialization flag.
31
+ * @type {boolean | null}
32
+ * @readonly
33
+ */
34
+ this.materialized = materialized;
25
35
  }
26
36
 
27
37
  toString() {
28
- return `"${this.name}" AS (${this.query})`;
38
+ const flag = this.materialized;
39
+ const mat = flag === true ? ' MATERIALIZED'
40
+ : flag === false ? ' NOT MATERIALIZED'
41
+ : '';
42
+ return `"${this.name}" AS${mat} (${this.query})`;
29
43
  }
30
44
  }