@uwdata/mosaic-sql 0.15.0 → 0.16.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.
@@ -19,4 +19,4 @@ export class SelectClauseNode extends SQLNode {
19
19
  readonly alias: string;
20
20
  }
21
21
  import { SQLNode } from './node.js';
22
- import { ExprNode } from './node.js';
22
+ import type { ExprNode } from './node.js';
@@ -172,7 +172,7 @@ export class WindowFrameNode extends SQLNode {
172
172
  export type FrameExtent = [any, any] | ParamLike;
173
173
  import { SQLNode } from './node.js';
174
174
  import { ExprNode } from './node.js';
175
- import { AggregateNode } from './aggregate.js';
175
+ import type { AggregateNode } from './aggregate.js';
176
176
  import type { ExprVarArgs } from '../types.js';
177
177
  import { FunctionNode } from './function.js';
178
178
  import type { WindowFunctionName } from '../types.js';
@@ -29,4 +29,4 @@ export class WithClauseNode extends SQLNode {
29
29
  readonly materialized: boolean | null;
30
30
  }
31
31
  import { SQLNode } from './node.js';
32
- import { Query } from './query.js';
32
+ import type { Query } from './query.js';
@@ -7,5 +7,5 @@
7
7
  */
8
8
  export function column(name: string | ParamLike, table?: string | string[] | TableRefNode): ColumnRefNode;
9
9
  import type { ParamLike } from '../types.js';
10
- import { TableRefNode } from '../ast/table-ref.js';
10
+ import type { TableRefNode } from '../ast/table-ref.js';
11
11
  import type { ColumnRefNode } from '../ast/column-ref.js';
@@ -9,5 +9,5 @@
9
9
  * @returns {WithClauseNode}
10
10
  */
11
11
  export function cte(name: string, query: Query, materialized?: boolean | null): WithClauseNode;
12
- import { Query } from '../ast/query.js';
12
+ import type { Query } from '../ast/query.js';
13
13
  import { WithClauseNode } from '../ast/with.js';
@@ -1,10 +1,10 @@
1
1
  /**
2
2
  * Rewrite a SQL expression, based on a map of nodes to replace.
3
- * This method updates the expression in place.
3
+ * This method copies nodes as needed; it does not modify the input node.
4
4
  * @param {ExprNode} node The root AST node of the expression.
5
5
  * @param {Map<ExprNode, ExprNode>} map The rewrite map.
6
6
  * When encountered, key nodes are replaced by value nodes.
7
7
  * @returns {ExprNode}
8
8
  */
9
9
  export function rewrite(node: ExprNode, map: Map<ExprNode, ExprNode>): ExprNode;
10
- import { ExprNode } from '../ast/node.js';
10
+ import type { ExprNode } from '../ast/node.js';
@@ -28,7 +28,7 @@ export function collectColumns(root: SQLNode): ColumnRefNode[];
28
28
  * @returns {ParamLike[]}
29
29
  */
30
30
  export function collectParams(root: SQLNode): ParamLike[];
31
- import { SQLNode } from '../ast/node.js';
32
- import { AggregateNode } from '../ast/aggregate.js';
33
- import { ColumnRefNode } from '../ast/column-ref.js';
31
+ import type { SQLNode } from '../ast/node.js';
32
+ import type { AggregateNode } from '../ast/aggregate.js';
33
+ import type { ColumnRefNode } from '../ast/column-ref.js';
34
34
  import type { ParamLike } from '../types.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uwdata/mosaic-sql",
3
- "version": "0.15.0",
3
+ "version": "0.16.2",
4
4
  "description": "SQL query construction and analysis.",
5
5
  "keywords": [
6
6
  "sql",
@@ -27,5 +27,5 @@
27
27
  "tsc": "tsc -p jsconfig.json",
28
28
  "prepublishOnly": "npm run test && npm run lint && npm run build"
29
29
  },
30
- "gitHead": "671ad1ba86749a8435bd4aa7e722e2a8553f2cb0"
30
+ "gitHead": "26d2719f4bcab471d2831145e1f03f39f3509869"
31
31
  }
package/src/ast/select.js CHANGED
@@ -1,7 +1,8 @@
1
+ /** @import { ExprNode } from './node.js' */
1
2
  import { SELECT_CLAUSE } from '../constants.js';
2
3
  import { quoteIdentifier } from '../util/string.js';
3
4
  import { ColumnRefNode } from './column-ref.js';
4
- import { ExprNode, SQLNode } from './node.js';
5
+ import { SQLNode } from './node.js';
5
6
 
