@uwdata/mosaic-sql 0.12.2 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/types/ast/query.d.ts +59 -14
- package/dist/types/ast/with.d.ts +11 -1
- package/dist/types/functions/aggregate.d.ts +6 -0
- package/dist/types/functions/cte.d.ts +13 -0
- package/dist/types/index.d.ts +2 -1
- package/dist/types/types.d.ts +3 -1
- package/package.json +9 -9
- package/src/ast/literal.js +1 -1
- package/src/ast/query.js +102 -33
- package/src/ast/with.js +16 -2
- package/src/functions/aggregate.js +9 -0
- package/src/functions/cte.js +16 -0
- package/src/index.js +2 -1
- package/src/transforms/m4.js +12 -3
- package/src/types.ts +6 -1
- package/vitest.config.ts +3 -0
- package/dist/mosaic-sql.js +0 -2610
- package/dist/mosaic-sql.min.js +0 -1
package/dist/mosaic-sql.js
DELETED
|
@@ -1,2610 +0,0 @@
|
|
|
1
|
-
// src/constants.js
|
|
2
|
-
var COLUMN_REF = "COLUMN_REF";
|
|
3
|
-
var COLUMN_PARAM = "COLUMN_PARAM";
|
|
4
|
-
var TABLE_REF = "TABLE_REF";
|
|
5
|
-
var LITERAL = "LITERAL";
|
|
6
|
-
var INTERVAL = "INTERVAL";
|
|
7
|
-
var ORDER_BY = "ORDER_BY";
|
|
8
|
-
var CAST = "CAST";
|
|
9
|
-
var CASE = "CASE";
|
|
10
|
-
var WHEN = "WHEN";
|
|
11
|
-
var UNARY_OPERATOR = "UNARY";
|
|
12
|
-
var UNARY_POSTFIX_OPERATOR = "UNARY_POSTFIX";
|
|
13
|
-
var BINARY_OPERATOR = "BINARY";
|
|
14
|
-
var BETWEEN_OPERATOR = "BETWEEN";
|
|
15
|
-
var NOT_BETWEEN_OPERATOR = "NOT_BETWEEN";
|
|
16
|
-
var LOGICAL_OPERATOR = "LOGICAL_OPERATOR";
|
|
17
|
-
var IN_OPERATOR = "IN";
|
|
18
|
-
var FUNCTION = "FUNCTION";
|
|
19
|
-
var AGGREGATE = "AGGREGATE";
|
|
20
|
-
var WINDOW = "WINDOW";
|
|
21
|
-
var WINDOW_DEF = "WINDOW_DEF";
|
|
22
|
-
var WINDOW_FRAME = "WINDOW_FRAME";
|
|
23
|
-
var EXPRESSION = "EXPRESSION";
|
|
24
|
-
var FRAGMENT = "FRAGMENT";
|
|
25
|
-
var VERBATIM = "VERBATIM";
|
|
26
|
-
var PARAM = "PARAM";
|
|
27
|
-
var WITH_CLAUSE = "WITH_CLAUSE";
|
|
28
|
-
var SELECT_CLAUSE = "SELECT_CLAUSE";
|
|
29
|
-
var FROM_CLAUSE = "FROM_CLAUSE";
|
|
30
|
-
var SAMPLE_CLAUSE = "SAMPLE_CLAUSE";
|
|
31
|
-
var WINDOW_CLAUSE = "WINDOW_CLAUSE";
|
|
32
|
-
var SELECT_QUERY = "SELECT_QUERY";
|
|
33
|
-
var DESCRIBE_QUERY = "DESCRIBE_QUERY";
|
|
34
|
-
var SET_OPERATION = "SET_OPERATION";
|
|
35
|
-
|
|
36
|
-
// src/ast/node.js
|
|
37
|
-
function isNode(value) {
|
|
38
|
-
return value instanceof SQLNode;
|
|
39
|
-
}
|
|
40
|
-
var SQLNode = class {
|
|
41
|
-
/**
|
|
42
|
-
* Instantiate a SQL AST node.
|
|
43
|
-
* @param {string} type The SQL AST node type.
|
|
44
|
-
*/
|
|
45
|
-
constructor(type) {
|
|
46
|
-
this.type = type;
|
|
47
|
-
}
|
|
48
|
-
};
|
|
49
|
-
var ExprNode = class extends SQLNode {
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
// src/ast/literal.js
|
|
53
|
-
var LiteralNode = class extends ExprNode {
|
|
54
|
-
/**
|
|
55
|
-
* Instantiate an literal node.
|
|
56
|
-
* @param {*} value The literal value.
|
|
57
|
-
*/
|
|
58
|
-
constructor(value) {
|
|
59
|
-
super(LITERAL);
|
|
60
|
-
this.value = value;
|
|
61
|
-
}
|
|
62
|
-
/**
|
|
63
|
-
* Generate a SQL query string for this node.
|
|
64
|
-
* @returns {string}
|
|
65
|
-
*/
|
|
66
|
-
toString() {
|
|
67
|
-
return literalToSQL(this.value);
|
|
68
|
-
}
|
|
69
|
-
};
|
|
70
|
-
function literalToSQL(value) {
|
|
71
|
-
switch (typeof value) {
|
|
72
|
-
case "number":
|
|
73
|
-
return Number.isFinite(value) ? `${value}` : "NULL";
|
|
74
|
-
case "string":
|
|
75
|
-
return `'${value.replace(`'`, `''`)}'`;
|
|
76
|
-
case "boolean":
|
|
77
|
-
return value ? "TRUE" : "FALSE";
|
|
78
|
-
default:
|
|
79
|
-
if (value == null) {
|
|
80
|
-
return "NULL";
|
|
81
|
-
} else if (value instanceof Date) {
|
|
82
|
-
const ts = +value;
|
|
83
|
-
if (Number.isNaN(ts)) return "NULL";
|
|
84
|
-
const y2 = value.getUTCFullYear();
|
|
85
|
-
const m = value.getUTCMonth();
|
|
86
|
-
const d = value.getUTCDate();
|
|
87
|
-
return ts === Date.UTC(y2, m, d) ? `DATE '${y2}-${m + 1}-${d}'` : `epoch_ms(${ts})`;
|
|
88
|
-
} else if (value instanceof RegExp) {
|
|
89
|
-
return `'${value.source}'`;
|
|
90
|
-
} else {
|
|
91
|
-
return `${value}`;
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
// src/ast/param.js
|
|
97
|
-
var ParamNode = class extends ExprNode {
|
|
98
|
-
/**
|
|
99
|
-
* Instantiate a param node with a dynamic parameter.
|
|
100
|
-
* @param {import('../types.js').ParamLike} param The dynamic parameter.
|
|
101
|
-
*/
|
|
102
|
-
constructor(param) {
|
|
103
|
-
super(PARAM);
|
|
104
|
-
this.param = param;
|
|
105
|
-
}
|
|
106
|
-
/**
|
|
107
|
-
* Returns the current parameter value.
|
|
108
|
-
* @returns {*}
|
|
109
|
-
*/
|
|
110
|
-
get value() {
|
|
111
|
-
return this.param.value;
|
|
112
|
-
}
|
|
113
|
-
/**
|
|
114
|
-
* Generate a SQL query string for this node.
|
|
115
|
-
* @returns {string}
|
|
116
|
-
*/
|
|
117
|
-
toString() {
|
|
118
|
-
return literalToSQL(this.value);
|
|
119
|
-
}
|
|
120
|
-
};
|
|
121
|
-
|
|
122
|
-
// src/util/string.js
|
|
123
|
-
function parseIdentifier(id) {
|
|
124
|
-
return id.split(".");
|
|
125
|
-
}
|
|
126
|
-
function quoteIdentifier(value) {
|
|
127
|
-
return `"${value}"`;
|
|
128
|
-
}
|
|
129
|
-
function unquote(s) {
|
|
130
|
-
return s && isDoubleQuoted(s) ? s.slice(1, -1) : s;
|
|
131
|
-
}
|
|
132
|
-
function isDoubleQuoted(s) {
|
|
133
|
-
return s[0] === '"' && s[s.length - 1] === '"';
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
// src/ast/table-ref.js
|
|
137
|
-
function isTableRef(value) {
|
|
138
|
-
return value instanceof TableRefNode;
|
|
139
|
-
}
|
|
140
|
-
var TableRefNode = class extends ExprNode {
|
|
141
|
-
/**
|
|
142
|
-
* Instantiate a table reference node.
|
|
143
|
-
* @param {string | string[]} table The table name.
|
|
144
|
-
*/
|
|
145
|
-
constructor(table) {
|
|
146
|
-
super(TABLE_REF);
|
|
147
|
-
this.table = [table].flat();
|
|
148
|
-
}
|
|
149
|
-
/**
|
|
150
|
-
* The table name without database or schema namespaces.
|
|
151
|
-
* @returns {string}
|
|
152
|
-
*/
|
|
153
|
-
get name() {
|
|
154
|
-
return this.table[this.table.length - 1];
|
|
155
|
-
}
|
|
156
|
-
/**
|
|
157
|
-
* Generate a SQL query string for this node.
|
|
158
|
-
* @returns {string}
|
|
159
|
-
*/
|
|
160
|
-
toString() {
|
|
161
|
-
return this.table.map((t) => quoteIdentifier(t)).join(".");
|
|
162
|
-
}
|
|
163
|
-
};
|
|
164
|
-
|
|
165
|
-
// src/ast/function.js
|
|
166
|
-
var FunctionNode = class extends ExprNode {
|
|
167
|
-
/**
|
|
168
|
-
* Instantiate a function node.
|
|
169
|
-
* @param {string} name The function name.
|
|
170
|
-
* @param {ExprNode[]} [args=[]] The function arguments.
|
|
171
|
-
*/
|
|
172
|
-
constructor(name, args = []) {
|
|
173
|
-
super(FUNCTION);
|
|
174
|
-
this.name = name;
|
|
175
|
-
this.args = args;
|
|
176
|
-
}
|
|
177
|
-
/**
|
|
178
|
-
* Generate a SQL query string for this node.
|
|
179
|
-
* @returns {string}
|
|
180
|
-
*/
|
|
181
|
-
toString() {
|
|
182
|
-
const { name, args } = this;
|
|
183
|
-
return `${name}(${args.join(", ")})`;
|
|
184
|
-
}
|
|
185
|
-
};
|
|
186
|
-
|
|
187
|
-
// src/util/function.js
|
|
188
|
-
function fn(name, ...args) {
|
|
189
|
-
return new FunctionNode(name, argsList(args).map(asNode));
|
|
190
|
-
}
|
|
191
|
-
function aggFn(name, ...args) {
|
|
192
|
-
return new AggregateNode(name, argsList(args).map(asNode));
|
|
193
|
-
}
|
|
194
|
-
function winFn(name, ...args) {
|
|
195
|
-
return new WindowNode(
|
|
196
|
-
new WindowFunctionNode(name, argsList(args).map(asNode))
|
|
197
|
-
);
|
|
198
|
-
}
|
|
199
|
-
function exprList(list, cast2 = asNode) {
|
|
200
|
-
return list.flat().filter((x2) => x2 != null).map((x2) => cast2(x2));
|
|
201
|
-
}
|
|
202
|
-
function argsList(list) {
|
|
203
|
-
const n = list.length;
|
|
204
|
-
let i = n;
|
|
205
|
-
for (; i > 0 && list[i - 1] === void 0; --i) ;
|
|
206
|
-
return i < n ? list.slice(0, i) : list;
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
// src/util/type-check.js
|
|
210
|
-
function isString(value) {
|
|
211
|
-
return typeof value === "string";
|
|
212
|
-
}
|
|
213
|
-
function isArray(value) {
|
|
214
|
-
return Array.isArray(value);
|
|
215
|
-
}
|
|
216
|
-
function isParamLike(value) {
|
|
217
|
-
return value && typeof value.addEventListener === "function" && value.dynamic !== false && "value" in value;
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
// src/ast/window.js
|
|
221
|
-
var WindowClauseNode = class extends SQLNode {
|
|
222
|
-
/**
|
|
223
|
-
* Instantiate a window clause node.
|
|
224
|
-
* @param {string} name The window name.
|
|
225
|
-
* @param {WindowDefNode} def The window definition.
|
|
226
|
-
*/
|
|
227
|
-
constructor(name, def) {
|
|
228
|
-
super(WINDOW_CLAUSE);
|
|
229
|
-
this.name = name;
|
|
230
|
-
this.def = def;
|
|
231
|
-
}
|
|
232
|
-
toString() {
|
|
233
|
-
return `${quoteIdentifier(this.name)} AS ${this.def}`;
|
|
234
|
-
}
|
|
235
|
-
};
|
|
236
|
-
var WindowNode = class _WindowNode extends ExprNode {
|
|
237
|
-
/**
|
|
238
|
-
* Instantiate a window node.
|
|
239
|
-
* @param {WindowFunctionNode | AggregateNode} func The window function call.
|
|
240
|
-
* @param {WindowDefNode} [over] The window definition or name.
|
|
241
|
-
*/
|
|
242
|
-
constructor(func, over2 = new WindowDefNode()) {
|
|
243
|
-
super(WINDOW);
|
|
244
|
-
this.func = func;
|
|
245
|
-
this.def = over2;
|
|
246
|
-
}
|
|
247
|
-
/**
|
|
248
|
-
* Return an updated window over a named window definition.
|
|
249
|
-
* @param {string} name The window definition name.
|
|
250
|
-
* @returns {WindowNode} A new window node.
|
|
251
|
-
*/
|
|
252
|
-
over(name) {
|
|
253
|
-
return new _WindowNode(this.func, this.def.over(name));
|
|
254
|
-
}
|
|
255
|
-
/**
|
|
256
|
-
* Return an updated window with the given partitions.
|
|
257
|
-
* @param {...import('../types.js').ExprVarArgs} expr The partition by criteria.
|
|
258
|
-
* @returns {WindowNode} A new window node.
|
|
259
|
-
*/
|
|
260
|
-
partitionby(...expr) {
|
|
261
|
-
return new _WindowNode(this.func, this.def.partitionby(...expr));
|
|
262
|
-
}
|
|
263
|
-
/**
|
|
264
|
-
* Return an updated window with the given ordering.
|
|
265
|
-
* @param {...import('../types.js').ExprVarArgs} expr The order by criteria.
|
|
266
|
-
* @returns {WindowNode} A new window node.
|
|
267
|
-
*/
|
|
268
|
-
orderby(...expr) {
|
|
269
|
-
return new _WindowNode(this.func, this.def.orderby(...expr));
|
|
270
|
-
}
|
|
271
|
-
/**
|
|
272
|
-
* Return an updated window with the given rows frame.
|
|
273
|
-
* @param {FrameExtent} extent The row-based window frame extent.
|
|
274
|
-
* @returns {WindowNode} A new window node.
|
|
275
|
-
*/
|
|
276
|
-
rows(extent) {
|
|
277
|
-
return new _WindowNode(this.func, this.def.rows(extent));
|
|
278
|
-
}
|
|
279
|
-
/**
|
|
280
|
-
* Return an updated window with the given range frame.
|
|
281
|
-
* @param {FrameExtent} extent The range-based window frame extent.
|
|
282
|
-
* @returns {WindowNode} A new window node.
|
|
283
|
-
*/
|
|
284
|
-
range(extent) {
|
|
285
|
-
return new _WindowNode(this.func, this.def.range(extent));
|
|
286
|
-
}
|
|
287
|
-
/**
|
|
288
|
-
* Generate a SQL query string for this node.
|
|
289
|
-
* @returns {string}
|
|
290
|
-
*/
|
|
291
|
-
toString() {
|
|
292
|
-
return `${this.func} OVER ${this.def}`;
|
|
293
|
-
}
|
|
294
|
-
};
|
|
295
|
-
var WindowFunctionNode = class extends FunctionNode {
|
|
296
|
-
/**
|
|
297
|
-
* Instantiate a window function call node.
|
|
298
|
-
* @param {import('../types.js').WindowFunctionName} name The function name.
|
|
299
|
-
* @param {ExprNode[]} [args=[]] The function arguments.
|
|
300
|
-
*/
|
|
301
|
-
constructor(name, args) {
|
|
302
|
-
super(name, args);
|
|
303
|
-
}
|
|
304
|
-
};
|
|
305
|
-
var WindowDefNode = class extends SQLNode {
|
|
306
|
-
/**
|
|
307
|
-
* Instantiate a window definition node.
|
|
308
|
-
* @param {string} [name] The base window definition name.
|
|
309
|
-
* @param {ExprNode[]} [partition] The partition by criteria.
|
|
310
|
-
* @param {ExprNode[]} [order] The order by criteria.
|
|
311
|
-
* @param {WindowFrameNode} [frame] The window frame definition.
|
|
312
|
-
*/
|
|
313
|
-
constructor(name, partition, order, frame) {
|
|
314
|
-
super(WINDOW_DEF);
|
|
315
|
-
this.name = name;
|
|
316
|
-
this.partition = partition;
|
|
317
|
-
this.order = order;
|
|
318
|
-
this.frame = frame;
|
|
319
|
-
}
|
|
320
|
-
/**
|
|
321
|
-
* Return an updated window definition with the given base name.
|
|
322
|
-
* @param {string} name The base window definition name.
|
|
323
|
-
* @returns {WindowDefNode} A new window definition node.
|
|
324
|
-
*/
|
|
325
|
-
over(name) {
|
|
326
|
-
return deriveDef(this, { name });
|
|
327
|
-
}
|
|
328
|
-
/**
|
|
329
|
-
* Return an updated window definition with the given partitions.
|
|
330
|
-
* @param {...import('../types.js').ExprVarArgs} expr The partition by criteria.
|
|
331
|
-
* @returns {WindowDefNode} A new window definition node.
|
|
332
|
-
*/
|
|
333
|
-
partitionby(...expr) {
|
|
334
|
-
return deriveDef(this, { partition: exprList(expr) });
|
|
335
|
-
}
|
|
336
|
-
/**
|
|
337
|
-
* Return an updated window definition with the given ordering.
|
|
338
|
-
* @param {...import('../types.js').ExprVarArgs} expr The order by criteria.
|
|
339
|
-
* @returns {WindowDefNode} A new window definition node.
|
|
340
|
-
*/
|
|
341
|
-
orderby(...expr) {
|
|
342
|
-
return deriveDef(this, { order: exprList(expr) });
|
|
343
|
-
}
|
|
344
|
-
/**
|
|
345
|
-
* Return an updated window definition with the given rows frame.
|
|
346
|
-
* @param {FrameExtent} extent The row-based window frame extent.
|
|
347
|
-
* @returns {WindowDefNode} A new window definition node.
|
|
348
|
-
*/
|
|
349
|
-
rows(extent) {
|
|
350
|
-
return deriveDef(this, { frame: new WindowFrameNode(extent) });
|
|
351
|
-
}
|
|
352
|
-
/**
|
|
353
|
-
* Return an updated window definition with the given range frame.
|
|
354
|
-
* @param {FrameExtent} extent The range-based window frame extent.
|
|
355
|
-
* @returns {WindowDefNode} A new window definition node.
|
|
356
|
-
*/
|
|
357
|
-
range(extent) {
|
|
358
|
-
return deriveDef(this, { frame: new WindowFrameNode(extent, true) });
|
|
359
|
-
}
|
|
360
|
-
/**
|
|
361
|
-
* Generate a SQL query string for this node.
|
|
362
|
-
* @returns {string}
|
|
363
|
-
*/
|
|
364
|
-
toString() {
|
|
365
|
-
const { name, partition, order, frame } = this;
|
|
366
|
-
const base = name && quoteIdentifier(name);
|
|
367
|
-
const def = [
|
|
368
|
-
base,
|
|
369
|
-
partition?.length && `PARTITION BY ${partition.join(", ")}`,
|
|
370
|
-
order?.length && `ORDER BY ${order.join(", ")}`,
|
|
371
|
-
frame
|
|
372
|
-
].filter((x2) => x2);
|
|
373
|
-
return base && def.length < 2 ? base : `(${def.join(" ")})`;
|
|
374
|
-
}
|
|
375
|
-
};
|
|
376
|
-
var WindowFrameNode = class extends SQLNode {
|
|
377
|
-
/**
|
|
378
|
-
* Instantiate a window frame definition node.
|
|
379
|
-
* @param {FrameExtent} extent The frame extent as [preceding, following]
|
|
380
|
-
* row or interval offsets.
|
|
381
|
-
* @param {boolean} [range] The frame type: `true` for range, otherwise rows.
|
|
382
|
-
* @param {ExprNode} [exclude] The window exclusion criteria.
|
|
383
|
-
*/
|
|
384
|
-
constructor(extent, range = false, exclude = void 0) {
|
|
385
|
-
super(WINDOW_FRAME);
|
|
386
|
-
this.extent = isParamLike(extent) ? new ParamNode(extent) : extent;
|
|
387
|
-
this.range = range;
|
|
388
|
-
this.exclude = exclude;
|
|
389
|
-
}
|
|
390
|
-
/**
|
|
391
|
-
* Generate a SQL query string for this node.
|
|
392
|
-
* @returns {string}
|
|
393
|
-
*/
|
|
394
|
-
toString() {
|
|
395
|
-
const { range, exclude, extent } = this;
|
|
396
|
-
const type = range ? "RANGE" : "ROWS";
|
|
397
|
-
const [prev, next] = isNode(extent) ? extent.value : extent;
|
|
398
|
-
const a = frameValue(prev, "PRECEDING");
|
|
399
|
-
const b = frameValue(next, "FOLLOWING");
|
|
400
|
-
return `${type} BETWEEN ${a} AND ${b}${exclude ? ` ${exclude}` : ""}`;
|
|
401
|
-
}
|
|
402
|
-
};
|
|
403
|
-
function deriveDef(def, options) {
|
|
404
|
-
return new WindowDefNode(
|
|
405
|
-
options.name ?? def.name,
|
|
406
|
-
options.partition ?? def.partition,
|
|
407
|
-
options.order ?? def.order,
|
|
408
|
-
options.frame ?? def.frame
|
|
409
|
-
);
|
|
410
|
-
}
|
|
411
|
-
function frameValue(value, order) {
|
|
412
|
-
return value === 0 ? "CURRENT ROW" : Number.isFinite(value) ? `${Math.abs(value)} ${order}` : `UNBOUNDED ${order}`;
|
|
413
|
-
}
|
|
414
|
-
|
|
415
|
-
// src/ast/column-ref.js
|
|
416
|
-
function isColumnRef(value) {
|
|
417
|
-
return value instanceof ColumnRefNode;
|
|
418
|
-
}
|
|
419
|
-
var ColumnRefNode = class extends ExprNode {
|
|
420
|
-
/**
|
|
421
|
-
* Instantiate a column reference node.
|
|
422
|
-
* @param {import('./table-ref.js').TableRefNode} [table] The table reference.
|
|
423
|
-
*/
|
|
424
|
-
constructor(type, table) {
|
|
425
|
-
super(type);
|
|
426
|
-
this.table = table;
|
|
427
|
-
}
|
|
428
|
-
/**
|
|
429
|
-
* Returns the column name.
|
|
430
|
-
* @returns {string}
|
|
431
|
-
*/
|
|
432
|
-
get column() {
|
|
433
|
-
return null;
|
|
434
|
-
}
|
|
435
|
-
/**
|
|
436
|
-
* Generate a SQL query string for this node.
|
|
437
|
-
* @returns {string}
|
|
438
|
-
*/
|
|
439
|
-
toString() {
|
|
440
|
-
const { column: column2, table } = this;
|
|
441
|
-
const tref = `${table ?? ""}`;
|
|
442
|
-
const id = column2 === "*" ? "*" : quoteIdentifier(column2);
|
|
443
|
-
return (tref ? tref + "." : "") + id;
|
|
444
|
-
}
|
|
445
|
-
};
|
|
446
|
-
var ColumnNameRefNode = class extends ColumnRefNode {
|
|
447
|
-
/**
|
|
448
|
-
* Instantiate a column reference node.
|
|
449
|
-
* @param {string} name The column name.
|
|
450
|
-
* @param {import('./table-ref.js').TableRefNode} [table] The table reference.
|
|
451
|
-
*/
|
|
452
|
-
constructor(name, table) {
|
|
453
|
-
super(COLUMN_REF, table);
|
|
454
|
-
this.name = name;
|
|
455
|
-
}
|
|
456
|
-
/**
|
|
457
|
-
* Returns the column name.
|
|
458
|
-
* @returns {string}
|
|
459
|
-
*/
|
|
460
|
-
get column() {
|
|
461
|
-
return this.name;
|
|
462
|
-
}
|
|
463
|
-
};
|
|
464
|
-
|
|
465
|
-
// src/ast/column-param.js
|
|
466
|
-
function isColumnParam(value) {
|
|
467
|
-
return value instanceof ColumnParamNode;
|
|
468
|
-
}
|
|
469
|
-
var ColumnParamNode = class extends ColumnRefNode {
|
|
470
|
-
/**
|
|
471
|
-
* Instantiate a column param node.
|
|
472
|
-
* @param {import('./param.js').ParamNode} param The column name as a
|
|
473
|
-
* parameter node.
|
|
474
|
-
* @param {import('./table-ref.js').TableRefNode} [table] The table
|
|
475
|
-
* reference.
|
|
476
|
-
*/
|
|
477
|
-
constructor(param, table) {
|
|
478
|
-
super(COLUMN_PARAM, table);
|
|
479
|
-
this.param = param;
|
|
480
|
-
}
|
|
481
|
-
/**
|
|
482
|
-
* Returns the column name.
|
|
483
|
-
* @returns {string}
|
|
484
|
-
*/
|
|
485
|
-
get column() {
|
|
486
|
-
return `${this.param.value}`;
|
|
487
|
-
}
|
|
488
|
-
};
|
|
489
|
-
|
|
490
|
-
// src/functions/column.js
|
|
491
|
-
function column(name, table) {
|
|
492
|
-
const tref = asTableRef(table);
|
|
493
|
-
return isParamLike(name) ? new ColumnParamNode(new ParamNode(name), tref) : new ColumnNameRefNode(name, tref);
|
|
494
|
-
}
|
|
495
|
-
|
|
496
|
-
// src/ast/verbatim.js
|
|
497
|
-
var VerbatimNode = class extends ExprNode {
|
|
498
|
-
/**
|
|
499
|
-
* Instantiate a raw node with verbatim content.
|
|
500
|
-
* @param {string} value The verbatim content to include.
|
|
501
|
-
*/
|
|
502
|
-
constructor(value) {
|
|
503
|
-
super(VERBATIM);
|
|
504
|
-
this.value = value;
|
|
505
|
-
}
|
|
506
|
-
/**
|
|
507
|
-
* Generate a SQL query string for this node.
|
|
508
|
-
* @returns {string}
|
|
509
|
-
*/
|
|
510
|
-
toString() {
|
|
511
|
-
return this.value;
|
|
512
|
-
}
|
|
513
|
-
};
|
|
514
|
-
|
|
515
|
-
// src/functions/literal.js
|
|
516
|
-
function literal(value) {
|
|
517
|
-
return new LiteralNode(value);
|
|
518
|
-
}
|
|
519
|
-
function verbatim(value) {
|
|
520
|
-
return new VerbatimNode(value);
|
|
521
|
-
}
|
|
522
|
-
|
|
523
|
-
// src/functions/table-ref.js
|
|
524
|
-
function tableRef(...ids) {
|
|
525
|
-
const args = exprList(ids, String);
|
|
526
|
-
return args?.length ? new TableRefNode(args) : void 0;
|
|
527
|
-
}
|
|
528
|
-
|
|
529
|
-
// src/util/ast.js
|
|
530
|
-
function asNode(value) {
|
|
531
|
-
return isString(value) ? parseColumnRef(value) : asLiteral(value);
|
|
532
|
-
}
|
|
533
|
-
function asVerbatim(value) {
|
|
534
|
-
return isString(value) ? verbatim(value) : asLiteral(value);
|
|
535
|
-
}
|
|
536
|
-
function asLiteral(value) {
|
|
537
|
-
return value instanceof ExprNode ? value : isParamLike(value) ? new ParamNode(value) : literal(value);
|
|
538
|
-
}
|
|
539
|
-
function asTableRef(value) {
|
|
540
|
-
return isString(value) ? parseTableRef(value) : isArray(value) ? tableRef(value) : value;
|
|
541
|
-
}
|
|
542
|
-
function parseColumnRef(ref) {
|
|
543
|
-
const ids = parseIdentifier(ref);
|
|
544
|
-
return column(ids.pop(), tableRef(ids));
|
|
545
|
-
}
|
|
546
|
-
function parseTableRef(ref) {
|
|
547
|
-
return tableRef(parseIdentifier(ref));
|
|
548
|
-
}
|
|
549
|
-
function over() {
|
|
550
|
-
return new WindowDefNode();
|
|
551
|
-
}
|
|
552
|
-
|
|
553
|
-
// src/ast/aggregate.js
|
|
554
|
-
var AggregateNode = class _AggregateNode extends ExprNode {
|
|
555
|
-
/**
|
|
556
|
-
* Instantiate an aggregate function node.
|
|
557
|
-
* @param {string} name The aggregate function name.
|
|
558
|
-
* @param {ExprNode[]} args The aggregate function arguments.
|
|
559
|
-
* @param {boolean} [distinct] The distinct flag.
|
|
560
|
-
* @param {ExprNode} [filter] Filter expression.
|
|
561
|
-
*/
|
|
562
|
-
constructor(name, args, distinct, filter) {
|
|
563
|
-
super(AGGREGATE);
|
|
564
|
-
this.name = name;
|
|
565
|
-
this.args = args;
|
|
566
|
-
this.isDistinct = distinct;
|
|
567
|
-
this.filter = filter;
|
|
568
|
-
}
|
|
569
|
-
/**
|
|
570
|
-
* Return a new derived aggregate over distinct values.
|
|
571
|
-
* @param {boolean} [isDistinct=true] The distinct flag.
|
|
572
|
-
* @returns {AggregateNode} A new aggregate node.
|
|
573
|
-
*/
|
|
574
|
-
distinct(isDistinct2 = true) {
|
|
575
|
-
return new _AggregateNode(this.name, this.args, isDistinct2, this.filter);
|
|
576
|
-
}
|
|
577
|
-
/**
|
|
578
|
-
* Return a new derived aggregate function that filters values.
|
|
579
|
-
* @param {ExprNode | string} filter The filter expression.
|
|
580
|
-
* @returns {AggregateNode} A new aggregate node.
|
|
581
|
-
*/
|
|
582
|
-
where(filter) {
|
|
583
|
-
if (isString(filter)) filter = asVerbatim(filter);
|
|
584
|
-
return new _AggregateNode(this.name, this.args, this.isDistinct, filter);
|
|
585
|
-
}
|
|
586
|
-
/**
|
|
587
|
-
* Return a new window function over this aggregate.
|
|
588
|
-
* @returns {WindowNode} A new window node.
|
|
589
|
-
*/
|
|
590
|
-
window() {
|
|
591
|
-
return new WindowNode(this);
|
|
592
|
-
}
|
|
593
|
-
/**
|
|
594
|
-
* Return a new window function over this aggregate with the given partitions.
|
|
595
|
-
* @param {...import('../types.js').ExprVarArgs} expr The partition by criteria.
|
|
596
|
-
* @returns {WindowNode} A new window node.
|
|
597
|
-
*/
|
|
598
|
-
partitionby(...expr) {
|
|
599
|
-
return this.window().partitionby(...expr);
|
|
600
|
-
}
|
|
601
|
-
/**
|
|
602
|
-
* Return a new window function over this aggregate with the given ordering.
|
|
603
|
-
* @param {...import('../types.js').ExprVarArgs} expr The order by criteria.
|
|
604
|
-
* @returns {WindowNode} A new window node.
|
|
605
|
-
*/
|
|
606
|
-
orderby(...expr) {
|
|
607
|
-
return this.window().orderby(...expr);
|
|
608
|
-
}
|
|
609
|
-
/**
|
|
610
|
-
* Generate a SQL query string for this node.
|
|
611
|
-
* @returns {string}
|
|
612
|
-
*/
|
|
613
|
-
toString() {
|
|
614
|
-
const { name, args, isDistinct: isDistinct2, filter } = this;
|
|
615
|
-
const dist = isDistinct2 ? "DISTINCT " : "";
|
|
616
|
-
const arg = args?.length ? args.join(", ") : "*";
|
|
617
|
-
const filt = filter ? ` FILTER (WHERE ${filter})` : "";
|
|
618
|
-
return `${name}(${dist}${arg})${filt}`;
|
|
619
|
-
}
|
|
620
|
-
};
|
|
621
|
-
var aggregateNames = [
|
|
622
|
-
"any_value",
|
|
623
|
-
"approx_count_distinct",
|
|
624
|
-
"approx_quantile",
|
|
625
|
-
"arbitrary",
|
|
626
|
-
"arg_max",
|
|
627
|
-
"arg_max_null",
|
|
628
|
-
"arg_min",
|
|
629
|
-
"arg_min_null",
|
|
630
|
-
"array_agg",
|
|
631
|
-
"avg",
|
|
632
|
-
"bit_and",
|
|
633
|
-
"bit_or",
|
|
634
|
-
"bit_xor",
|
|
635
|
-
"bitstring_agg",
|
|
636
|
-
"bool_and",
|
|
637
|
-
"bool_or",
|
|
638
|
-
"corr",
|
|
639
|
-
"count",
|
|
640
|
-
"covar_pop",
|
|
641
|
-
"covar_samp",
|
|
642
|
-
"entropy",
|
|
643
|
-
"favg",
|
|
644
|
-
"first",
|
|
645
|
-
"fsum",
|
|
646
|
-
"geomean",
|
|
647
|
-
"kurtosis_pop",
|
|
648
|
-
"kurtosis",
|
|
649
|
-
"last",
|
|
650
|
-
"mad",
|
|
651
|
-
"max",
|
|
652
|
-
"max_by",
|
|
653
|
-
"median",
|
|
654
|
-
"min",
|
|
655
|
-
"min_by",
|
|
656
|
-
"mode",
|
|
657
|
-
"product",
|
|
658
|
-
"quantile",
|
|
659
|
-
"quantile_cont",
|
|
660
|
-
"quantile_disc",
|
|
661
|
-
"regr_avgx",
|
|
662
|
-
"regr_avgy",
|
|
663
|
-
"regr_count",
|
|
664
|
-
"regr_intercept",
|
|
665
|
-
"regr_r2",
|
|
666
|
-
"regr_sxx",
|
|
667
|
-
"regr_sxy",
|
|
668
|
-
"regr_syy",
|
|
669
|
-
"regr_slope",
|
|
670
|
-
"reservoir_quantile",
|
|
671
|
-
"skewness",
|
|
672
|
-
"stddev",
|
|
673
|
-
"stddev_pop",
|
|
674
|
-
"stddev_samp",
|
|
675
|
-
"string_agg",
|
|
676
|
-
"sum",
|
|
677
|
-
"variance",
|
|
678
|
-
"var_pop",
|
|
679
|
-
"var_samp"
|
|
680
|
-
];
|
|
681
|
-
|
|
682
|
-
// src/ast/between-op.js
|
|
683
|
-
var AbstractBetweenOpNode = class extends ExprNode {
|
|
684
|
-
/**
|
|
685
|
-
* Instantiate an abstract between operator node.
|
|
686
|
-
* @param {string} type The node type.
|
|
687
|
-
* @param {ExprNode} expr The input expression.
|
|
688
|
-
* @param {[ExprNode, ExprNode]} extent The range extent.
|
|
689
|
-
*/
|
|
690
|
-
constructor(type, expr, extent) {
|
|
691
|
-
super(type);
|
|
692
|
-
this.expr = expr;
|
|
693
|
-
this.extent = extent;
|
|
694
|
-
}
|
|
695
|
-
/**
|
|
696
|
-
* Generate a SQL query string for this node.
|
|
697
|
-
* @returns {string}
|
|
698
|
-
*/
|
|
699
|
-
toSQL(op) {
|
|
700
|
-
const { extent: r, expr } = this;
|
|
701
|
-
return r ? `(${expr} ${op} ${r[0]} AND ${r[1]})` : "";
|
|
702
|
-
}
|
|
703
|
-
};
|
|
704
|
-
var BetweenOpNode = class extends AbstractBetweenOpNode {
|
|
705
|
-
/**
|
|
706
|
-
* Instantiate a between operator node.
|
|
707
|
-
* @param {ExprNode} expr The input expression.
|
|
708
|
-
* @param {[ExprNode, ExprNode]} extent
|
|
709
|
-
* The range extent.
|
|
710
|
-
*/
|
|
711
|
-
constructor(expr, extent) {
|
|
712
|
-
super(BETWEEN_OPERATOR, expr, extent);
|
|
713
|
-
}
|
|
714
|
-
/**
|
|
715
|
-
* Generate a SQL query string for this node.
|
|
716
|
-
* @returns {string}
|
|
717
|
-
*/
|
|
718
|
-
toString() {
|
|
719
|
-
return super.toSQL("BETWEEN");
|
|
720
|
-
}
|
|
721
|
-
};
|
|
722
|
-
var NotBetweenOpNode = class extends AbstractBetweenOpNode {
|
|
723
|
-
/**
|
|
724
|
-
* Instantiate a not between operator node.
|
|
725
|
-
* @param {ExprNode} expr The input expression.
|
|
726
|
-
* @param {[ExprNode, ExprNode]} extent
|
|
727
|
-
* The range extent.
|
|
728
|
-
*/
|
|
729
|
-
constructor(expr, extent) {
|
|
730
|
-
super(NOT_BETWEEN_OPERATOR, expr, extent);
|
|
731
|
-
}
|
|
732
|
-
/**
|
|
733
|
-
* Generate a SQL query string for this node.
|
|
734
|
-
* @returns {string}
|
|
735
|
-
*/
|
|
736
|
-
toString() {
|
|
737
|
-
return super.toSQL("NOT BETWEEN");
|
|
738
|
-
}
|
|
739
|
-
};
|
|
740
|
-
|
|
741
|
-
// src/ast/binary-op.js
|
|
742
|
-
var BinaryOpNode = class extends ExprNode {
|
|
743
|
-
/**
|
|
744
|
-
* Instantiate a binary operator node.
|
|
745
|
-
* @param {string} op The operator type.
|
|
746
|
-
* @param {ExprNode} left The left input expression.
|
|
747
|
-
* @param {ExprNode} right The right input expression.
|
|
748
|
-
*/
|
|
749
|
-
constructor(op, left, right) {
|
|
750
|
-
super(BINARY_OPERATOR);
|
|
751
|
-
this.op = op;
|
|
752
|
-
this.left = left;
|
|
753
|
-
this.right = right;
|
|
754
|
-
}
|
|
755
|
-
/**
|
|
756
|
-
* Generate a SQL query string for this node.
|
|
757
|
-
* @returns {string}
|
|
758
|
-
*/
|
|
759
|
-
toString() {
|
|
760
|
-
return `(${this.left} ${this.op} ${this.right})`;
|
|
761
|
-
}
|
|
762
|
-
};
|
|
763
|
-
|
|
764
|
-
// src/ast/case.js
|
|
765
|
-
var CaseNode = class _CaseNode extends ExprNode {
|
|
766
|
-
/**
|
|
767
|
-
* Instantiate a case node.
|
|
768
|
-
* @param {ExprNode} [expr] An optional base expression, that comes
|
|
769
|
-
* immediately after the CASE keyword. If specified, this case statement
|
|
770
|
-
* acts like a switch statement, with WHEN expressions as values to
|
|
771
|
-
* match against the switch value rather than boolean conditions.
|
|
772
|
-
* @param {WhenNode[]} [when] An array of WHEN/THEN expression nodes.
|
|
773
|
-
* @param {ExprNode} [elseExpr] An ELSE expression.
|
|
774
|
-
*/
|
|
775
|
-
constructor(expr = void 0, when = [], elseExpr = void 0) {
|
|
776
|
-
super(CASE);
|
|
777
|
-
this.expr = expr;
|
|
778
|
-
this._when = when;
|
|
779
|
-
this._else = elseExpr;
|
|
780
|
-
}
|
|
781
|
-
/**
|
|
782
|
-
* Return a new case node with the given conditional added as
|
|
783
|
-
* the last WHEN / THEN pair.
|
|
784
|
-
* @param {import('../types.js').ExprValue} cond
|
|
785
|
-
* The WHEN condition expression.
|
|
786
|
-
* @param {import('../types.js').ExprValue} value
|
|
787
|
-
* The THEN value expression.
|
|
788
|
-
* @returns {CaseNode}
|
|
789
|
-
*/
|
|
790
|
-
when(cond2, value) {
|
|
791
|
-
return new _CaseNode(
|
|
792
|
-
this.expr,
|
|
793
|
-
this._when.concat(new WhenNode(asNode(cond2), asNode(value))),
|
|
794
|
-
this._else
|
|
795
|
-
);
|
|
796
|
-
}
|
|
797
|
-
/**
|
|
798
|
-
* Return a new case node with the given ELSE expression.
|
|
799
|
-
* @param {import('../types.js').ExprValue} expr The ELSE expression.
|
|
800
|
-
* @returns {CaseNode}
|
|
801
|
-
*/
|
|
802
|
-
else(expr) {
|
|
803
|
-
return new _CaseNode(this.expr, this._when, asNode(expr));
|
|
804
|
-
}
|
|
805
|
-
/**
|
|
806
|
-
* Generate a SQL query string for this node.
|
|
807
|
-
* @returns {string}
|
|
808
|
-
*/
|
|
809
|
-
toString() {
|
|
810
|
-
return "CASE " + (this.expr ? `${this.expr} ` : "") + this._when.join(" ") + (this._else ? ` ELSE ${this._else}` : "") + " END";
|
|
811
|
-
}
|
|
812
|
-
};
|
|
813
|
-
var WhenNode = class extends SQLNode {
|
|
814
|
-
/**
|
|
815
|
-
* Instantiate a case node.
|
|
816
|
-
* @param {ExprNode} when The WHEN condition expression.
|
|
817
|
-
* @param {ExprNode} then The THEN value expression.
|
|
818
|
-
*/
|
|
819
|
-
constructor(when, then) {
|
|
820
|
-
super(WHEN);
|
|
821
|
-
this.when = when;
|
|
822
|
-
this.then = then;
|
|
823
|
-
}
|
|
824
|
-
/**
|
|
825
|
-
* Generate a SQL query string for this node.
|
|
826
|
-
* @returns {string}
|
|
827
|
-
*/
|
|
828
|
-
toString() {
|
|
829
|
-
return `WHEN ${this.when} THEN ${this.then}`;
|
|
830
|
-
}
|
|
831
|
-
};
|
|
832
|
-
|
|
833
|
-
// src/ast/cast.js
|
|
834
|
-
var CastNode = class extends ExprNode {
|
|
835
|
-
/**
|
|
836
|
-
* Instantiate a cast node.
|
|
837
|
-
* @param {ExprNode} expr The expression to type cast.
|
|
838
|
-
* @param {string} type The type to cast to.
|
|
839
|
-
*/
|
|
840
|
-
constructor(expr, type) {
|
|
841
|
-
super(CAST);
|
|
842
|
-
this.expr = expr;
|
|
843
|
-
this.cast = type;
|
|
844
|
-
}
|
|
845
|
-
/**
|
|
846
|
-
* Generate a SQL query string for this node.
|
|
847
|
-
* @returns {string}
|
|
848
|
-
*/
|
|
849
|
-
toString() {
|
|
850
|
-
return `(${this.expr})::${this.cast}`;
|
|
851
|
-
}
|
|
852
|
-
};
|
|
853
|
-
|
|
854
|
-
// src/ast/fragment.js
|
|
855
|
-
var FragmentNode = class extends ExprNode {
|
|
856
|
-
/**
|
|
857
|
-
* Instantiate a fragment node with arbitrary content.
|
|
858
|
-
* @param {ExprNode[]} spans The consecutive parts making up the fragment.
|
|
859
|
-
*/
|
|
860
|
-
constructor(spans) {
|
|
861
|
-
super(FRAGMENT);
|
|
862
|
-
this.spans = spans;
|
|
863
|
-
}
|
|
864
|
-
/**
|
|
865
|
-
* Generate a SQL query string for this node.
|
|
866
|
-
* @returns {string}
|
|
867
|
-
*/
|
|
868
|
-
toString() {
|
|
869
|
-
return this.spans.join("");
|
|
870
|
-
}
|
|
871
|
-
};
|
|
872
|
-
|
|
873
|
-
// src/ast/sample.js
|
|
874
|
-
var SampleClauseNode = class extends SQLNode {
|
|
875
|
-
/**
|
|
876
|
-
* Instantiate a sample clause node.
|
|
877
|
-
* @param {number} size The sample size as either a row count or percentage.
|
|
878
|
-
* @param {boolean} [perc=false] Flag indicating if the sampling unit is
|
|
879
|
-
* rows (`false`) or a percentage (`true`).
|
|
880
|
-
* @param {SampleMethod} [method] The sampling method. If unspecified,
|
|
881
|
-
* a default method is applied based on the sampling unit.
|
|
882
|
-
* @param {number} [seed] The random seed.
|
|
883
|
-
*/
|
|
884
|
-
constructor(size, perc = false, method = void 0, seed = void 0) {
|
|
885
|
-
super(SAMPLE_CLAUSE);
|
|
886
|
-
this.size = size;
|
|
887
|
-
this.perc = perc;
|
|
888
|
-
this.method = method;
|
|
889
|
-
this.seed = seed;
|
|
890
|
-
}
|
|
891
|
-
toString() {
|
|
892
|
-
const { size, perc, method, seed } = this;
|
|
893
|
-
const unit = perc ? "%" : " ROWS";
|
|
894
|
-
const s = seed != null ? `, ${seed}` : "";
|
|
895
|
-
return `${size}${unit}${method ? ` (${method}${s})` : ""}`;
|
|
896
|
-
}
|
|
897
|
-
};
|
|
898
|
-
|
|
899
|
-
// src/ast/select.js
|
|
900
|
-
var SelectClauseNode = class extends SQLNode {
|
|
901
|
-
/**
|
|
902
|
-
* Instantiate a select node.
|
|
903
|
-
* @param {ExprNode} expr The select expression.
|
|
904
|
-
* @param {string} alias The output name.
|
|
905
|
-
*/
|
|
906
|
-
constructor(expr, alias) {
|
|
907
|
-
super(SELECT_CLAUSE);
|
|
908
|
-
this.expr = expr;
|
|
909
|
-
this.alias = alias;
|
|
910
|
-
}
|
|
911
|
-
/**
|
|
912
|
-
* Generate a SQL query string for this node.
|
|
913
|
-
* @returns {string}
|
|
914
|
-
*/
|
|
915
|
-
toString() {
|
|
916
|
-
const { expr, alias } = this;
|
|
917
|
-
return !alias || isColumnRefFor(expr, alias) ? `${expr}` : `${expr} AS ${quoteIdentifier(alias)}`;
|
|
918
|
-
}
|
|
919
|
-
};
|
|
920
|
-
function isColumnRefFor(expr, name) {
|
|
921
|
-
return expr instanceof ColumnRefNode && expr.table == null && expr.column === name;
|
|
922
|
-
}
|
|
923
|
-
|
|
924
|
-
// src/ast/with.js
|
|
925
|
-
var WithClauseNode = class extends SQLNode {
|
|
926
|
-
/**
|
|
927
|
-
* Instantiate a with clause node for a common table expression (CTE).
|
|
928
|
-
* @param {string} name The common table expression (CTE) name.
|
|
929
|
-
* @param {Query} query The common table expression (CTE) query.
|
|
930
|
-
*/
|
|
931
|
-
constructor(name, query) {
|
|
932
|
-
super(WITH_CLAUSE);
|
|
933
|
-
this.name = name;
|
|
934
|
-
this.query = query;
|
|
935
|
-
}
|
|
936
|
-
toString() {
|
|
937
|
-
return `"${this.name}" AS (${this.query})`;
|
|
938
|
-
}
|
|
939
|
-
};
|
|
940
|
-
|
|
941
|
-
// src/ast/query.js
|
|
942
|
-
function isQuery(value) {
|
|
943
|
-
return value instanceof Query;
|
|
944
|
-
}
|
|
945
|
-
function isSelectQuery(value) {
|
|
946
|
-
return value instanceof SelectQuery;
|
|
947
|
-
}
|
|
948
|
-
function isDescribeQuery(value) {
|
|
949
|
-
return value instanceof DescribeQuery;
|
|
950
|
-
}
|
|
951
|
-
var Query = class extends ExprNode {
|
|
952
|
-
/**
|
|
953
|
-
* Create a new select query with the given SELECT expressions.
|
|
954
|
-
* @param {...import('../types.js').SelectExpr} expr The SELECT expressions.
|
|
955
|
-
* @returns {SelectQuery}
|
|
956
|
-
*/
|
|
957
|
-
static select(...expr) {
|
|
958
|
-
return new SelectQuery().select(...expr);
|
|
959
|
-
}
|
|
960
|
-
/**
|
|
961
|
-
* Create a new select query with the given FROM expressions.
|
|
962
|
-
* @param {...import('../types.js').FromExpr} expr The FROM expressions.
|
|
963
|
-
* @returns {SelectQuery}
|
|
964
|
-
*/
|
|
965
|
-
static from(...expr) {
|
|
966
|
-
return new SelectQuery().from(...expr);
|
|
967
|
-
}
|
|
968
|
-
/**
|
|
969
|
-
* Create a new select query with the given WITH CTE queries.
|
|
970
|
-
* @param {...import('../types.js').WithExpr} expr The WITH CTE queries.
|
|
971
|
-
* @returns {SelectQuery}
|
|
972
|
-
*/
|
|
973
|
-
static with(...expr) {
|
|
974
|
-
return new SelectQuery().with(...expr);
|
|
975
|
-
}
|
|
976
|
-
/**
|
|
977
|
-
* Create a new UNION set operation over the given queries.
|
|
978
|
-
* @param {...Query} queries The queries.
|
|
979
|
-
* @returns {SetOperation}
|
|
980
|
-
*/
|
|
981
|
-
static union(...queries) {
|
|
982
|
-
return new SetOperation("UNION", queries.flat());
|
|
983
|
-
}
|
|
984
|
-
/**
|
|
985
|
-
* Create a new UNION ALL set operation over the given queries.
|
|
986
|
-
* @param {...Query} queries The queries.
|
|
987
|
-
* @returns {SetOperation}
|
|
988
|
-
*/
|
|
989
|
-
static unionAll(...queries) {
|
|
990
|
-
return new SetOperation("UNION ALL", queries.flat());
|
|
991
|
-
}
|
|
992
|
-
/**
|
|
993
|
-
* Create a new INTERSECT set operation over the given queries.
|
|
994
|
-
* @param {...Query} queries The queries.
|
|
995
|
-
* @returns {SetOperation}
|
|
996
|
-
*/
|
|
997
|
-
static intersect(...queries) {
|
|
998
|
-
return new SetOperation("INTERSECT", queries.flat());
|
|
999
|
-
}
|
|
1000
|
-
/**
|
|
1001
|
-
* Create a new EXCEPT set operation over the given queries.
|
|
1002
|
-
* @param {...Query} queries The queries.
|
|
1003
|
-
* @returns {SetOperation}
|
|
1004
|
-
*/
|
|
1005
|
-
static except(...queries) {
|
|
1006
|
-
return new SetOperation("EXCEPT", queries.flat());
|
|
1007
|
-
}
|
|
1008
|
-
/**
|
|
1009
|
-
* Create a new describe query for the given input query.
|
|
1010
|
-
* @param {Query} query The query to describe.
|
|
1011
|
-
* @returns {DescribeQuery}
|
|
1012
|
-
*/
|
|
1013
|
-
static describe(query) {
|
|
1014
|
-
return new DescribeQuery(query);
|
|
1015
|
-
}
|
|
1016
|
-
/**
|
|
1017
|
-
* Instantiate a new query.
|
|
1018
|
-
*/
|
|
1019
|
-
constructor(type) {
|
|
1020
|
-
super(type);
|
|
1021
|
-
this._orderby = [];
|
|
1022
|
-
this._limit = void 0;
|
|
1023
|
-
this._offset = void 0;
|
|
1024
|
-
this.cteFor = null;
|
|
1025
|
-
}
|
|
1026
|
-
/**
|
|
1027
|
-
* Return a list of subqueries.
|
|
1028
|
-
* @returns {Query[]}
|
|
1029
|
-
*/
|
|
1030
|
-
get subqueries() {
|
|
1031
|
-
return [];
|
|
1032
|
-
}
|
|
1033
|
-
/**
|
|
1034
|
-
* Clone this query.
|
|
1035
|
-
* @returns {Query}
|
|
1036
|
-
*/
|
|
1037
|
-
clone() {
|
|
1038
|
-
return this;
|
|
1039
|
-
}
|
|
1040
|
-
/**
|
|
1041
|
-
* Add ORDER BY expressions.
|
|
1042
|
-
* @param {...import('../types.js').OrderByExpr} expr Expressions to add.
|
|
1043
|
-
* @returns
|
|
1044
|
-
*/
|
|
1045
|
-
orderby(...expr) {
|
|
1046
|
-
this._orderby = this._orderby.concat(exprList(expr));
|
|
1047
|
-
return this;
|
|
1048
|
-
}
|
|
1049
|
-
/**
|
|
1050
|
-
* Set the query result LIMIT.
|
|
1051
|
-
* @param {number} value The limit value.
|
|
1052
|
-
* @returns {this}
|
|
1053
|
-
*/
|
|
1054
|
-
limit(value) {
|
|
1055
|
-
this._limit = Number.isFinite(value) ? value : void 0;
|
|
1056
|
-
return this;
|
|
1057
|
-
}
|
|
1058
|
-
/**
|
|
1059
|
-
* Set the query result OFFSET.
|
|
1060
|
-
* @param {number} value The offset value.
|
|
1061
|
-
* @returns {this}
|
|
1062
|
-
*/
|
|
1063
|
-
offset(value) {
|
|
1064
|
-
this._offset = Number.isFinite(value) ? value : void 0;
|
|
1065
|
-
return this;
|
|
1066
|
-
}
|
|
1067
|
-
};
|
|
1068
|
-
var SelectQuery = class _SelectQuery extends Query {
|
|
1069
|
-
/**
|
|
1070
|
-
* Instantiate a new select query.
|
|
1071
|
-
*/
|
|
1072
|
-
constructor() {
|
|
1073
|
-
super(SELECT_QUERY);
|
|
1074
|
-
this._with = [];
|
|
1075
|
-
this._select = [];
|
|
1076
|
-
this._from = [];
|
|
1077
|
-
this._where = [];
|
|
1078
|
-
this._sample = void 0;
|
|
1079
|
-
this._groupby = [];
|
|
1080
|
-
this._having = [];
|
|
1081
|
-
this._window = [];
|
|
1082
|
-
this._qualify = [];
|
|
1083
|
-
}
|
|
1084
|
-
/**
|
|
1085
|
-
* Return a list of subqueries.
|
|
1086
|
-
* @returns {Query[]}
|
|
1087
|
-
*/
|
|
1088
|
-
get subqueries() {
|
|
1089
|
-
const q = this.cteFor || this;
|
|
1090
|
-
const w = q instanceof _SelectQuery ? q._with : [];
|
|
1091
|
-
const cte = w.reduce((obj, c) => (obj[c.name] = c.query, obj), {});
|
|
1092
|
-
const queries = [];
|
|
1093
|
-
this._from.forEach(({ expr }) => {
|
|
1094
|
-
if (isQuery(expr)) {
|
|
1095
|
-
queries.push(expr);
|
|
1096
|
-
} else if (isTableRef(expr)) {
|
|
1097
|
-
const subq = cte[expr.name];
|
|
1098
|
-
if (subq) queries.push(subq);
|
|
1099
|
-
}
|
|
1100
|
-
});
|
|
1101
|
-
return queries;
|
|
1102
|
-
}
|
|
1103
|
-
/**
|
|
1104
|
-
* Clone this query.
|
|
1105
|
-
* @returns {SelectQuery}
|
|
1106
|
-
*/
|
|
1107
|
-
clone() {
|
|
1108
|
-
return Object.assign(new _SelectQuery(), this);
|
|
1109
|
-
}
|
|
1110
|
-
/**
|
|
1111
|
-
* Add WITH common table expressions (CTEs).
|
|
1112
|
-
* @param {...import('../types.js').WithExpr} expr Expressions to add.
|
|
1113
|
-
* @returns {this}
|
|
1114
|
-
*/
|
|
1115
|
-
with(...expr) {
|
|
1116
|
-
const list = [];
|
|
1117
|
-
const add2 = (name, q) => {
|
|
1118
|
-
const query = q.clone();
|
|
1119
|
-
query.cteFor = this;
|
|
1120
|
-
list.push(new WithClauseNode(name, query));
|
|
1121
|
-
};
|
|
1122
|
-
expr.flat().forEach((e) => {
|
|
1123
|
-
if (e != null) for (const name in e) add2(name, e[name]);
|
|
1124
|
-
});
|
|
1125
|
-
this._with = this._with.concat(list);
|
|
1126
|
-
return this;
|
|
1127
|
-
}
|
|
1128
|
-
/**
|
|
1129
|
-
* Add SELECT expressions.
|
|
1130
|
-
* @param {...import('../types.js').SelectExpr} expr Expressions to add.
|
|
1131
|
-
* @returns {this}
|
|
1132
|
-
*/
|
|
1133
|
-
select(...expr) {
|
|
1134
|
-
const list = [];
|
|
1135
|
-
const add2 = (v, as) => list.push(
|
|
1136
|
-
new SelectClauseNode(v == null ? v : asNode(v), unquote(as))
|
|
1137
|
-
);
|
|
1138
|
-
expr.flat().forEach((e) => {
|
|
1139
|
-
if (e == null) return;
|
|
1140
|
-
else if (isString(e)) add2(e, e);
|
|
1141
|
-
else if (isColumnRef(e)) add2(e, e.column);
|
|
1142
|
-
else if (isArray(e)) add2(e[1], e[0]);
|
|
1143
|
-
else for (const alias in e) add2(e[alias], alias);
|
|
1144
|
-
});
|
|
1145
|
-
const keys = new Set(list.map((x2) => x2.alias));
|
|
1146
|
-
this._select = this._select.filter((x2) => !keys.has(x2.alias)).concat(list.filter((x2) => x2.expr));
|
|
1147
|
-
return this;
|
|
1148
|
-
}
|
|
1149
|
-
/**
|
|
1150
|
-
* Set SELECT expressions, replacing any prior expressions.
|
|
1151
|
-
* @param {...import('../types.js').SelectExpr} expr Expressions to add.
|
|
1152
|
-
* @returns {this}
|
|
1153
|
-
*/
|
|
1154
|
-
setSelect(...expr) {
|
|
1155
|
-
this._select = [];
|
|
1156
|
-
return this.select(...expr);
|
|
1157
|
-
}
|
|
1158
|
-
/**
|
|
1159
|
-
* Indicate if this query should retrieve distinct values only.
|
|
1160
|
-
* @param {boolean} value The distinct flag
|
|
1161
|
-
* @returns {this}
|
|
1162
|
-
*/
|
|
1163
|
-
distinct(value = true) {
|
|
1164
|
-
this._distinct = !!value;
|
|
1165
|
-
return this;
|
|
1166
|
-
}
|
|
1167
|
-
/**
|
|
1168
|
-
* Add table FROM expressions.
|
|
1169
|
-
* @param {...import('../types.js').FromExpr} expr Expressions to add.
|
|
1170
|
-
* @returns {this}
|
|
1171
|
-
*/
|
|
1172
|
-
from(...expr) {
|
|
1173
|
-
const list = [];
|
|
1174
|
-
const add2 = (v, as) => list.push(new FromClauseNode(asTableRef(v), unquote(as)));
|
|
1175
|
-
expr.flat().forEach((e) => {
|
|
1176
|
-
if (e == null) return;
|
|
1177
|
-
else if (isString(e)) add2(e, e);
|
|
1178
|
-
else if (isTableRef(e)) add2(e, e.name);
|
|
1179
|
-
else if (isNode(e)) add2(e);
|
|
1180
|
-
else if (isArray(e)) add2(e[1], e[0]);
|
|
1181
|
-
else for (const alias in e) add2(e[alias], alias);
|
|
1182
|
-
});
|
|
1183
|
-
this._from = this._from.concat(list);
|
|
1184
|
-
return this;
|
|
1185
|
-
}
|
|
1186
|
-
/**
|
|
1187
|
-
* Set FROM expressions, replacing any prior expressions.
|
|
1188
|
-
* @param {...import('../types.js').FromExpr} expr Expressions to add.
|
|
1189
|
-
* @returns {this}
|
|
1190
|
-
*/
|
|
1191
|
-
setFrom(...expr) {
|
|
1192
|
-
this._from = [];
|
|
1193
|
-
return this.from(...expr);
|
|
1194
|
-
}
|
|
1195
|
-
/**
|
|
1196
|
-
* Set SAMPLE settings.
|
|
1197
|
-
* @param {number | SampleClauseNode} value Either a sample clause node
|
|
1198
|
-
* or the sample size as either a row count or percentage.
|
|
1199
|
-
* @param {import('./sample.js').SampleMethod} [method] The sampling method
|
|
1200
|
-
* to use.
|
|
1201
|
-
* @param {number} [seed] The random seed.
|
|
1202
|
-
* @returns {this}
|
|
1203
|
-
*/
|
|
1204
|
-
sample(value, method, seed) {
|
|
1205
|
-
let clause;
|
|
1206
|
-
if (typeof value === "number") {
|
|
1207
|
-
const perc = value > 0 && value < 1;
|
|
1208
|
-
const size = perc ? value * 100 : Math.floor(value);
|
|
1209
|
-
clause = new SampleClauseNode(size, perc, method, seed);
|
|
1210
|
-
} else {
|
|
1211
|
-
clause = value;
|
|
1212
|
-
}
|
|
1213
|
-
this._sample = clause;
|
|
1214
|
-
return this;
|
|
1215
|
-
}
|
|
1216
|
-
/**
|
|
1217
|
-
* Add WHERE expressions.
|
|
1218
|
-
* @param {...import('../types.js').FilterExpr} expr Expressions to add.
|
|
1219
|
-
* @returns {this}
|
|
1220
|
-
*/
|
|
1221
|
-
where(...expr) {
|
|
1222
|
-
this._where = this._where.concat(exprList(expr, asVerbatim));
|
|
1223
|
-
return this;
|
|
1224
|
-
}
|
|
1225
|
-
/**
|
|
1226
|
-
* Set WHERE expressions, replacing any prior expressions.
|
|
1227
|
-
* @param {...import('../types.js').FilterExpr} expr Expressions to add.
|
|
1228
|
-
* @returns {this}
|
|
1229
|
-
*/
|
|
1230
|
-
setWhere(...expr) {
|
|
1231
|
-
this._where = [];
|
|
1232
|
-
return this.where(...expr);
|
|
1233
|
-
}
|
|
1234
|
-
/**
|
|
1235
|
-
* Add GROUP BY expressions.
|
|
1236
|
-
* @param {...import('../types.js').GroupByExpr} expr Expressions to add.
|
|
1237
|
-
* @returns {this}
|
|
1238
|
-
*/
|
|
1239
|
-
groupby(...expr) {
|
|
1240
|
-
this._groupby = this._groupby.concat(exprList(expr));
|
|
1241
|
-
return this;
|
|
1242
|
-
}
|
|
1243
|
-
/**
|
|
1244
|
-
* Set GROUP BY expressions, replacing any prior expressions.
|
|
1245
|
-
* @param {...import('../types.js').GroupByExpr} expr Expressions to add.
|
|
1246
|
-
* @returns {this}
|
|
1247
|
-
*/
|
|
1248
|
-
setGroupby(...expr) {
|
|
1249
|
-
this._groupby = [];
|
|
1250
|
-
return this.groupby(...expr);
|
|
1251
|
-
}
|
|
1252
|
-
/**
|
|
1253
|
-
* Add HAVING expressions.
|
|
1254
|
-
* @param {...import('../types.js').FilterExpr} expr Expressions to add.
|
|
1255
|
-
* @returns {this}
|
|
1256
|
-
*/
|
|
1257
|
-
having(...expr) {
|
|
1258
|
-
this._having = this._having.concat(exprList(expr, asVerbatim));
|
|
1259
|
-
return this;
|
|
1260
|
-
}
|
|
1261
|
-
/**
|
|
1262
|
-
* Add WINDOW definitions.
|
|
1263
|
-
* @param {...any} expr Expressions to add.
|
|
1264
|
-
* @returns {this}
|
|
1265
|
-
*/
|
|
1266
|
-
window(...expr) {
|
|
1267
|
-
const list = [];
|
|
1268
|
-
expr.flat().forEach((e) => {
|
|
1269
|
-
if (e != null) for (const name in e) {
|
|
1270
|
-
list.push(new WindowClauseNode(unquote(name), e[name]));
|
|
1271
|
-
}
|
|
1272
|
-
});
|
|
1273
|
-
this._window = this._window.concat(list);
|
|
1274
|
-
return this;
|
|
1275
|
-
}
|
|
1276
|
-
/**
|
|
1277
|
-
* Add QUALIFY expressions.
|
|
1278
|
-
* @param {...import('../types.js').FilterExpr} expr Expressions to add.
|
|
1279
|
-
* @returns {this}
|
|
1280
|
-
*/
|
|
1281
|
-
qualify(...expr) {
|
|
1282
|
-
this._qualify = this._qualify.concat(exprList(expr, asVerbatim));
|
|
1283
|
-
return this;
|
|
1284
|
-
}
|
|
1285
|
-
/**
|
|
1286
|
-
* Generate a SQL query string.
|
|
1287
|
-
* @returns {string}
|
|
1288
|
-
*/
|
|
1289
|
-
toString() {
|
|
1290
|
-
const {
|
|
1291
|
-
_with,
|
|
1292
|
-
_select,
|
|
1293
|
-
_distinct,
|
|
1294
|
-
_from,
|
|
1295
|
-
_sample,
|
|
1296
|
-
_where,
|
|
1297
|
-
_groupby,
|
|
1298
|
-
_having,
|
|
1299
|
-
_window,
|
|
1300
|
-
_qualify,
|
|
1301
|
-
_orderby,
|
|
1302
|
-
_limit,
|
|
1303
|
-
_offset
|
|
1304
|
-
} = this;
|
|
1305
|
-
const sql2 = [];
|
|
1306
|
-
if (_with.length) sql2.push(`WITH ${_with.join(", ")}`);
|
|
1307
|
-
sql2.push(`SELECT${_distinct ? " DISTINCT" : ""} ${_select.join(", ")}`);
|
|
1308
|
-
if (_from.length) sql2.push(`FROM ${_from.join(", ")}`);
|
|
1309
|
-
if (_where.length) {
|
|
1310
|
-
const clauses = _where.map(String).filter((x2) => x2).join(" AND ");
|
|
1311
|
-
if (clauses) sql2.push(`WHERE ${clauses}`);
|
|
1312
|
-
}
|
|
1313
|
-
if (_sample) sql2.push(`USING SAMPLE ${_sample}`);
|
|
1314
|
-
if (_groupby.length) {
|
|
1315
|
-
sql2.push(`GROUP BY ${_groupby.join(", ")}`);
|
|
1316
|
-
}
|
|
1317
|
-
if (_having.length) {
|
|
1318
|
-
const clauses = _having.map(String).filter((x2) => x2).join(" AND ");
|
|
1319
|
-
if (clauses) sql2.push(`HAVING ${clauses}`);
|
|
1320
|
-
}
|
|
1321
|
-
if (_window.length) sql2.push(`WINDOW ${_window.join(", ")}`);
|
|
1322
|
-
if (_qualify.length) {
|
|
1323
|
-
const clauses = _qualify.map(String).filter((x2) => x2).join(" AND ");
|
|
1324
|
-
if (clauses) sql2.push(`QUALIFY ${clauses}`);
|
|
1325
|
-
}
|
|
1326
|
-
if (_orderby.length) sql2.push(`ORDER BY ${_orderby.join(", ")}`);
|
|
1327
|
-
if (Number.isFinite(_limit)) sql2.push(`LIMIT ${_limit}`);
|
|
1328
|
-
if (Number.isFinite(_offset)) sql2.push(`OFFSET ${_offset}`);
|
|
1329
|
-
return sql2.join(" ");
|
|
1330
|
-
}
|
|
1331
|
-
};
|
|
1332
|
-
var DescribeQuery = class _DescribeQuery extends SQLNode {
|
|
1333
|
-
/**
|
|
1334
|
-
* Instantiate a describe query.
|
|
1335
|
-
*/
|
|
1336
|
-
constructor(query) {
|
|
1337
|
-
super(DESCRIBE_QUERY);
|
|
1338
|
-
this.query = query;
|
|
1339
|
-
}
|
|
1340
|
-
/**
|
|
1341
|
-
* Clone this describe query.
|
|
1342
|
-
* @returns {DescribeQuery}
|
|
1343
|
-
*/
|
|
1344
|
-
clone() {
|
|
1345
|
-
return new _DescribeQuery(this.query.clone());
|
|
1346
|
-
}
|
|
1347
|
-
/**
|
|
1348
|
-
* Generate a SQL query string.
|
|
1349
|
-
* @returns {string}
|
|
1350
|
-
*/
|
|
1351
|
-
toString() {
|
|
1352
|
-
return `DESCRIBE ${this.query}`;
|
|
1353
|
-
}
|
|
1354
|
-
};
|
|
1355
|
-
var SetOperation = class _SetOperation extends Query {
|
|
1356
|
-
/**
|
|
1357
|
-
* Instantiate a new set operation instance.
|
|
1358
|
-
* @param {string} op The set operation.
|
|
1359
|
-
* @param {Query[]} queries The subqueries.
|
|
1360
|
-
*/
|
|
1361
|
-
constructor(op, queries) {
|
|
1362
|
-
super(SET_OPERATION);
|
|
1363
|
-
this.op = op;
|
|
1364
|
-
this.queries = queries;
|
|
1365
|
-
}
|
|
1366
|
-
/**
|
|
1367
|
-
* Return a list of subqueries.
|
|
1368
|
-
* @returns {Query[]}
|
|
1369
|
-
*/
|
|
1370
|
-
get subqueries() {
|
|
1371
|
-
const { queries, cteFor } = this;
|
|
1372
|
-
if (cteFor) queries.forEach((q) => q.cteFor = cteFor);
|
|
1373
|
-
return queries;
|
|
1374
|
-
}
|
|
1375
|
-
/**
|
|
1376
|
-
* Clone this set operation.
|
|
1377
|
-
* @returns {SetOperation}
|
|
1378
|
-
*/
|
|
1379
|
-
clone() {
|
|
1380
|
-
const { op, queries, ...rest } = this;
|
|
1381
|
-
return Object.assign(new _SetOperation(op, queries), rest);
|
|
1382
|
-
}
|
|
1383
|
-
/**
|
|
1384
|
-
* Generate a SQL query string.
|
|
1385
|
-
* @returns {string}
|
|
1386
|
-
*/
|
|
1387
|
-
toString() {
|
|
1388
|
-
const { op, queries, _orderby, _limit, _offset } = this;
|
|
1389
|
-
const sql2 = [queries.join(` ${op} `)];
|
|
1390
|
-
if (_orderby.length) sql2.push(`ORDER BY ${_orderby.join(", ")}`);
|
|
1391
|
-
if (Number.isFinite(_limit)) sql2.push(`LIMIT ${_limit}`);
|
|
1392
|
-
if (Number.isFinite(_offset)) sql2.push(`OFFSET ${_offset}`);
|
|
1393
|
-
return sql2.join(" ");
|
|
1394
|
-
}
|
|
1395
|
-
};
|
|
1396
|
-
|
|
1397
|
-
// src/ast/from.js
|
|
1398
|
-
var FromClauseNode = class extends SQLNode {
|
|
1399
|
-
/**
|
|
1400
|
-
* Instantiate a from node.
|
|
1401
|
-
* @param {SQLNode} expr The from expression.
|
|
1402
|
-
* @param {string} alias The output name.
|
|
1403
|
-
*/
|
|
1404
|
-
constructor(expr, alias) {
|
|
1405
|
-
super(FROM_CLAUSE);
|
|
1406
|
-
this.expr = expr;
|
|
1407
|
-
this.alias = alias;
|
|
1408
|
-
}
|
|
1409
|
-
/**
|
|
1410
|
-
* Generate a SQL query string for this node.
|
|
1411
|
-
* @returns {string}
|
|
1412
|
-
*/
|
|
1413
|
-
toString() {
|
|
1414
|
-
const { expr, alias } = this;
|
|
1415
|
-
const ref = isQuery(expr) ? `(${expr})` : `${expr}`;
|
|
1416
|
-
return alias && !(isTableRef(expr) && expr.table.join(".") === alias) ? `${ref} AS ${quoteIdentifier(alias)}` : `${ref}`;
|
|
1417
|
-
}
|
|
1418
|
-
};
|
|
1419
|
-
|
|
1420
|
-
// src/ast/in-op.js
|
|
1421
|
-
var InOpNode = class extends ExprNode {
|
|
1422
|
-
/**
|
|
1423
|
-
* Instantiate an in operator node.
|
|
1424
|
-
* @param {ExprNode} expr The input expression.
|
|
1425
|
-
* @param {ExprNode[]} values The value set.
|
|
1426
|
-
*/
|
|
1427
|
-
constructor(expr, values) {
|
|
1428
|
-
super(IN_OPERATOR);
|
|
1429
|
-
this.expr = expr;
|
|
1430
|
-
this.values = values;
|
|
1431
|
-
}
|
|
1432
|
-
/**
|
|
1433
|
-
* Generate a SQL query string for this node.
|
|
1434
|
-
* @returns {string}
|
|
1435
|
-
*/
|
|
1436
|
-
toString() {
|
|
1437
|
-
return `(${this.expr} IN (${this.values.join(", ")}))`;
|
|
1438
|
-
}
|
|
1439
|
-
};
|
|
1440
|
-
|
|
1441
|
-
// src/ast/interval.js
|
|
1442
|
-
var IntervalNode = class extends ExprNode {
|
|
1443
|
-
/**
|
|
1444
|
-
* Instantiate an interval node.
|
|
1445
|
-
* @param {string} name The interval name.
|
|
1446
|
-
* @param {number} [steps=1] The interval steps.
|
|
1447
|
-
*/
|
|
1448
|
-
constructor(name, steps = 1) {
|
|
1449
|
-
super(INTERVAL);
|
|
1450
|
-
this.name = name;
|
|
1451
|
-
this.steps = steps;
|
|
1452
|
-
}
|
|
1453
|
-
/**
|
|
1454
|
-
* Generate a SQL query string for this node.
|
|
1455
|
-
* @returns {string}
|
|
1456
|
-
*/
|
|
1457
|
-
toString() {
|
|
1458
|
-
return `INTERVAL ${this.steps} ${this.name}`;
|
|
1459
|
-
}
|
|
1460
|
-
};
|
|
1461
|
-
|
|
1462
|
-
// src/ast/logical-op.js
|
|
1463
|
-
var LogicalOpNode = class extends ExprNode {
|
|
1464
|
-
/**
|
|
1465
|
-
* Instantiate a logical operator node.
|
|
1466
|
-
* @param {string} op The logical operation.
|
|
1467
|
-
* @param {T[]} clauses The input clause expressions.
|
|
1468
|
-
*/
|
|
1469
|
-
constructor(op, clauses) {
|
|
1470
|
-
super(LOGICAL_OPERATOR);
|
|
1471
|
-
this.op = op;
|
|
1472
|
-
this.clauses = clauses;
|
|
1473
|
-
}
|
|
1474
|
-
/**
|
|
1475
|
-
* Generate a SQL query string for this node.
|
|
1476
|
-
* @returns {string}
|
|
1477
|
-
*/
|
|
1478
|
-
toString() {
|
|
1479
|
-
const c = this.clauses;
|
|
1480
|
-
return c.length === 0 ? "" : c.length === 1 ? `${c[0]}` : `(${c.join(` ${this.op} `)})`;
|
|
1481
|
-
}
|
|
1482
|
-
};
|
|
1483
|
-
var AndNode = class extends LogicalOpNode {
|
|
1484
|
-
/**
|
|
1485
|
-
* Instantiate a logical AND operator node.
|
|
1486
|
-
* @param {T[]} clauses The input clause expressions.
|
|
1487
|
-
*/
|
|
1488
|
-
constructor(clauses) {
|
|
1489
|
-
super("AND", clauses);
|
|
1490
|
-
}
|
|
1491
|
-
};
|
|
1492
|
-
var OrNode = class extends LogicalOpNode {
|
|
1493
|
-
/**
|
|
1494
|
-
* Instantiate a logical OR operator node.
|
|
1495
|
-
* @param {T[]} clauses The input clause expressions.
|
|
1496
|
-
*/
|
|
1497
|
-
constructor(clauses) {
|
|
1498
|
-
super("OR", clauses);
|
|
1499
|
-
}
|
|
1500
|
-
};
|
|
1501
|
-
|
|
1502
|
-
// src/ast/order-by.js
|
|
1503
|
-
var OrderByNode = class extends ExprNode {
|
|
1504
|
-
/**
|
|
1505
|
-
* Instantiate an order by entry node.
|
|
1506
|
-
* @param {ExprNode} expr The expression to order by.
|
|
1507
|
-
* @param {boolean | undefined} [desc] Flag indicating descending order.
|
|
1508
|
-
* @param {boolean | undefined} [nullsFirst] Flag indicating if null
|
|
1509
|
-
* values should be sorted first.
|
|
1510
|
-
*/
|
|
1511
|
-
constructor(expr, desc2, nullsFirst) {
|
|
1512
|
-
super(ORDER_BY);
|
|
1513
|
-
this.expr = expr;
|
|
1514
|
-
this.desc = desc2;
|
|
1515
|
-
this.nullsFirst = nullsFirst;
|
|
1516
|
-
}
|
|
1517
|
-
/**
|
|
1518
|
-
* Generate a SQL query string for this node.
|
|
1519
|
-
* @returns {string}
|
|
1520
|
-
*/
|
|
1521
|
-
toString() {
|
|
1522
|
-
const { expr, desc: desc2, nullsFirst } = this;
|
|
1523
|
-
const dir = desc2 ? " DESC" : desc2 === false ? " ASC" : "";
|
|
1524
|
-
const nf = nullsFirst ? " NULLS FIRST" : nullsFirst === false ? " NULLS LAST" : "";
|
|
1525
|
-
return `${expr}${dir}${nf}`;
|
|
1526
|
-
}
|
|
1527
|
-
};
|
|
1528
|
-
|
|
1529
|
-
// src/ast/unary-op.js
|
|
1530
|
-
var AbstractUnaryOpNode = class extends ExprNode {
|
|
1531
|
-
/**
|
|
1532
|
-
* Instantiate an abstract unary operator node.
|
|
1533
|
-
* @param {string} type The node type.
|
|
1534
|
-
* @param {string} op The operator type.
|
|
1535
|
-
* @param {ExprNode} expr The input expression.
|
|
1536
|
-
*/
|
|
1537
|
-
constructor(type, op, expr) {
|
|
1538
|
-
super(type);
|
|
1539
|
-
this.op = op;
|
|
1540
|
-
this.expr = expr;
|
|
1541
|
-
}
|
|
1542
|
-
};
|
|
1543
|
-
var UnaryOpNode = class extends AbstractUnaryOpNode {
|
|
1544
|
-
/**
|
|
1545
|
-
* Instantiate a unary operator node.
|
|
1546
|
-
* @param {string} op The operator type.
|
|
1547
|
-
* @param {ExprNode} expr The input expression.
|
|
1548
|
-
*/
|
|
1549
|
-
constructor(op, expr) {
|
|
1550
|
-
super(UNARY_OPERATOR, op, expr);
|
|
1551
|
-
}
|
|
1552
|
-
/**
|
|
1553
|
-
* Generate a SQL query string for this node.
|
|
1554
|
-
* @returns {string}
|
|
1555
|
-
*/
|
|
1556
|
-
toString() {
|
|
1557
|
-
return `(${this.op} ${this.expr})`;
|
|
1558
|
-
}
|
|
1559
|
-
};
|
|
1560
|
-
var UnaryPosftixOpNode = class extends AbstractUnaryOpNode {
|
|
1561
|
-
/**
|
|
1562
|
-
* Instantiate a unary operator node.
|
|
1563
|
-
* @param {string} op The operator type.
|
|
1564
|
-
* @param {ExprNode} expr The input expression.
|
|
1565
|
-
*/
|
|
1566
|
-
constructor(op, expr) {
|
|
1567
|
-
super(UNARY_POSTFIX_OPERATOR, op, expr);
|
|
1568
|
-
}
|
|
1569
|
-
/**
|
|
1570
|
-
* Generate a SQL query string for this node.
|
|
1571
|
-
* @returns {string}
|
|
1572
|
-
*/
|
|
1573
|
-
toString() {
|
|
1574
|
-
return `(${this.expr} ${this.op})`;
|
|
1575
|
-
}
|
|
1576
|
-
};
|
|
1577
|
-
|
|
1578
|
-
// src/functions/aggregate.js
|
|
1579
|
-
function argmax(y2, x2) {
|
|
1580
|
-
return aggFn("arg_max", y2, x2);
|
|
1581
|
-
}
|
|
1582
|
-
function argmin(y2, x2) {
|
|
1583
|
-
return aggFn("arg_min", y2, x2);
|
|
1584
|
-
}
|
|
1585
|
-
function arrayAgg(expr) {
|
|
1586
|
-
return aggFn("array_agg", expr);
|
|
1587
|
-
}
|
|
1588
|
-
function avg(expr) {
|
|
1589
|
-
return aggFn("avg", expr);
|
|
1590
|
-
}
|
|
1591
|
-
function corr(x2, y2) {
|
|
1592
|
-
return aggFn("corr", x2, y2);
|
|
1593
|
-
}
|
|
1594
|
-
function count(expr) {
|
|
1595
|
-
return aggFn("count", expr);
|
|
1596
|
-
}
|
|
1597
|
-
function covariance(x2, y2) {
|
|
1598
|
-
return aggFn("covar_samp", x2, y2);
|
|
1599
|
-
}
|
|
1600
|
-
function covarPop(x2, y2) {
|
|
1601
|
-
return aggFn("covar_pop", x2, y2);
|
|
1602
|
-
}
|
|
1603
|
-
function entropy(expr) {
|
|
1604
|
-
return aggFn("entropy", expr);
|
|
1605
|
-
}
|
|
1606
|
-
function first(expr) {
|
|
1607
|
-
return aggFn("first", expr);
|
|
1608
|
-
}
|
|
1609
|
-
function kurtosis(expr) {
|
|
1610
|
-
return aggFn("kurtosis", expr);
|
|
1611
|
-
}
|
|
1612
|
-
function mad(expr) {
|
|
1613
|
-
return aggFn("mad", expr);
|
|
1614
|
-
}
|
|
1615
|
-
function max(expr) {
|
|
1616
|
-
return aggFn("max", expr);
|
|
1617
|
-
}
|
|
1618
|
-
function median(expr) {
|
|
1619
|
-
return aggFn("median", expr);
|
|
1620
|
-
}
|
|
1621
|
-
function min(expr) {
|
|
1622
|
-
return aggFn("min", expr);
|
|
1623
|
-
}
|
|
1624
|
-
function mode(expr) {
|
|
1625
|
-
return aggFn("mode", expr);
|
|
1626
|
-
}
|
|
1627
|
-
function last(expr) {
|
|
1628
|
-
return aggFn("last", expr);
|
|
1629
|
-
}
|
|
1630
|
-
function product(expr) {
|
|
1631
|
-
return aggFn("product", expr);
|
|
1632
|
-
}
|
|
1633
|
-
function quantile(expr, p) {
|
|
1634
|
-
return aggFn("quantile", expr, p);
|
|
1635
|
-
}
|
|
1636
|
-
function regrAvgX(x2, y2) {
|
|
1637
|
-
return aggFn("regr_avgx", x2, y2);
|
|
1638
|
-
}
|
|
1639
|
-
function regrAvgY(x2, y2) {
|
|
1640
|
-
return aggFn("regr_avgy", x2, y2);
|
|
1641
|
-
}
|
|
1642
|
-
function regrCount(x2, y2) {
|
|
1643
|
-
return aggFn("regr_count", x2, y2);
|
|
1644
|
-
}
|
|
1645
|
-
function regrIntercept(x2, y2) {
|
|
1646
|
-
return aggFn("regr_intercept", x2, y2);
|
|
1647
|
-
}
|
|
1648
|
-
function regrR2(x2, y2) {
|
|
1649
|
-
return aggFn("regr_r2", x2, y2);
|
|
1650
|
-
}
|
|
1651
|
-
function regrSXX(x2, y2) {
|
|
1652
|
-
return aggFn("regr_sxx", x2, y2);
|
|
1653
|
-
}
|
|
1654
|
-
function regrSXY(x2, y2) {
|
|
1655
|
-
return aggFn("regr_sxy", x2, y2);
|
|
1656
|
-
}
|
|
1657
|
-
function regrSYY(x2, y2) {
|
|
1658
|
-
return aggFn("regr_syy", x2, y2);
|
|
1659
|
-
}
|
|
1660
|
-
function regrSlope(x2, y2) {
|
|
1661
|
-
return aggFn("regr_slope", x2, y2);
|
|
1662
|
-
}
|
|
1663
|
-
function skewness(expr) {
|
|
1664
|
-
return aggFn("skewness", expr);
|
|
1665
|
-
}
|
|
1666
|
-
function stddev(expr) {
|
|
1667
|
-
return aggFn("stddev", expr);
|
|
1668
|
-
}
|
|
1669
|
-
function stddevPop(expr) {
|
|
1670
|
-
return aggFn("stddev_pop", expr);
|
|
1671
|
-
}
|
|
1672
|
-
function stringAgg(expr) {
|
|
1673
|
-
return aggFn("string_agg", expr);
|
|
1674
|
-
}
|
|
1675
|
-
function sum(expr) {
|
|
1676
|
-
return aggFn("sum", expr);
|
|
1677
|
-
}
|
|
1678
|
-
function variance(expr) {
|
|
1679
|
-
return aggFn("var_samp", expr);
|
|
1680
|
-
}
|
|
1681
|
-
function varPop(expr) {
|
|
1682
|
-
return aggFn("var_pop", expr);
|
|
1683
|
-
}
|
|
1684
|
-
|
|
1685
|
-
// src/functions/case.js
|
|
1686
|
-
function cond(when, then, other) {
|
|
1687
|
-
return when ? new CaseNode(void 0, [new WhenNode(asNode(when), asNode(then))], asNode(other)) : new CaseNode();
|
|
1688
|
-
}
|
|
1689
|
-
|
|
1690
|
-
// src/functions/cast.js
|
|
1691
|
-
function cast(expr, type) {
|
|
1692
|
-
return new CastNode(asNode(expr), type);
|
|
1693
|
-
}
|
|
1694
|
-
function int32(expr) {
|
|
1695
|
-
return cast(expr, "INTEGER");
|
|
1696
|
-
}
|
|
1697
|
-
function float32(expr) {
|
|
1698
|
-
return cast(expr, "FLOAT");
|
|
1699
|
-
}
|
|
1700
|
-
function float64(expr) {
|
|
1701
|
-
return cast(expr, "DOUBLE");
|
|
1702
|
-
}
|
|
1703
|
-
|
|
1704
|
-
// src/functions/datetime.js
|
|
1705
|
-
function interval(unit, steps) {
|
|
1706
|
-
return new IntervalNode(unit, steps);
|
|
1707
|
-
}
|
|
1708
|
-
function epoch_ms(expr) {
|
|
1709
|
-
return fn("epoch_ms", expr);
|
|
1710
|
-
}
|
|
1711
|
-
function dateBin(expr, unit, steps = 1) {
|
|
1712
|
-
return fn("time_bucket", interval(unit, steps), expr);
|
|
1713
|
-
}
|
|
1714
|
-
function dateMonth(expr) {
|
|
1715
|
-
return fn("make_date", 2012, fn("month", expr), 1);
|
|
1716
|
-
}
|
|
1717
|
-
function dateMonthDay(expr) {
|
|
1718
|
-
const d = asNode(expr);
|
|
1719
|
-
return fn("make_date", 2012, fn("month", d), fn("day", d));
|
|
1720
|
-
}
|
|
1721
|
-
function dateDay(expr) {
|
|
1722
|
-
return fn("make_date", 2012, 1, fn("day", expr));
|
|
1723
|
-
}
|
|
1724
|
-
|
|
1725
|
-
// src/functions/numeric.js
|
|
1726
|
-
function isNaN(expr) {
|
|
1727
|
-
return fn("isnan", expr);
|
|
1728
|
-
}
|
|
1729
|
-
function isFinite(expr) {
|
|
1730
|
-
return fn("isfinite", expr);
|
|
1731
|
-
}
|
|
1732
|
-
function isInfinite(expr) {
|
|
1733
|
-
return fn("isinf", expr);
|
|
1734
|
-
}
|
|
1735
|
-
function greatest(...expr) {
|
|
1736
|
-
return fn("greatest", ...expr);
|
|
1737
|
-
}
|
|
1738
|
-
function least(...expr) {
|
|
1739
|
-
return fn("least", ...expr);
|
|
1740
|
-
}
|
|
1741
|
-
function exp(expr) {
|
|
1742
|
-
return fn("exp", expr);
|
|
1743
|
-
}
|
|
1744
|
-
function log(expr) {
|
|
1745
|
-
return fn("log", expr);
|
|
1746
|
-
}
|
|
1747
|
-
function ln(expr) {
|
|
1748
|
-
return fn("ln", expr);
|
|
1749
|
-
}
|
|
1750
|
-
function sign(expr) {
|
|
1751
|
-
return fn("sign", expr);
|
|
1752
|
-
}
|
|
1753
|
-
function abs(expr) {
|
|
1754
|
-
return fn("abs", expr);
|
|
1755
|
-
}
|
|
1756
|
-
function sqrt(expr) {
|
|
1757
|
-
return fn("sqrt", expr);
|
|
1758
|
-
}
|
|
1759
|
-
function ceil(expr) {
|
|
1760
|
-
return fn("ceil", expr);
|
|
1761
|
-
}
|
|
1762
|
-
function floor(expr) {
|
|
1763
|
-
return fn("floor", expr);
|
|
1764
|
-
}
|
|
1765
|
-
function round(expr, places) {
|
|
1766
|
-
return fn("round", expr, places);
|
|
1767
|
-
}
|
|
1768
|
-
function trunc(expr) {
|
|
1769
|
-
return fn("trunc", expr);
|
|
1770
|
-
}
|
|
1771
|
-
|
|
1772
|
-
// src/functions/operators.js
|
|
1773
|
-
function unaryOp(op, expr) {
|
|
1774
|
-
return new UnaryOpNode(op, asNode(expr));
|
|
1775
|
-
}
|
|
1776
|
-
function unaryPostfixOp(op, expr) {
|
|
1777
|
-
return new UnaryPosftixOpNode(op, asNode(expr));
|
|
1778
|
-
}
|
|
1779
|
-
function binaryOp(op, left, right) {
|
|
1780
|
-
return new BinaryOpNode(op, asNode(left), asNode(right));
|
|
1781
|
-
}
|
|
1782
|
-
function betweenOp(expr, extent, negate = false) {
|
|
1783
|
-
const Op = negate ? NotBetweenOpNode : BetweenOpNode;
|
|
1784
|
-
return new Op(asNode(expr), extent?.map(asNode));
|
|
1785
|
-
}
|
|
1786
|
-
function and(...clauses) {
|
|
1787
|
-
return new AndNode(exprList(clauses));
|
|
1788
|
-
}
|
|
1789
|
-
function or(...clauses) {
|
|
1790
|
-
return new OrNode(exprList(clauses));
|
|
1791
|
-
}
|
|
1792
|
-
function not(expr) {
|
|
1793
|
-
return unaryOp("NOT", expr);
|
|
1794
|
-
}
|
|
1795
|
-
function isNull(expr) {
|
|
1796
|
-
return unaryPostfixOp("IS NULL", expr);
|
|
1797
|
-
}
|
|
1798
|
-
function isNotNull(expr) {
|
|
1799
|
-
return unaryPostfixOp("IS NOT NULL", expr);
|
|
1800
|
-
}
|
|
1801
|
-
function bitNot(expr) {
|
|
1802
|
-
return unaryOp("~", expr);
|
|
1803
|
-
}
|
|
1804
|
-
function bitAnd(left, right) {
|
|
1805
|
-
return binaryOp("&", left, right);
|
|
1806
|
-
}
|
|
1807
|
-
function bitOr(left, right) {
|
|
1808
|
-
return binaryOp("|", left, right);
|
|
1809
|
-
}
|
|
1810
|
-
function bitLeft(left, right) {
|
|
1811
|
-
return binaryOp("<<", left, right);
|
|
1812
|
-
}
|
|
1813
|
-
function bitRight(left, right) {
|
|
1814
|
-
return binaryOp(">>", left, right);
|
|
1815
|
-
}
|
|
1816
|
-
function add(left, right) {
|
|
1817
|
-
return binaryOp("+", left, right);
|
|
1818
|
-
}
|
|
1819
|
-
function sub(left, right) {
|
|
1820
|
-
return binaryOp("-", left, right);
|
|
1821
|
-
}
|
|
1822
|
-
function mul(left, right) {
|
|
1823
|
-
return binaryOp("*", left, right);
|
|
1824
|
-
}
|
|
1825
|
-
function div(left, right) {
|
|
1826
|
-
return binaryOp("/", left, right);
|
|
1827
|
-
}
|
|
1828
|
-
function idiv(left, right) {
|
|
1829
|
-
return binaryOp("//", left, right);
|
|
1830
|
-
}
|
|
1831
|
-
function mod(left, right) {
|
|
1832
|
-
return binaryOp("%", left, right);
|
|
1833
|
-
}
|
|
1834
|
-
function pow(left, right) {
|
|
1835
|
-
return binaryOp("**", left, right);
|
|
1836
|
-
}
|
|
1837
|
-
function eq(left, right) {
|
|
1838
|
-
return binaryOp("=", left, right);
|
|
1839
|
-
}
|
|
1840
|
-
function neq(left, right) {
|
|
1841
|
-
return binaryOp("<>", left, right);
|
|
1842
|
-
}
|
|
1843
|
-
function lt(left, right) {
|
|
1844
|
-
return binaryOp("<", left, right);
|
|
1845
|
-
}
|
|
1846
|
-
function gt(left, right) {
|
|
1847
|
-
return binaryOp(">", left, right);
|
|
1848
|
-
}
|
|
1849
|
-
function lte(left, right) {
|
|
1850
|
-
return binaryOp("<=", left, right);
|
|
1851
|
-
}
|
|
1852
|
-
function gte(left, right) {
|
|
1853
|
-
return binaryOp(">=", left, right);
|
|
1854
|
-
}
|
|
1855
|
-
function isDistinct(left, right) {
|
|
1856
|
-
return binaryOp("IS DISTINCT FROM", left, right);
|
|
1857
|
-
}
|
|
1858
|
-
function isNotDistinct(left, right) {
|
|
1859
|
-
return binaryOp("IS NOT DISTINCT FROM", left, right);
|
|
1860
|
-
}
|
|
1861
|
-
function isBetween(expr, extent) {
|
|
1862
|
-
return betweenOp(expr, extent, false);
|
|
1863
|
-
}
|
|
1864
|
-
function isNotBetween(expr, extent) {
|
|
1865
|
-
return betweenOp(expr, extent, true);
|
|
1866
|
-
}
|
|
1867
|
-
function isIn(expr, values) {
|
|
1868
|
-
return new InOpNode(asNode(expr), values.map(asNode));
|
|
1869
|
-
}
|
|
1870
|
-
|
|
1871
|
-
// src/functions/order-by.js
|
|
1872
|
-
function asc(expr, nullsFirst) {
|
|
1873
|
-
return new OrderByNode(asNode(expr), false, nullsFirst);
|
|
1874
|
-
}
|
|
1875
|
-
function desc(expr, nullsFirst) {
|
|
1876
|
-
return new OrderByNode(asNode(expr), true, nullsFirst);
|
|
1877
|
-
}
|
|
1878
|
-
|
|
1879
|
-
// src/functions/spatial.js
|
|
1880
|
-
function geojson(expr) {
|
|
1881
|
-
return fn("st_asgeojson", expr);
|
|
1882
|
-
}
|
|
1883
|
-
function x(expr) {
|
|
1884
|
-
return fn("st_x", expr);
|
|
1885
|
-
}
|
|
1886
|
-
function y(expr) {
|
|
1887
|
-
return fn("st_y", expr);
|
|
1888
|
-
}
|
|
1889
|
-
function centroid(expr) {
|
|
1890
|
-
return fn("st_centroid", expr);
|
|
1891
|
-
}
|
|
1892
|
-
function centroidX(expr) {
|
|
1893
|
-
return x(centroid(expr));
|
|
1894
|
-
}
|
|
1895
|
-
function centroidY(expr) {
|
|
1896
|
-
return y(centroid(expr));
|
|
1897
|
-
}
|
|
1898
|
-
|
|
1899
|
-
// src/functions/sql-template-tag.js
|
|
1900
|
-
function sql(strings, ...exprs) {
|
|
1901
|
-
return new FragmentNode(parseSQL(strings, exprs));
|
|
1902
|
-
}
|
|
1903
|
-
function parseSQL(strings, exprs) {
|
|
1904
|
-
const spans = [strings[0]];
|
|
1905
|
-
const n = exprs.length;
|
|
1906
|
-
for (let i = 0, k = 0; i < n; ) {
|
|
1907
|
-
const e = exprs[i];
|
|
1908
|
-
if (isNode(e)) {
|
|
1909
|
-
spans[++k] = e;
|
|
1910
|
-
} else if (isParamLike(e)) {
|
|
1911
|
-
spans[++k] = new ParamNode(e);
|
|
1912
|
-
} else {
|
|
1913
|
-
spans[k] += isString(e) ? e : literal(e);
|
|
1914
|
-
}
|
|
1915
|
-
const s = strings[++i];
|
|
1916
|
-
if (isNode(spans[k])) {
|
|
1917
|
-
spans[++k] = s;
|
|
1918
|
-
} else {
|
|
1919
|
-
spans[k] += s;
|
|
1920
|
-
}
|
|
1921
|
-
}
|
|
1922
|
-
return spans.filter((s) => s).map((s) => isString(s) ? new VerbatimNode(s) : s);
|
|
1923
|
-
}
|
|
1924
|
-
|
|
1925
|
-
// src/functions/string.js
|
|
1926
|
-
function strFn(name, expr, ...args) {
|
|
1927
|
-
return fn(name, expr, ...argsList(args).map(asLiteral));
|
|
1928
|
-
}
|
|
1929
|
-
function regexp_matches(string, pattern, options) {
|
|
1930
|
-
return strFn("regexp_matches", string, pattern, options);
|
|
1931
|
-
}
|
|
1932
|
-
function contains(string, search_string) {
|
|
1933
|
-
return strFn("contains", string, search_string);
|
|
1934
|
-
}
|
|
1935
|
-
function prefix(string, search_string) {
|
|
1936
|
-
return strFn("starts_with", string, search_string);
|
|
1937
|
-
}
|
|
1938
|
-
function suffix(string, search_string) {
|
|
1939
|
-
return strFn("ends_with", string, search_string);
|
|
1940
|
-
}
|
|
1941
|
-
function lower(string) {
|
|
1942
|
-
return strFn("lower", string);
|
|
1943
|
-
}
|
|
1944
|
-
function upper(string) {
|
|
1945
|
-
return strFn("upper", string);
|
|
1946
|
-
}
|
|
1947
|
-
function length(value) {
|
|
1948
|
-
return strFn("length", value);
|
|
1949
|
-
}
|
|
1950
|
-
|
|
1951
|
-
// src/functions/window.js
|
|
1952
|
-
function row_number() {
|
|
1953
|
-
return winFn("row_number");
|
|
1954
|
-
}
|
|
1955
|
-
function rank() {
|
|
1956
|
-
return winFn("rank");
|
|
1957
|
-
}
|
|
1958
|
-
function dense_rank() {
|
|
1959
|
-
return winFn("dense_rank");
|
|
1960
|
-
}
|
|
1961
|
-
function percent_rank() {
|
|
1962
|
-
return winFn("percent_rank");
|
|
1963
|
-
}
|
|
1964
|
-
function cume_dist() {
|
|
1965
|
-
return winFn("cume_dist");
|
|
1966
|
-
}
|
|
1967
|
-
function ntile(num_buckets) {
|
|
1968
|
-
return winFn("ntile", num_buckets);
|
|
1969
|
-
}
|
|
1970
|
-
function lag(expr, offset, defaultValue) {
|
|
1971
|
-
return winFn("lag", expr, offset, defaultValue);
|
|
1972
|
-
}
|
|
1973
|
-
function lead(expr, offset, defaultValue) {
|
|
1974
|
-
return winFn("lead", expr, offset, defaultValue);
|
|
1975
|
-
}
|
|
1976
|
-
function first_value(expr) {
|
|
1977
|
-
return winFn("first_value", expr);
|
|
1978
|
-
}
|
|
1979
|
-
function last_value(expr) {
|
|
1980
|
-
return winFn("last_value", expr);
|
|
1981
|
-
}
|
|
1982
|
-
function nth_value(expr, nth) {
|
|
1983
|
-
return winFn("nth_value", expr, nth);
|
|
1984
|
-
}
|
|
1985
|
-
|
|
1986
|
-
// src/visit/recurse.js
|
|
1987
|
-
var recurse = {
|
|
1988
|
-
[AGGREGATE]: ["args", "filter"],
|
|
1989
|
-
[BETWEEN_OPERATOR]: ["expr", "extent"],
|
|
1990
|
-
[BINARY_OPERATOR]: ["left", "right"],
|
|
1991
|
-
[CASE]: ["expr", "_when", "_else"],
|
|
1992
|
-
[CAST]: ["expr"],
|
|
1993
|
-
[COLUMN_PARAM]: ["param", "table"],
|
|
1994
|
-
[COLUMN_REF]: ["table"],
|
|
1995
|
-
[DESCRIBE_QUERY]: ["query"],
|
|
1996
|
-
[EXPRESSION]: ["node"],
|
|
1997
|
-
[FRAGMENT]: ["spans"],
|
|
1998
|
-
[FROM_CLAUSE]: ["expr"],
|
|
1999
|
-
[FUNCTION]: ["args"],
|
|
2000
|
-
[IN_OPERATOR]: ["expr", "values"],
|
|
2001
|
-
[LOGICAL_OPERATOR]: ["clauses"],
|
|
2002
|
-
[NOT_BETWEEN_OPERATOR]: ["expr", "extent"],
|
|
2003
|
-
[ORDER_BY]: ["expr"],
|
|
2004
|
-
[PARAM]: ["value"],
|
|
2005
|
-
[SELECT_CLAUSE]: ["expr"],
|
|
2006
|
-
[SELECT_QUERY]: ["_with", "_select", "_from", "_where", "_sample", "_groupby", "_having", "_window", "_qualify", "_orderby"],
|
|
2007
|
-
[SET_OPERATION]: ["subqueries", "_orderby"],
|
|
2008
|
-
[UNARY_OPERATOR]: ["expr"],
|
|
2009
|
-
[WHEN]: ["when", "then"],
|
|
2010
|
-
[WINDOW]: ["func", "def"],
|
|
2011
|
-
[WINDOW_CLAUSE]: ["def"],
|
|
2012
|
-
[WINDOW_DEF]: ["partition", "order", "frame"],
|
|
2013
|
-
[WINDOW_FRAME]: ["extent"]
|
|
2014
|
-
};
|
|
2015
|
-
|
|
2016
|
-
// src/visit/rewrite.js
|
|
2017
|
-
function rewrite(node, map) {
|
|
2018
|
-
if (map.has(node)) {
|
|
2019
|
-
return map.get(node);
|
|
2020
|
-
} else if (isNode(node)) {
|
|
2021
|
-
const props = recurse[node.type];
|
|
2022
|
-
const n = props?.length ?? 0;
|
|
2023
|
-
for (let i = 0; i < n; ++i) {
|
|
2024
|
-
const prop = props[i];
|
|
2025
|
-
const child = node[prop];
|
|
2026
|
-
if (Array.isArray(child)) {
|
|
2027
|
-
const m = child.length;
|
|
2028
|
-
for (let j = 0; j < m; ++j) {
|
|
2029
|
-
child[j] = rewrite(child[j], map);
|
|
2030
|
-
}
|
|
2031
|
-
} else if (child) {
|
|
2032
|
-
node[prop] = rewrite(child, map);
|
|
2033
|
-
}
|
|
2034
|
-
}
|
|
2035
|
-
}
|
|
2036
|
-
return node;
|
|
2037
|
-
}
|
|
2038
|
-
|
|
2039
|
-
// src/visit/walk.js
|
|
2040
|
-
function walk(node, visit) {
|
|
2041
|
-
if (!isNode(node)) return;
|
|
2042
|
-
const result = visit(node);
|
|
2043
|
-
if (result) return result;
|
|
2044
|
-
const props = recurse[node.type];
|
|
2045
|
-
const n = props?.length ?? 0;
|
|
2046
|
-
for (let i = 0; i < n; ++i) {
|
|
2047
|
-
const value = node[props[i]];
|
|
2048
|
-
if (Array.isArray(value)) {
|
|
2049
|
-
const m = value.length;
|
|
2050
|
-
for (let j = 0; j < m; ++j) {
|
|
2051
|
-
if (value[j] && +walk(value[j], visit) < 0) {
|
|
2052
|
-
return result;
|
|
2053
|
-
}
|
|
2054
|
-
}
|
|
2055
|
-
} else if (value && +walk(value, visit) < 0) {
|
|
2056
|
-
return -1;
|
|
2057
|
-
}
|
|
2058
|
-
}
|
|
2059
|
-
}
|
|
2060
|
-
|
|
2061
|
-
// src/visit/visitors.js
|
|
2062
|
-
var aggrRegExp = new RegExp(`^(${aggregateNames.join("|")})$`);
|
|
2063
|
-
var funcRegExp = /(\\'|\\"|"(?:\\"|[^"])*"|'(?:\\'|[^'])*'|\w+\()/g;
|
|
2064
|
-
function hasVerbatimAggregate(s) {
|
|
2065
|
-
return s.split(funcRegExp).some((tok) => tok.endsWith("(") && aggrRegExp.test(tok.slice(0, -1)));
|
|
2066
|
-
}
|
|
2067
|
-
function isAggregateExpression(root) {
|
|
2068
|
-
let agg = 0;
|
|
2069
|
-
walk(root, (node) => {
|
|
2070
|
-
switch (node.type) {
|
|
2071
|
-
case WINDOW:
|
|
2072
|
-
return -1;
|
|
2073
|
-
// aggs can't include windows
|
|
2074
|
-
case AGGREGATE:
|
|
2075
|
-
agg |= 1;
|
|
2076
|
-
return -1;
|
|
2077
|
-
case FRAGMENT:
|
|
2078
|
-
case VERBATIM: {
|
|
2079
|
-
let s = `${node}`.toLowerCase();
|
|
2080
|
-
const sub2 = s.indexOf("(select ");
|
|
2081
|
-
if (sub2 >= 0) s = s.slice(0, sub2);
|
|
2082
|
-
if (s.includes(") over ")) return -1;
|
|
2083
|
-
if (hasVerbatimAggregate(s)) {
|
|
2084
|
-
agg |= 2;
|
|
2085
|
-
return -1;
|
|
2086
|
-
}
|
|
2087
|
-
return 1;
|
|
2088
|
-
}
|
|
2089
|
-
}
|
|
2090
|
-
});
|
|
2091
|
-
return agg;
|
|
2092
|
-
}
|
|
2093
|
-
function collectAggregates(root) {
|
|
2094
|
-
const aggs = /* @__PURE__ */ new Set();
|
|
2095
|
-
walk(root, (node) => {
|
|
2096
|
-
if (node.type === AGGREGATE) {
|
|
2097
|
-
aggs.add(node);
|
|
2098
|
-
}
|
|
2099
|
-
});
|
|
2100
|
-
return Array.from(aggs);
|
|
2101
|
-
}
|
|
2102
|
-
function collectColumns(root) {
|
|
2103
|
-
const cols = {};
|
|
2104
|
-
walk(root, (node) => {
|
|
2105
|
-
if (node.type === COLUMN_REF || node.type === COLUMN_PARAM) {
|
|
2106
|
-
cols[node] = node;
|
|
2107
|
-
}
|
|
2108
|
-
});
|
|
2109
|
-
return Object.values(cols);
|
|
2110
|
-
}
|
|
2111
|
-
function collectParams(root) {
|
|
2112
|
-
const params = /* @__PURE__ */ new Set();
|
|
2113
|
-
walk(root, (node) => {
|
|
2114
|
-
if (node.type === PARAM) {
|
|
2115
|
-
params.add(
|
|
2116
|
-
/** @type {import('../ast/param.js').ParamNode} */
|
|
2117
|
-
node.param
|
|
2118
|
-
);
|
|
2119
|
-
}
|
|
2120
|
-
});
|
|
2121
|
-
return Array.from(params);
|
|
2122
|
-
}
|
|
2123
|
-
|
|
2124
|
-
// src/load/create.js
|
|
2125
|
-
function createTable(name, query, {
|
|
2126
|
-
replace = false,
|
|
2127
|
-
temp = false,
|
|
2128
|
-
view = false
|
|
2129
|
-
} = {}) {
|
|
2130
|
-
return "CREATE" + (replace ? " OR REPLACE " : " ") + (temp ? "TEMP " : "") + (view ? "VIEW" : "TABLE") + (replace ? " " : " IF NOT EXISTS ") + name + " AS " + query;
|
|
2131
|
-
}
|
|
2132
|
-
function createSchema(name, {
|
|
2133
|
-
strict = false
|
|
2134
|
-
} = {}) {
|
|
2135
|
-
return "CREATE SCHEMA " + (strict ? "" : "IF NOT EXISTS ") + name;
|
|
2136
|
-
}
|
|
2137
|
-
|
|
2138
|
-
// src/load/extension.js
|
|
2139
|
-
function loadExtension(name) {
|
|
2140
|
-
return `INSTALL ${name}; LOAD ${name}`;
|
|
2141
|
-
}
|
|
2142
|
-
|
|
2143
|
-
// src/load/sql-from.js
|
|
2144
|
-
function sqlFrom(data, {
|
|
2145
|
-
columns = Object.keys(data?.[0] || {})
|
|
2146
|
-
} = {}) {
|
|
2147
|
-
let keys = [];
|
|
2148
|
-
if (Array.isArray(columns)) {
|
|
2149
|
-
keys = columns;
|
|
2150
|
-
columns = keys.reduce((m, k) => (m[k] = k, m), {});
|
|
2151
|
-
} else if (columns) {
|
|
2152
|
-
keys = Object.keys(columns);
|
|
2153
|
-
}
|
|
2154
|
-
if (!keys.length) {
|
|
2155
|
-
throw new Error("Can not create table from empty column set.");
|
|
2156
|
-
}
|
|
2157
|
-
const subq = [];
|
|
2158
|
-
for (const datum of data) {
|
|
2159
|
-
const sel = keys.map((k) => `${asLiteral(datum[k])} AS "${columns[k]}"`);
|
|
2160
|
-
subq.push(`(SELECT ${sel.join(", ")})`);
|
|
2161
|
-
}
|
|
2162
|
-
return subq.join(" UNION ALL ");
|
|
2163
|
-
}
|
|
2164
|
-
|
|
2165
|
-
// src/load/load.js
|
|
2166
|
-
function load(method, tableName, fileName, options = {}, defaults = {}) {
|
|
2167
|
-
const { select = ["*"], where, view, temp, replace, ...file } = options;
|
|
2168
|
-
const params = parameters({ ...defaults, ...file });
|
|
2169
|
-
const read = `${method}('${fileName}'${params ? ", " + params : ""})`;
|
|
2170
|
-
const filter = where ? ` WHERE ${where}` : "";
|
|
2171
|
-
const query = `SELECT ${select.join(", ")} FROM ${read}${filter}`;
|
|
2172
|
-
return createTable(tableName, query, { view, temp, replace });
|
|
2173
|
-
}
|
|
2174
|
-
function loadCSV(tableName, fileName, options) {
|
|
2175
|
-
return load("read_csv", tableName, fileName, options, { auto_detect: true, sample_size: -1 });
|
|
2176
|
-
}
|
|
2177
|
-
function loadJSON(tableName, fileName, options) {
|
|
2178
|
-
return load("read_json", tableName, fileName, options, { auto_detect: true, format: "auto" });
|
|
2179
|
-
}
|
|
2180
|
-
function loadParquet(tableName, fileName, options) {
|
|
2181
|
-
return load("read_parquet", tableName, fileName, options);
|
|
2182
|
-
}
|
|
2183
|
-
function loadSpatial(tableName, fileName, options = {}) {
|
|
2184
|
-
const { options: opt, ...rest } = options;
|
|
2185
|
-
if (opt) {
|
|
2186
|
-
const open = Array.isArray(opt) ? opt.join(", ") : typeof opt === "string" ? opt : Object.entries(opt).map(([key, value]) => `${key}=${value}`).join(", ");
|
|
2187
|
-
Object.assign(rest, { open_options: open.toUpperCase() });
|
|
2188
|
-
}
|
|
2189
|
-
return load("st_read", tableName, fileName, rest);
|
|
2190
|
-
}
|
|
2191
|
-
function loadObjects(tableName, data, options = {}) {
|
|
2192
|
-
const { select = ["*"], ...opt } = options;
|
|
2193
|
-
const values = sqlFrom(data);
|
|
2194
|
-
const query = select.length === 1 && select[0] === "*" ? values : `SELECT ${select} FROM ${values}`;
|
|
2195
|
-
return createTable(tableName, query, opt);
|
|
2196
|
-
}
|
|
2197
|
-
function parameters(options) {
|
|
2198
|
-
return Object.entries(options).map(([key, value]) => `${key}=${toDuckDBValue(value)}`).join(", ");
|
|
2199
|
-
}
|
|
2200
|
-
function toDuckDBValue(value) {
|
|
2201
|
-
switch (typeof value) {
|
|
2202
|
-
case "boolean":
|
|
2203
|
-
return String(value);
|
|
2204
|
-
case "string":
|
|
2205
|
-
return `'${value}'`;
|
|
2206
|
-
case "undefined":
|
|
2207
|
-
case "object":
|
|
2208
|
-
if (value == null) {
|
|
2209
|
-
return "NULL";
|
|
2210
|
-
} else if (Array.isArray(value)) {
|
|
2211
|
-
return "[" + value.map((v) => toDuckDBValue(v)).join(", ") + "]";
|
|
2212
|
-
} else {
|
|
2213
|
-
return "{" + Object.entries(value).map(([k, v]) => `'${k}': ${toDuckDBValue(v)}`).join(", ") + "}";
|
|
2214
|
-
}
|
|
2215
|
-
default:
|
|
2216
|
-
return value;
|
|
2217
|
-
}
|
|
2218
|
-
}
|
|
2219
|
-
|
|
2220
|
-
// src/transforms/bin-1d.js
|
|
2221
|
-
function bin1d(x2, lo, hi, bins, reverse) {
|
|
2222
|
-
const diff = reverse ? sub(hi, float64(x2)) : sub(float64(x2), lo);
|
|
2223
|
-
const scale = hi === lo ? 0 : bins / (hi - lo);
|
|
2224
|
-
return scale ? mul(diff, float64(scale)) : diff;
|
|
2225
|
-
}
|
|
2226
|
-
|
|
2227
|
-
// src/transforms/bin-2d.js
|
|
2228
|
-
function bin2d(q, xp, yp, aggs, xn, groupby) {
|
|
2229
|
-
return q.select({
|
|
2230
|
-
index: add(int32(floor(xp)), mul(int32(floor(yp)), xn)),
|
|
2231
|
-
...aggs
|
|
2232
|
-
}).groupby("index", groupby);
|
|
2233
|
-
}
|
|
2234
|
-
|
|
2235
|
-
// src/transforms/bin-linear-1d.js
|
|
2236
|
-
function binLinear1d(query, x2, weight = void 0, groupby = []) {
|
|
2237
|
-
const w = weight ? (x3) => mul(x3, weight) : (x3) => x3;
|
|
2238
|
-
const p0 = floor(x2);
|
|
2239
|
-
const p1 = add(p0, 1);
|
|
2240
|
-
return Query.from(Query.unionAll(
|
|
2241
|
-
query.clone().select({ i: int32(p0), w: w(sub(p1, x2)) }),
|
|
2242
|
-
query.clone().select({ i: int32(p1), w: w(sub(x2, p0)) })
|
|
2243
|
-
)).select({ index: "i", density: sum("w") }, groupby).groupby("index", groupby).having(neq("density", 0));
|
|
2244
|
-
}
|
|
2245
|
-
|
|
2246
|
-
// src/transforms/bin-linear-2d.js
|
|
2247
|
-
function identity(x2) {
|
|
2248
|
-
return x2;
|
|
2249
|
-
}
|
|
2250
|
-
function binLinear2d(q, xp, yp, weight, xn, groupby = []) {
|
|
2251
|
-
const w = weight ? (x2) => mul(x2, weight) : identity;
|
|
2252
|
-
const subq = (i, w2) => q.clone().select({ xp, yp, i, w: w2 });
|
|
2253
|
-
const index = (x2, y2) => add(x2, mul(y2, xn));
|
|
2254
|
-
const xu = int32(floor(xp));
|
|
2255
|
-
const yu = int32(floor(yp));
|
|
2256
|
-
const xv = add(xu, 1);
|
|
2257
|
-
const yv = add(yu, 1);
|
|
2258
|
-
const xpu = sub(xp, xu);
|
|
2259
|
-
const xvp = sub(xv, xp);
|
|
2260
|
-
const ypu = sub(yp, yu);
|
|
2261
|
-
const yvp = sub(yv, yp);
|
|
2262
|
-
return Query.from(Query.unionAll(
|
|
2263
|
-
// grid[xu + yu * xn] += (xv - xp) * (yv - yp) * wi
|
|
2264
|
-
subq(index(xu, yu), w(mul(xvp, yvp))),
|
|
2265
|
-
// grid[xu + yv * xn] += (xv - xp) * (yp - yu) * wi
|
|
2266
|
-
subq(index(xu, yv), w(mul(xvp, ypu))),
|
|
2267
|
-
// grid[xv + yu * xn] += (xp - xu) * (yv - yp) * wi
|
|
2268
|
-
subq(index(xv, yu), w(mul(xpu, yvp))),
|
|
2269
|
-
// grid[xv + yv * xn] += (xp - xu) * (yp - yu) * wi
|
|
2270
|
-
subq(index(xv, yv), w(mul(xpu, ypu)))
|
|
2271
|
-
)).select({ index: "i", density: sum("w") }, groupby).groupby("index", groupby).having(neq("density", 0));
|
|
2272
|
-
}
|
|
2273
|
-
|
|
2274
|
-
// src/transforms/line-density.js
|
|
2275
|
-
function lineDensity(q, x2, y2, z, xn, yn, groupby = [], normalize = true) {
|
|
2276
|
-
q.select({
|
|
2277
|
-
x: int32(floor(x2)),
|
|
2278
|
-
y: int32(floor(y2))
|
|
2279
|
-
});
|
|
2280
|
-
const groups = groupby.concat(z);
|
|
2281
|
-
const pairs = Query.from(q).select(groups, {
|
|
2282
|
-
x0: "x",
|
|
2283
|
-
y0: "y",
|
|
2284
|
-
dx: sub(lead("x").over("sw"), "x"),
|
|
2285
|
-
dy: sub(lead("y").over("sw"), "y")
|
|
2286
|
-
}).window({
|
|
2287
|
-
sw: over().partitionby(groups).orderby(asc("x"))
|
|
2288
|
-
}).qualify([
|
|
2289
|
-
or(lt("x0", xn), lt(add("x0", "dx"), xn)),
|
|
2290
|
-
or(lt("y0", yn), lt(add("y0", "dy"), yn)),
|
|
2291
|
-
or(gt("x0", 0), gt(add("x0", "dx"), 0)),
|
|
2292
|
-
or(gt("y0", 0), gt(add("y0", "dy"), 0))
|
|
2293
|
-
]);
|
|
2294
|
-
const num = Query.select({ x: greatest(max(abs("dx")), max(abs("dy"))) }).from("pairs");
|
|
2295
|
-
const indices = Query.select({
|
|
2296
|
-
i: int32(sql`UNNEST(range((${num})))`)
|
|
2297
|
-
});
|
|
2298
|
-
const raster = Query.unionAll(
|
|
2299
|
-
Query.select(groups, {
|
|
2300
|
-
x: add("x0", "i"),
|
|
2301
|
-
y: add("y0", int32(round(div(mul("i", "dy"), "dx"))))
|
|
2302
|
-
}).from("pairs", "indices").where([lte(abs("dy"), abs("dx")), lt("i", abs("dx"))]),
|
|
2303
|
-
Query.select(groups, {
|
|
2304
|
-
x: add("x0", int32(round(div(mul(mul(sign("dy"), "i"), "dx"), "dy")))),
|
|
2305
|
-
y: add("y0", mul(sign("dy"), "i"))
|
|
2306
|
-
}).from("pairs", "indices").where([gt(abs("dy"), abs("dx")), lt("i", abs("dy"))]),
|
|
2307
|
-
Query.select(groups, { x: "x0", y: "y0" }).from("pairs").where(isNull("dx"))
|
|
2308
|
-
);
|
|
2309
|
-
const points = Query.from("raster").select(
|
|
2310
|
-
groups,
|
|
2311
|
-
"x",
|
|
2312
|
-
"y",
|
|
2313
|
-
normalize ? { w: div(1, count().partitionby(["x"].concat(groups))) } : null
|
|
2314
|
-
).where([lte(0, "x"), lt("x", xn), lte(0, "y"), lt("y", yn)]);
|
|
2315
|
-
return Query.with({ pairs, indices, raster, points }).from("points").select(groupby, {
|
|
2316
|
-
index: add("x", mul("y", int32(xn))),
|
|
2317
|
-
density: normalize ? sum("w") : count()
|
|
2318
|
-
}).groupby("index", groupby);
|
|
2319
|
-
}
|
|
2320
|
-
|
|
2321
|
-
// src/transforms/m4.js
|
|
2322
|
-
function m4(input, bin, x2, y2, groups = []) {
|
|
2323
|
-
const pixel = int32(floor(bin));
|
|
2324
|
-
const q = (sel) => Query.from(input).select(sel).groupby(pixel, groups);
|
|
2325
|
-
return Query.union(
|
|
2326
|
-
q([{ [x2]: min(x2), [y2]: argmin(y2, x2) }, ...groups]),
|
|
2327
|
-
q([{ [x2]: max(x2), [y2]: argmax(y2, x2) }, ...groups]),
|
|
2328
|
-
q([{ [x2]: argmin(x2, y2), [y2]: min(y2) }, ...groups]),
|
|
2329
|
-
q([{ [x2]: argmax(x2, y2), [y2]: max(y2) }, ...groups])
|
|
2330
|
-
).orderby(groups, x2);
|
|
2331
|
-
}
|
|
2332
|
-
|
|
2333
|
-
// src/transforms/scales.js
|
|
2334
|
-
var identity2 = (x2) => x2;
|
|
2335
|
-
function scaleLinear() {
|
|
2336
|
-
return {
|
|
2337
|
-
apply: identity2,
|
|
2338
|
-
invert: identity2,
|
|
2339
|
-
sqlApply: asNode,
|
|
2340
|
-
sqlInvert: identity2
|
|
2341
|
-
};
|
|
2342
|
-
}
|
|
2343
|
-
function scaleLog({ base = null } = {}) {
|
|
2344
|
-
if (base == null || base === Math.E) {
|
|
2345
|
-
return {
|
|
2346
|
-
apply: Math.log,
|
|
2347
|
-
invert: Math.exp,
|
|
2348
|
-
sqlApply: (c) => ln(c),
|
|
2349
|
-
sqlInvert: (c) => exp(c)
|
|
2350
|
-
};
|
|
2351
|
-
} else if (base === 10) {
|
|
2352
|
-
return {
|
|
2353
|
-
apply: Math.log10,
|
|
2354
|
-
invert: (x2) => Math.pow(10, x2),
|
|
2355
|
-
sqlApply: (c) => log(c),
|
|
2356
|
-
sqlInvert: (c) => pow(10, c)
|
|
2357
|
-
};
|
|
2358
|
-
} else {
|
|
2359
|
-
const b = +base;
|
|
2360
|
-
return {
|
|
2361
|
-
apply: (x2) => Math.log(x2) / Math.log(b),
|
|
2362
|
-
invert: (x2) => Math.pow(b, x2),
|
|
2363
|
-
sqlApply: (c) => div(ln(c), ln(b)),
|
|
2364
|
-
sqlInvert: (c) => pow(b, c)
|
|
2365
|
-
};
|
|
2366
|
-
}
|
|
2367
|
-
}
|
|
2368
|
-
function scaleSymlog({ constant = 1 } = {}) {
|
|
2369
|
-
const _ = +constant;
|
|
2370
|
-
return {
|
|
2371
|
-
apply: (x2) => Math.sign(x2) * Math.log1p(Math.abs(x2)),
|
|
2372
|
-
invert: (x2) => Math.sign(x2) * Math.exp(Math.abs(x2) - _),
|
|
2373
|
-
sqlApply: (c) => (c = asNode(c), mul(sign(c), ln(add(_, abs(c))))),
|
|
2374
|
-
sqlInvert: (c) => mul(sign(c), sub(exp(abs(c)), _))
|
|
2375
|
-
};
|
|
2376
|
-
}
|
|
2377
|
-
function scaleSqrt() {
|
|
2378
|
-
return {
|
|
2379
|
-
apply: (x2) => Math.sign(x2) * Math.sqrt(Math.abs(x2)),
|
|
2380
|
-
invert: (x2) => Math.sign(x2) * x2 * x2,
|
|
2381
|
-
sqlApply: (c) => (c = asNode(c), mul(sign(c), sqrt(abs(c)))),
|
|
2382
|
-
sqlInvert: (c) => mul(sign(c), pow(c, 2))
|
|
2383
|
-
};
|
|
2384
|
-
}
|
|
2385
|
-
function scalePow({ exponent = 1 } = {}) {
|
|
2386
|
-
const e = +exponent;
|
|
2387
|
-
return {
|
|
2388
|
-
apply: (x2) => Math.sign(x2) * Math.pow(Math.abs(x2), e),
|
|
2389
|
-
invert: (x2) => Math.sign(x2) * Math.pow(Math.abs(x2), 1 / e),
|
|
2390
|
-
sqlApply: (c) => (c = asNode(c), mul(sign(c), pow(abs(c), e))),
|
|
2391
|
-
sqlInvert: (c) => mul(sign(c), pow(abs(c), div(1, e)))
|
|
2392
|
-
};
|
|
2393
|
-
}
|
|
2394
|
-
function scaleTime() {
|
|
2395
|
-
return {
|
|
2396
|
-
apply: (x2) => +x2,
|
|
2397
|
-
invert: (x2) => new Date(x2),
|
|
2398
|
-
sqlApply: (c) => c instanceof Date ? literal(+c) : isDateLiteral(c) ? literal(+c.value) : epoch_ms(c),
|
|
2399
|
-
sqlInvert: identity2
|
|
2400
|
-
};
|
|
2401
|
-
}
|
|
2402
|
-
var scales = {
|
|
2403
|
-
identity: scaleLinear,
|
|
2404
|
-
linear: scaleLinear,
|
|
2405
|
-
log: scaleLog,
|
|
2406
|
-
symlog: scaleSymlog,
|
|
2407
|
-
sqrt: scaleSqrt,
|
|
2408
|
-
pow: scalePow,
|
|
2409
|
-
time: scaleTime,
|
|
2410
|
-
utc: scaleTime
|
|
2411
|
-
};
|
|
2412
|
-
function scaleTransform(options) {
|
|
2413
|
-
const scale = scales[options.type];
|
|
2414
|
-
return scale ? { ...options, ...scale(options) } : null;
|
|
2415
|
-
}
|
|
2416
|
-
function isDateLiteral(x2) {
|
|
2417
|
-
return x2 instanceof LiteralNode && x2.value instanceof Date;
|
|
2418
|
-
}
|
|
2419
|
-
export {
|
|
2420
|
-
AggregateNode,
|
|
2421
|
-
AndNode,
|
|
2422
|
-
BetweenOpNode,
|
|
2423
|
-
BinaryOpNode,
|
|
2424
|
-
CaseNode,
|
|
2425
|
-
CastNode,
|
|
2426
|
-
ColumnNameRefNode,
|
|
2427
|
-
ColumnParamNode,
|
|
2428
|
-
ColumnRefNode,
|
|
2429
|
-
DescribeQuery,
|
|
2430
|
-
ExprNode,
|
|
2431
|
-
FragmentNode,
|
|
2432
|
-
FromClauseNode,
|
|
2433
|
-
FunctionNode,
|
|
2434
|
-
InOpNode,
|
|
2435
|
-
IntervalNode,
|
|
2436
|
-
LiteralNode,
|
|
2437
|
-
NotBetweenOpNode,
|
|
2438
|
-
OrNode,
|
|
2439
|
-
OrderByNode,
|
|
2440
|
-
ParamNode,
|
|
2441
|
-
Query,
|
|
2442
|
-
SQLNode,
|
|
2443
|
-
SampleClauseNode,
|
|
2444
|
-
SelectClauseNode,
|
|
2445
|
-
SelectQuery,
|
|
2446
|
-
SetOperation,
|
|
2447
|
-
TableRefNode,
|
|
2448
|
-
UnaryOpNode,
|
|
2449
|
-
UnaryPosftixOpNode,
|
|
2450
|
-
VerbatimNode,
|
|
2451
|
-
WhenNode,
|
|
2452
|
-
WindowClauseNode,
|
|
2453
|
-
WindowDefNode,
|
|
2454
|
-
WindowFrameNode,
|
|
2455
|
-
WindowFunctionNode,
|
|
2456
|
-
WindowNode,
|
|
2457
|
-
WithClauseNode,
|
|
2458
|
-
abs,
|
|
2459
|
-
add,
|
|
2460
|
-
and,
|
|
2461
|
-
argmax,
|
|
2462
|
-
argmin,
|
|
2463
|
-
arrayAgg,
|
|
2464
|
-
asLiteral,
|
|
2465
|
-
asNode,
|
|
2466
|
-
asTableRef,
|
|
2467
|
-
asVerbatim,
|
|
2468
|
-
asc,
|
|
2469
|
-
avg,
|
|
2470
|
-
bin1d,
|
|
2471
|
-
bin2d,
|
|
2472
|
-
binLinear1d,
|
|
2473
|
-
binLinear2d,
|
|
2474
|
-
bitAnd,
|
|
2475
|
-
bitLeft,
|
|
2476
|
-
bitNot,
|
|
2477
|
-
bitOr,
|
|
2478
|
-
bitRight,
|
|
2479
|
-
cast,
|
|
2480
|
-
ceil,
|
|
2481
|
-
centroid,
|
|
2482
|
-
centroidX,
|
|
2483
|
-
centroidY,
|
|
2484
|
-
collectAggregates,
|
|
2485
|
-
collectColumns,
|
|
2486
|
-
collectParams,
|
|
2487
|
-
column,
|
|
2488
|
-
cond,
|
|
2489
|
-
contains,
|
|
2490
|
-
corr,
|
|
2491
|
-
count,
|
|
2492
|
-
covarPop,
|
|
2493
|
-
covariance,
|
|
2494
|
-
createSchema,
|
|
2495
|
-
createTable,
|
|
2496
|
-
cume_dist,
|
|
2497
|
-
dateBin,
|
|
2498
|
-
dateDay,
|
|
2499
|
-
dateMonth,
|
|
2500
|
-
dateMonthDay,
|
|
2501
|
-
dense_rank,
|
|
2502
|
-
desc,
|
|
2503
|
-
div,
|
|
2504
|
-
entropy,
|
|
2505
|
-
epoch_ms,
|
|
2506
|
-
eq,
|
|
2507
|
-
exp,
|
|
2508
|
-
first,
|
|
2509
|
-
first_value,
|
|
2510
|
-
float32,
|
|
2511
|
-
float64,
|
|
2512
|
-
floor,
|
|
2513
|
-
geojson,
|
|
2514
|
-
greatest,
|
|
2515
|
-
gt,
|
|
2516
|
-
gte,
|
|
2517
|
-
idiv,
|
|
2518
|
-
int32,
|
|
2519
|
-
interval,
|
|
2520
|
-
isAggregateExpression,
|
|
2521
|
-
isBetween,
|
|
2522
|
-
isColumnParam,
|
|
2523
|
-
isColumnRef,
|
|
2524
|
-
isDescribeQuery,
|
|
2525
|
-
isDistinct,
|
|
2526
|
-
isFinite,
|
|
2527
|
-
isIn,
|
|
2528
|
-
isInfinite,
|
|
2529
|
-
isNaN,
|
|
2530
|
-
isNode,
|
|
2531
|
-
isNotBetween,
|
|
2532
|
-
isNotDistinct,
|
|
2533
|
-
isNotNull,
|
|
2534
|
-
isNull,
|
|
2535
|
-
isParamLike,
|
|
2536
|
-
isQuery,
|
|
2537
|
-
isSelectQuery,
|
|
2538
|
-
isTableRef,
|
|
2539
|
-
kurtosis,
|
|
2540
|
-
lag,
|
|
2541
|
-
last,
|
|
2542
|
-
last_value,
|
|
2543
|
-
lead,
|
|
2544
|
-
least,
|
|
2545
|
-
length,
|
|
2546
|
-
lineDensity,
|
|
2547
|
-
literal,
|
|
2548
|
-
ln,
|
|
2549
|
-
loadCSV,
|
|
2550
|
-
loadExtension,
|
|
2551
|
-
loadJSON,
|
|
2552
|
-
loadObjects,
|
|
2553
|
-
loadParquet,
|
|
2554
|
-
loadSpatial,
|
|
2555
|
-
log,
|
|
2556
|
-
lower,
|
|
2557
|
-
lt,
|
|
2558
|
-
lte,
|
|
2559
|
-
m4,
|
|
2560
|
-
mad,
|
|
2561
|
-
max,
|
|
2562
|
-
median,
|
|
2563
|
-
min,
|
|
2564
|
-
mod,
|
|
2565
|
-
mode,
|
|
2566
|
-
mul,
|
|
2567
|
-
neq,
|
|
2568
|
-
not,
|
|
2569
|
-
nth_value,
|
|
2570
|
-
ntile,
|
|
2571
|
-
or,
|
|
2572
|
-
over,
|
|
2573
|
-
percent_rank,
|
|
2574
|
-
pow,
|
|
2575
|
-
prefix,
|
|
2576
|
-
product,
|
|
2577
|
-
quantile,
|
|
2578
|
-
rank,
|
|
2579
|
-
regexp_matches,
|
|
2580
|
-
regrAvgX,
|
|
2581
|
-
regrAvgY,
|
|
2582
|
-
regrCount,
|
|
2583
|
-
regrIntercept,
|
|
2584
|
-
regrR2,
|
|
2585
|
-
regrSXX,
|
|
2586
|
-
regrSXY,
|
|
2587
|
-
regrSYY,
|
|
2588
|
-
regrSlope,
|
|
2589
|
-
rewrite,
|
|
2590
|
-
round,
|
|
2591
|
-
row_number,
|
|
2592
|
-
scaleTransform,
|
|
2593
|
-
sign,
|
|
2594
|
-
skewness,
|
|
2595
|
-
sql,
|
|
2596
|
-
sqrt,
|
|
2597
|
-
stddev,
|
|
2598
|
-
stddevPop,
|
|
2599
|
-
stringAgg,
|
|
2600
|
-
sub,
|
|
2601
|
-
suffix,
|
|
2602
|
-
sum,
|
|
2603
|
-
trunc,
|
|
2604
|
-
upper,
|
|
2605
|
-
varPop,
|
|
2606
|
-
variance,
|
|
2607
|
-
walk,
|
|
2608
|
-
x,
|
|
2609
|
-
y
|
|
2610
|
-
};
|