data-finder-ts 0.1.0 → 0.1.4
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/README.md +17 -55
- package/dist/chunk-4JVW4TAB.js +180 -0
- package/dist/chunk-4JVW4TAB.js.map +1 -0
- package/dist/chunk-4LNZV6EN.js +500 -0
- package/dist/chunk-4LNZV6EN.js.map +1 -0
- package/dist/chunk-FJYA2ASS.js +136 -0
- package/dist/chunk-FJYA2ASS.js.map +1 -0
- package/dist/chunk-FLEIUDZZ.js +14 -0
- package/dist/chunk-FLEIUDZZ.js.map +1 -0
- package/dist/chunk-MH4XMYVB.js +696 -0
- package/dist/chunk-MH4XMYVB.js.map +1 -0
- package/dist/chunk-PMPLCEWQ.js +90 -0
- package/dist/chunk-PMPLCEWQ.js.map +1 -0
- package/dist/chunk-UYMOE6YU.js +509 -0
- package/dist/chunk-UYMOE6YU.js.map +1 -0
- package/dist/datafinder/attribute.cjs +320 -0
- package/dist/datafinder/attribute.cjs.map +1 -0
- package/dist/datafinder/attribute.d.cts +86 -0
- package/dist/datafinder/attribute.d.ts +86 -0
- package/dist/datafinder/attribute.js +8 -0
- package/dist/datafinder/attribute.js.map +1 -0
- package/dist/datafinder/finder-registry.cjs +39 -0
- package/dist/datafinder/finder-registry.cjs.map +1 -0
- package/dist/datafinder/finder-registry.d.cts +4 -0
- package/dist/datafinder/finder-registry.d.ts +4 -0
- package/dist/datafinder/finder-registry.js +9 -0
- package/dist/datafinder/finder-registry.js.map +1 -0
- package/dist/datafinder/runner.cjs +1595 -0
- package/dist/datafinder/runner.cjs.map +1 -0
- package/dist/datafinder/runner.d.cts +44 -0
- package/dist/datafinder/runner.d.ts +44 -0
- package/dist/datafinder/runner.js +26 -0
- package/dist/datafinder/runner.js.map +1 -0
- package/dist/datafinder/sql-generator.cjs +1467 -0
- package/dist/datafinder/sql-generator.cjs.map +1 -0
- package/dist/datafinder/sql-generator.d.cts +8 -0
- package/dist/datafinder/sql-generator.d.ts +8 -0
- package/dist/datafinder/sql-generator.js +15 -0
- package/dist/datafinder/sql-generator.js.map +1 -0
- package/dist/datafinder/typed-attributes.cjs +909 -0
- package/dist/datafinder/typed-attributes.cjs.map +1 -0
- package/dist/datafinder/typed-attributes.d.cts +242 -0
- package/dist/datafinder/typed-attributes.d.ts +242 -0
- package/dist/datafinder/typed-attributes.js +25 -0
- package/dist/datafinder/typed-attributes.js.map +1 -0
- package/dist/index.cjs +2153 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +28 -0
- package/dist/index.d.ts +28 -0
- package/dist/index.js +199 -0
- package/dist/index.js.map +1 -0
- package/dist/model/milestoning.cjs +145 -0
- package/dist/model/milestoning.cjs.map +1 -0
- package/dist/model/milestoning.d.cts +40 -0
- package/dist/model/milestoning.d.ts +40 -0
- package/dist/model/milestoning.js +18 -0
- package/dist/model/milestoning.js.map +1 -0
- package/dist/model/relational.cjs +579 -0
- package/dist/model/relational.cjs.map +1 -0
- package/dist/model/relational.d.cts +291 -0
- package/dist/model/relational.d.ts +291 -0
- package/dist/model/relational.js +99 -0
- package/dist/model/relational.js.map +1 -0
- package/package.json +6 -4
|
@@ -0,0 +1,1467 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/datafinder/sql-generator.ts
|
|
21
|
+
var sql_generator_exports = {};
|
|
22
|
+
__export(sql_generator_exports, {
|
|
23
|
+
buildQueryOperation: () => buildQueryOperation,
|
|
24
|
+
selectSqlToString: () => selectSqlToString,
|
|
25
|
+
toSql: () => toSql
|
|
26
|
+
});
|
|
27
|
+
module.exports = __toCommonJS(sql_generator_exports);
|
|
28
|
+
|
|
29
|
+
// src/model/relational.ts
|
|
30
|
+
var RelationalOperationElement = class {
|
|
31
|
+
};
|
|
32
|
+
var Operation = class extends RelationalOperationElement {
|
|
33
|
+
andOp(other) {
|
|
34
|
+
return new LogicalOperation(this, "AND" /* AND */, other);
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
var NoOperation = class extends Operation {
|
|
38
|
+
andOp(other) {
|
|
39
|
+
return other;
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
var ConstantOperation = class extends RelationalOperationElement {
|
|
43
|
+
};
|
|
44
|
+
var IntegerConstantOperation = class extends ConstantOperation {
|
|
45
|
+
constructor(value) {
|
|
46
|
+
super();
|
|
47
|
+
this.value = value;
|
|
48
|
+
}
|
|
49
|
+
value;
|
|
50
|
+
};
|
|
51
|
+
var FloatConstantOperation = class extends ConstantOperation {
|
|
52
|
+
constructor(value) {
|
|
53
|
+
super();
|
|
54
|
+
this.value = value;
|
|
55
|
+
}
|
|
56
|
+
value;
|
|
57
|
+
};
|
|
58
|
+
var StringConstantOperation = class extends ConstantOperation {
|
|
59
|
+
constructor(value) {
|
|
60
|
+
super();
|
|
61
|
+
this.value = value;
|
|
62
|
+
}
|
|
63
|
+
value;
|
|
64
|
+
};
|
|
65
|
+
var DateConstantOperation = class extends ConstantOperation {
|
|
66
|
+
constructor(value) {
|
|
67
|
+
super();
|
|
68
|
+
this.value = value;
|
|
69
|
+
}
|
|
70
|
+
value;
|
|
71
|
+
};
|
|
72
|
+
var DateTimeConstantOperation = class extends ConstantOperation {
|
|
73
|
+
constructor(value) {
|
|
74
|
+
super();
|
|
75
|
+
this.value = value;
|
|
76
|
+
}
|
|
77
|
+
value;
|
|
78
|
+
};
|
|
79
|
+
var DecimalConstantOperation = class extends ConstantOperation {
|
|
80
|
+
constructor(value) {
|
|
81
|
+
super();
|
|
82
|
+
this.value = value;
|
|
83
|
+
}
|
|
84
|
+
value;
|
|
85
|
+
};
|
|
86
|
+
var BooleanConstantOperation = class extends ConstantOperation {
|
|
87
|
+
constructor(value) {
|
|
88
|
+
super();
|
|
89
|
+
this.value = value;
|
|
90
|
+
}
|
|
91
|
+
value;
|
|
92
|
+
};
|
|
93
|
+
var UnaryOperation = class extends Operation {
|
|
94
|
+
constructor(element) {
|
|
95
|
+
super();
|
|
96
|
+
this.element = element;
|
|
97
|
+
}
|
|
98
|
+
element;
|
|
99
|
+
};
|
|
100
|
+
var BinaryOperation = class extends Operation {
|
|
101
|
+
constructor(left, right) {
|
|
102
|
+
super();
|
|
103
|
+
this.left = left;
|
|
104
|
+
this.right = right;
|
|
105
|
+
}
|
|
106
|
+
left;
|
|
107
|
+
right;
|
|
108
|
+
};
|
|
109
|
+
var IsNullOperation = class extends UnaryOperation {
|
|
110
|
+
};
|
|
111
|
+
var IsNotNullOperation = class extends UnaryOperation {
|
|
112
|
+
};
|
|
113
|
+
var ComparisonOperation = class extends BinaryOperation {
|
|
114
|
+
constructor(left, operator, right) {
|
|
115
|
+
super(left, right);
|
|
116
|
+
this.operator = operator;
|
|
117
|
+
}
|
|
118
|
+
operator;
|
|
119
|
+
};
|
|
120
|
+
var LogicalOperation = class extends BinaryOperation {
|
|
121
|
+
constructor(left, operator, right) {
|
|
122
|
+
super(left, right);
|
|
123
|
+
this.operator = operator;
|
|
124
|
+
}
|
|
125
|
+
operator;
|
|
126
|
+
};
|
|
127
|
+
var WindowSpecification = class {
|
|
128
|
+
constructor(partitionBy = [], orderBy = []) {
|
|
129
|
+
this.partitionBy = partitionBy;
|
|
130
|
+
this.orderBy = orderBy;
|
|
131
|
+
}
|
|
132
|
+
partitionBy;
|
|
133
|
+
orderBy;
|
|
134
|
+
};
|
|
135
|
+
var AggregateOperation = class _AggregateOperation extends UnaryOperation {
|
|
136
|
+
constructor(element, operator, displayName, window) {
|
|
137
|
+
super(element);
|
|
138
|
+
this.operator = operator;
|
|
139
|
+
this.displayName = displayName;
|
|
140
|
+
this.window = window;
|
|
141
|
+
}
|
|
142
|
+
operator;
|
|
143
|
+
displayName;
|
|
144
|
+
window;
|
|
145
|
+
over(partitionBy, orderBy) {
|
|
146
|
+
return new _AggregateOperation(
|
|
147
|
+
this.element,
|
|
148
|
+
this.operator,
|
|
149
|
+
this.displayName,
|
|
150
|
+
new WindowSpecification(partitionBy ?? [], orderBy ?? [])
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
var WindowFunctionOperation = class _WindowFunctionOperation extends UnaryOperation {
|
|
155
|
+
constructor(element, func, displayName, secondArg, extraArgs = [], window) {
|
|
156
|
+
super(element);
|
|
157
|
+
this.func = func;
|
|
158
|
+
this.displayName = displayName;
|
|
159
|
+
this.secondArg = secondArg;
|
|
160
|
+
this.extraArgs = extraArgs;
|
|
161
|
+
this.window = window;
|
|
162
|
+
}
|
|
163
|
+
func;
|
|
164
|
+
displayName;
|
|
165
|
+
secondArg;
|
|
166
|
+
extraArgs;
|
|
167
|
+
window;
|
|
168
|
+
over(partitionBy, orderBy) {
|
|
169
|
+
return new _WindowFunctionOperation(
|
|
170
|
+
this.element,
|
|
171
|
+
this.func,
|
|
172
|
+
this.displayName,
|
|
173
|
+
this.secondArg,
|
|
174
|
+
[...this.extraArgs],
|
|
175
|
+
new WindowSpecification(partitionBy ?? [], orderBy ?? [])
|
|
176
|
+
);
|
|
177
|
+
}
|
|
178
|
+
};
|
|
179
|
+
var ScalarFunctionOperation = class extends UnaryOperation {
|
|
180
|
+
constructor(element, func, displayName, secondArg, extraArgs = []) {
|
|
181
|
+
super(element);
|
|
182
|
+
this.func = func;
|
|
183
|
+
this.displayName = displayName;
|
|
184
|
+
this.secondArg = secondArg;
|
|
185
|
+
this.extraArgs = extraArgs;
|
|
186
|
+
}
|
|
187
|
+
func;
|
|
188
|
+
displayName;
|
|
189
|
+
secondArg;
|
|
190
|
+
extraArgs;
|
|
191
|
+
};
|
|
192
|
+
var DateExtractOperation = class extends UnaryOperation {
|
|
193
|
+
constructor(element, part, displayName) {
|
|
194
|
+
super(element);
|
|
195
|
+
this.part = part;
|
|
196
|
+
this.displayName = displayName;
|
|
197
|
+
}
|
|
198
|
+
part;
|
|
199
|
+
displayName;
|
|
200
|
+
};
|
|
201
|
+
var DateArithmeticOperation = class extends UnaryOperation {
|
|
202
|
+
constructor(element, n, unit, isAdd = true, displayName) {
|
|
203
|
+
super(element);
|
|
204
|
+
this.n = n;
|
|
205
|
+
this.unit = unit;
|
|
206
|
+
this.isAdd = isAdd;
|
|
207
|
+
this.displayName = displayName;
|
|
208
|
+
}
|
|
209
|
+
n;
|
|
210
|
+
unit;
|
|
211
|
+
isAdd;
|
|
212
|
+
displayName;
|
|
213
|
+
};
|
|
214
|
+
var DateDiffOperation = class extends UnaryOperation {
|
|
215
|
+
constructor(element, other, unit, displayName) {
|
|
216
|
+
super(element);
|
|
217
|
+
this.other = other;
|
|
218
|
+
this.unit = unit;
|
|
219
|
+
this.displayName = displayName;
|
|
220
|
+
}
|
|
221
|
+
other;
|
|
222
|
+
unit;
|
|
223
|
+
displayName;
|
|
224
|
+
};
|
|
225
|
+
var Column = class extends RelationalOperationElement {
|
|
226
|
+
constructor(name, type, owner, primaryKey = false) {
|
|
227
|
+
super();
|
|
228
|
+
this.name = name;
|
|
229
|
+
this.type = type;
|
|
230
|
+
this.owner = owner;
|
|
231
|
+
this.primaryKey = primaryKey;
|
|
232
|
+
}
|
|
233
|
+
name;
|
|
234
|
+
type;
|
|
235
|
+
owner;
|
|
236
|
+
primaryKey;
|
|
237
|
+
table;
|
|
238
|
+
};
|
|
239
|
+
var Table = class {
|
|
240
|
+
constructor(name, columns, schema) {
|
|
241
|
+
this.name = name;
|
|
242
|
+
this.schema = schema;
|
|
243
|
+
for (const col of columns) {
|
|
244
|
+
if (this._columnsByName.has(col.name)) {
|
|
245
|
+
throw new Error(`Duplicate column name '${col.name}' in table '${name}'`);
|
|
246
|
+
}
|
|
247
|
+
this._columnsByName.set(col.name, col);
|
|
248
|
+
col.table = this;
|
|
249
|
+
}
|
|
250
|
+
schema?.tables.push(this);
|
|
251
|
+
}
|
|
252
|
+
name;
|
|
253
|
+
schema;
|
|
254
|
+
_columnsByName = /* @__PURE__ */ new Map();
|
|
255
|
+
foreignKeys = [];
|
|
256
|
+
get columns() {
|
|
257
|
+
return Array.from(this._columnsByName.values());
|
|
258
|
+
}
|
|
259
|
+
get qualifiedName() {
|
|
260
|
+
if (!this.schema) return this.name;
|
|
261
|
+
if (!this.schema.datastore) return `${this.schema.name}.${this.name}`;
|
|
262
|
+
return `${this.schema.datastore.namespace(this.schema.name)}.${this.name}`;
|
|
263
|
+
}
|
|
264
|
+
};
|
|
265
|
+
var ColumnWithJoin = class extends RelationalOperationElement {
|
|
266
|
+
/**
|
|
267
|
+
* `embedded` is an alternate reference to a flat (denormalized) column on the owning table that
|
|
268
|
+
* holds the same value without the join; the SQL generator uses it when the join can be elided.
|
|
269
|
+
*/
|
|
270
|
+
constructor(column, parent, embedded) {
|
|
271
|
+
super();
|
|
272
|
+
this.column = column;
|
|
273
|
+
this.parent = parent;
|
|
274
|
+
this.embedded = embedded;
|
|
275
|
+
}
|
|
276
|
+
column;
|
|
277
|
+
parent;
|
|
278
|
+
embedded;
|
|
279
|
+
};
|
|
280
|
+
var SortOperation = class {
|
|
281
|
+
constructor(column, direction) {
|
|
282
|
+
this.column = column;
|
|
283
|
+
this.direction = direction;
|
|
284
|
+
}
|
|
285
|
+
column;
|
|
286
|
+
direction;
|
|
287
|
+
};
|
|
288
|
+
var CountAllOperation = class extends RelationalOperationElement {
|
|
289
|
+
constructor(table) {
|
|
290
|
+
super();
|
|
291
|
+
this.table = table;
|
|
292
|
+
}
|
|
293
|
+
table;
|
|
294
|
+
};
|
|
295
|
+
var Alias = class extends RelationalOperationElement {
|
|
296
|
+
constructor(element, name) {
|
|
297
|
+
super();
|
|
298
|
+
this.element = element;
|
|
299
|
+
this.name = name;
|
|
300
|
+
}
|
|
301
|
+
element;
|
|
302
|
+
name;
|
|
303
|
+
};
|
|
304
|
+
var ExistsOperation = class extends RelationalOperationElement {
|
|
305
|
+
constructor(node) {
|
|
306
|
+
super();
|
|
307
|
+
this.node = node;
|
|
308
|
+
}
|
|
309
|
+
node;
|
|
310
|
+
andOp(other) {
|
|
311
|
+
return new LogicalOperation(this, "AND" /* AND */, other);
|
|
312
|
+
}
|
|
313
|
+
};
|
|
314
|
+
var NotExistsOperation = class extends RelationalOperationElement {
|
|
315
|
+
constructor(node) {
|
|
316
|
+
super();
|
|
317
|
+
this.node = node;
|
|
318
|
+
}
|
|
319
|
+
node;
|
|
320
|
+
andOp(other) {
|
|
321
|
+
return new LogicalOperation(this, "AND" /* AND */, other);
|
|
322
|
+
}
|
|
323
|
+
};
|
|
324
|
+
var SelectOperation = class {
|
|
325
|
+
constructor(display, filter, orderBy = [], groupBy = [], limit, table, joinFilters = /* @__PURE__ */ new Map()) {
|
|
326
|
+
this.display = display;
|
|
327
|
+
this.filter = filter;
|
|
328
|
+
this.orderBy = orderBy;
|
|
329
|
+
this.groupBy = groupBy;
|
|
330
|
+
this.limit = limit;
|
|
331
|
+
this.table = table;
|
|
332
|
+
this.joinFilters = joinFilters;
|
|
333
|
+
}
|
|
334
|
+
display;
|
|
335
|
+
filter;
|
|
336
|
+
orderBy;
|
|
337
|
+
groupBy;
|
|
338
|
+
limit;
|
|
339
|
+
table;
|
|
340
|
+
joinFilters;
|
|
341
|
+
};
|
|
342
|
+
|
|
343
|
+
// src/datafinder/attribute.ts
|
|
344
|
+
var Attribute = class _Attribute {
|
|
345
|
+
_displayName;
|
|
346
|
+
_column;
|
|
347
|
+
_owner;
|
|
348
|
+
_parent;
|
|
349
|
+
_embedded;
|
|
350
|
+
constructor(displayName, columnName, columnDbType, owner, parent, embedded) {
|
|
351
|
+
this._displayName = displayName;
|
|
352
|
+
this._column = new Column(columnName, columnDbType, owner);
|
|
353
|
+
this._owner = owner;
|
|
354
|
+
this._parent = parent;
|
|
355
|
+
this._embedded = embedded;
|
|
356
|
+
}
|
|
357
|
+
column() {
|
|
358
|
+
return this._column;
|
|
359
|
+
}
|
|
360
|
+
owner() {
|
|
361
|
+
return this._owner;
|
|
362
|
+
}
|
|
363
|
+
parent() {
|
|
364
|
+
return this._parent;
|
|
365
|
+
}
|
|
366
|
+
displayName() {
|
|
367
|
+
return this._displayName;
|
|
368
|
+
}
|
|
369
|
+
/** Alternate attribute on a flat column of the owning table, used in place of this one when its join is elided. */
|
|
370
|
+
embedded() {
|
|
371
|
+
return this._embedded;
|
|
372
|
+
}
|
|
373
|
+
cwj() {
|
|
374
|
+
return new ColumnWithJoin(this._column, this._parent, this._embedded?.cwj());
|
|
375
|
+
}
|
|
376
|
+
/** Count the number of non-null values. Use in a projection with `groupByOp` to aggregate per group. */
|
|
377
|
+
count() {
|
|
378
|
+
return new AggregateOperation(
|
|
379
|
+
this.cwj(),
|
|
380
|
+
"COUNT" /* COUNT */,
|
|
381
|
+
this._displayName + " Count"
|
|
382
|
+
);
|
|
383
|
+
}
|
|
384
|
+
/** Sort this attribute in ascending order. Pass to `orderByOp` or a window function's `orderBy`. */
|
|
385
|
+
ascending() {
|
|
386
|
+
return new SortOperation(this.cwj(), "ASC" /* ASC */);
|
|
387
|
+
}
|
|
388
|
+
/** Sort this attribute in descending order. Pass to `orderByOp` or a window function's `orderBy`. */
|
|
389
|
+
descending() {
|
|
390
|
+
return new SortOperation(this.cwj(), "DESC" /* DESC */);
|
|
391
|
+
}
|
|
392
|
+
/** Filter to rows where this attribute has no value. */
|
|
393
|
+
isNull() {
|
|
394
|
+
return new IsNullOperation(this.cwj());
|
|
395
|
+
}
|
|
396
|
+
/** Filter to rows where this attribute has a value. */
|
|
397
|
+
isNotNull() {
|
|
398
|
+
return new IsNotNullOperation(this.cwj());
|
|
399
|
+
}
|
|
400
|
+
_windowSpec(partitionBy, orderBy) {
|
|
401
|
+
const pbArr = partitionBy === void 0 ? [] : Array.isArray(partitionBy) ? partitionBy : [partitionBy];
|
|
402
|
+
const pb = pbArr.map((x) => x instanceof _Attribute ? x.cwj() : x);
|
|
403
|
+
const ob = orderBy === void 0 ? [] : Array.isArray(orderBy) ? orderBy : [orderBy];
|
|
404
|
+
return new WindowSpecification(pb, ob);
|
|
405
|
+
}
|
|
406
|
+
/**
|
|
407
|
+
* Assign a rank to each row within the ordered window, following pandas `Series.rank` conventions.
|
|
408
|
+
*
|
|
409
|
+
* `method` controls tie-breaking (default `'min'`):
|
|
410
|
+
* - `'min'` — tied rows share the lowest rank; the next rank skips.
|
|
411
|
+
* - `'dense'` — like `'min'` but ranks are contiguous (no gaps).
|
|
412
|
+
* - `'first'` — each row gets a unique sequential integer (no ties).
|
|
413
|
+
* - `'max'` — only meaningful with `pct: true` (see below).
|
|
414
|
+
*
|
|
415
|
+
* When `pct: true` the result is a relative rank between 0 and 1:
|
|
416
|
+
* - `method: 'min'` (default) → fraction of values strictly below this row (PERCENT_RANK).
|
|
417
|
+
* - `method: 'max'` → fraction of values at or below this row (cumulative distribution).
|
|
418
|
+
*
|
|
419
|
+
* `partitionBy` restarts the ranking within each group of distinct values.
|
|
420
|
+
*/
|
|
421
|
+
rank(opts = {}) {
|
|
422
|
+
const { method = "min", pct = false, partitionBy, orderBy } = opts;
|
|
423
|
+
let func;
|
|
424
|
+
let name;
|
|
425
|
+
if (pct) {
|
|
426
|
+
if (method === "max") {
|
|
427
|
+
func = "CUME_DIST" /* CUME_DIST */;
|
|
428
|
+
name = "Cume Dist";
|
|
429
|
+
} else {
|
|
430
|
+
func = "PERCENT_RANK" /* PERCENT_RANK */;
|
|
431
|
+
name = "Percent Rank";
|
|
432
|
+
}
|
|
433
|
+
} else if (method === "first") {
|
|
434
|
+
func = "ROW_NUMBER" /* ROW_NUMBER */;
|
|
435
|
+
name = "Row Number";
|
|
436
|
+
} else if (method === "dense") {
|
|
437
|
+
func = "DENSE_RANK" /* DENSE_RANK */;
|
|
438
|
+
name = "Dense Rank";
|
|
439
|
+
} else {
|
|
440
|
+
func = "RANK" /* RANK */;
|
|
441
|
+
name = "Rank";
|
|
442
|
+
}
|
|
443
|
+
return new WindowFunctionOperation(null, func, name, void 0, [], this._windowSpec(partitionBy, orderBy));
|
|
444
|
+
}
|
|
445
|
+
/**
|
|
446
|
+
* Split rows into `buckets` equal-sized quantile bins ordered by `orderBy`.
|
|
447
|
+
* Each row receives a bucket number from 1 (lowest) to `buckets` (highest).
|
|
448
|
+
* Named after `pandas.qcut`.
|
|
449
|
+
*/
|
|
450
|
+
qcut(buckets, opts = {}) {
|
|
451
|
+
return new WindowFunctionOperation(
|
|
452
|
+
null,
|
|
453
|
+
"NTILE" /* NTILE */,
|
|
454
|
+
"Quantile",
|
|
455
|
+
buckets,
|
|
456
|
+
[],
|
|
457
|
+
this._windowSpec(opts.partitionBy, opts.orderBy)
|
|
458
|
+
);
|
|
459
|
+
}
|
|
460
|
+
/**
|
|
461
|
+
* Return the value of this attribute from `periods` rows earlier (positive) or later (negative)
|
|
462
|
+
* within the ordered window, following `pandas.Series.shift`.
|
|
463
|
+
* Rows with no neighbour at the given offset return `null` (or `fillValue` if provided).
|
|
464
|
+
*/
|
|
465
|
+
shift(periods = 1, opts = {}) {
|
|
466
|
+
const extraArgs = opts.fillValue !== void 0 ? [opts.fillValue] : [];
|
|
467
|
+
const func = periods >= 0 ? "LAG" /* LAG */ : "LEAD" /* LEAD */;
|
|
468
|
+
const label = periods >= 0 ? "Lag" : "Lead";
|
|
469
|
+
return new WindowFunctionOperation(
|
|
470
|
+
this.cwj(),
|
|
471
|
+
func,
|
|
472
|
+
label + " " + this._displayName,
|
|
473
|
+
Math.abs(periods),
|
|
474
|
+
extraArgs,
|
|
475
|
+
this._windowSpec(opts.partitionBy, opts.orderBy)
|
|
476
|
+
);
|
|
477
|
+
}
|
|
478
|
+
/**
|
|
479
|
+
* Return the first value of this attribute in the window frame.
|
|
480
|
+
* Use `partitionBy` to restart the frame for each group.
|
|
481
|
+
*/
|
|
482
|
+
first(opts = {}) {
|
|
483
|
+
return new WindowFunctionOperation(
|
|
484
|
+
this.cwj(),
|
|
485
|
+
"FIRST_VALUE" /* FIRST_VALUE */,
|
|
486
|
+
"First " + this._displayName,
|
|
487
|
+
void 0,
|
|
488
|
+
[],
|
|
489
|
+
this._windowSpec(opts.partitionBy, opts.orderBy)
|
|
490
|
+
);
|
|
491
|
+
}
|
|
492
|
+
/**
|
|
493
|
+
* Return the last value of this attribute in the window frame.
|
|
494
|
+
* Use `partitionBy` to restart the frame for each group.
|
|
495
|
+
*/
|
|
496
|
+
last(opts = {}) {
|
|
497
|
+
return new WindowFunctionOperation(
|
|
498
|
+
this.cwj(),
|
|
499
|
+
"LAST_VALUE" /* LAST_VALUE */,
|
|
500
|
+
"Last " + this._displayName,
|
|
501
|
+
void 0,
|
|
502
|
+
[],
|
|
503
|
+
this._windowSpec(opts.partitionBy, opts.orderBy)
|
|
504
|
+
);
|
|
505
|
+
}
|
|
506
|
+
};
|
|
507
|
+
|
|
508
|
+
// src/model/milestoning.ts
|
|
509
|
+
var MilestoningColumns = class {
|
|
510
|
+
};
|
|
511
|
+
var ProcessingTemporalColumns = class extends MilestoningColumns {
|
|
512
|
+
constructor(startAtColumn, endAtColumn, infiniteDatetime) {
|
|
513
|
+
super();
|
|
514
|
+
this.startAtColumn = startAtColumn;
|
|
515
|
+
this.endAtColumn = endAtColumn;
|
|
516
|
+
this.infiniteDatetime = infiniteDatetime;
|
|
517
|
+
}
|
|
518
|
+
startAtColumn;
|
|
519
|
+
endAtColumn;
|
|
520
|
+
infiniteDatetime;
|
|
521
|
+
columns() {
|
|
522
|
+
return [this.startAtColumn, this.endAtColumn];
|
|
523
|
+
}
|
|
524
|
+
};
|
|
525
|
+
var SingleBusinessDateColumn = class extends MilestoningColumns {
|
|
526
|
+
constructor(businessDateColumn) {
|
|
527
|
+
super();
|
|
528
|
+
this.businessDateColumn = businessDateColumn;
|
|
529
|
+
}
|
|
530
|
+
businessDateColumn;
|
|
531
|
+
columns() {
|
|
532
|
+
return [this.businessDateColumn];
|
|
533
|
+
}
|
|
534
|
+
};
|
|
535
|
+
var BusinessDateAndProcessingTemporalColumns = class extends MilestoningColumns {
|
|
536
|
+
constructor(businessDateColumn, startAtColumn, endAtColumn, infiniteDatetime) {
|
|
537
|
+
super();
|
|
538
|
+
this.businessDateColumn = businessDateColumn;
|
|
539
|
+
this.startAtColumn = startAtColumn;
|
|
540
|
+
this.endAtColumn = endAtColumn;
|
|
541
|
+
this.infiniteDatetime = infiniteDatetime;
|
|
542
|
+
}
|
|
543
|
+
businessDateColumn;
|
|
544
|
+
startAtColumn;
|
|
545
|
+
endAtColumn;
|
|
546
|
+
infiniteDatetime;
|
|
547
|
+
columns() {
|
|
548
|
+
return [this.businessDateColumn, this.startAtColumn, this.endAtColumn];
|
|
549
|
+
}
|
|
550
|
+
};
|
|
551
|
+
var BiTemporalColumns = class extends MilestoningColumns {
|
|
552
|
+
constructor(businessDateFromColumn, businessDateToColumn, startAtColumn, endAtColumn, infiniteDatetime) {
|
|
553
|
+
super();
|
|
554
|
+
this.businessDateFromColumn = businessDateFromColumn;
|
|
555
|
+
this.businessDateToColumn = businessDateToColumn;
|
|
556
|
+
this.startAtColumn = startAtColumn;
|
|
557
|
+
this.endAtColumn = endAtColumn;
|
|
558
|
+
this.infiniteDatetime = infiniteDatetime;
|
|
559
|
+
}
|
|
560
|
+
businessDateFromColumn;
|
|
561
|
+
businessDateToColumn;
|
|
562
|
+
startAtColumn;
|
|
563
|
+
endAtColumn;
|
|
564
|
+
infiniteDatetime;
|
|
565
|
+
columns() {
|
|
566
|
+
return [
|
|
567
|
+
this.businessDateFromColumn,
|
|
568
|
+
this.businessDateToColumn,
|
|
569
|
+
this.startAtColumn,
|
|
570
|
+
this.endAtColumn
|
|
571
|
+
];
|
|
572
|
+
}
|
|
573
|
+
};
|
|
574
|
+
var MilestonedTable = class extends Table {
|
|
575
|
+
constructor(name, columns, milestoningColumns, schema) {
|
|
576
|
+
super(name, columns, schema);
|
|
577
|
+
this.milestoningColumns = milestoningColumns;
|
|
578
|
+
for (const col of milestoningColumns.columns()) {
|
|
579
|
+
col.table = this;
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
milestoningColumns;
|
|
583
|
+
};
|
|
584
|
+
|
|
585
|
+
// src/datafinder/typed-attributes.ts
|
|
586
|
+
function parseDate(value) {
|
|
587
|
+
if (value instanceof Date) return value;
|
|
588
|
+
const d = new Date(value);
|
|
589
|
+
if (isNaN(d.getTime())) throw new Error(`Cannot parse date: ${value}`);
|
|
590
|
+
return d;
|
|
591
|
+
}
|
|
592
|
+
var DateAttribute = class extends Attribute {
|
|
593
|
+
constructor(displayName, columnName, columnDbType, owner, parent, embedded) {
|
|
594
|
+
super(displayName, columnName, columnDbType, owner, parent, embedded);
|
|
595
|
+
}
|
|
596
|
+
/** Filter to rows where this date equals `value`. */
|
|
597
|
+
eq(value) {
|
|
598
|
+
return new ComparisonOperation(this.cwj(), "EQUAL" /* EQUAL */, new DateConstantOperation(parseDate(value)));
|
|
599
|
+
}
|
|
600
|
+
/** Filter to rows where this date does not equal `value`. */
|
|
601
|
+
ne(value) {
|
|
602
|
+
return new ComparisonOperation(this.cwj(), "NOT_EQUAL" /* NOT_EQUAL */, new DateConstantOperation(parseDate(value)));
|
|
603
|
+
}
|
|
604
|
+
/** Filter to rows where this date is after `value`. */
|
|
605
|
+
gt(value) {
|
|
606
|
+
return new ComparisonOperation(this.cwj(), "GREATER_THAN" /* GREATER_THAN */, new DateConstantOperation(parseDate(value)));
|
|
607
|
+
}
|
|
608
|
+
/** Filter to rows where this date is before `value`. */
|
|
609
|
+
lt(value) {
|
|
610
|
+
return new ComparisonOperation(this.cwj(), "LESS_THAN" /* LESS_THAN */, new DateConstantOperation(parseDate(value)));
|
|
611
|
+
}
|
|
612
|
+
/** Filter to rows where this date is on or after `value`. */
|
|
613
|
+
gte(value) {
|
|
614
|
+
return new ComparisonOperation(this.cwj(), "GREATER_THAN_OR_EQUAL_TO" /* GREATER_THAN_OR_EQUAL_TO */, new DateConstantOperation(parseDate(value)));
|
|
615
|
+
}
|
|
616
|
+
/** Filter to rows where this date is on or before `value`. */
|
|
617
|
+
lte(value) {
|
|
618
|
+
return new ComparisonOperation(this.cwj(), "LESS_THAN_OR_EQUAL_TO" /* LESS_THAN_OR_EQUAL_TO */, new DateConstantOperation(parseDate(value)));
|
|
619
|
+
}
|
|
620
|
+
/** Extract the four-digit calendar year. */
|
|
621
|
+
year() {
|
|
622
|
+
return new DateExtractOperation(this.cwj(), "YEAR" /* YEAR */, "Year " + this.displayName());
|
|
623
|
+
}
|
|
624
|
+
/** Extract the month number (1–12). */
|
|
625
|
+
month() {
|
|
626
|
+
return new DateExtractOperation(this.cwj(), "MONTH" /* MONTH */, "Month " + this.displayName());
|
|
627
|
+
}
|
|
628
|
+
/** Extract the day of the month (1–31). */
|
|
629
|
+
day() {
|
|
630
|
+
return new DateExtractOperation(this.cwj(), "DAY" /* DAY */, "Day " + this.displayName());
|
|
631
|
+
}
|
|
632
|
+
/** Extract the quarter (1–4). */
|
|
633
|
+
quarter() {
|
|
634
|
+
return new DateExtractOperation(this.cwj(), "QUARTER" /* QUARTER */, "Quarter " + this.displayName());
|
|
635
|
+
}
|
|
636
|
+
/** Extract the ISO week number (1–53). */
|
|
637
|
+
week() {
|
|
638
|
+
return new DateExtractOperation(this.cwj(), "WEEK" /* WEEK */, "Week " + this.displayName());
|
|
639
|
+
}
|
|
640
|
+
/** Extract the day of the week (0 = Sunday through 6 = Saturday). */
|
|
641
|
+
dayOfWeek() {
|
|
642
|
+
return new DateExtractOperation(this.cwj(), "DOW" /* DOW */, "Day Of Week " + this.displayName());
|
|
643
|
+
}
|
|
644
|
+
/** Add `n` days to this date. */
|
|
645
|
+
addDays(n) {
|
|
646
|
+
return new DateArithmeticOperation(this.cwj(), n, "DAY" /* DAY */, true, "Add Days " + this.displayName());
|
|
647
|
+
}
|
|
648
|
+
/** Add `n` months to this date. */
|
|
649
|
+
addMonths(n) {
|
|
650
|
+
return new DateArithmeticOperation(this.cwj(), n, "MONTH" /* MONTH */, true, "Add Months " + this.displayName());
|
|
651
|
+
}
|
|
652
|
+
/** Add `n` years to this date. */
|
|
653
|
+
addYears(n) {
|
|
654
|
+
return new DateArithmeticOperation(this.cwj(), n, "YEAR" /* YEAR */, true, "Add Years " + this.displayName());
|
|
655
|
+
}
|
|
656
|
+
/** Subtract `n` days from this date. */
|
|
657
|
+
subtractDays(n) {
|
|
658
|
+
return new DateArithmeticOperation(this.cwj(), n, "DAY" /* DAY */, false, "Subtract Days " + this.displayName());
|
|
659
|
+
}
|
|
660
|
+
/** Subtract `n` months from this date. */
|
|
661
|
+
subtractMonths(n) {
|
|
662
|
+
return new DateArithmeticOperation(this.cwj(), n, "MONTH" /* MONTH */, false, "Subtract Months " + this.displayName());
|
|
663
|
+
}
|
|
664
|
+
/** Subtract `n` years from this date. */
|
|
665
|
+
subtractYears(n) {
|
|
666
|
+
return new DateArithmeticOperation(this.cwj(), n, "YEAR" /* YEAR */, false, "Subtract Years " + this.displayName());
|
|
667
|
+
}
|
|
668
|
+
/** Number of whole days between this date and `other`. */
|
|
669
|
+
diffDays(other) {
|
|
670
|
+
return new DateDiffOperation(this.cwj(), other, "DAY" /* DAY */, "Diff Days " + this.displayName());
|
|
671
|
+
}
|
|
672
|
+
/** Number of whole months between this date and `other`. */
|
|
673
|
+
diffMonths(other) {
|
|
674
|
+
return new DateDiffOperation(this.cwj(), other, "MONTH" /* MONTH */, "Diff Months " + this.displayName());
|
|
675
|
+
}
|
|
676
|
+
/** Number of whole years between this date and `other`. */
|
|
677
|
+
diffYears(other) {
|
|
678
|
+
return new DateDiffOperation(this.cwj(), other, "YEAR" /* YEAR */, "Diff Years " + this.displayName());
|
|
679
|
+
}
|
|
680
|
+
};
|
|
681
|
+
var DateTimeAttribute = class extends Attribute {
|
|
682
|
+
constructor(displayName, columnName, columnDbType, owner, parent, embedded) {
|
|
683
|
+
super(displayName, columnName, columnDbType, owner, parent, embedded);
|
|
684
|
+
}
|
|
685
|
+
/** Filter to rows where this timestamp equals `value`. */
|
|
686
|
+
eq(value) {
|
|
687
|
+
return new ComparisonOperation(this.cwj(), "EQUAL" /* EQUAL */, new DateTimeConstantOperation(parseDate(value)));
|
|
688
|
+
}
|
|
689
|
+
/** Filter to rows where this timestamp does not equal `value`. */
|
|
690
|
+
ne(value) {
|
|
691
|
+
return new ComparisonOperation(this.cwj(), "NOT_EQUAL" /* NOT_EQUAL */, new DateTimeConstantOperation(parseDate(value)));
|
|
692
|
+
}
|
|
693
|
+
/** Filter to rows where this timestamp is after `value`. */
|
|
694
|
+
gt(value) {
|
|
695
|
+
return new ComparisonOperation(this.cwj(), "GREATER_THAN" /* GREATER_THAN */, new DateTimeConstantOperation(parseDate(value)));
|
|
696
|
+
}
|
|
697
|
+
/** Filter to rows where this timestamp is before `value`. */
|
|
698
|
+
lt(value) {
|
|
699
|
+
return new ComparisonOperation(this.cwj(), "LESS_THAN" /* LESS_THAN */, new DateTimeConstantOperation(parseDate(value)));
|
|
700
|
+
}
|
|
701
|
+
/** Filter to rows where this timestamp is on or after `value`. */
|
|
702
|
+
gte(value) {
|
|
703
|
+
return new ComparisonOperation(this.cwj(), "GREATER_THAN_OR_EQUAL_TO" /* GREATER_THAN_OR_EQUAL_TO */, new DateTimeConstantOperation(parseDate(value)));
|
|
704
|
+
}
|
|
705
|
+
/** Filter to rows where this timestamp is on or before `value`. */
|
|
706
|
+
lte(value) {
|
|
707
|
+
return new ComparisonOperation(this.cwj(), "LESS_THAN_OR_EQUAL_TO" /* LESS_THAN_OR_EQUAL_TO */, new DateTimeConstantOperation(parseDate(value)));
|
|
708
|
+
}
|
|
709
|
+
/** Extract the four-digit calendar year. */
|
|
710
|
+
year() {
|
|
711
|
+
return new DateExtractOperation(this.cwj(), "YEAR" /* YEAR */, "Year " + this.displayName());
|
|
712
|
+
}
|
|
713
|
+
/** Extract the month number (1–12). */
|
|
714
|
+
month() {
|
|
715
|
+
return new DateExtractOperation(this.cwj(), "MONTH" /* MONTH */, "Month " + this.displayName());
|
|
716
|
+
}
|
|
717
|
+
/** Extract the day of the month (1–31). */
|
|
718
|
+
day() {
|
|
719
|
+
return new DateExtractOperation(this.cwj(), "DAY" /* DAY */, "Day " + this.displayName());
|
|
720
|
+
}
|
|
721
|
+
/** Extract the hour (0–23). */
|
|
722
|
+
hour() {
|
|
723
|
+
return new DateExtractOperation(this.cwj(), "HOUR" /* HOUR */, "Hour " + this.displayName());
|
|
724
|
+
}
|
|
725
|
+
/** Extract the minute (0–59). */
|
|
726
|
+
minute() {
|
|
727
|
+
return new DateExtractOperation(this.cwj(), "MINUTE" /* MINUTE */, "Minute " + this.displayName());
|
|
728
|
+
}
|
|
729
|
+
/** Extract the second (0–59). */
|
|
730
|
+
second() {
|
|
731
|
+
return new DateExtractOperation(this.cwj(), "SECOND" /* SECOND */, "Second " + this.displayName());
|
|
732
|
+
}
|
|
733
|
+
/** Extract the quarter (1–4). */
|
|
734
|
+
quarter() {
|
|
735
|
+
return new DateExtractOperation(this.cwj(), "QUARTER" /* QUARTER */, "Quarter " + this.displayName());
|
|
736
|
+
}
|
|
737
|
+
/** Extract the ISO week number (1–53). */
|
|
738
|
+
week() {
|
|
739
|
+
return new DateExtractOperation(this.cwj(), "WEEK" /* WEEK */, "Week " + this.displayName());
|
|
740
|
+
}
|
|
741
|
+
/** Extract the day of the week (0 = Sunday through 6 = Saturday). */
|
|
742
|
+
dayOfWeek() {
|
|
743
|
+
return new DateExtractOperation(this.cwj(), "DOW" /* DOW */, "Day Of Week " + this.displayName());
|
|
744
|
+
}
|
|
745
|
+
/** Add `n` days to this timestamp. */
|
|
746
|
+
addDays(n) {
|
|
747
|
+
return new DateArithmeticOperation(this.cwj(), n, "DAY" /* DAY */, true, "Add Days " + this.displayName());
|
|
748
|
+
}
|
|
749
|
+
/** Add `n` months to this timestamp. */
|
|
750
|
+
addMonths(n) {
|
|
751
|
+
return new DateArithmeticOperation(this.cwj(), n, "MONTH" /* MONTH */, true, "Add Months " + this.displayName());
|
|
752
|
+
}
|
|
753
|
+
/** Add `n` years to this timestamp. */
|
|
754
|
+
addYears(n) {
|
|
755
|
+
return new DateArithmeticOperation(this.cwj(), n, "YEAR" /* YEAR */, true, "Add Years " + this.displayName());
|
|
756
|
+
}
|
|
757
|
+
/** Add `n` hours to this timestamp. */
|
|
758
|
+
addHours(n) {
|
|
759
|
+
return new DateArithmeticOperation(this.cwj(), n, "HOUR" /* HOUR */, true, "Add Hours " + this.displayName());
|
|
760
|
+
}
|
|
761
|
+
/** Add `n` minutes to this timestamp. */
|
|
762
|
+
addMinutes(n) {
|
|
763
|
+
return new DateArithmeticOperation(this.cwj(), n, "MINUTE" /* MINUTE */, true, "Add Minutes " + this.displayName());
|
|
764
|
+
}
|
|
765
|
+
/** Add `n` seconds to this timestamp. */
|
|
766
|
+
addSeconds(n) {
|
|
767
|
+
return new DateArithmeticOperation(this.cwj(), n, "SECOND" /* SECOND */, true, "Add Seconds " + this.displayName());
|
|
768
|
+
}
|
|
769
|
+
/** Subtract `n` days from this timestamp. */
|
|
770
|
+
subtractDays(n) {
|
|
771
|
+
return new DateArithmeticOperation(this.cwj(), n, "DAY" /* DAY */, false, "Subtract Days " + this.displayName());
|
|
772
|
+
}
|
|
773
|
+
/** Subtract `n` months from this timestamp. */
|
|
774
|
+
subtractMonths(n) {
|
|
775
|
+
return new DateArithmeticOperation(this.cwj(), n, "MONTH" /* MONTH */, false, "Subtract Months " + this.displayName());
|
|
776
|
+
}
|
|
777
|
+
/** Subtract `n` years from this timestamp. */
|
|
778
|
+
subtractYears(n) {
|
|
779
|
+
return new DateArithmeticOperation(this.cwj(), n, "YEAR" /* YEAR */, false, "Subtract Years " + this.displayName());
|
|
780
|
+
}
|
|
781
|
+
/** Subtract `n` hours from this timestamp. */
|
|
782
|
+
subtractHours(n) {
|
|
783
|
+
return new DateArithmeticOperation(this.cwj(), n, "HOUR" /* HOUR */, false, "Subtract Hours " + this.displayName());
|
|
784
|
+
}
|
|
785
|
+
/** Subtract `n` minutes from this timestamp. */
|
|
786
|
+
subtractMinutes(n) {
|
|
787
|
+
return new DateArithmeticOperation(this.cwj(), n, "MINUTE" /* MINUTE */, false, "Subtract Minutes " + this.displayName());
|
|
788
|
+
}
|
|
789
|
+
/** Subtract `n` seconds from this timestamp. */
|
|
790
|
+
subtractSeconds(n) {
|
|
791
|
+
return new DateArithmeticOperation(this.cwj(), n, "SECOND" /* SECOND */, false, "Subtract Seconds " + this.displayName());
|
|
792
|
+
}
|
|
793
|
+
/** Number of whole days between this timestamp and `other`. */
|
|
794
|
+
diffDays(other) {
|
|
795
|
+
return new DateDiffOperation(this.cwj(), other, "DAY" /* DAY */, "Diff Days " + this.displayName());
|
|
796
|
+
}
|
|
797
|
+
/** Number of whole months between this timestamp and `other`. */
|
|
798
|
+
diffMonths(other) {
|
|
799
|
+
return new DateDiffOperation(this.cwj(), other, "MONTH" /* MONTH */, "Diff Months " + this.displayName());
|
|
800
|
+
}
|
|
801
|
+
/** Number of whole years between this timestamp and `other`. */
|
|
802
|
+
diffYears(other) {
|
|
803
|
+
return new DateDiffOperation(this.cwj(), other, "YEAR" /* YEAR */, "Diff Years " + this.displayName());
|
|
804
|
+
}
|
|
805
|
+
/** Number of whole hours between this timestamp and `other`. */
|
|
806
|
+
diffHours(other) {
|
|
807
|
+
return new DateDiffOperation(this.cwj(), other, "HOUR" /* HOUR */, "Diff Hours " + this.displayName());
|
|
808
|
+
}
|
|
809
|
+
/** Number of whole minutes between this timestamp and `other`. */
|
|
810
|
+
diffMinutes(other) {
|
|
811
|
+
return new DateDiffOperation(this.cwj(), other, "MINUTE" /* MINUTE */, "Diff Minutes " + this.displayName());
|
|
812
|
+
}
|
|
813
|
+
/** Number of whole seconds between this timestamp and `other`. */
|
|
814
|
+
diffSeconds(other) {
|
|
815
|
+
return new DateDiffOperation(this.cwj(), other, "SECOND" /* SECOND */, "Diff Seconds " + this.displayName());
|
|
816
|
+
}
|
|
817
|
+
};
|
|
818
|
+
|
|
819
|
+
// src/datafinder/sql-generator.ts
|
|
820
|
+
var TableAlias = class {
|
|
821
|
+
constructor(table, alias) {
|
|
822
|
+
this.table = table;
|
|
823
|
+
this.alias = alias;
|
|
824
|
+
}
|
|
825
|
+
table;
|
|
826
|
+
alias;
|
|
827
|
+
};
|
|
828
|
+
var TableAliasColumn = class extends RelationalOperationElement {
|
|
829
|
+
constructor(column, tableAlias) {
|
|
830
|
+
super();
|
|
831
|
+
this.column = column;
|
|
832
|
+
this.tableAlias = tableAlias;
|
|
833
|
+
}
|
|
834
|
+
column;
|
|
835
|
+
tableAlias;
|
|
836
|
+
};
|
|
837
|
+
var Join = class {
|
|
838
|
+
constructor(source, target, filterOp) {
|
|
839
|
+
this.source = source;
|
|
840
|
+
this.target = target;
|
|
841
|
+
this.filterOp = filterOp;
|
|
842
|
+
}
|
|
843
|
+
source;
|
|
844
|
+
target;
|
|
845
|
+
filterOp;
|
|
846
|
+
};
|
|
847
|
+
function sqlFormatDatetime(value) {
|
|
848
|
+
const pad = (n, w = 2) => String(n).padStart(w, "0");
|
|
849
|
+
return `'${value.getUTCFullYear()}-${pad(value.getUTCMonth() + 1)}-${pad(value.getUTCDate())} ${pad(value.getUTCHours())}:${pad(value.getUTCMinutes())}:${pad(value.getUTCSeconds())}'`;
|
|
850
|
+
}
|
|
851
|
+
function sqlFormatDate(value) {
|
|
852
|
+
const pad = (n) => String(n).padStart(2, "0");
|
|
853
|
+
return `'${value.getUTCFullYear()}-${pad(value.getUTCMonth() + 1)}-${pad(value.getUTCDate())}'`;
|
|
854
|
+
}
|
|
855
|
+
var LOGICAL_OPERATOR_STR = {
|
|
856
|
+
["AND" /* AND */]: " AND ",
|
|
857
|
+
["OR" /* OR */]: " OR "
|
|
858
|
+
};
|
|
859
|
+
var COMPARISON_OPERATOR_STR = {
|
|
860
|
+
["EQUAL" /* EQUAL */]: " = ",
|
|
861
|
+
["NOT_EQUAL" /* NOT_EQUAL */]: " <> ",
|
|
862
|
+
["LESS_THAN" /* LESS_THAN */]: " < ",
|
|
863
|
+
["GREATER_THAN" /* GREATER_THAN */]: " > ",
|
|
864
|
+
["LESS_THAN_OR_EQUAL_TO" /* LESS_THAN_OR_EQUAL_TO */]: " <= ",
|
|
865
|
+
["GREATER_THAN_OR_EQUAL_TO" /* GREATER_THAN_OR_EQUAL_TO */]: " >= ",
|
|
866
|
+
["LIKE" /* LIKE */]: " LIKE ",
|
|
867
|
+
["NOT_LIKE" /* NOT_LIKE */]: " NOT LIKE "
|
|
868
|
+
};
|
|
869
|
+
var AGGREGATE_SQL_NAMES = {
|
|
870
|
+
["AVERAGE" /* AVERAGE */]: "AVG"
|
|
871
|
+
};
|
|
872
|
+
var WINDOW_SQL_NAMES = {
|
|
873
|
+
["ROW_NUMBER" /* ROW_NUMBER */]: "ROW_NUMBER",
|
|
874
|
+
["RANK" /* RANK */]: "RANK",
|
|
875
|
+
["DENSE_RANK" /* DENSE_RANK */]: "DENSE_RANK",
|
|
876
|
+
["NTILE" /* NTILE */]: "NTILE",
|
|
877
|
+
["LAG" /* LAG */]: "LAG",
|
|
878
|
+
["LEAD" /* LEAD */]: "LEAD",
|
|
879
|
+
["FIRST_VALUE" /* FIRST_VALUE */]: "FIRST_VALUE",
|
|
880
|
+
["LAST_VALUE" /* LAST_VALUE */]: "LAST_VALUE",
|
|
881
|
+
["CUME_DIST" /* CUME_DIST */]: "CUME_DIST",
|
|
882
|
+
["PERCENT_RANK" /* PERCENT_RANK */]: "PERCENT_RANK"
|
|
883
|
+
};
|
|
884
|
+
var SCALAR_SQL_NAMES = {
|
|
885
|
+
["ABS" /* ABS */]: "ABS",
|
|
886
|
+
["CEILING" /* CEILING */]: "CEILING",
|
|
887
|
+
["FLOOR" /* FLOOR */]: "FLOOR",
|
|
888
|
+
["MOD" /* MOD */]: "MOD",
|
|
889
|
+
["POWER" /* POWER */]: "POWER",
|
|
890
|
+
["SQRT" /* SQRT */]: "SQRT",
|
|
891
|
+
["ROUND" /* ROUND */]: "ROUND",
|
|
892
|
+
["UPPER" /* UPPER */]: "UPPER",
|
|
893
|
+
["LOWER" /* LOWER */]: "LOWER",
|
|
894
|
+
["TRIM" /* TRIM */]: "TRIM",
|
|
895
|
+
["LTRIM" /* LTRIM */]: "LTRIM",
|
|
896
|
+
["RTRIM" /* RTRIM */]: "RTRIM",
|
|
897
|
+
["LENGTH" /* LENGTH */]: "LENGTH",
|
|
898
|
+
["REVERSE" /* REVERSE */]: "REVERSE",
|
|
899
|
+
["LEFT" /* LEFT */]: "LEFT",
|
|
900
|
+
["RIGHT" /* RIGHT */]: "RIGHT",
|
|
901
|
+
["REPEAT" /* REPEAT */]: "REPEAT",
|
|
902
|
+
["REPLACE" /* REPLACE */]: "REPLACE",
|
|
903
|
+
["SUBSTRING" /* SUBSTRING */]: "SUBSTRING"
|
|
904
|
+
};
|
|
905
|
+
function constantValueString(op) {
|
|
906
|
+
if (op instanceof StringConstantOperation) return "'" + op.value + "'";
|
|
907
|
+
if (op instanceof DateConstantOperation) return sqlFormatDate(op.value);
|
|
908
|
+
if (op instanceof DateTimeConstantOperation) return sqlFormatDatetime(op.value);
|
|
909
|
+
if (op instanceof IntegerConstantOperation) return String(op.value);
|
|
910
|
+
if (op instanceof FloatConstantOperation) return String(op.value);
|
|
911
|
+
if (op instanceof BooleanConstantOperation) return op.value ? "TRUE" : "FALSE";
|
|
912
|
+
if (op instanceof DecimalConstantOperation) return String(op.value);
|
|
913
|
+
throw new Error("Unknown constant operation");
|
|
914
|
+
}
|
|
915
|
+
function windowSpecToString(window) {
|
|
916
|
+
const parts = [];
|
|
917
|
+
if (window.partitionBy.length > 0) {
|
|
918
|
+
parts.push("PARTITION BY " + window.partitionBy.map((p) => sqlOperationToString(p)).join(", "));
|
|
919
|
+
}
|
|
920
|
+
if (window.orderBy.length > 0) {
|
|
921
|
+
parts.push("ORDER BY " + window.orderBy.map(
|
|
922
|
+
(s) => sqlOperationToString(s.column) + (s.direction === "ASC" /* ASC */ ? " ASC" : " DESC")
|
|
923
|
+
).join(", "));
|
|
924
|
+
}
|
|
925
|
+
return "OVER (" + parts.join(" ") + ")";
|
|
926
|
+
}
|
|
927
|
+
function sqlOperationToString(operation) {
|
|
928
|
+
if (operation instanceof TableAliasColumn) {
|
|
929
|
+
return operation.tableAlias.alias + "." + operation.column.name;
|
|
930
|
+
}
|
|
931
|
+
if (operation instanceof WindowFunctionOperation) {
|
|
932
|
+
const fn = WINDOW_SQL_NAMES[operation.func];
|
|
933
|
+
const parts = [];
|
|
934
|
+
if (operation.element !== null && operation.element !== void 0) {
|
|
935
|
+
parts.push(sqlOperationToString(operation.element));
|
|
936
|
+
}
|
|
937
|
+
if (operation.secondArg !== void 0) parts.push(String(operation.secondArg));
|
|
938
|
+
for (const arg of operation.extraArgs) {
|
|
939
|
+
parts.push(typeof arg === "string" ? "'" + arg + "'" : String(arg));
|
|
940
|
+
}
|
|
941
|
+
const sql = fn + "(" + parts.join(", ") + ")";
|
|
942
|
+
return sql + (operation.window !== void 0 ? " " + windowSpecToString(operation.window) : " OVER ()");
|
|
943
|
+
}
|
|
944
|
+
if (operation instanceof AggregateOperation) {
|
|
945
|
+
const fn = AGGREGATE_SQL_NAMES[operation.operator] ?? operation.operator;
|
|
946
|
+
let sql = fn + "(" + sqlOperationToString(operation.element) + ")";
|
|
947
|
+
if (operation.window !== void 0) {
|
|
948
|
+
sql += " " + windowSpecToString(operation.window);
|
|
949
|
+
}
|
|
950
|
+
return sql;
|
|
951
|
+
}
|
|
952
|
+
if (operation instanceof ScalarFunctionOperation) {
|
|
953
|
+
const fn = SCALAR_SQL_NAMES[operation.func];
|
|
954
|
+
const parts = [sqlOperationToString(operation.element)];
|
|
955
|
+
if (operation.secondArg !== void 0) parts.push(String(operation.secondArg));
|
|
956
|
+
for (const arg of operation.extraArgs) {
|
|
957
|
+
parts.push(typeof arg === "string" ? "'" + arg + "'" : String(arg));
|
|
958
|
+
}
|
|
959
|
+
return fn + "(" + parts.join(", ") + ")";
|
|
960
|
+
}
|
|
961
|
+
if (operation instanceof DateExtractOperation) {
|
|
962
|
+
return "EXTRACT(" + operation.part + " FROM " + sqlOperationToString(operation.element) + ")";
|
|
963
|
+
}
|
|
964
|
+
if (operation instanceof DateArithmeticOperation) {
|
|
965
|
+
const op = operation.isAdd ? "+" : "-";
|
|
966
|
+
return sqlOperationToString(operation.element) + " " + op + " INTERVAL " + operation.n + " " + operation.unit;
|
|
967
|
+
}
|
|
968
|
+
if (operation instanceof DateDiffOperation) {
|
|
969
|
+
const otherSql = sqlFormatDatetime(operation.other);
|
|
970
|
+
return "DATE_DIFF('" + operation.unit.toLowerCase() + "', " + sqlOperationToString(operation.element) + ", " + otherSql + ")";
|
|
971
|
+
}
|
|
972
|
+
if (operation instanceof CountAllOperation) return "COUNT(*)";
|
|
973
|
+
if (operation instanceof Alias) {
|
|
974
|
+
return sqlOperationToString(operation.element) + ' AS "' + operation.name + '"';
|
|
975
|
+
}
|
|
976
|
+
throw new TypeError("Unknown operation in sqlOperationToString: " + operation.constructor.name);
|
|
977
|
+
}
|
|
978
|
+
function embeddedOf(ref) {
|
|
979
|
+
return ref instanceof Attribute ? ref.embedded() : ref.embedded;
|
|
980
|
+
}
|
|
981
|
+
function findColumn(operation) {
|
|
982
|
+
if (operation instanceof UnaryOperation) return findColumn(operation.element);
|
|
983
|
+
if (operation instanceof ColumnWithJoin) return operation;
|
|
984
|
+
throw new TypeError("Cannot find ColumnWithJoin in: " + operation.constructor.name);
|
|
985
|
+
}
|
|
986
|
+
function openEndClause(endAttr, value, infiniteDatetime) {
|
|
987
|
+
const gtOp = endAttr instanceof DateTimeAttribute ? endAttr.gt(value) : endAttr.gt(value);
|
|
988
|
+
if (infiniteDatetime === void 0) {
|
|
989
|
+
const colRef = new ColumnWithJoin(endAttr.column(), endAttr.parent());
|
|
990
|
+
return new LogicalOperation(gtOp, "OR" /* OR */, new IsNullOperation(colRef));
|
|
991
|
+
}
|
|
992
|
+
return gtOp;
|
|
993
|
+
}
|
|
994
|
+
function buildMilestoningFilterOperation(businessDate, processingDatetime, table, joinNode) {
|
|
995
|
+
const mc = table.milestoningColumns;
|
|
996
|
+
const ops = [];
|
|
997
|
+
if (mc instanceof BiTemporalColumns) {
|
|
998
|
+
if (businessDate !== null) {
|
|
999
|
+
const dateFrom = new DateAttribute("business_date_from", mc.businessDateFromColumn.name, mc.businessDateFromColumn.type, mc.businessDateFromColumn.table.qualifiedName, joinNode);
|
|
1000
|
+
const dateTo = new DateAttribute("business_date_to", mc.businessDateToColumn.name, mc.businessDateToColumn.type, mc.businessDateToColumn.table.qualifiedName, joinNode);
|
|
1001
|
+
ops.push(new LogicalOperation(dateFrom.lte(businessDate), "AND" /* AND */, openEndClause(dateTo, businessDate, mc.infiniteDatetime)));
|
|
1002
|
+
}
|
|
1003
|
+
if (processingDatetime !== null) {
|
|
1004
|
+
const startAt = new DateTimeAttribute("start_at", mc.startAtColumn.name, mc.startAtColumn.type, mc.startAtColumn.table.qualifiedName, joinNode);
|
|
1005
|
+
const endAt = new DateTimeAttribute("end_at", mc.endAtColumn.name, mc.endAtColumn.type, mc.endAtColumn.table.qualifiedName, joinNode);
|
|
1006
|
+
ops.push(new LogicalOperation(startAt.lte(processingDatetime), "AND" /* AND */, openEndClause(endAt, processingDatetime, mc.infiniteDatetime)));
|
|
1007
|
+
}
|
|
1008
|
+
} else if (mc instanceof BusinessDateAndProcessingTemporalColumns) {
|
|
1009
|
+
if (businessDate !== null) {
|
|
1010
|
+
const businessAtt = new DateAttribute("business_date", mc.businessDateColumn.name, mc.businessDateColumn.type, mc.businessDateColumn.table.qualifiedName, joinNode);
|
|
1011
|
+
ops.push(businessAtt.eq(businessDate));
|
|
1012
|
+
}
|
|
1013
|
+
if (processingDatetime !== null) {
|
|
1014
|
+
const startAt = new DateTimeAttribute("start_at", mc.startAtColumn.name, mc.startAtColumn.type, mc.startAtColumn.table.qualifiedName, joinNode);
|
|
1015
|
+
const endAt = new DateTimeAttribute("end_at", mc.endAtColumn.name, mc.endAtColumn.type, mc.endAtColumn.table.qualifiedName, joinNode);
|
|
1016
|
+
ops.push(new LogicalOperation(startAt.lte(processingDatetime), "AND" /* AND */, openEndClause(endAt, processingDatetime, mc.infiniteDatetime)));
|
|
1017
|
+
}
|
|
1018
|
+
} else if (mc instanceof ProcessingTemporalColumns && processingDatetime !== null) {
|
|
1019
|
+
const startAt = new DateTimeAttribute("start_at", mc.startAtColumn.name, mc.startAtColumn.type, mc.startAtColumn.table.qualifiedName, joinNode);
|
|
1020
|
+
const endAt = new DateTimeAttribute("end_at", mc.endAtColumn.name, mc.endAtColumn.type, mc.endAtColumn.table.qualifiedName, joinNode);
|
|
1021
|
+
ops.push(new LogicalOperation(startAt.lte(processingDatetime), "AND" /* AND */, openEndClause(endAt, processingDatetime, mc.infiniteDatetime)));
|
|
1022
|
+
} else if (mc instanceof SingleBusinessDateColumn && businessDate !== null) {
|
|
1023
|
+
const businessAtt = new DateAttribute("business_date", mc.businessDateColumn.name, mc.businessDateColumn.type, mc.businessDateColumn.table.qualifiedName, joinNode);
|
|
1024
|
+
ops.push(businessAtt.eq(businessDate));
|
|
1025
|
+
}
|
|
1026
|
+
if (ops.length === 0) return null;
|
|
1027
|
+
if (ops.length === 1) return ops[0];
|
|
1028
|
+
return new LogicalOperation(ops[0], "AND" /* AND */, ops[1]);
|
|
1029
|
+
}
|
|
1030
|
+
function buildMilestoningFilterOperationForDateRange(businessDateFrom, businessDateTo, processingDatetime, table, joinNode) {
|
|
1031
|
+
const mc = table.milestoningColumns;
|
|
1032
|
+
const ops = [];
|
|
1033
|
+
const hasRange = businessDateFrom !== null && businessDateTo !== null;
|
|
1034
|
+
const processingOp = (m) => {
|
|
1035
|
+
const startAt = new DateTimeAttribute("start_at", m.startAtColumn.name, m.startAtColumn.type, m.startAtColumn.table.qualifiedName, joinNode);
|
|
1036
|
+
const endAt = new DateTimeAttribute("end_at", m.endAtColumn.name, m.endAtColumn.type, m.endAtColumn.table.qualifiedName, joinNode);
|
|
1037
|
+
return new LogicalOperation(startAt.lte(processingDatetime), "AND" /* AND */, openEndClause(endAt, processingDatetime, m.infiniteDatetime));
|
|
1038
|
+
};
|
|
1039
|
+
if (mc instanceof BiTemporalColumns) {
|
|
1040
|
+
if (hasRange) {
|
|
1041
|
+
const dateFrom = new DateAttribute("business_date_from", mc.businessDateFromColumn.name, mc.businessDateFromColumn.type, mc.businessDateFromColumn.table.qualifiedName, joinNode);
|
|
1042
|
+
const dateTo = new DateAttribute("business_date_to", mc.businessDateToColumn.name, mc.businessDateToColumn.type, mc.businessDateToColumn.table.qualifiedName, joinNode);
|
|
1043
|
+
ops.push(new LogicalOperation(dateFrom.lte(businessDateTo), "AND" /* AND */, openEndClause(dateTo, businessDateFrom, mc.infiniteDatetime)));
|
|
1044
|
+
}
|
|
1045
|
+
if (processingDatetime !== null) ops.push(processingOp(mc));
|
|
1046
|
+
} else if (mc instanceof BusinessDateAndProcessingTemporalColumns) {
|
|
1047
|
+
if (hasRange) {
|
|
1048
|
+
const businessAtt = new DateAttribute("business_date", mc.businessDateColumn.name, mc.businessDateColumn.type, mc.businessDateColumn.table.qualifiedName, joinNode);
|
|
1049
|
+
ops.push(new LogicalOperation(businessAtt.gte(businessDateFrom), "AND" /* AND */, businessAtt.lte(businessDateTo)));
|
|
1050
|
+
}
|
|
1051
|
+
if (processingDatetime !== null) ops.push(processingOp(mc));
|
|
1052
|
+
} else if (mc instanceof ProcessingTemporalColumns) {
|
|
1053
|
+
if (processingDatetime !== null) ops.push(processingOp(mc));
|
|
1054
|
+
} else if (mc instanceof SingleBusinessDateColumn && hasRange) {
|
|
1055
|
+
const businessAtt = new DateAttribute("business_date", mc.businessDateColumn.name, mc.businessDateColumn.type, mc.businessDateColumn.table.qualifiedName, joinNode);
|
|
1056
|
+
ops.push(new LogicalOperation(businessAtt.gte(businessDateFrom), "AND" /* AND */, businessAtt.lte(businessDateTo)));
|
|
1057
|
+
}
|
|
1058
|
+
if (ops.length === 0) return null;
|
|
1059
|
+
if (ops.length === 1) return ops[0];
|
|
1060
|
+
return new LogicalOperation(ops[0], "AND" /* AND */, ops[1]);
|
|
1061
|
+
}
|
|
1062
|
+
function walkRefs(op, visit, visitExists) {
|
|
1063
|
+
if (op === null || op === void 0) return;
|
|
1064
|
+
if (op instanceof Attribute || op instanceof ColumnWithJoin) {
|
|
1065
|
+
visit(op);
|
|
1066
|
+
} else if (op instanceof ExistsOperation || op instanceof NotExistsOperation) {
|
|
1067
|
+
visitExists?.(op.node);
|
|
1068
|
+
} else if (op instanceof AggregateOperation) {
|
|
1069
|
+
walkRefs(op.element, visit, visitExists);
|
|
1070
|
+
if (op.window) walkWindowSpec(op.window, visit, visitExists);
|
|
1071
|
+
} else if (op instanceof WindowFunctionOperation) {
|
|
1072
|
+
if (op.element) walkRefs(op.element, visit, visitExists);
|
|
1073
|
+
if (op.window) walkWindowSpec(op.window, visit, visitExists);
|
|
1074
|
+
} else if (op instanceof ScalarFunctionOperation || op instanceof DateExtractOperation || op instanceof DateArithmeticOperation || op instanceof DateDiffOperation || op instanceof IsNullOperation || op instanceof IsNotNullOperation) {
|
|
1075
|
+
walkRefs(op.element, visit, visitExists);
|
|
1076
|
+
} else if (op instanceof SortOperation) {
|
|
1077
|
+
walkRefs(op.column, visit, visitExists);
|
|
1078
|
+
} else if (op instanceof LogicalOperation || op instanceof ComparisonOperation) {
|
|
1079
|
+
walkRefs(op.left, visit, visitExists);
|
|
1080
|
+
walkRefs(op.right, visit, visitExists);
|
|
1081
|
+
}
|
|
1082
|
+
}
|
|
1083
|
+
function walkWindowSpec(window, visit, visitExists) {
|
|
1084
|
+
for (const p of window.partitionBy) walkRefs(p, visit, visitExists);
|
|
1085
|
+
for (const s of window.orderBy) walkRefs(s.column, visit, visitExists);
|
|
1086
|
+
}
|
|
1087
|
+
function buildJoinFilterFromProperties(node, filter, columnMap) {
|
|
1088
|
+
const ops = [];
|
|
1089
|
+
for (const [key, value] of Object.entries(filter)) {
|
|
1090
|
+
const entry = columnMap[key];
|
|
1091
|
+
if (entry === void 0) {
|
|
1092
|
+
throw new Error(`Unknown property '${key}' \u2014 valid properties are: ${Object.keys(columnMap).sort().join(", ")}`);
|
|
1093
|
+
}
|
|
1094
|
+
const [name, type, table] = entry;
|
|
1095
|
+
const col = new ColumnWithJoin(new Column(name, type, table), node);
|
|
1096
|
+
let constant;
|
|
1097
|
+
if (typeof value === "boolean") constant = new BooleanConstantOperation(value);
|
|
1098
|
+
else if (typeof value === "number") constant = Number.isInteger(value) ? new IntegerConstantOperation(value) : new FloatConstantOperation(value);
|
|
1099
|
+
else if (value instanceof Date) constant = type.toUpperCase() === "DATE" ? new DateConstantOperation(value) : new DateTimeConstantOperation(value);
|
|
1100
|
+
else constant = new StringConstantOperation(String(value));
|
|
1101
|
+
ops.push(new ComparisonOperation(col, "EQUAL" /* EQUAL */, constant));
|
|
1102
|
+
}
|
|
1103
|
+
return ops.reduce((acc, op) => new LogicalOperation(acc, "AND" /* AND */, op));
|
|
1104
|
+
}
|
|
1105
|
+
function withAncestors(nodes) {
|
|
1106
|
+
const ordered = /* @__PURE__ */ new Set();
|
|
1107
|
+
const add = (node) => {
|
|
1108
|
+
if (ordered.has(node)) return;
|
|
1109
|
+
if (node.parent !== void 0) add(node.parent);
|
|
1110
|
+
ordered.add(node);
|
|
1111
|
+
};
|
|
1112
|
+
for (const node of nodes) add(node);
|
|
1113
|
+
return [...ordered];
|
|
1114
|
+
}
|
|
1115
|
+
function buildQueryOperation(businessDate, processingDatetime, columns, table, op, orderBy = [], groupBy = [], limit, businessDateTo = null) {
|
|
1116
|
+
let filter = op;
|
|
1117
|
+
const milestoningFor = (t, node) => businessDateTo !== null ? buildMilestoningFilterOperationForDateRange(businessDate, businessDateTo, processingDatetime, t, node) : buildMilestoningFilterOperation(businessDate, processingDatetime, t, node);
|
|
1118
|
+
if (table instanceof MilestonedTable) {
|
|
1119
|
+
const milestonedOp = milestoningFor(table);
|
|
1120
|
+
if (milestonedOp !== null) {
|
|
1121
|
+
filter = filter instanceof NoOperation ? milestonedOp : new LogicalOperation(filter, "AND" /* AND */, milestonedOp);
|
|
1122
|
+
}
|
|
1123
|
+
}
|
|
1124
|
+
const requiredJoins = /* @__PURE__ */ new Set();
|
|
1125
|
+
const collect = (ref) => {
|
|
1126
|
+
const parent = ref instanceof Attribute ? ref.parent() : ref.parent;
|
|
1127
|
+
if (parent !== void 0) requiredJoins.add(parent);
|
|
1128
|
+
};
|
|
1129
|
+
const collectNode = (node) => requiredJoins.add(node);
|
|
1130
|
+
for (const col of columns) walkRefs(col, collect, collectNode);
|
|
1131
|
+
for (const expr of groupBy) walkRefs(expr, collect, collectNode);
|
|
1132
|
+
for (const sort of orderBy) walkRefs(sort, collect, collectNode);
|
|
1133
|
+
walkRefs(op, collect, collectNode);
|
|
1134
|
+
const joinFilters = /* @__PURE__ */ new Map();
|
|
1135
|
+
for (const node of withAncestors(requiredJoins)) {
|
|
1136
|
+
let combined;
|
|
1137
|
+
if (Object.keys(node.join.filterKwargs).length > 0) {
|
|
1138
|
+
combined = buildJoinFilterFromProperties(node, node.join.filterKwargs, node.join.filterColumnMap);
|
|
1139
|
+
}
|
|
1140
|
+
if (node.join.target instanceof MilestonedTable) {
|
|
1141
|
+
const milestonedOp = milestoningFor(node.join.target, node);
|
|
1142
|
+
if (milestonedOp !== null) {
|
|
1143
|
+
combined = combined === void 0 ? milestonedOp : new LogicalOperation(combined, "AND" /* AND */, milestonedOp);
|
|
1144
|
+
}
|
|
1145
|
+
}
|
|
1146
|
+
if (combined !== void 0) joinFilters.set(node, combined);
|
|
1147
|
+
}
|
|
1148
|
+
return new SelectOperation(columns, filter, orderBy, groupBy, limit, table, joinFilters);
|
|
1149
|
+
}
|
|
1150
|
+
var SQLQueryGenerator = class {
|
|
1151
|
+
_select = [];
|
|
1152
|
+
_from = /* @__PURE__ */ new Set();
|
|
1153
|
+
_join = [];
|
|
1154
|
+
_groupByParts = [];
|
|
1155
|
+
_orderByParts = [];
|
|
1156
|
+
_where = "";
|
|
1157
|
+
_limit;
|
|
1158
|
+
_tableAliasIncr = 0;
|
|
1159
|
+
_tableAliasesByTable = /* @__PURE__ */ new Map();
|
|
1160
|
+
_addedJoinIds = /* @__PURE__ */ new Set();
|
|
1161
|
+
_rootTable;
|
|
1162
|
+
_elidableNodes = /* @__PURE__ */ new Set();
|
|
1163
|
+
_joinFilters = /* @__PURE__ */ new Map();
|
|
1164
|
+
generate(select) {
|
|
1165
|
+
this._rootTable = select.table;
|
|
1166
|
+
this._elidableNodes = this._computeElidableNodes(select);
|
|
1167
|
+
this._joinFilters = select.joinFilters;
|
|
1168
|
+
if (this._rootTable !== void 0) {
|
|
1169
|
+
this._from.add(this._tableAliasForTable(this._rootTable.qualifiedName, this._rootTable.qualifiedName));
|
|
1170
|
+
}
|
|
1171
|
+
this.processSelect(select.display);
|
|
1172
|
+
this._where = this.buildFilter(select.filter);
|
|
1173
|
+
const groupByJoins = /* @__PURE__ */ new Map();
|
|
1174
|
+
for (const expr of select.groupBy) {
|
|
1175
|
+
this._collectRequiredJoins(expr, groupByJoins);
|
|
1176
|
+
}
|
|
1177
|
+
for (const node of groupByJoins.values()) {
|
|
1178
|
+
this._addJoin(node);
|
|
1179
|
+
}
|
|
1180
|
+
this._groupByParts = select.groupBy.map((a) => this._attrToColString(a));
|
|
1181
|
+
this._orderByParts = select.orderBy.map(
|
|
1182
|
+
(s) => this.buildFilter(s.column) + (s.direction === "ASC" /* ASC */ ? " ASC" : " DESC")
|
|
1183
|
+
);
|
|
1184
|
+
this._limit = select.limit;
|
|
1185
|
+
}
|
|
1186
|
+
_attrToColString(attr) {
|
|
1187
|
+
const { column, parent } = this._resolve(attr);
|
|
1188
|
+
const ta = this._tableAliasForTable(column.owner, parent ?? column.owner);
|
|
1189
|
+
return ta.alias + "." + column.name;
|
|
1190
|
+
}
|
|
1191
|
+
_collectRequiredJoins(op, out) {
|
|
1192
|
+
walkRefs(op, (ref) => {
|
|
1193
|
+
const { parent } = this._resolve(ref);
|
|
1194
|
+
if (parent !== void 0) out.set(parent, parent);
|
|
1195
|
+
});
|
|
1196
|
+
}
|
|
1197
|
+
/**
|
|
1198
|
+
* Determine upfront which join nodes can be satisfied entirely by embedded (join-less) alternates:
|
|
1199
|
+
* a node is elidable when every reference to it has an embedded alternate. A reference without one
|
|
1200
|
+
* (e.g. a milestoning column) keeps the join for every reference to that node.
|
|
1201
|
+
*/
|
|
1202
|
+
_computeElidableNodes(select) {
|
|
1203
|
+
const refsByNode = /* @__PURE__ */ new Map();
|
|
1204
|
+
const record = (ref) => {
|
|
1205
|
+
const parent = ref instanceof Attribute ? ref.parent() : ref.parent;
|
|
1206
|
+
if (parent === void 0) return;
|
|
1207
|
+
const refs = refsByNode.get(parent);
|
|
1208
|
+
if (refs) refs.push(ref);
|
|
1209
|
+
else refsByNode.set(parent, [ref]);
|
|
1210
|
+
};
|
|
1211
|
+
for (const col of select.display) walkRefs(col, record);
|
|
1212
|
+
for (const expr of select.groupBy) walkRefs(expr, record);
|
|
1213
|
+
for (const sort of select.orderBy) walkRefs(sort, record);
|
|
1214
|
+
walkRefs(select.filter, record);
|
|
1215
|
+
const elidable = /* @__PURE__ */ new Set();
|
|
1216
|
+
for (const [node, refs] of refsByNode) {
|
|
1217
|
+
if (refs.every((ref) => embeddedOf(ref) !== void 0)) elidable.add(node);
|
|
1218
|
+
}
|
|
1219
|
+
return elidable;
|
|
1220
|
+
}
|
|
1221
|
+
/** The (column, parent) a reference should resolve to, substituting its embedded alternate when its join is elided. */
|
|
1222
|
+
_resolve(ref) {
|
|
1223
|
+
const column = ref instanceof Attribute ? ref.column() : ref.column;
|
|
1224
|
+
const parent = ref instanceof Attribute ? ref.parent() : ref.parent;
|
|
1225
|
+
if (parent !== void 0 && this._elidableNodes.has(parent)) {
|
|
1226
|
+
const embedded = embeddedOf(ref);
|
|
1227
|
+
if (embedded !== void 0) return this._resolve(embedded);
|
|
1228
|
+
}
|
|
1229
|
+
return { column, parent };
|
|
1230
|
+
}
|
|
1231
|
+
_rewriteWindowSpec(window) {
|
|
1232
|
+
const partitionBy = window.partitionBy.map((p) => this._rewriteOperation(p));
|
|
1233
|
+
const orderBy = window.orderBy.map((s) => new SortOperation(this._rewriteOperation(s.column), s.direction));
|
|
1234
|
+
return new WindowSpecification(partitionBy, orderBy);
|
|
1235
|
+
}
|
|
1236
|
+
_rewriteOperation(op) {
|
|
1237
|
+
if (op instanceof Attribute || op instanceof ColumnWithJoin) {
|
|
1238
|
+
const { column, parent } = this._resolve(op);
|
|
1239
|
+
return new TableAliasColumn(column, this._tableAliasForTable(column.owner, parent ?? column.owner));
|
|
1240
|
+
}
|
|
1241
|
+
if (op instanceof Column) {
|
|
1242
|
+
const ta = this._tableAliasForTable(op.owner, op.owner);
|
|
1243
|
+
return new TableAliasColumn(op, ta);
|
|
1244
|
+
}
|
|
1245
|
+
if (op instanceof AggregateOperation) {
|
|
1246
|
+
return new AggregateOperation(
|
|
1247
|
+
this._rewriteOperation(op.element),
|
|
1248
|
+
op.operator,
|
|
1249
|
+
op.displayName,
|
|
1250
|
+
op.window ? this._rewriteWindowSpec(op.window) : void 0
|
|
1251
|
+
);
|
|
1252
|
+
}
|
|
1253
|
+
if (op instanceof WindowFunctionOperation) {
|
|
1254
|
+
const el = op.element ? this._rewriteOperation(op.element) : null;
|
|
1255
|
+
return new WindowFunctionOperation(
|
|
1256
|
+
el,
|
|
1257
|
+
op.func,
|
|
1258
|
+
op.displayName,
|
|
1259
|
+
op.secondArg,
|
|
1260
|
+
[...op.extraArgs],
|
|
1261
|
+
op.window ? this._rewriteWindowSpec(op.window) : void 0
|
|
1262
|
+
);
|
|
1263
|
+
}
|
|
1264
|
+
if (op instanceof ScalarFunctionOperation) {
|
|
1265
|
+
return new ScalarFunctionOperation(this._rewriteOperation(op.element), op.func, op.displayName, op.secondArg, op.extraArgs);
|
|
1266
|
+
}
|
|
1267
|
+
if (op instanceof DateExtractOperation) {
|
|
1268
|
+
return new DateExtractOperation(this._rewriteOperation(op.element), op.part, op.displayName);
|
|
1269
|
+
}
|
|
1270
|
+
if (op instanceof DateArithmeticOperation) {
|
|
1271
|
+
return new DateArithmeticOperation(this._rewriteOperation(op.element), op.n, op.unit, op.isAdd, op.displayName);
|
|
1272
|
+
}
|
|
1273
|
+
if (op instanceof DateDiffOperation) {
|
|
1274
|
+
return new DateDiffOperation(this._rewriteOperation(op.element), op.other, op.unit, op.displayName);
|
|
1275
|
+
}
|
|
1276
|
+
return op;
|
|
1277
|
+
}
|
|
1278
|
+
processSelect(cols) {
|
|
1279
|
+
const requiredJoins = /* @__PURE__ */ new Map();
|
|
1280
|
+
for (const col of cols) {
|
|
1281
|
+
this._collectRequiredJoins(col, requiredJoins);
|
|
1282
|
+
}
|
|
1283
|
+
for (const node of requiredJoins.values()) {
|
|
1284
|
+
this._addJoin(node);
|
|
1285
|
+
}
|
|
1286
|
+
for (const col of cols) {
|
|
1287
|
+
if (col instanceof Attribute) {
|
|
1288
|
+
const { column, parent: node } = this._resolve(col);
|
|
1289
|
+
let ta;
|
|
1290
|
+
if (node !== void 0) {
|
|
1291
|
+
ta = this._tableAliasForTable(column.owner, node);
|
|
1292
|
+
} else {
|
|
1293
|
+
ta = this._tableAliasForTable(column.owner, column.owner);
|
|
1294
|
+
this._from.add(ta);
|
|
1295
|
+
}
|
|
1296
|
+
this._select.push(new Alias(new TableAliasColumn(column, ta), col.displayName()));
|
|
1297
|
+
} else if (col instanceof WindowFunctionOperation) {
|
|
1298
|
+
const rewritten = this._rewriteOperation(col);
|
|
1299
|
+
let alias;
|
|
1300
|
+
if (col.displayName) {
|
|
1301
|
+
alias = col.displayName;
|
|
1302
|
+
} else if (["ROW_NUMBER" /* ROW_NUMBER */, "RANK" /* RANK */, "DENSE_RANK" /* DENSE_RANK */].includes(col.func)) {
|
|
1303
|
+
alias = col.func.replace(/_/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
|
|
1304
|
+
} else if (col.element) {
|
|
1305
|
+
alias = col.func + " " + findColumn(col).column.name;
|
|
1306
|
+
} else {
|
|
1307
|
+
alias = col.func;
|
|
1308
|
+
}
|
|
1309
|
+
this._select.push(new Alias(rewritten, alias));
|
|
1310
|
+
} else if (col instanceof AggregateOperation) {
|
|
1311
|
+
const colNested = this._resolve(findColumn(col));
|
|
1312
|
+
const node = colNested.parent;
|
|
1313
|
+
let ta;
|
|
1314
|
+
if (node !== void 0) {
|
|
1315
|
+
ta = this._tableAliasForTable(colNested.column.owner, node);
|
|
1316
|
+
} else {
|
|
1317
|
+
ta = this._tableAliasForTable(colNested.column.owner, colNested.column.owner);
|
|
1318
|
+
this._from.add(ta);
|
|
1319
|
+
}
|
|
1320
|
+
const alias = col.displayName ?? col.operator + " " + findColumn(col).column.name;
|
|
1321
|
+
const rewrittenAgg = new AggregateOperation(
|
|
1322
|
+
new TableAliasColumn(colNested.column, ta),
|
|
1323
|
+
col.operator,
|
|
1324
|
+
void 0,
|
|
1325
|
+
col.window ? this._rewriteWindowSpec(col.window) : void 0
|
|
1326
|
+
);
|
|
1327
|
+
this._select.push(new Alias(rewrittenAgg, alias));
|
|
1328
|
+
} else if (col instanceof ScalarFunctionOperation) {
|
|
1329
|
+
const colNested = this._resolve(findColumn(col));
|
|
1330
|
+
const node = colNested.parent;
|
|
1331
|
+
let ta;
|
|
1332
|
+
if (node !== void 0) {
|
|
1333
|
+
ta = this._tableAliasForTable(colNested.column.owner, node);
|
|
1334
|
+
} else {
|
|
1335
|
+
ta = this._tableAliasForTable(colNested.column.owner, colNested.column.owner);
|
|
1336
|
+
this._from.add(ta);
|
|
1337
|
+
}
|
|
1338
|
+
const alias = col.displayName ?? col.func + " " + findColumn(col).column.name;
|
|
1339
|
+
this._select.push(new Alias(
|
|
1340
|
+
new ScalarFunctionOperation(new TableAliasColumn(colNested.column, ta), col.func, void 0, col.secondArg, col.extraArgs),
|
|
1341
|
+
alias
|
|
1342
|
+
));
|
|
1343
|
+
} else if (col instanceof DateExtractOperation || col instanceof DateArithmeticOperation || col instanceof DateDiffOperation) {
|
|
1344
|
+
const colNested = this._resolve(findColumn(col));
|
|
1345
|
+
const node = colNested.parent;
|
|
1346
|
+
let ta;
|
|
1347
|
+
if (node !== void 0) {
|
|
1348
|
+
ta = this._tableAliasForTable(colNested.column.owner, node);
|
|
1349
|
+
} else {
|
|
1350
|
+
ta = this._tableAliasForTable(colNested.column.owner, colNested.column.owner);
|
|
1351
|
+
this._from.add(ta);
|
|
1352
|
+
}
|
|
1353
|
+
const alias = col.displayName ?? findColumn(col).column.name;
|
|
1354
|
+
let aliasedOp;
|
|
1355
|
+
if (col instanceof DateExtractOperation) {
|
|
1356
|
+
aliasedOp = new DateExtractOperation(new TableAliasColumn(colNested.column, ta), col.part);
|
|
1357
|
+
} else if (col instanceof DateArithmeticOperation) {
|
|
1358
|
+
aliasedOp = new DateArithmeticOperation(new TableAliasColumn(colNested.column, ta), col.n, col.unit, col.isAdd);
|
|
1359
|
+
} else {
|
|
1360
|
+
aliasedOp = new DateDiffOperation(new TableAliasColumn(colNested.column, ta), col.other, col.unit);
|
|
1361
|
+
}
|
|
1362
|
+
this._select.push(new Alias(aliasedOp, alias));
|
|
1363
|
+
} else if (col instanceof CountAllOperation) {
|
|
1364
|
+
const ta = this._tableAliasForTable(col.table, col.table);
|
|
1365
|
+
this._from.add(ta);
|
|
1366
|
+
this._select.push(new Alias(col, "Count"));
|
|
1367
|
+
}
|
|
1368
|
+
}
|
|
1369
|
+
}
|
|
1370
|
+
_addJoin(node) {
|
|
1371
|
+
if (this._addedJoinIds.has(node)) return;
|
|
1372
|
+
if (node.parent !== void 0) this._addJoin(node.parent);
|
|
1373
|
+
this._addedJoinIds.add(node);
|
|
1374
|
+
const join = node.join;
|
|
1375
|
+
const left = join.left;
|
|
1376
|
+
const srcTa = this._tableAliasForTable(left.owner, node.parent ?? left.owner);
|
|
1377
|
+
if (node.parent === void 0) this._from.add(srcTa);
|
|
1378
|
+
const sc = new TableAliasColumn(left, srcTa);
|
|
1379
|
+
const right = join.right;
|
|
1380
|
+
const tc = new TableAliasColumn(right, this._tableAliasForTable(right.owner, node));
|
|
1381
|
+
const queryFilter = this._joinFilters.get(node);
|
|
1382
|
+
const filterOp = join.filter !== void 0 && queryFilter !== void 0 ? new LogicalOperation(join.filter, "AND" /* AND */, queryFilter) : join.filter ?? queryFilter;
|
|
1383
|
+
this._join.push(new Join(sc, tc, filterOp));
|
|
1384
|
+
}
|
|
1385
|
+
buildFilter(op) {
|
|
1386
|
+
if (op instanceof NoOperation) return "";
|
|
1387
|
+
if (op instanceof ExistsOperation) {
|
|
1388
|
+
const col = op.node.join.right;
|
|
1389
|
+
return this.buildFilter(new ColumnWithJoin(col, op.node)) + " IS NOT NULL";
|
|
1390
|
+
}
|
|
1391
|
+
if (op instanceof NotExistsOperation) {
|
|
1392
|
+
const col = op.node.join.right;
|
|
1393
|
+
return this.buildFilter(new ColumnWithJoin(col, op.node)) + " IS NULL";
|
|
1394
|
+
}
|
|
1395
|
+
if (op instanceof IsNotNullOperation) return this.buildFilter(op.element) + " IS NOT NULL";
|
|
1396
|
+
if (op instanceof IsNullOperation) return this.buildFilter(op.element) + " IS NULL";
|
|
1397
|
+
if (op instanceof LogicalOperation) {
|
|
1398
|
+
let left = this.buildFilter(op.left);
|
|
1399
|
+
let right = this.buildFilter(op.right);
|
|
1400
|
+
if (op.left instanceof LogicalOperation) left = "(" + left + ")";
|
|
1401
|
+
if (op.right instanceof LogicalOperation) right = "(" + right + ")";
|
|
1402
|
+
return left + LOGICAL_OPERATOR_STR[op.operator] + right;
|
|
1403
|
+
}
|
|
1404
|
+
if (op instanceof ComparisonOperation) {
|
|
1405
|
+
return this.buildFilter(op.left) + COMPARISON_OPERATOR_STR[op.operator] + this.buildFilter(op.right);
|
|
1406
|
+
}
|
|
1407
|
+
if (op instanceof ConstantOperation) return constantValueString(op);
|
|
1408
|
+
if (op instanceof ColumnWithJoin) {
|
|
1409
|
+
const { column, parent: node } = this._resolve(op);
|
|
1410
|
+
let ta;
|
|
1411
|
+
if (node !== void 0) {
|
|
1412
|
+
ta = this._tableAliasForTable(column.owner, node);
|
|
1413
|
+
this._addJoin(node);
|
|
1414
|
+
} else {
|
|
1415
|
+
ta = this._tableAliasForTable(column.owner, column.owner);
|
|
1416
|
+
}
|
|
1417
|
+
return ta.alias + "." + column.name;
|
|
1418
|
+
}
|
|
1419
|
+
if (op instanceof Column) {
|
|
1420
|
+
const ta = this._tableAliasForTable(op.owner, op.owner);
|
|
1421
|
+
return ta.alias + "." + op.name;
|
|
1422
|
+
}
|
|
1423
|
+
throw new Error("Unknown operation in buildFilter: " + op.constructor.name);
|
|
1424
|
+
}
|
|
1425
|
+
_tableAliasForTable(table, key) {
|
|
1426
|
+
if (this._tableAliasesByTable.has(key)) {
|
|
1427
|
+
return this._tableAliasesByTable.get(key);
|
|
1428
|
+
}
|
|
1429
|
+
const ta = new TableAlias(table, "t" + this._tableAliasIncr++);
|
|
1430
|
+
this._tableAliasesByTable.set(key, ta);
|
|
1431
|
+
return ta;
|
|
1432
|
+
}
|
|
1433
|
+
buildQueryString() {
|
|
1434
|
+
const joins = this._join.map(
|
|
1435
|
+
(j) => " LEFT OUTER JOIN " + j.target.tableAlias.table + " AS " + j.target.tableAlias.alias + " ON " + j.source.tableAlias.alias + "." + j.source.column.name + " = " + j.target.tableAlias.alias + "." + j.target.column.name + (j.filterOp ? " AND " + this.buildFilter(j.filterOp) : "")
|
|
1436
|
+
);
|
|
1437
|
+
return "SELECT " + this._select.map((ca) => sqlOperationToString(ca)).join(",") + " FROM " + Array.from(this._from).map((ta) => ta.table + " AS " + ta.alias).join(",") + joins.join("") + this._buildWhere() + this._buildGroupBy() + this._buildOrderBy() + this._buildLimit();
|
|
1438
|
+
}
|
|
1439
|
+
_buildWhere() {
|
|
1440
|
+
return this._where.length > 0 ? " WHERE " + this._where : "";
|
|
1441
|
+
}
|
|
1442
|
+
_buildGroupBy() {
|
|
1443
|
+
return this._groupByParts.length > 0 ? " GROUP BY " + this._groupByParts.join(", ") : "";
|
|
1444
|
+
}
|
|
1445
|
+
_buildOrderBy() {
|
|
1446
|
+
return this._orderByParts.length > 0 ? " ORDER BY " + this._orderByParts.join(", ") : "";
|
|
1447
|
+
}
|
|
1448
|
+
_buildLimit() {
|
|
1449
|
+
return this._limit !== void 0 ? " LIMIT " + this._limit : "";
|
|
1450
|
+
}
|
|
1451
|
+
};
|
|
1452
|
+
function selectSqlToString(selectOperation) {
|
|
1453
|
+
const qg = new SQLQueryGenerator();
|
|
1454
|
+
qg.generate(selectOperation);
|
|
1455
|
+
return qg.buildQueryString();
|
|
1456
|
+
}
|
|
1457
|
+
function toSql(businessDate, processingDatetime, columns, table, op, orderBy = [], groupBy = [], limit, businessDateTo = null) {
|
|
1458
|
+
const selectOp = buildQueryOperation(businessDate, processingDatetime, columns, table, op, orderBy, groupBy, limit, businessDateTo);
|
|
1459
|
+
return selectSqlToString(selectOp);
|
|
1460
|
+
}
|
|
1461
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
1462
|
+
0 && (module.exports = {
|
|
1463
|
+
buildQueryOperation,
|
|
1464
|
+
selectSqlToString,
|
|
1465
|
+
toSql
|
|
1466
|
+
});
|
|
1467
|
+
//# sourceMappingURL=sql-generator.cjs.map
|