@uwdata/mosaic-sql 0.10.0 → 0.12.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.
Files changed (142) hide show
  1. package/dist/mosaic-sql.js +2242 -1064
  2. package/dist/mosaic-sql.min.js +1 -1
  3. package/dist/types/ast/aggregate.d.ts +70 -0
  4. package/dist/types/ast/between-op.d.ts +46 -0
  5. package/dist/types/ast/binary-op.d.ts +28 -0
  6. package/dist/types/ast/case.d.ts +68 -0
  7. package/dist/types/ast/cast.d.ts +21 -0
  8. package/dist/types/ast/column-param.d.ts +17 -0
  9. package/dist/types/ast/column-ref.d.ts +39 -0
  10. package/dist/types/ast/fragment.d.ts +14 -0
  11. package/dist/types/ast/from.d.ts +21 -0
  12. package/dist/types/ast/function.d.ts +21 -0
  13. package/dist/types/ast/in-op.d.ts +21 -0
  14. package/dist/types/ast/interval.d.ts +21 -0
  15. package/dist/types/ast/literal.d.ts +15 -0
  16. package/dist/types/ast/logical-op.d.ts +46 -0
  17. package/dist/types/ast/node.d.ts +24 -0
  18. package/dist/types/ast/order-by.d.ts +29 -0
  19. package/dist/types/ast/param.d.ts +19 -0
  20. package/dist/types/ast/query.d.ts +268 -0
  21. package/dist/types/ast/sample.d.ts +42 -0
  22. package/dist/types/ast/select.d.ts +22 -0
  23. package/dist/types/ast/table-ref.d.ts +25 -0
  24. package/dist/types/ast/unary-op.d.ts +39 -0
  25. package/dist/types/ast/verbatim.d.ts +9 -0
  26. package/dist/types/ast/window.d.ts +177 -0
  27. package/dist/types/ast/with.d.ts +22 -0
  28. package/dist/types/constants.d.ts +38 -0
  29. package/dist/types/functions/aggregate.d.ts +229 -0
  30. package/dist/types/functions/case.d.ts +15 -0
  31. package/dist/types/functions/cast.d.ts +26 -0
  32. package/dist/types/functions/column.d.ts +9 -0
  33. package/dist/types/functions/datetime.d.ts +44 -0
  34. package/dist/types/functions/literal.d.ts +16 -0
  35. package/dist/types/functions/numeric.d.ts +93 -0
  36. package/dist/types/functions/operators.d.ts +198 -0
  37. package/dist/types/functions/order-by.d.ts +17 -0
  38. package/dist/types/functions/spatial.d.ts +37 -0
  39. package/dist/types/functions/sql-template-tag.d.ts +16 -0
  40. package/dist/types/functions/string.d.ts +55 -0
  41. package/dist/types/functions/table-ref.d.ts +9 -0
  42. package/dist/types/functions/window.d.ts +87 -0
  43. package/dist/types/index-types.d.ts +2 -0
  44. package/dist/types/index.d.ts +53 -0
  45. package/dist/types/load/create.d.ts +8 -0
  46. package/dist/types/load/extension.d.ts +1 -0
  47. package/dist/types/load/load.d.ts +12 -0
  48. package/dist/types/load/sql-from.d.ts +11 -0
  49. package/dist/types/transforms/bin-1d.d.ts +14 -0
  50. package/dist/types/transforms/bin-2d.d.ts +18 -0
  51. package/dist/types/transforms/bin-linear-1d.d.ts +9 -0
  52. package/dist/types/transforms/bin-linear-2d.d.ts +18 -0
  53. package/dist/types/transforms/line-density.d.ts +23 -0
  54. package/dist/types/transforms/m4.d.ts +18 -0
  55. package/dist/types/transforms/scales.d.ts +1 -0
  56. package/dist/types/types.d.ts +59 -0
  57. package/dist/types/util/ast.d.ts +60 -0
  58. package/dist/types/util/function.d.ts +54 -0
  59. package/dist/types/util/string.d.ts +3 -0
  60. package/dist/types/util/type-check.d.ts +18 -0
  61. package/dist/types/visit/recurse.d.ts +28 -0
  62. package/dist/types/visit/rewrite.d.ts +10 -0
  63. package/dist/types/visit/visitors.d.ts +33 -0
  64. package/dist/types/visit/walk.d.ts +7 -0
  65. package/jsconfig.json +11 -0
  66. package/package.json +6 -4
  67. package/src/ast/aggregate.js +164 -0
  68. package/src/ast/between-op.js +75 -0
  69. package/src/ast/binary-op.js +40 -0
  70. package/src/ast/case.js +105 -0
  71. package/src/ast/cast.js +34 -0
  72. package/src/ast/column-param.js +29 -0
  73. package/src/ast/column-ref.js +72 -0
  74. package/src/ast/fragment.js +26 -0
  75. package/src/ast/from.js +40 -0
  76. package/src/ast/function.js +34 -0
  77. package/src/ast/in-op.js +33 -0
  78. package/src/ast/interval.js +33 -0
  79. package/src/ast/literal.js +55 -0
  80. package/src/ast/logical-op.js +67 -0
  81. package/src/ast/node.js +29 -0
  82. package/src/ast/order-by.js +48 -0
  83. package/src/ast/param.js +35 -0
  84. package/src/ast/query.js +578 -0
  85. package/src/ast/sample.js +53 -0
  86. package/src/ast/select.js +44 -0
  87. package/src/ast/table-ref.js +44 -0
  88. package/src/ast/unary-op.js +64 -0
  89. package/src/ast/verbatim.js +26 -0
  90. package/src/ast/window.js +290 -0
  91. package/src/ast/with.js +30 -0
  92. package/src/constants.js +44 -0
  93. package/src/functions/aggregate.js +335 -0
  94. package/src/functions/case.js +21 -0
  95. package/src/functions/cast.js +39 -0
  96. package/src/functions/column.js +20 -0
  97. package/src/functions/datetime.js +65 -0
  98. package/src/functions/literal.js +22 -0
  99. package/src/functions/numeric.js +139 -0
  100. package/src/functions/operators.js +298 -0
  101. package/src/functions/order-by.js +24 -0
  102. package/src/functions/spatial.js +56 -0
  103. package/src/functions/sql-template-tag.js +51 -0
  104. package/src/functions/string.js +82 -0
  105. package/src/functions/table-ref.js +14 -0
  106. package/src/functions/window.js +121 -0
  107. package/src/index-types.ts +2 -0
  108. package/src/index.js +57 -155
  109. package/src/load/create.js +10 -2
  110. package/src/load/load.js +4 -4
  111. package/src/load/sql-from.js +7 -6
  112. package/src/transforms/bin-1d.js +21 -0
  113. package/src/transforms/bin-2d.js +29 -0
  114. package/src/transforms/bin-linear-1d.js +26 -0
  115. package/src/transforms/bin-linear-2d.js +71 -0
  116. package/src/transforms/line-density.js +113 -0
  117. package/src/transforms/m4.js +38 -0
  118. package/src/{scales.js → transforms/scales.js} +31 -17
  119. package/src/types.ts +96 -0
  120. package/src/util/ast.js +96 -0
  121. package/src/util/function.js +78 -0
  122. package/src/util/string.js +16 -0
  123. package/src/util/type-check.js +29 -0
  124. package/src/visit/recurse.js +57 -0
  125. package/src/visit/rewrite.js +32 -0
  126. package/src/visit/visitors.js +108 -0
  127. package/src/visit/walk.js +30 -0
  128. package/tsconfig.json +12 -0
  129. package/src/Query.js +0 -593
  130. package/src/aggregates.js +0 -185
  131. package/src/cast.js +0 -19
  132. package/src/datetime.js +0 -31
  133. package/src/desc.js +0 -13
  134. package/src/expression.js +0 -170
  135. package/src/functions.js +0 -25
  136. package/src/literal.js +0 -6
  137. package/src/operators.js +0 -54
  138. package/src/ref.js +0 -109
  139. package/src/repeat.js +0 -3
  140. package/src/spatial.js +0 -10
  141. package/src/to-sql.js +0 -52
  142. package/src/windows.js +0 -239