6
7
  export class SelectClauseNode extends SQLNode {
7
8
  /**
package/src/ast/window.js CHANGED
@@ -1,4 +1,5 @@
1
1
  /**
2
+ * @import { AggregateNode } from './aggregate.js'
2
3
  * @import { ExprVarArgs, WindowFunctionName } from '../types.js'
3
4
  * @import { ParamLike } from '../types.js'
4
5
  */
@@ -6,7 +7,6 @@ import { WINDOW, WINDOW_CLAUSE, WINDOW_DEF, WINDOW_FRAME } from '../constants.js
6
7
  import { exprList } from '../util/function.js';
7
8
  import { quoteIdentifier } from '../util/string.js';
8
9
  import { isParamLike } from '../util/type-check.js';
9
- import { AggregateNode } from './aggregate.js';
10
10
  import { FunctionNode } from './function.js';
11
11
  import { ExprNode, isNode, SQLNode } from './node.js';
12
12
  import { ParamNode } from './param.js';
package/src/ast/with.js CHANGED
@@ -1,6 +1,6 @@
1
+ /** @import { Query } from './query.js' */
1
2
  import { WITH_CLAUSE } from '../constants.js';
2
3
  import { SQLNode } from './node.js';
3
- import { Query } from './query.js';
4
4
 
5
5
  export class WithClauseNode extends SQLNode {
6
6
  /**
@@ -1,11 +1,11 @@
1
1
  /**
2
2
  * @import { ColumnRefNode } from '../ast/column-ref.js'
3
+ * @import { TableRefNode } from '../ast/table-ref.js'
3
4
  * @import { ParamLike } from '../types.js'
4
5
  */
5
6
  import { ColumnParamNode } from '../ast/column-param.js';
6
7
  import { ColumnNameRefNode } from '../ast/column-ref.js';
7
8
  import { ParamNode } from '../ast/param.js';
8
- import { TableRefNode } from '../ast/table-ref.js';
9
9
  import { asTableRef } from '../util/ast.js';
10
10
  import { isParamLike } from '../util/type-check.js';
11
11
 
@@ -1,4 +1,4 @@
1
- import { Query } from '../ast/query.js';
1
+ /** @import { Query } from '../ast/query.js' */
2
2
  import { WithClauseNode } from '../ast/with.js';
3
3
 
4
4
  /**
@@ -1,9 +1,10 @@
1
- import { ExprNode, isNode } from '../ast/node.js';
1
+ /** @import { ExprNode } from '../ast/node.js' */
2
+ import { isNode } from '../ast/node.js';
2
3
  import { recurse } from './recurse.js';
3
4
 
4
5
  /**
5
6
  * Rewrite a SQL expression, based on a map of nodes to replace.
6
- * This method updates the expression in place.
7
+ * This method copies nodes as needed; it does not modify the input node.
7
8
  * @param {ExprNode} node The root AST node of the expression.
8
9
  * @param {Map<ExprNode, ExprNode>} map The rewrite map.
9
10
  * When encountered, key nodes are replaced by value nodes.
@@ -15,18 +16,30 @@ export function rewrite(node, map) {
15
16
  } else if (isNode(node)) {
16
17
  const props = recurse[node.type];
17
18
  const n = props?.length ?? 0;
18
- for (let i = 0; i < n; ++i) {
19
- const prop = props[i];
20
- const child = node[prop];
21
- if (Array.isArray(child)) {
22
- const m = child.length;
23
- for (let j = 0; j < m; ++j) {
24
- child[j] = rewrite(child[j], map);
19
+ if (n > 0) {
20
+ node = cloneNode(node);
21
+ for (let i = 0; i < n; ++i) {
22
+ const prop = props[i];
23
+ const child = node[prop];
24
+ if (Array.isArray(child)) {
25
+ const m = child.length;
26
+ for (let j = 0; j < m; ++j) {
27
+ child[j] = rewrite(child[j], map);
28
+ }
29
+ } else if (child) {
30
+ node[prop] = rewrite(child, map);
25
31
  }
26
- } else if (child) {
27
- node[prop] = rewrite(child, map);
28
32
  }
29
33
  }
30
34
  }
31
35
  return node;
32
36
  }
37
+
38
+ // TODO: consider typed node.clone() methods
39
+ function cloneNode(node) {
40
+ const clone = new node.constructor();
41
+ for (const key in node) {
42
+ clone[key] = node[key];
43
+ }
44
+ return clone;
45
+ }
@@ -1,11 +1,12 @@
1
1
  /**
2
+ * @import { AggregateNode } from '../ast/aggregate.js'
3
+ * @import { ColumnRefNode } from '../ast/column-ref.js'
4
+ * @import { SQLNode } from '../ast/node.js'
2
5
  * @import { ParamNode } from '../ast/param.js'
3
6
  * @import { ParamLike } from '../types.js'
4
7
  */
5
8
  import { AGGREGATE, COLUMN_PARAM, COLUMN_REF, FRAGMENT, PARAM, VERBATIM, WINDOW } from '../constants.js';
6
- import { aggregateNames, AggregateNode } from '../ast/aggregate.js';
7
- import { ColumnRefNode } from '../ast/column-ref.js';
8
- import { SQLNode } from '../ast/node.js';
9
+ import { aggregateNames } from '../ast/aggregate.js';
9
10
  import { walk } from './walk.js';
10
11
 
11
12
  // regexp to match valid aggregate function names