@uwdata/mosaic-sql 0.19.0 → 0.20.1
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/aggregate.d.ts +0 -4
- package/dist/src/ast/aggregate.d.ts.map +1 -1
- package/dist/src/ast/aggregate.js +0 -15
- package/dist/src/ast/aggregate.js.map +1 -1
- package/dist/src/ast/between-op.d.ts +0 -8
- package/dist/src/ast/between-op.d.ts.map +1 -1
- package/dist/src/ast/between-op.js +0 -12
- package/dist/src/ast/between-op.js.map +1 -1
- package/dist/src/ast/binary-op.d.ts +0 -4
- package/dist/src/ast/binary-op.d.ts.map +1 -1
- package/dist/src/ast/binary-op.js +0 -6
- package/dist/src/ast/binary-op.js.map +1 -1
- package/dist/src/ast/case.d.ts +0 -8
- package/dist/src/ast/case.d.ts.map +1 -1
- package/dist/src/ast/case.js +0 -16
- package/dist/src/ast/case.js.map +1 -1
- package/dist/src/ast/cast.d.ts +0 -4
- package/dist/src/ast/cast.d.ts.map +1 -1
- package/dist/src/ast/cast.js +0 -7
- package/dist/src/ast/cast.js.map +1 -1
- package/dist/src/ast/collate.d.ts +0 -4
- package/dist/src/ast/collate.d.ts.map +1 -1
- package/dist/src/ast/collate.js +0 -6
- package/dist/src/ast/collate.js.map +1 -1
- package/dist/src/ast/column-ref.d.ts +0 -4
- package/dist/src/ast/column-ref.d.ts.map +1 -1
- package/dist/src/ast/column-ref.js +0 -10
- package/dist/src/ast/column-ref.js.map +1 -1
- package/dist/src/ast/fragment.d.ts +0 -4
- package/dist/src/ast/fragment.d.ts.map +1 -1
- package/dist/src/ast/fragment.js +0 -6
- package/dist/src/ast/fragment.js.map +1 -1
- package/dist/src/ast/from.d.ts +10 -3
- package/dist/src/ast/from.d.ts.map +1 -1
- package/dist/src/ast/from.js +11 -12
- package/dist/src/ast/from.js.map +1 -1
- package/dist/src/ast/function.d.ts +0 -4
- package/dist/src/ast/function.d.ts.map +1 -1
- package/dist/src/ast/function.js +0 -7
- package/dist/src/ast/function.js.map +1 -1
- package/dist/src/ast/in-op.d.ts +0 -4
- package/dist/src/ast/in-op.d.ts.map +1 -1
- package/dist/src/ast/in-op.js +0 -6
- package/dist/src/ast/in-op.js.map +1 -1
- package/dist/src/ast/interval.d.ts +0 -4
- package/dist/src/ast/interval.d.ts.map +1 -1
- package/dist/src/ast/interval.js +0 -6
- package/dist/src/ast/interval.js.map +1 -1
- package/dist/src/ast/join.d.ts +45 -0
- package/dist/src/ast/join.d.ts.map +1 -0
- package/dist/src/ast/join.js +47 -0
- package/dist/src/ast/join.js.map +1 -0
- package/dist/src/ast/list.d.ts +0 -4
- package/dist/src/ast/list.d.ts.map +1 -1
- package/dist/src/ast/list.js +0 -6
- package/dist/src/ast/list.js.map +1 -1
- package/dist/src/ast/literal.d.ts +0 -4
- package/dist/src/ast/literal.d.ts.map +1 -1
- package/dist/src/ast/literal.js +0 -6
- package/dist/src/ast/literal.js.map +1 -1
- package/dist/src/ast/logical-op.d.ts +0 -4
- package/dist/src/ast/logical-op.d.ts.map +1 -1
- package/dist/src/ast/logical-op.js +0 -9
- package/dist/src/ast/logical-op.js.map +1 -1
- package/dist/src/ast/node.d.ts +13 -0
- package/dist/src/ast/node.d.ts.map +1 -1
- package/dist/src/ast/node.js +25 -3
- package/dist/src/ast/node.js.map +1 -1
- package/dist/src/ast/order-by.d.ts +0 -4
- package/dist/src/ast/order-by.d.ts.map +1 -1
- package/dist/src/ast/order-by.js +0 -13
- package/dist/src/ast/order-by.js.map +1 -1
- package/dist/src/ast/param.d.ts +0 -4
- package/dist/src/ast/param.d.ts.map +1 -1
- package/dist/src/ast/param.js +0 -7
- package/dist/src/ast/param.js.map +1 -1
- package/dist/src/ast/query.d.ts +2 -14
- package/dist/src/ast/query.d.ts.map +1 -1
- package/dist/src/ast/query.js +14 -91
- package/dist/src/ast/query.js.map +1 -1
- package/dist/src/ast/sample.d.ts +0 -4
- package/dist/src/ast/sample.d.ts.map +1 -1
- package/dist/src/ast/sample.js +0 -9
- package/dist/src/ast/sample.js.map +1 -1
- package/dist/src/ast/select.d.ts +0 -4
- package/dist/src/ast/select.d.ts.map +1 -1
- package/dist/src/ast/select.js +0 -16
- package/dist/src/ast/select.js.map +1 -1
- package/dist/src/ast/subquery.d.ts +0 -4
- package/dist/src/ast/subquery.d.ts.map +1 -1
- package/dist/src/ast/subquery.js +0 -6
- package/dist/src/ast/subquery.js.map +1 -1
- package/dist/src/ast/table-ref.d.ts +0 -4
- package/dist/src/ast/table-ref.d.ts.map +1 -1
- package/dist/src/ast/table-ref.js +0 -7
- package/dist/src/ast/table-ref.js.map +1 -1
- package/dist/src/ast/unary-op.d.ts +0 -8
- package/dist/src/ast/unary-op.d.ts.map +1 -1
- package/dist/src/ast/unary-op.js +0 -12
- package/dist/src/ast/unary-op.js.map +1 -1
- package/dist/src/ast/unnest.d.ts +0 -4
- package/dist/src/ast/unnest.d.ts.map +1 -1
- package/dist/src/ast/unnest.js +0 -8
- package/dist/src/ast/unnest.js.map +1 -1
- package/dist/src/ast/verbatim.d.ts +0 -4
- package/dist/src/ast/verbatim.d.ts.map +1 -1
- package/dist/src/ast/verbatim.js +0 -6
- package/dist/src/ast/verbatim.js.map +1 -1
- package/dist/src/ast/window-frame.d.ts +0 -8
- package/dist/src/ast/window-frame.d.ts.map +1 -1
- package/dist/src/ast/window-frame.js +1 -29
- package/dist/src/ast/window-frame.js.map +1 -1
- package/dist/src/ast/window.d.ts +0 -16
- package/dist/src/ast/window.d.ts.map +1 -1
- package/dist/src/ast/window.js +0 -39
- package/dist/src/ast/window.js.map +1 -1
- package/dist/src/ast/with.d.ts +0 -4
- package/dist/src/ast/with.d.ts.map +1 -1
- package/dist/src/ast/with.js +0 -10
- package/dist/src/ast/with.js.map +1 -1
- package/dist/src/constants.d.ts +2 -0
- package/dist/src/constants.d.ts.map +1 -1
- package/dist/src/constants.js +2 -0
- package/dist/src/constants.js.map +1 -1
- package/dist/src/functions/from.d.ts +11 -0
- package/dist/src/functions/from.d.ts.map +1 -0
- package/dist/src/functions/from.js +12 -0
- package/dist/src/functions/from.js.map +1 -0
- package/dist/src/functions/join.d.ts +49 -0
- package/dist/src/functions/join.d.ts.map +1 -0
- package/dist/src/functions/join.js +50 -0
- package/dist/src/functions/join.js.map +1 -0
- package/dist/src/index.d.ts +7 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +8 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/init.d.ts +2 -0
- package/dist/src/init.d.ts.map +1 -0
- package/dist/src/init.js +5 -0
- package/dist/src/init.js.map +1 -0
- package/dist/src/transforms/bin-histogram.d.ts.map +1 -1
- package/dist/src/transforms/bin-histogram.js +7 -2
- package/dist/src/transforms/bin-histogram.js.map +1 -1
- package/dist/src/transforms/filter-query.d.ts.map +1 -1
- package/dist/src/transforms/filter-query.js +2 -0
- package/dist/src/transforms/filter-query.js.map +1 -1
- package/dist/src/transforms/util/time-interval.d.ts.map +1 -1
- package/dist/src/transforms/util/time-interval.js +3 -0
- package/dist/src/transforms/util/time-interval.js.map +1 -1
- package/dist/src/visit/codegen/duckdb.d.ts +49 -0
- package/dist/src/visit/codegen/duckdb.d.ts.map +1 -0
- package/dist/src/visit/codegen/duckdb.js +332 -0
- package/dist/src/visit/codegen/duckdb.js.map +1 -0
- package/dist/src/visit/codegen/sql.d.ts +60 -0
- package/dist/src/visit/codegen/sql.d.ts.map +1 -0
- package/dist/src/visit/codegen/sql.js +85 -0
- package/dist/src/visit/codegen/sql.js.map +1 -0
- 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/recurse.d.ts.map +1 -1
- package/dist/src/visit/recurse.js +2 -1
- package/dist/src/visit/recurse.js.map +1 -1
- 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/package.json +2 -2
- package/src/ast/aggregate.ts +0 -16
- package/src/ast/between-op.ts +0 -14
- package/src/ast/binary-op.ts +0 -7
- package/src/ast/case.ts +0 -18
- package/src/ast/cast.ts +0 -8
- package/src/ast/collate.ts +0 -7
- package/src/ast/column-ref.ts +0 -11
- package/src/ast/fragment.ts +0 -7
- package/src/ast/from.ts +12 -12
- package/src/ast/function.ts +0 -8
- package/src/ast/in-op.ts +0 -7
- package/src/ast/interval.ts +0 -7
- package/src/ast/join.ts +66 -0
- package/src/ast/list.ts +0 -7
- package/src/ast/literal.ts +0 -7
- package/src/ast/logical-op.ts +0 -10
- package/src/ast/node.ts +30 -3
- package/src/ast/order-by.ts +0 -14
- package/src/ast/param.ts +0 -8
- package/src/ast/query.ts +14 -102
- package/src/ast/sample.ts +0 -10
- package/src/ast/select.ts +0 -18
- package/src/ast/subquery.ts +0 -7
- package/src/ast/table-ref.ts +0 -8
- package/src/ast/unary-op.ts +0 -14
- package/src/ast/unnest.ts +0 -9
- package/src/ast/verbatim.ts +0 -7
- package/src/ast/window-frame.ts +1 -32
- package/src/ast/window.ts +0 -43
- package/src/ast/with.ts +0 -11
- package/src/constants.ts +2 -0
- package/src/functions/from.ts +18 -0
- package/src/functions/join.ts +101 -0
- package/src/index.ts +9 -1
- package/src/init.ts +5 -0
- package/src/transforms/bin-histogram.ts +8 -2
- package/src/transforms/filter-query.ts +2 -0
- package/src/transforms/util/time-interval.ts +4 -0
- package/src/visit/codegen/duckdb.ts +444 -0
- package/src/visit/codegen/sql.ts +213 -0
- package/src/visit/recurse.ts +2 -0
package/src/ast/window-frame.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { WINDOW_EXTENT_EXPR, WINDOW_FRAME } from '../constants.js';
|
|
2
2
|
import { type ParamLike } from '../types.js';
|
|
3
3
|
import { isParamLike } from '../util/type-check.js';
|
|
4
|
-
import { type ExprNode,
|
|
4
|
+
import { type ExprNode, SQLNode } from './node.js';
|
|
5
5
|
import { ParamNode } from './param.js';
|
|
6
6
|
|
|
7
7
|
export type FrameValue = ExprNode | number | null;
|
|
@@ -42,27 +42,6 @@ export class WindowFrameNode extends SQLNode {
|
|
|
42
42
|
this.extent = isParamLike(extent) ? new ParamNode(extent) : extent;
|
|
43
43
|
this.exclude = exclude;
|
|
44
44
|
}
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Generate a SQL query string for this node.
|
|
48
|
-
*/
|
|
49
|
-
toString() {
|
|
50
|
-
const { frameType, exclude, extent } = this;
|
|
51
|
-
const [prev, next] = isNode(extent)
|
|
52
|
-
? extent.value as [unknown, unknown]
|
|
53
|
-
: extent;
|
|
54
|
-
const a = asFrameExpr(prev, PRECEDING);
|
|
55
|
-
const b = asFrameExpr(next, FOLLOWING);
|
|
56
|
-
return `${frameType} BETWEEN ${a} AND ${b}${exclude ? ` ${exclude}` : ''}`;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
function asFrameExpr(value: unknown, scope: string) {
|
|
61
|
-
return value instanceof WindowFrameExprNode ? value
|
|
62
|
-
: value != null && typeof value !== 'number' ? `${value} ${scope}`
|
|
63
|
-
: value === 0 ? CURRENT_ROW
|
|
64
|
-
: !(value && Number.isFinite(value)) ? `${UNBOUNDED} ${scope}`
|
|
65
|
-
: `${Math.abs(value)} ${scope}`;
|
|
66
45
|
}
|
|
67
46
|
|
|
68
47
|
export class WindowFrameExprNode extends SQLNode {
|
|
@@ -84,14 +63,4 @@ export class WindowFrameExprNode extends SQLNode {
|
|
|
84
63
|
this.scope = scope;
|
|
85
64
|
this.expr = expr;
|
|
86
65
|
}
|
|
87
|
-
|
|
88
|
-
/**
|
|
89
|
-
* Generate a SQL query string for this node.
|
|
90
|
-
*/
|
|
91
|
-
toString() {
|
|
92
|
-
const { scope, expr } = this;
|
|
93
|
-
return scope === CURRENT_ROW
|
|
94
|
-
? scope
|
|
95
|
-
: `${expr ?? UNBOUNDED} ${scope}`;
|
|
96
|
-
}
|
|
97
66
|
}
|
package/src/ast/window.ts
CHANGED
|
@@ -3,7 +3,6 @@ import type { AggregateNode } from './aggregate.js';
|
|
|
3
3
|
import type { WindowFrameNode } from './window-frame.js';
|
|
4
4
|
import { WINDOW, WINDOW_CLAUSE, WINDOW_DEF, WINDOW_FUNCTION } from '../constants.js';
|
|
5
5
|
import { nodeList } from '../util/function.js';
|
|
6
|
-
import { quoteIdentifier } from '../util/string.js';
|
|
7
6
|
import { ExprNode, SQLNode } from './node.js';
|
|
8
7
|
|
|
9
8
|
export class WindowClauseNode extends SQLNode {
|
|
@@ -22,13 +21,6 @@ export class WindowClauseNode extends SQLNode {
|
|
|
22
21
|
this.name = name;
|
|
23
22
|
this.def = def;
|
|
24
23
|
}
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Generate a SQL query string for this node.
|
|
28
|
-
*/
|
|
29
|
-
toString() {
|
|
30
|
-
return `${quoteIdentifier(this.name)} AS ${this.def}`;
|
|
31
|
-
}
|
|
32
24
|
}
|
|
33
25
|
|
|
34
26
|
export class WindowNode extends ExprNode {
|
|
@@ -84,13 +76,6 @@ export class WindowNode extends ExprNode {
|
|
|
84
76
|
frame(framedef: WindowFrameNode) {
|
|
85
77
|
return new WindowNode(this.func, this.def.frame(framedef));
|
|
86
78
|
}
|
|
87
|
-
|
|
88
|
-
/**
|
|
89
|
-
* Generate a SQL query string for this node.
|
|
90
|
-
*/
|
|
91
|
-
toString() {
|
|
92
|
-
return `${this.func} OVER ${this.def}`;
|
|
93
|
-
}
|
|
94
79
|
}
|
|
95
80
|
|
|
96
81
|
export class WindowFunctionNode extends ExprNode {
|
|
@@ -123,19 +108,6 @@ export class WindowFunctionNode extends ExprNode {
|
|
|
123
108
|
this.ignoreNulls = ignoreNulls;
|
|
124
109
|
this.order = nodeList([argOrder]);
|
|
125
110
|
}
|
|
126
|
-
|
|
127
|
-
/**
|
|
128
|
-
* Generate a SQL query string for this node.
|
|
129
|
-
*/
|
|
130
|
-
toString() {
|
|
131
|
-
const { name, args, ignoreNulls, order } = this;
|
|
132
|
-
const arg = [
|
|
133
|
-
args.join(', '),
|
|
134
|
-
order.length ? `ORDER BY ${order.join(', ')}` : '',
|
|
135
|
-
ignoreNulls ? 'IGNORE NULLS' : ''
|
|
136
|
-
].filter(x => x).join(' ');
|
|
137
|
-
return `${name}(${arg})`;
|
|
138
|
-
}
|
|
139
111
|
}
|
|
140
112
|
|
|
141
113
|
export class WindowDefNode extends SQLNode {
|
|
@@ -203,21 +175,6 @@ export class WindowDefNode extends SQLNode {
|
|
|
203
175
|
frame(framedef: WindowFrameNode) {
|
|
204
176
|
return deriveDef(this, { framedef });
|
|
205
177
|
}
|
|
206
|
-
|
|
207
|
-
/**
|
|
208
|
-
* Generate a SQL query string for this node.
|
|
209
|
-
*/
|
|
210
|
-
toString() {
|
|
211
|
-
const { name, partition, order, framedef } = this;
|
|
212
|
-
const base = name && quoteIdentifier(name);
|
|
213
|
-
const def = [
|
|
214
|
-
base,
|
|
215
|
-
partition?.length && `PARTITION BY ${partition.join(', ')}`,
|
|
216
|
-
order?.length && `ORDER BY ${order.join(', ')}`,
|
|
217
|
-
framedef
|
|
218
|
-
].filter(x => x);
|
|
219
|
-
return base && def.length < 2 ? base : `(${def.join(' ')})`;
|
|
220
|
-
}
|
|
221
178
|
}
|
|
222
179
|
|
|
223
180
|
interface DeriveDefOptions {
|
package/src/ast/with.ts
CHANGED
|
@@ -29,15 +29,4 @@ export class WithClauseNode extends SQLNode {
|
|
|
29
29
|
this.query = query;
|
|
30
30
|
this.materialized = materialized;
|
|
31
31
|
}
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Generate a SQL query string for this node.
|
|
35
|
-
*/
|
|
36
|
-
toString() {
|
|
37
|
-
const flag = this.materialized;
|
|
38
|
-
const mat = flag === true ? ' MATERIALIZED'
|
|
39
|
-
: flag === false ? ' NOT MATERIALIZED'
|
|
40
|
-
: '';
|
|
41
|
-
return `"${this.name}" AS${mat} (${this.query})`;
|
|
42
|
-
}
|
|
43
32
|
}
|
package/src/constants.ts
CHANGED
|
@@ -27,6 +27,7 @@ export const WINDOW_FUNCTION = 'WINDOW_FUNCTION';
|
|
|
27
27
|
export const WINDOW_DEF = 'WINDOW_DEF';
|
|
28
28
|
export const WINDOW_FRAME = 'WINDOW_FRAME';
|
|
29
29
|
export const WINDOW_EXTENT_EXPR = 'WINDOW_EXTENT_EXPR';
|
|
30
|
+
export const CUSTOM = 'CUSTOM';
|
|
30
31
|
|
|
31
32
|
export const EXPRESSION = 'EXPRESSION';
|
|
32
33
|
export const FRAGMENT = 'FRAGMENT';
|
|
@@ -37,6 +38,7 @@ export const WITH_CLAUSE = 'WITH_CLAUSE';
|
|
|
37
38
|
export const WINDOW_CLAUSE = 'WINDOW_CLAUSE';
|
|
38
39
|
export const SELECT_CLAUSE = 'SELECT_CLAUSE';
|
|
39
40
|
export const FROM_CLAUSE = 'FROM_CLAUSE';
|
|
41
|
+
export const JOIN_CLAUSE = 'JOIN_CLAUSE';
|
|
40
42
|
export const SAMPLE_CLAUSE = 'SAMPLE_CLAUSE';
|
|
41
43
|
|
|
42
44
|
export const SELECT_QUERY = 'SELECT_QUERY';
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { FromClauseNode } from "../ast/from.js";
|
|
2
|
+
import { SampleClauseNode } from "../ast/sample.js";
|
|
3
|
+
import { TableRefNode } from "../ast/table-ref.js";
|
|
4
|
+
import { asTableRef } from "../util/ast.js";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Create a new table FROM reference, applicable in a query or join.
|
|
8
|
+
* @param table The table.
|
|
9
|
+
* @param alias An optional table alias.
|
|
10
|
+
* @param sample An optional table sample to apply.
|
|
11
|
+
*/
|
|
12
|
+
export function from(
|
|
13
|
+
table: string | string[] | TableRefNode,
|
|
14
|
+
alias?: string,
|
|
15
|
+
sample?: SampleClauseNode
|
|
16
|
+
) {
|
|
17
|
+
return new FromClauseNode(asTableRef(table)!, alias, sample);
|
|
18
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { ColumnRefNode } from '../ast/column-ref.js';
|
|
2
|
+
import { FromNode } from '../ast/from.js';
|
|
3
|
+
import { JoinNode, type JoinType, type JoinVariant } from '../ast/join.js';
|
|
4
|
+
import { ExprNode } from '../ast/node.js';
|
|
5
|
+
import { asNode, asTableRef } from '../util/ast.js';
|
|
6
|
+
|
|
7
|
+
type TableArg = string | string[] | FromNode;
|
|
8
|
+
|
|
9
|
+
/** Options for a JOIN operation. */
|
|
10
|
+
interface JoinOptions {
|
|
11
|
+
/** The join type (INNER, LEFT, RIGHT, FULL, SEMI, ANTI). */
|
|
12
|
+
type?: JoinType;
|
|
13
|
+
/**
|
|
14
|
+
* The join condition as a boolean expression.
|
|
15
|
+
* If specified, the *using* option must not be specified.
|
|
16
|
+
*/
|
|
17
|
+
on?: ExprNode;
|
|
18
|
+
/**
|
|
19
|
+
* The join condition as an array of columns to match.
|
|
20
|
+
* The column names must exist in both tables.
|
|
21
|
+
* If specified, the *on* option must not be specified.
|
|
22
|
+
*/
|
|
23
|
+
using?: (string | ColumnRefNode)[];
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function tableRef(x: TableArg) {
|
|
27
|
+
return x instanceof FromNode ? x : asTableRef(x)!;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function makeJoin(
|
|
31
|
+
left: TableArg,
|
|
32
|
+
right: TableArg,
|
|
33
|
+
variant?: JoinVariant,
|
|
34
|
+
options: JoinOptions = {}
|
|
35
|
+
) {
|
|
36
|
+
if (options.on && options.using) {
|
|
37
|
+
throw new Error('Only one join condition (on or using) can be applied.');
|
|
38
|
+
}
|
|
39
|
+
return new JoinNode(
|
|
40
|
+
tableRef(left),
|
|
41
|
+
tableRef(right),
|
|
42
|
+
variant,
|
|
43
|
+
options.type,
|
|
44
|
+
options.on,
|
|
45
|
+
options.using?.map(c => asNode(c) as ColumnRefNode)
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Create a new cross (cartesian product) join.
|
|
51
|
+
* @param left The left table to join.
|
|
52
|
+
* @param right The right table to join.
|
|
53
|
+
*/
|
|
54
|
+
export function cross_join(left: TableArg, right: TableArg) {
|
|
55
|
+
return makeJoin(left, right, 'CROSS');
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Create a new POSITIONAL join.
|
|
60
|
+
* @param left The left table to join.
|
|
61
|
+
* @param right The right table to join.
|
|
62
|
+
*/
|
|
63
|
+
export function positional_join(left: TableArg, right: TableArg) {
|
|
64
|
+
return makeJoin(left, right, 'POSITIONAL');
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Create a new join.
|
|
69
|
+
* @param left The left table to join.
|
|
70
|
+
* @param right The right table to join.
|
|
71
|
+
* @param options The join options.
|
|
72
|
+
*/
|
|
73
|
+
export function join(
|
|
74
|
+
left: TableArg,
|
|
75
|
+
right: TableArg,
|
|
76
|
+
options?: JoinOptions
|
|
77
|
+
) {
|
|
78
|
+
return makeJoin(
|
|
79
|
+
left,
|
|
80
|
+
right,
|
|
81
|
+
options?.on || options?.using ? 'REGULAR' : 'NATURAL',
|
|
82
|
+
options
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Create a new ASOF join.
|
|
88
|
+
* @param left The left table to join.
|
|
89
|
+
* @param right The right table to join.
|
|
90
|
+
* @param options The join options.
|
|
91
|
+
*/
|
|
92
|
+
export function asof_join(
|
|
93
|
+
left: TableArg,
|
|
94
|
+
right: TableArg,
|
|
95
|
+
options: JoinOptions
|
|
96
|
+
) {
|
|
97
|
+
if (!(options.on || options.using)) {
|
|
98
|
+
throw new Error('ASOF join requires a join condition.');
|
|
99
|
+
}
|
|
100
|
+
return makeJoin(left, right, 'ASOF', options);
|
|
101
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
// Initialize default visitor
|
|
2
|
+
import './init.js';
|
|
3
|
+
|
|
1
4
|
export { AggregateNode, aggregateNames, isAggregateFunction } from './ast/aggregate.js';
|
|
2
5
|
export { BetweenOpNode, NotBetweenOpNode } from './ast/between-op.js'
|
|
3
6
|
export { BinaryOpNode } from './ast/binary-op.js';
|
|
@@ -11,9 +14,10 @@ export { FromClauseNode } from './ast/from.js';
|
|
|
11
14
|
export { FunctionNode } from './ast/function.js';
|
|
12
15
|
export { InOpNode } from './ast/in-op.js';
|
|
13
16
|
export { IntervalNode } from './ast/interval.js';
|
|
17
|
+
export { JoinNode, type JoinType, type JoinVariant } from './ast/join.js';
|
|
14
18
|
export { ListNode } from './ast/list.js';
|
|
15
19
|
export { LiteralNode } from './ast/literal.js';
|
|
16
|
-
export { AndNode, OrNode } from './ast/logical-op.js';
|
|
20
|
+
export { LogicalOpNode, AndNode, OrNode } from './ast/logical-op.js';
|
|
17
21
|
export { SQLNode, ExprNode, isNode } from './ast/node.js';
|
|
18
22
|
export { OrderByNode } from './ast/order-by.js';
|
|
19
23
|
export { ParamNode } from './ast/param.js';
|
|
@@ -36,7 +40,9 @@ export { collate } from './functions/collate.js';
|
|
|
36
40
|
export { column } from './functions/column.js';
|
|
37
41
|
export { cte } from './functions/cte.js';
|
|
38
42
|
export { dateBin, dateMonth, dateMonthDay, dateDay, epoch_ms } from './functions/datetime.js';
|
|
43
|
+
export { from } from './functions/from.js';
|
|
39
44
|
export { days, hours, interval, microseconds, minutes, milliseconds, months, seconds, years } from './functions/interval.js';
|
|
45
|
+
export { asof_join, cross_join, join, positional_join } from './functions/join.js';
|
|
40
46
|
export { list, listContains, listHasAll, listHasAny } from './functions/list.js';
|
|
41
47
|
export { literal, verbatim } from './functions/literal.js';
|
|
42
48
|
export { abs, ceil, exp, floor, greatest, isFinite, isInfinite, isNaN, least, ln, log, round, sign, sqrt, trunc } from './functions/numeric.js';
|
|
@@ -54,6 +60,8 @@ export { deepClone } from './visit/clone.js';
|
|
|
54
60
|
export { rewrite } from './visit/rewrite.js';
|
|
55
61
|
export { collectAggregates, collectColumns, collectParams, isAggregateExpression } from './visit/visitors.js';
|
|
56
62
|
export { walk, type VisitorCallback, type VisitorResult } from './visit/walk.js';
|
|
63
|
+
export { SQLCodeGenerator } from './visit/codegen/sql.js';
|
|
64
|
+
export { DuckDBCodeGenerator, duckDBCodeGenerator } from './visit/codegen/duckdb.js';
|
|
57
65
|
|
|
58
66
|
export { createTable, createSchema } from './load/create.js';
|
|
59
67
|
export { loadExtension } from './load/extension.js';
|
package/src/init.ts
ADDED
|
@@ -3,6 +3,7 @@ import type { ExprValue } from '../types.js';
|
|
|
3
3
|
import { float64 } from '../functions/cast.js';
|
|
4
4
|
import { floor } from '../functions/numeric.js';
|
|
5
5
|
import { add, div, mul, sub } from '../functions/operators.js';
|
|
6
|
+
import { asNode } from '../util/ast.js';
|
|
6
7
|
import { binSpec } from './util/bin-step.js';
|
|
7
8
|
import { Scale, scaleTransform } from './scales.js';
|
|
8
9
|
|
|
@@ -47,14 +48,19 @@ export function binHistogram(
|
|
|
47
48
|
): ExprNode {
|
|
48
49
|
const [min, max] = extent;
|
|
49
50
|
const { offset = 0 } = options;
|
|
51
|
+
|
|
52
|
+
// handle degenerate extent
|
|
53
|
+
if (max === min) return offset ? add(offset, field) : asNode(field);
|
|
54
|
+
|
|
50
55
|
const { apply, sqlApply, sqlInvert } = transform;
|
|
51
56
|
const b = binSpec(apply(min), apply(max), options);
|
|
52
57
|
const col = sqlApply(field);
|
|
53
|
-
const alpha = (b.max - b.min) / b.steps;
|
|
58
|
+
const alpha = ((b.max - b.min) / b.steps) || 1;
|
|
54
59
|
|
|
55
60
|
let expr = b.min === 0 ? col : sub(col, b.min);
|
|
56
61
|
if (alpha !== 1) expr = div(expr, float64(alpha));
|
|
57
|
-
|
|
62
|
+
// add offset *after* floor to dodge nasty floating point nuances
|
|
63
|
+
expr = offset ? add(offset, floor(expr)) : floor(expr);
|
|
58
64
|
if (alpha !== 1) expr = mul(alpha, expr);
|
|
59
65
|
if (b.min !== 0) expr = add(b.min, expr);
|
|
60
66
|
return sqlInvert(expr);
|
|
@@ -3,6 +3,7 @@ import { isSelectQuery, type Query } from '../ast/query.js';
|
|
|
3
3
|
import { isTableRef, type TableRefNode } from '../ast/table-ref.js';
|
|
4
4
|
import { deepClone } from '../visit/clone.js';
|
|
5
5
|
import { walk } from '../visit/walk.js';
|
|
6
|
+
import { FromClauseNode } from '../ast/from.js';
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* Returns a generator function that clones the given query and adds
|
|
@@ -18,6 +19,7 @@ export function filterQuery(query: Query, tableRef: TableRefNode) {
|
|
|
18
19
|
if (
|
|
19
20
|
isSelectQuery(node) &&
|
|
20
21
|
node._from.length === 1 &&
|
|
22
|
+
node._from[0] instanceof FromClauseNode &&
|
|
21
23
|
isTableRef(node._from[0].expr) &&
|
|
22
24
|
arrayEquals(node._from[0].expr.table, tableRef.table)
|
|
23
25
|
) {
|
|
@@ -63,6 +63,10 @@ export function timeInterval(
|
|
|
63
63
|
steps: number
|
|
64
64
|
): ({ unit: TimeUnit, step: number }) {
|
|
65
65
|
const span = +max - +min;
|
|
66
|
+
|
|
67
|
+
// if degenerate span, default to one day
|
|
68
|
+
if (span === 0) return { unit: DAY, step: 1 };
|
|
69
|
+
|
|
66
70
|
const t = span / steps; // target step size duration
|
|
67
71
|
const i = bisect(units, t, v => v.dt);
|
|
68
72
|
|