@uwdata/mosaic-sql 0.24.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.
Files changed (38) hide show
  1. package/dist/src/ast/index.d.ts +32 -0
  2. package/dist/src/ast/index.d.ts.map +1 -0
  3. package/dist/src/ast/index.js +32 -0
  4. package/dist/src/ast/index.js.map +1 -0
  5. package/dist/src/ast/query.d.ts +6 -1
  6. package/dist/src/ast/query.d.ts.map +1 -1
  7. package/dist/src/ast/query.js +16 -1
  8. package/dist/src/ast/query.js.map +1 -1
  9. package/dist/src/index.d.ts +1 -31
  10. package/dist/src/index.d.ts.map +1 -1
  11. package/dist/src/index.js +1 -31
  12. package/dist/src/index.js.map +1 -1
  13. package/dist/src/visit/codegen/duckdb.d.ts +1 -1
  14. package/dist/src/visit/codegen/duckdb.d.ts.map +1 -1
  15. package/dist/src/visit/codegen/duckdb.js +1 -1
  16. package/dist/src/visit/codegen/duckdb.js.map +1 -1
  17. package/dist/src/visit/duckdb-visitor.d.ts +50 -0
  18. package/dist/src/visit/duckdb-visitor.d.ts.map +1 -0
  19. package/dist/src/visit/duckdb-visitor.js +350 -0
  20. package/dist/src/visit/duckdb-visitor.js.map +1 -0
  21. package/dist/src/visit/to-string-visitor.d.ts +60 -0
  22. package/dist/src/visit/to-string-visitor.d.ts.map +1 -0
  23. package/dist/src/visit/to-string-visitor.js +80 -0
  24. package/dist/src/visit/to-string-visitor.js.map +1 -0
  25. package/dist/src/visit/visitors.d.ts.map +1 -1
  26. package/dist/src/visit/visitors.js +5 -5
  27. package/dist/src/visit/visitors.js.map +1 -1
  28. package/dist/src/visit/walk.d.ts +1 -1
  29. package/dist/src/visit/walk.d.ts.map +1 -1
  30. package/dist/src/visit/walk.js +11 -3
  31. package/dist/src/visit/walk.js.map +1 -1
  32. package/package.json +2 -2
  33. package/src/ast/index.ts +31 -0
  34. package/src/ast/query.ts +18 -3
  35. package/src/index.ts +1 -31
  36. package/src/visit/codegen/duckdb.ts +1 -1
  37. package/src/visit/visitors.ts +4 -5
  38. 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.24.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": "4d41d46038d4438ce9283d13b875abf0a9b9c2f4"
32
+ "gitHead": "d4d41a3275dbd6bc7995e1d1a82b0be18769bbca"
33
33
  }
@@ -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 != null) for (const name in e) {
459
- list.push(new WindowClauseNode(unquote(name)!, e[name]));
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 { AggregateNode, aggregateNames, isAggregateFunction } from './ast/aggregate.js';
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';
@@ -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(walk(value[j], visit)) < 0) {
47
+ if (value[j] && Number(_walk(value[j], node, visit)) < 0) {
39
48
  return result;
40
49
  }
41
50
  }
42
- } else if (value && Number(walk(value, visit)) < 0) {
51
+ } else if (value && Number(_walk(value, node, visit)) < 0) {
43
52
  return -1;
44
53
  }
45
54
  }