package/src/aggregates.js DELETED
@@ -1,185 +0,0 @@
1
- import { SQLExpression, parseSQL, sql } from './expression.js';
2
- import { asColumn } from './ref.js';
3
- import { repeat } from './repeat.js';
4
- import { literalToSQL } from './to-sql.js';
5
- import { WindowFunction } from './windows.js';
6
-
7
- /**
8
- * Tag function for SQL aggregate expressions. Interpolated values
9
- * may be strings, other SQL expression objects (such as column
10
- * references), or parameterized values.
11
- */
12
- export function agg(strings, ...exprs) {
13
- return sql(strings, ...exprs).annotate({ aggregate: true });
14
- }
15
-
16
- /**
17
- * Base class for individual aggregate functions.
18
- * Most callers should use a dedicated aggregate function
19
- * rather than instantiate this class.
20
- */
21
- export class AggregateFunction extends SQLExpression {
22
- /**
23
- * Create a new AggregateFunction instance.
24
- * @param {*} op The aggregate operation.
25
- * @param {*} [args] The aggregate function arguments.
26
- * @param {*} [type] The SQL data type to cast to.
27
- * @param {boolean} [isDistinct] Flag indicating if this is a distinct value aggregate.
28
- * @param {*} [filter] Filtering expression to apply prior to aggregation.
29
- */
30
- constructor(op, args, type, isDistinct, filter) {
31
- args = (args || []).map(asColumn);
32
- const { strings, exprs } = aggExpr(op, args, type, isDistinct, filter);
33
- const { spans, cols } = parseSQL(strings, exprs);
34
- super(spans, cols);
35
- this.aggregate = op;
36
- this.args = args;
37
- this.type = type;
38
- this.isDistinct = isDistinct;
39
- this.filter = filter;
40
- }
41
-
42
- get basis() {
43
- return this.column;
44
- }
45
-
46
- get label() {
47
- const { aggregate: op, args, isDistinct } = this;
48
- const dist = isDistinct ? 'DISTINCT' + (args.length ? ' ' : '') : '';
49
- const tail = args.length ? `(${dist}${args.map(unquoted).join(', ')})` : '';
50
- return `${op.toLowerCase()}${tail}`;
51
- }
52
-
53
- /**
54
- * Return a new derived aggregate function over distinct values.
55
- * @returns {AggregateFunction} A new aggregate function.
56
- */
57
- distinct() {
58
- const { aggregate: op, args, type, filter } = this;
59
- return new AggregateFunction(op, args, type, true, filter);
60
- }
61
-
62
- /**
63
- * Return a new derived aggregate function that filters values.
64
- * @param {*} filter The filter expresion.
65
- * @returns {AggregateFunction} A new aggregate function.
66
- */
67
- where(filter) {
68
- const { aggregate: op, args, type, isDistinct } = this;
69
- return new AggregateFunction(op, args, type, isDistinct, filter);
70
- }
71
-
72
- /**
73
- * Return a new window function over this aggregate.
74
- * @returns {WindowFunction} A new aggregate function.
75
- */
76
- window() {
77
- const { aggregate: op, args, type, isDistinct } = this;
78
- const func = new AggregateFunction(op, args, null, isDistinct);
79
- return new WindowFunction(op, func, type);
80
- }
81
-
82
- /**
83
- * Return a window function over this aggregate with the given partitioning.
84
- * @param {*} expr The grouping (partition by) criteria for the window function.
85
- * @returns {WindowFunction} A new window function.
86
- */
87
- partitionby(...expr) {
88
- return this.window().partitionby(...expr);
89
- }
90
-
91
- /**
92
- * Return a window function over this aggregate with the given ordering.
93
- * @param {*} expr The sorting (order by) criteria for the window function.
94
- * @returns {WindowFunction} A new window function.
95
- */
96
- orderby(...expr) {
97
- return this.window().orderby(...expr);
98
- }
99
-
100
- /**
101
- * Return a window function over this aggregate with the given row frame.
102
- * @param {(number|null)[] | import('./expression.js').ParamLike} frame The row-based window frame.
103
- * @returns {WindowFunction} A new window function.
104
- */
105
- rows(frame) {
106
- return this.window().rows(frame);
107
- }
108
-
109
- /**
110
- * Return a window function over this aggregate with the given range frame.
111
- * @param {(number|null)[] | import('./expression.js').ParamLike} frame The range-based window frame.
112
- * @returns {WindowFunction} A new window function.
113
- */
114
- range(frame) {
115
- return this.window().range(frame);
116
- }
117
- }
118
-
119
- function aggExpr(op, args, type, isDistinct, filter) {
120
- const close = `)${type ? `::${type}` : ''}`;
121
- let strings = [`${op}(${isDistinct ? 'DISTINCT ' :''}`];
122
- let exprs = [];
123
- if (args.length) {
124
- strings = strings.concat([
125
- ...repeat(args.length - 1, ', '),
126
- `${close}${filter ? ' FILTER (WHERE ' : ''}`,
127
- ...(filter ? [')'] : [])
128
- ]);
129
- exprs = [...args, ...(filter ? [filter] : [])];
130
- } else {
131
- strings[0] += '*' + close;
132
- }
133
- return { exprs, strings };
134
- }
135
-
136
- function unquoted(value) {
137
- const s = literalToSQL(value);
138
- return s && s.startsWith('"') && s.endsWith('"') ? s.slice(1, -1) : s
139
- }
140
-
141
- function aggf(op, type) {
142
- return (...args) => new AggregateFunction(op, args, type);
143
- }
144
-
145
- export const count = aggf('COUNT', 'INTEGER');
146
- export const avg = aggf('AVG');
147
- export const mean = aggf('AVG');
148
- export const mad = aggf('MAD');
149
- export const max = aggf('MAX');
150
- export const min = aggf('MIN');
151
- export const sum = aggf('SUM', 'DOUBLE');
152
- export const product = aggf('PRODUCT');
153
- export const median = aggf('MEDIAN');
154
- export const quantile = aggf('QUANTILE');
155
- export const mode = aggf('MODE');
156
-
157
- export const variance = aggf('VARIANCE');
158
- export const stddev = aggf('STDDEV');
159
- export const skewness = aggf('SKEWNESS');
160
- export const kurtosis = aggf('KURTOSIS');
161
- export const entropy = aggf('ENTROPY');
162
- export const varPop = aggf('VAR_POP');
163
- export const stddevPop = aggf('STDDEV_POP');
164
-
165
- export const corr = aggf('CORR');
166
- export const covariance = aggf('COVAR_SAMP');
167
- export const covarPop = aggf('COVAR_POP');
168
- export const regrIntercept = aggf('REGR_INTERCEPT');
169
- export const regrSlope = aggf('REGR_SLOPE');
170
- export const regrCount = aggf('REGR_COUNT');
171
- export const regrR2 = aggf('REGR_R2');
172
- export const regrSYY = aggf('REGR_SYY');
173
- export const regrSXX = aggf('REGR_SXX');
174
- export const regrSXY = aggf('REGR_SXY');
175
- export const regrAvgX = aggf('REGR_AVGX');
176
- export const regrAvgY = aggf('REGR_AVGY');
177
-
178
- export const first = aggf('FIRST');
179
- export const last = aggf('LAST');
180
-
181
- export const argmin = aggf('ARG_MIN');
182
- export const argmax = aggf('ARG_MAX');
183
-
184
- export const stringAgg = aggf('STRING_AGG');
185
- export const arrayAgg = aggf('ARRAY_AGG');
package/src/cast.js DELETED
@@ -1,19 +0,0 @@
1
- import { sql } from './expression.js';
2
- import { asColumn } from './ref.js';
3
-
4
- export function cast(expr, type) {
5
- const arg = asColumn(expr);
6
- const e = sql`CAST(${arg} AS ${type})`;
7
- Object.defineProperty(e, 'label', {
8
- enumerable: true,
9
- get() { return expr.label; }
10
- });
11
- Object.defineProperty(e, 'aggregate', {
12
- enumerable: true,
13
- get() { return expr.aggregate || false; }
14
- });
15
- return e;
16
- }
17
-
18
- export const castDouble = expr => cast(expr, 'DOUBLE');
19
- export const castInteger = expr => cast(expr, 'INTEGER');
package/src/datetime.js DELETED
@@ -1,31 +0,0 @@
1
- import { sql } from './expression.js';
2
- import { asColumn } from './ref.js';
3
-
4
- export const epoch_ms = expr => {
5
- return sql`epoch_ms(${asColumn(expr)})`;
6
- };
7
-
8
- export function dateBin(expr, interval, steps = 1) {
9
- const i = `INTERVAL ${steps} ${interval}`;
10
- const d = asColumn(expr);
11
- return sql`TIME_BUCKET(${i}, ${d})`
12
- .annotate({ label: interval });
13
- }
14
-
15
- export const dateMonth = expr => {
16
- const d = asColumn(expr);
17
- return sql`MAKE_DATE(2012, MONTH(${d}), 1)`
18
- .annotate({ label: 'month' });
19
- };
20
-
21
- export const dateMonthDay = expr => {
22
- const d = asColumn(expr);
23
- return sql`MAKE_DATE(2012, MONTH(${d}), DAY(${d}))`
24
- .annotate({ label: 'date' });
25
- };
26
-
27
- export const dateDay = expr => {
28
- const d = asColumn(expr);
29
- return sql`MAKE_DATE(2012, 1, DAY(${d}))`
30
- .annotate({ label: 'date' });
31
- };
package/src/desc.js DELETED
@@ -1,13 +0,0 @@
1
- import { sql } from './expression.js';
2
- import { asColumn } from './ref.js';
3
-
4
- /**
5
- * Annotate an expression to indicate descending sort order.
6
- * Null values are ordered last.
7
- * @param {import('./expression.js').SQLExpression|string} expr A SQL expression or column name string.
8
- * @returns {import('./expression.js').SQLExpression} An expression with descending order.
9
- */
10
- export function desc(expr) {
11
- const e = asColumn(expr);
12
- return sql`${e} DESC NULLS LAST`.annotate({ label: e?.label, desc: true });
13
- }
package/src/expression.js DELETED
@@ -1,170 +0,0 @@
1
- import { literalToSQL } from './to-sql.js';
2
-
3
- /**
4
- * @typedef {{
5
- * value: any;
6
- * addEventListener(type: string, callback: Function): any;
7
- * column?: string,
8
- * columns?: string[]
9
- * }} ParamLike
10
- */
11
-
12
- /**
13
- * Test if a value is parameter-like. Parameters have addEventListener methods.
14
- * @param {*} value The value to test.
15
- * @returns {value is ParamLike} True if the value is param-like, false otherwise.
16
- */
17
- export const isParamLike = value => typeof value?.addEventListener === 'function';
18
-
19
- /**
20
- * Test if a value is a SQL expression instance.
21
- * @param {*} value The value to test.
22
- * @returns {value is SQLExpression} True if value is a SQL expression, false otherwise.
23
- */
24
- export function isSQLExpression(value) {
25
- return value instanceof SQLExpression;
26
- }
27
-
28
- /**
29
- * Base class for all SQL expressions. Most callers should use the `sql`
30
- * template tag rather than instantiate this class.
31
- */
32
- export class SQLExpression {
33
-
34
- /**
35
- * Create a new SQL expression instance.
36
- * @param {(string | ParamLike | SQLExpression | import('./ref.js').Ref)[]} parts The parts of the expression.
37
- * @param {string[]} [columns=[]] The column dependencies
38
- * @param {object} [props] Additional properties for this expression.
39
- */
40
- constructor(parts, columns, props) {
41
- this._expr = Array.isArray(parts) ? parts : [parts];
42
- this._deps = columns || [];
43
- this.annotate(props);
44
-
45
- const params = this._expr.filter(part => isParamLike(part));
46
- if (params.length > 0) {
47
- /** @type {ParamLike[]} */
48
- // @ts-ignore
49
- this._params = Array.from(new Set(params));
50
- this._params.forEach(param => {
51
- param.addEventListener('value', () => update(this, this.map?.get('value')));
52
- });
53
- } else {
54
- // do not support event listeners if not needed
55
- // this causes the expression instance to NOT be param-like
56
- this.addEventListener = undefined;
57
- }
58
- }
59
-
60
- /**
61
- * A reference to this expression.
62
- * Provides compatibility with param-like objects.
63
- */
64
- get value() {
65
- return this;
66
- }
67
-
68
- /**
69
- * The column dependencies of this expression.
70
- * @returns {string[]} The columns dependencies.
71
- */
72
- get columns() {
73
- const { _params, _deps } = this;
74
- if (_params) {
75
- // pull latest dependencies, as they may change across updates
76
- const pset = new Set(_params.flatMap(p => {
77
- const cols = p.value?.columns;
78
- return Array.isArray(cols) ? cols : [];
79
- }));
80
- if (pset.size) {
81
- const set = new Set(_deps);
82
- pset.forEach(col => set.add(col));
83
- return Array.from(set);
84
- }
85
- }
86
- // if no params, return fixed dependencies
87
- return _deps;
88
- }
89
-
90
- /**
91
- * The first column dependency in this expression, or undefined if none.
92
- * @returns {string} The first column dependency.
93
- */
94
- get column() {
95
- return this._deps.length ? this._deps[0] : this.columns[0];
96
- }
97
-
98
- /**
99
- * Annotate this expression instance with additional properties.
100
- * @param {object[]} [props] One or more objects with properties to add.
101
- * @returns This SQL expression.
102
- */
103
- annotate(...props) {
104
- return Object.assign(this, ...props);
105
- }
106
-
107
- /**
108
- * Generate a SQL code string corresponding to this expression.
109
- * @returns {string} A SQL code string.
110
- */
111
- toString() {
112
- return this._expr
113
- .map(p => isParamLike(p) && !isSQLExpression(p) ? literalToSQL(p.value) : p)
114
- .join('');
115
- }
116
-
117
- /**
118
- * Add an event listener callback for the provided event type.
119
- * @param {string} type The event type to listen for (for example, "value").
120
- * @param {(a: SQLExpression) => Promise?} callback The callback function to
121
- * invoke upon updates. A callback may optionally return a Promise that
122
- * upstream listeners may await before proceeding.
123
- */
124
- addEventListener(type, callback) {
125
- const map = this.map || (this.map = new Map());
126
- const set = map.get(type) || (map.set(type, new Set), map.get(type));
127
- set.add(callback);
128
- }
129
- }
130
-
131
- function update(expr, callbacks) {
132
- if (callbacks?.size) {
133
- return Promise.allSettled(Array.from(callbacks, fn => fn(expr)));
134
- }
135
- }
136
-
137
- export function parseSQL(strings, exprs) {
138
- const spans = [strings[0]];
139
- const cols = new Set;
140
- const n = exprs.length;
141
- for (let i = 0, k = 0; i < n;) {
142
- const e = exprs[i];
143
- if (isParamLike(e)) {
144
- spans[++k] = e;
145
- } else {
146
- if (Array.isArray(e?.columns)) {
147
- e.columns.forEach(col => cols.add(col));
148
- }
149
- spans[k] += typeof e === 'string' ? e : literalToSQL(e);
150
- }
151
- const s = strings[++i];
152
- if (isParamLike(spans[k])) {
153
- spans[++k] = s;
154
- } else {
155
- spans[k] += s;
156
- }
157
- }
158
-
159
- return { spans, cols: Array.from(cols) };
160
- }
161
-
162
- /**
163
- * Tag function for SQL expressions. Interpolated values
164
- * may be strings, other SQL expression objects (such as column
165
- * references), or parameterized values.
166
- */
167
- export function sql(strings, ...exprs) {
168
- const { spans, cols } = parseSQL(strings, exprs);
169
- return new SQLExpression(spans, cols);
170
- }
package/src/functions.js DELETED
@@ -1,25 +0,0 @@
1
- import { sql } from './expression.js';
2
- import { asColumn } from './ref.js';
3
- import { repeat } from './repeat.js';
4
-
5
- export function functionCall(op, type) {
6
- return (...values) => {
7
- const args = values.map(asColumn);
8
- const cast = type ? `::${type}` : '';
9
- const expr = args.length
10
- ? sql([`${op}(`, ...repeat(args.length - 1, ', '), `)${cast}`], ...args)
11
- : sql`${op}()${cast}`;
12
- return expr.annotate({ func: op, args });
13
- }
14
- }
15
-
16
- export const regexp_matches = functionCall('REGEXP_MATCHES');
17
- export const contains = functionCall('CONTAINS');
18
- export const prefix = functionCall('PREFIX');
19
- export const suffix = functionCall('SUFFIX');
20
- export const lower = functionCall('LOWER');
21
- export const upper = functionCall('UPPER');
22
- export const length = functionCall('LENGTH');
23
- export const isNaN = functionCall('ISNAN');
24
- export const isFinite = functionCall('ISFINITE');
25
- export const isInfinite = functionCall('ISINF');
package/src/literal.js DELETED
@@ -1,6 +0,0 @@
1
- import { literalToSQL } from './to-sql.js';
2
-
3
- export const literal = value => ({
4
- value,
5
- toString: () => literalToSQL(value)
6
- });
package/src/operators.js DELETED
@@ -1,54 +0,0 @@
1
- import { sql } from './expression.js';
2
- import { asColumn } from './ref.js';
3
-
4
- function visit(callback) {
5
- callback(this.op, this);
6
- this.children?.forEach(v => v.visit(callback));
7
- }
8
-
9
- function logical(op, clauses) {
10
- const children = clauses.filter(x => x != null).map(asColumn);
11
- const strings = children.map((c, i) => i ? ` ${op} ` : '');
12
- if (children.length === 1) {
13
- strings.push('')
14
- } else if (children.length > 1) {
15
- strings[0] = '(';
16
- strings.push(')');
17
- }
18
- return sql(strings, ...children).annotate({ op, children, visit });
19
- }
20
-
21
- export const and = (...clauses) => logical('AND', clauses.flat());
22
- export const or = (...clauses) => logical('OR', clauses.flat());
23
-
24
- const unaryOp = op => a => sql`(${op} ${asColumn(a)})`.annotate({ op, a, visit });
25
-
26
- export const not = unaryOp('NOT');
27
-
28
- const unaryPostOp = op => a => sql`(${asColumn(a)} ${op})`.annotate({ op, a, visit });
29
-
30
- export const isNull = unaryPostOp('IS NULL');
31
- export const isNotNull = unaryPostOp('IS NOT NULL');
32
-
33
- const binaryOp = op => (a, b) => sql`(${asColumn(a)} ${op} ${asColumn(b)})`.annotate({ op, a, b, visit });
34
-
35
- export const eq = binaryOp('=');
36
- export const neq = binaryOp('<>');
37
- export const lt = binaryOp('<');
38
- export const gt = binaryOp('>');
39
- export const lte = binaryOp('<=');
40
- export const gte = binaryOp('>=');
41
- export const isDistinct = binaryOp('IS DISTINCT FROM');
42
- export const isNotDistinct = binaryOp('IS NOT DISTINCT FROM');
43
-
44
- function rangeOp(op, a, range, exclusive) {
45
- a = asColumn(a);
46
- const prefix = op.startsWith('NOT ') ? 'NOT ' : '';
47
- const expr = !range ? sql``
48
- : exclusive ? sql`${prefix}(${range[0]} <= ${a} AND ${a} < ${range[1]})`
49
- : sql`(${a} ${op} ${range[0]} AND ${range[1]})`;
50
- return expr.annotate({ op, visit, field: a, range });
51
- }
52
-
53
- export const isBetween = (a, range, exclusive) => rangeOp('BETWEEN', a, range, exclusive);
54
- export const isNotBetween = (a, range, exclusive) => rangeOp('NOT BETWEEN', a, range, exclusive);
package/src/ref.js DELETED
@@ -1,109 +0,0 @@
1
- /**
2
- * Class representing a table and/or column reference.
3
- */
4
- export class Ref {
5
- /**
6
- * Create a new Ref instance.
7
- * @param {string|Ref|null} table The table name.
8
- * @param {string|null} [column] The column name.
9
- */
10
- constructor(table, column) {
11
- if (table) this.table = String(table);
12
- if (column) this.column = column;
13
- }
14
-
15
- /**
16
- * Get the list of referenced columns. Either a single element array
17
- * if column is non-null, otherwise an empty array.
18
- */
19
- get columns() {
20
- return this.column ? [this.column] : [];
21
- }
22
-
23
- /**
24
- * Generate a SQL string for this reference.
25
- * @returns {string} The SQL string.
26
- */
27
- toString() {
28
- const { table, column } = this;
29
- if (column) {
30
- const col = column.startsWith('*') ? column : `"${column}"`;
31
- return `${table ? `${quoteTableName(table)}.` : ''}${col}`;
32
- } else {
33
- return table ? quoteTableName(table) : 'NULL';
34
- }
35
- }
36
- }
37
-
38
- /**
39
- * Quote a table name. For example, `foo.bar` becomes `"foo"."bar".
40
- * @param {string} table the name of the table which may contain a database reference
41
- * @returns The quoted table name.
42
- */
43
- function quoteTableName(table) {
44
- const pieces = table.split('.');
45
- return pieces.map(p => `"${p}"`).join('.');
46
- }
47
-
48
- /**
49
- * Test is a reference refers to a given column name.
50
- * @param {*} ref The reference to test.
51
- * @param {string} name The column name to check for.
52
- * @returns {boolean} True if ref is a Ref instance that refers to
53
- * the given column name. False otherwise.
54
- */
55
- export function isColumnRefFor(ref, name) {
56
- return ref instanceof Ref && ref.column === name;
57
- }
58
-
59
- /**
60
- * Interpret a value, defaulting to a column reference.
61
- * @param {*} value The value to interpret. If string-typed,
62
- * a new column reference will be returned.
63
- * @returns {*} A column reference or the input value.
64
- */
65
- export function asColumn(value) {
66
- return typeof value === 'string' ? column(value) : value;
67
- }
68
-
69
- /**
70
- * Interpret a value, defaulting to a table (relation) reference.
71
- * @param {*} value The value to interpret. If string-typed,
72
- * a new table (relation) reference will be returned.
73
- * @returns {*} A table reference or the input value.
74
- */
75
- export function asRelation(value) {
76
- return typeof value === 'string' ? relation(value) : value;
77
- }
78
-
79
- /**
80
- * Create a table (relation) reference.
81
- * @param {string} name The table (relation) name.
82
- * @returns {Ref} The generated table reference.
83
- */
84
- export function relation(name) {
85
- return new Ref(name);
86
- }
87
-
88
- /**
89
- * Create a column reference.
90
- * @param {string} table The table name (optional).
91
- * @param {string} [column] The column name.
92
- * @returns {Ref} The generated column reference.
93
- */
94
- export function column(table, column = null) {
95
- if (arguments.length === 1) {
96
- column = table;
97
- table = null;
98
- }
99
- return new Ref(table, column);
100
- }
101
-
102
- /**
103
- * Create a reference to all columns in a table (relation).
104
- * @param {string} table The table name.
105
- * @returns {Ref} The generated reference.
106
- */
107
- export function all(table) {
108
- return new Ref(table, '*');
109
- }
package/src/repeat.js DELETED
@@ -1,3 +0,0 @@
1
- export function repeat(length, str) {
2
- return Array.from({ length }, () => str);
3
- }
package/src/spatial.js DELETED
@@ -1,10 +0,0 @@
1
- import { functionCall } from './functions.js';
2
-
3
- export const geojson = functionCall('ST_AsGeoJSON');
4
-
5
- export const x = functionCall('ST_X');
6
- export const y = functionCall('ST_Y');
7
-
8
- export const centroid = functionCall('ST_CENTROID');
9
- export const centroidX = geom => x(centroid(geom));
10
- export const centroidY = geom => y(centroid(geom));
package/src/to-sql.js DELETED
@@ -1,52 +0,0 @@
1
- /**
2
- * Convert a value to a corresponding SQL string.
3
- * Input string values are assumed to be column references,
4
- * otherwise the logic of literalToSQL applies.
5
- * @param {*} value The value to convert to SQL.
6
- * @returns {string} A SQL string.
7
- */
8
- export function toSQL(value) {
9
- return typeof value === 'string'
10
- ? `"${value}"` // strings as column refs
11
- : literalToSQL(value);
12
- }
13
-
14
- /**
15
- * Convert a literal value to a corresponding SQL string.
16
- * The values null, undefined, Infinity, NaN, and invalid
17
- * dates are converted to SQL NULL values.
18
- * UTC dates map to the SQL Date type, otherwise JavaScript
19
- * date values map to the SQL Timestamp type.
20
- * Values that are not JavaScript Date, RegExp, or primitive types
21
- * are coerced to strings, relying on a defined toString method.
22
- * @param {*} value The literal value.
23
- * @returns {string} A SQL string.
24
- */
25
- export function literalToSQL(value) {
26
- switch (typeof value) {
27
- case 'boolean':
28
- return value ? 'TRUE' : 'FALSE';
29
- case 'string':
30
- return `'${value.replace(`'`, `''`)}'`;
31
- case 'number':
32
- return Number.isFinite(value) ? String(value) : 'NULL';
33
- default:
34
- if (value == null) {
35
- return 'NULL';
36
- } else if (value instanceof Date) {
37
- const ts = +value;
38
- if (Number.isNaN(ts)) return 'NULL';
39
- const y = value.getUTCFullYear();
40
- const m = value.getUTCMonth();
41
- const d = value.getUTCDate();
42
- return ts === Date.UTC(y, m, d)
43
- ? `MAKE_DATE(${y}, ${m+1}, ${d})` // utc date
44
- : `EPOCH_MS(${ts})`; // timestamp
45
- } else if (value instanceof RegExp) {
46
- return `'${value.source}'`;
47
- } else {
48
- // otherwise rely on string coercion
49
- return String(value);
50
- }
51
- }
52
- }