@uwdata/mosaic-sql 0.23.0 → 0.24.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/ast/index.d.ts +32 -0
- package/dist/src/ast/index.d.ts.map +1 -0
- package/dist/src/ast/index.js +32 -0
- package/dist/src/ast/index.js.map +1 -0
- package/dist/src/ast/query.d.ts +6 -1
- package/dist/src/ast/query.d.ts.map +1 -1
- package/dist/src/ast/query.js +16 -1
- package/dist/src/ast/query.js.map +1 -1
- package/dist/src/index.d.ts +1 -31
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +1 -31
- package/dist/src/index.js.map +1 -1
- package/dist/src/visit/codegen/duckdb.d.ts +1 -1
- package/dist/src/visit/codegen/duckdb.d.ts.map +1 -1
- package/dist/src/visit/codegen/duckdb.js +1 -1
- package/dist/src/visit/codegen/duckdb.js.map +1 -1
- package/dist/src/visit/duckdb-visitor.d.ts +50 -0
- package/dist/src/visit/duckdb-visitor.d.ts.map +1 -0
- package/dist/src/visit/duckdb-visitor.js +350 -0
- package/dist/src/visit/duckdb-visitor.js.map +1 -0
- package/dist/src/visit/to-string-visitor.d.ts +60 -0
- package/dist/src/visit/to-string-visitor.d.ts.map +1 -0
- package/dist/src/visit/to-string-visitor.js +80 -0
- package/dist/src/visit/to-string-visitor.js.map +1 -0
- package/dist/src/visit/visitors.d.ts.map +1 -1
- package/dist/src/visit/visitors.js +5 -5
- package/dist/src/visit/visitors.js.map +1 -1
- package/dist/src/visit/walk.d.ts +1 -1
- package/dist/src/visit/walk.d.ts.map +1 -1
- package/dist/src/visit/walk.js +11 -3
- package/dist/src/visit/walk.js.map +1 -1
- package/package.json +2 -2
- package/src/ast/index.ts +31 -0
- package/src/ast/query.ts +18 -3
- package/src/index.ts +1 -31
- package/src/visit/codegen/duckdb.ts +1 -1
- package/src/visit/visitors.ts +4 -5
- package/src/visit/walk.ts +13 -4
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uwdata/mosaic-sql",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.24.2",
|
|
4
4
|
"description": "SQL query construction and analysis.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"sql",
|
|
@@ -29,5 +29,5 @@
|
|
|
29
29
|
"test": "vitest run",
|
|
30
30
|
"prepublishOnly": "pnpm run test && pnpm run lint && tsc --build"
|
|
31
31
|
},
|
|
32
|
-
"gitHead": "
|
|
32
|
+
"gitHead": "d4d41a3275dbd6bc7995e1d1a82b0be18769bbca"
|
|
33
33
|
}
|
package/src/ast/index.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export { AggregateNode, aggregateNames, isAggregateFunction } from './aggregate.js';
|
|
2
|
+
export { BetweenOpNode, NotBetweenOpNode } from './between-op.js'
|
|
3
|
+
export { BinaryOpNode } from './binary-op.js';
|
|
4
|
+
export { CaseNode, WhenNode } from './case.js';
|
|
5
|
+
export { CastNode } from './cast.js';
|
|
6
|
+
export { CollateNode } from './collate.js';
|
|
7
|
+
export { ColumnParamNode, isColumnParam } from './column-param.js';
|
|
8
|
+
export { ColumnRefNode, ColumnNameRefNode, isColumnRef } from './column-ref.js';
|
|
9
|
+
export { FragmentNode } from './fragment.js';
|
|
10
|
+
export { FromClauseNode } from './from.js';
|
|
11
|
+
export { FunctionNode } from './function.js';
|
|
12
|
+
export { InOpNode } from './in-op.js';
|
|
13
|
+
export { IntervalNode } from './interval.js';
|
|
14
|
+
export { JoinNode, type JoinType, type JoinVariant } from './join.js';
|
|
15
|
+
export { ListNode } from './list.js';
|
|
16
|
+
export { LiteralNode } from './literal.js';
|
|
17
|
+
export { LogicalOpNode, AndNode, OrNode } from './logical-op.js';
|
|
18
|
+
export { SQLNode, ExprNode, isNode } from './node.js';
|
|
19
|
+
export { OrderByNode } from './order-by.js';
|
|
20
|
+
export { ParamNode } from './param.js';
|
|
21
|
+
export { CreateQuery, type CreateTableOptions, CreateSchemaQuery, type CreateSchemaOptions, DescribeQuery, Query, SelectQuery, SetOperation, isCreateQuery, isCreateSchemaQuery, isDescribeQuery, isQuery, isSelectQuery } from './query.js';
|
|
22
|
+
export { SampleClauseNode } from './sample.js';
|
|
23
|
+
export { ScalarSubqueryNode } from './subquery.js';
|
|
24
|
+
export { SelectClauseNode } from './select.js';
|
|
25
|
+
export { TableRefNode, isTableRef } from './table-ref.js';
|
|
26
|
+
export { UnaryOpNode, UnaryPostfixOpNode } from './unary-op.js';
|
|
27
|
+
export { UnnestNode } from './unnest.js';
|
|
28
|
+
export { VerbatimNode } from './verbatim.js';
|
|
29
|
+
export { WindowClauseNode, WindowDefNode, WindowFunctionNode, WindowNode } from './window.js';
|
|
30
|
+
export { WindowFrameNode, WindowFrameExprNode, type FrameExclude, type FrameExtent, type FrameScope, type FrameType, type FrameValue } from './window-frame.js';
|
|
31
|
+
export { WithClauseNode } from './with.js';
|
package/src/ast/query.ts
CHANGED
|
@@ -216,6 +216,15 @@ export class Query extends ExprNode {
|
|
|
216
216
|
return this;
|
|
217
217
|
}
|
|
218
218
|
|
|
219
|
+
/**
|
|
220
|
+
* Set ORDER BY expressions, replacing any prior expressions.
|
|
221
|
+
* @param expr Expressions to add.
|
|
222
|
+
*/
|
|
223
|
+
setOrderby(...expr: OrderByExpr[]): this {
|
|
224
|
+
this._orderby = [];
|
|
225
|
+
return this.orderby(...expr);
|
|
226
|
+
}
|
|
227
|
+
|
|
219
228
|
/**
|
|
220
229
|
* Set the query result LIMIT as a percentage value.
|
|
221
230
|
* @param value The limit percentage value.
|
|
@@ -452,11 +461,17 @@ export class SelectQuery extends Query {
|
|
|
452
461
|
* Add WINDOW definitions.
|
|
453
462
|
* @param expr Window definitions to add.
|
|
454
463
|
*/
|
|
455
|
-
window(...expr: (Record<string, WindowDefNode> | null)[]): this {
|
|
464
|
+
window(...expr: (Record<string, WindowDefNode> | WindowClauseNode | WindowClauseNode[] | null)[]): this {
|
|
456
465
|
const list: WindowClauseNode[] = [];
|
|
457
466
|
expr.flat().forEach(e => {
|
|
458
|
-
if (e
|
|
459
|
-
|
|
467
|
+
if (e == null) {
|
|
468
|
+
return;
|
|
469
|
+
} else if (e instanceof WindowClauseNode) {
|
|
470
|
+
list.push(e);
|
|
471
|
+
} else {
|
|
472
|
+
for (const name in e) {
|
|
473
|
+
list.push(new WindowClauseNode(unquote(name)!, e[name]));
|
|
474
|
+
}
|
|
460
475
|
}
|
|
461
476
|
});
|
|
462
477
|
this._window = this._window.concat(list);
|
package/src/index.ts
CHANGED
|
@@ -1,37 +1,7 @@
|
|
|
1
1
|
// Initialize default visitor
|
|
2
2
|
import './init.js';
|
|
3
3
|
|
|
4
|
-
export
|
|
5
|
-
export { BetweenOpNode, NotBetweenOpNode } from './ast/between-op.js'
|
|
6
|
-
export { BinaryOpNode } from './ast/binary-op.js';
|
|
7
|
-
export { CaseNode, WhenNode } from './ast/case.js';
|
|
8
|
-
export { CastNode } from './ast/cast.js';
|
|
9
|
-
export { CollateNode } from './ast/collate.js';
|
|
10
|
-
export { ColumnParamNode, isColumnParam } from './ast/column-param.js';
|
|
11
|
-
export { ColumnRefNode, ColumnNameRefNode, isColumnRef } from './ast/column-ref.js';
|
|
12
|
-
export { FragmentNode } from './ast/fragment.js';
|
|
13
|
-
export { FromClauseNode } from './ast/from.js';
|
|
14
|
-
export { FunctionNode } from './ast/function.js';
|
|
15
|
-
export { InOpNode } from './ast/in-op.js';
|
|
16
|
-
export { IntervalNode } from './ast/interval.js';
|
|
17
|
-
export { JoinNode, type JoinType, type JoinVariant } from './ast/join.js';
|
|
18
|
-
export { ListNode } from './ast/list.js';
|
|
19
|
-
export { LiteralNode } from './ast/literal.js';
|
|
20
|
-
export { LogicalOpNode, AndNode, OrNode } from './ast/logical-op.js';
|
|
21
|
-
export { SQLNode, ExprNode, isNode } from './ast/node.js';
|
|
22
|
-
export { OrderByNode } from './ast/order-by.js';
|
|
23
|
-
export { ParamNode } from './ast/param.js';
|
|
24
|
-
export { CreateQuery, type CreateTableOptions, CreateSchemaQuery, type CreateSchemaOptions, DescribeQuery, Query, SelectQuery, SetOperation, isCreateQuery, isCreateSchemaQuery, isDescribeQuery, isQuery, isSelectQuery } from './ast/query.js';
|
|
25
|
-
export { SampleClauseNode } from './ast/sample.js';
|
|
26
|
-
export { ScalarSubqueryNode } from './ast/subquery.js';
|
|
27
|
-
export { SelectClauseNode } from './ast/select.js';
|
|
28
|
-
export { TableRefNode, isTableRef } from './ast/table-ref.js';
|
|
29
|
-
export { UnaryOpNode, UnaryPostfixOpNode } from './ast/unary-op.js';
|
|
30
|
-
export { UnnestNode } from './ast/unnest.js';
|
|
31
|
-
export { VerbatimNode } from './ast/verbatim.js';
|
|
32
|
-
export { WindowClauseNode, WindowDefNode, WindowFunctionNode, WindowNode } from './ast/window.js';
|
|
33
|
-
export { WindowFrameNode, WindowFrameExprNode, type FrameExclude, type FrameExtent, type FrameScope, type FrameType, type FrameValue } from './ast/window-frame.js';
|
|
34
|
-
export { WithClauseNode } from './ast/with.js';
|
|
4
|
+
export * from './ast/index.js';
|
|
35
5
|
|
|
36
6
|
export { argmax, argmin, arrayAgg, avg, corr, count, covariance, covarPop, entropy, first, geomean, kurtosis, mad, max, median, min, mode, last, product, quantile, regrAvgX, regrAvgY, regrCount, regrIntercept, regrR2, regrSXX, regrSXY, regrSYY, regrSlope, skewness, stddev, stddevPop, stringAgg, sum, variance, varPop } from './functions/aggregate.js';
|
|
37
7
|
export { cond } from './functions/case.js';
|
|
@@ -45,7 +45,7 @@ import {
|
|
|
45
45
|
isNode,
|
|
46
46
|
isQuery,
|
|
47
47
|
isTableRef
|
|
48
|
-
} from '../../index.js';
|
|
48
|
+
} from '../../ast/index.js';
|
|
49
49
|
import { quoteIdentifier } from '../../util/string.js';
|
|
50
50
|
import { literalToSQL } from '../../ast/literal.js';
|
|
51
51
|
import { SQLCodeGenerator } from './sql.js';
|
package/src/visit/visitors.ts
CHANGED
|
@@ -31,11 +31,10 @@ function hasVerbatimAggregate(s: string) {
|
|
|
31
31
|
*/
|
|
32
32
|
export function isAggregateExpression(root: SQLNode) {
|
|
33
33
|
let agg = 0;
|
|
34
|
-
walk(root, (node) => {
|
|
34
|
+
walk(root, (node, parent) => {
|
|
35
35
|
switch (node.type) {
|
|
36
|
-
case WINDOW:
|
|
37
|
-
return -1; // aggs can't include windows
|
|
38
36
|
case AGGREGATE:
|
|
37
|
+
if (parent?.type === WINDOW) break;
|
|
39
38
|
agg |= 1;
|
|
40
39
|
return -1;
|
|
41
40
|
case FRAGMENT:
|
|
@@ -65,8 +64,8 @@ export function isAggregateExpression(root: SQLNode) {
|
|
|
65
64
|
*/
|
|
66
65
|
export function collectAggregates(root: SQLNode) {
|
|
67
66
|
const aggs = new Set<AggregateNode>();
|
|
68
|
-
walk(root, (node) => {
|
|
69
|
-
if (node.type === AGGREGATE) {
|
|
67
|
+
walk(root, (node, parent) => {
|
|
68
|
+
if (node.type === AGGREGATE && parent?.type !== WINDOW) {
|
|
70
69
|
aggs.add(node as AggregateNode);
|
|
71
70
|
}
|
|
72
71
|
});
|
package/src/visit/walk.ts
CHANGED
|
@@ -15,7 +15,7 @@ export type VisitorResult = boolean | number | null | undefined | void;
|
|
|
15
15
|
/**
|
|
16
16
|
* SQL AST traversal callback function.
|
|
17
17
|
*/
|
|
18
|
-
export type VisitorCallback = (node: SQLNode) => VisitorResult;
|
|
18
|
+
export type VisitorCallback = (node: SQLNode, parent?: SQLNode) => VisitorResult;
|
|
19
19
|
|
|
20
20
|
/**
|
|
21
21
|
* Perform a traversal of a SQL expression AST.
|
|
@@ -23,8 +23,17 @@ export type VisitorCallback = (node: SQLNode) => VisitorResult;
|
|
|
23
23
|
* @param visit Visitor callback function.
|
|
24
24
|
*/
|
|
25
25
|
export function walk(node: unknown, visit: VisitorCallback): VisitorResult {
|
|
26
|
+
return _walk(node, undefined, visit);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Perform a traversal of a SQL expression AST.
|
|
31
|
+
* @param node Root node for AST traversal.
|
|
32
|
+
* @param visit Visitor callback function.
|
|
33
|
+
*/
|
|
34
|
+
function _walk(node: unknown, parent: SQLNode | undefined, visit: VisitorCallback): VisitorResult {
|
|
26
35
|
if (!isNode(node)) return;
|
|
27
|
-
const result = visit(node);
|
|
36
|
+
const result = visit(node, parent);
|
|
28
37
|
if (result) return result;
|
|
29
38
|
|
|
30
39
|
const props = recurse[node.type];
|
|
@@ -35,11 +44,11 @@ export function walk(node: unknown, visit: VisitorCallback): VisitorResult {
|
|
|
35
44
|
if (Array.isArray(value)) {
|
|
36
45
|
const m = value.length;
|
|
37
46
|
for (let j = 0; j < m; ++j) {
|
|
38
|
-
if (value[j] && Number(
|
|
47
|
+
if (value[j] && Number(_walk(value[j], node, visit)) < 0) {
|
|
39
48
|
return result;
|
|
40
49
|
}
|
|
41
50
|
}
|
|
42
|
-
} else if (value && Number(
|
|
51
|
+
} else if (value && Number(_walk(value, node, visit)) < 0) {
|
|
43
52
|
return -1;
|
|
44
53
|
}
|
|
45
54
|
}
|