data-finder-ts 0.1.3 → 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-V647VNMY.js → chunk-4JVW4TAB.js} +59 -14
- package/dist/chunk-4JVW4TAB.js.map +1 -0
- package/dist/{chunk-5K2Z3YDY.js → chunk-4LNZV6EN.js} +138 -31
- package/dist/chunk-4LNZV6EN.js.map +1 -0
- package/dist/{chunk-6QTCGJWX.js → chunk-FJYA2ASS.js} +46 -8
- package/dist/chunk-FJYA2ASS.js.map +1 -0
- package/dist/{chunk-DFYZVBII.js → chunk-MH4XMYVB.js} +186 -142
- package/dist/chunk-MH4XMYVB.js.map +1 -0
- package/dist/{chunk-EYXBYV2X.js → chunk-PMPLCEWQ.js} +2 -2
- package/dist/{chunk-3SSWFES4.js → chunk-UYMOE6YU.js} +64 -3
- package/dist/chunk-UYMOE6YU.js.map +1 -0
- package/dist/datafinder/attribute.cjs +64 -13
- package/dist/datafinder/attribute.cjs.map +1 -1
- package/dist/datafinder/attribute.d.cts +48 -7
- package/dist/datafinder/attribute.d.ts +48 -7
- package/dist/datafinder/attribute.js +2 -2
- package/dist/datafinder/runner.cjs +389 -140
- package/dist/datafinder/runner.cjs.map +1 -1
- package/dist/datafinder/runner.d.cts +14 -3
- package/dist/datafinder/runner.d.ts +14 -3
- package/dist/datafinder/runner.js +12 -6
- package/dist/datafinder/sql-generator.cjs +344 -138
- package/dist/datafinder/sql-generator.cjs.map +1 -1
- package/dist/datafinder/sql-generator.d.cts +4 -13
- package/dist/datafinder/sql-generator.d.ts +4 -13
- package/dist/datafinder/sql-generator.js +5 -7
- package/dist/datafinder/typed-attributes.cjs +199 -41
- package/dist/datafinder/typed-attributes.cjs.map +1 -1
- package/dist/datafinder/typed-attributes.d.cts +120 -13
- package/dist/datafinder/typed-attributes.d.ts +120 -13
- package/dist/datafinder/typed-attributes.js +3 -3
- package/dist/index.cjs +507 -176
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +16 -15
- package/dist/index.d.ts +16 -15
- package/dist/index.js +49 -9
- package/dist/index.js.map +1 -1
- package/dist/model/milestoning.cjs.map +1 -1
- package/dist/model/milestoning.js +2 -2
- package/dist/model/relational.cjs +66 -1
- package/dist/model/relational.cjs.map +1 -1
- package/dist/model/relational.d.cts +47 -2
- package/dist/model/relational.d.ts +47 -2
- package/dist/model/relational.js +9 -1
- package/package.json +4 -2
- package/dist/chunk-3SSWFES4.js.map +0 -1
- package/dist/chunk-5K2Z3YDY.js.map +0 -1
- package/dist/chunk-6QTCGJWX.js.map +0 -1
- package/dist/chunk-DFYZVBII.js.map +0 -1
- package/dist/chunk-V647VNMY.js.map +0 -1
- /package/dist/{chunk-EYXBYV2X.js.map → chunk-PMPLCEWQ.js.map} +0 -0
|
@@ -20,9 +20,12 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/datafinder/runner.ts
|
|
21
21
|
var runner_exports = {};
|
|
22
22
|
__export(runner_exports, {
|
|
23
|
+
DEFAULT_TIMEOUT_MS: () => DEFAULT_TIMEOUT_MS,
|
|
23
24
|
FinderResult: () => FinderResult,
|
|
25
|
+
QueryTimeoutError: () => QueryTimeoutError,
|
|
24
26
|
clearRunner: () => clearRunner,
|
|
25
27
|
convertInputsAndSelect: () => convertInputsAndSelect,
|
|
28
|
+
convertInputsAndSelectForDateRange: () => convertInputsAndSelectForDateRange,
|
|
26
29
|
getRunner: () => getRunner,
|
|
27
30
|
registerRunner: () => registerRunner
|
|
28
31
|
});
|
|
@@ -265,13 +268,19 @@ var Table = class {
|
|
|
265
268
|
}
|
|
266
269
|
};
|
|
267
270
|
var ColumnWithJoin = class extends RelationalOperationElement {
|
|
268
|
-
|
|
271
|
+
/**
|
|
272
|
+
* `embedded` is an alternate reference to a flat (denormalized) column on the owning table that
|
|
273
|
+
* holds the same value without the join; the SQL generator uses it when the join can be elided.
|
|
274
|
+
*/
|
|
275
|
+
constructor(column, parent, embedded) {
|
|
269
276
|
super();
|
|
270
277
|
this.column = column;
|
|
271
278
|
this.parent = parent;
|
|
279
|
+
this.embedded = embedded;
|
|
272
280
|
}
|
|
273
281
|
column;
|
|
274
282
|
parent;
|
|
283
|
+
embedded;
|
|
275
284
|
};
|
|
276
285
|
var SortOperation = class {
|
|
277
286
|
constructor(column, direction) {
|
|
@@ -288,18 +297,67 @@ var CountAllOperation = class extends RelationalOperationElement {
|
|
|
288
297
|
}
|
|
289
298
|
table;
|
|
290
299
|
};
|
|
300
|
+
var Alias = class extends RelationalOperationElement {
|
|
301
|
+
constructor(element, name) {
|
|
302
|
+
super();
|
|
303
|
+
this.element = element;
|
|
304
|
+
this.name = name;
|
|
305
|
+
}
|
|
306
|
+
element;
|
|
307
|
+
name;
|
|
308
|
+
};
|
|
309
|
+
var ExistsOperation = class extends RelationalOperationElement {
|
|
310
|
+
constructor(node) {
|
|
311
|
+
super();
|
|
312
|
+
this.node = node;
|
|
313
|
+
}
|
|
314
|
+
node;
|
|
315
|
+
andOp(other) {
|
|
316
|
+
return new LogicalOperation(this, "AND" /* AND */, other);
|
|
317
|
+
}
|
|
318
|
+
};
|
|
319
|
+
var NotExistsOperation = class extends RelationalOperationElement {
|
|
320
|
+
constructor(node) {
|
|
321
|
+
super();
|
|
322
|
+
this.node = node;
|
|
323
|
+
}
|
|
324
|
+
node;
|
|
325
|
+
andOp(other) {
|
|
326
|
+
return new LogicalOperation(this, "AND" /* AND */, other);
|
|
327
|
+
}
|
|
328
|
+
};
|
|
329
|
+
var SelectOperation = class {
|
|
330
|
+
constructor(display, filter, orderBy = [], groupBy = [], limit, table, joinFilters = /* @__PURE__ */ new Map()) {
|
|
331
|
+
this.display = display;
|
|
332
|
+
this.filter = filter;
|
|
333
|
+
this.orderBy = orderBy;
|
|
334
|
+
this.groupBy = groupBy;
|
|
335
|
+
this.limit = limit;
|
|
336
|
+
this.table = table;
|
|
337
|
+
this.joinFilters = joinFilters;
|
|
338
|
+
}
|
|
339
|
+
display;
|
|
340
|
+
filter;
|
|
341
|
+
orderBy;
|
|
342
|
+
groupBy;
|
|
343
|
+
limit;
|
|
344
|
+
table;
|
|
345
|
+
joinFilters;
|
|
346
|
+
};
|
|
291
347
|
|
|
292
348
|
// src/datafinder/attribute.ts
|
|
293
|
-
var Attribute = class {
|
|
349
|
+
var Attribute = class _Attribute {
|
|
294
350
|
_displayName;
|
|
295
351
|
_column;
|
|
296
352
|
_owner;
|
|
297
353
|
_parent;
|
|
298
|
-
|
|
354
|
+
_embedded;
|
|
355
|
+
constructor(displayName, columnName, columnDbType, owner, parent, embedded) {
|
|
299
356
|
this._displayName = displayName;
|
|
300
357
|
this._column = new Column(columnName, columnDbType, owner);
|
|
301
358
|
this._owner = owner;
|
|
302
359
|
this._parent = parent;
|
|
360
|
+
this._embedded = embedded;
|
|
303
361
|
}
|
|
304
362
|
column() {
|
|
305
363
|
return this._column;
|
|
@@ -313,33 +371,58 @@ var Attribute = class {
|
|
|
313
371
|
displayName() {
|
|
314
372
|
return this._displayName;
|
|
315
373
|
}
|
|
374
|
+
/** Alternate attribute on a flat column of the owning table, used in place of this one when its join is elided. */
|
|
375
|
+
embedded() {
|
|
376
|
+
return this._embedded;
|
|
377
|
+
}
|
|
316
378
|
cwj() {
|
|
317
|
-
return new ColumnWithJoin(this._column, this._parent);
|
|
379
|
+
return new ColumnWithJoin(this._column, this._parent, this._embedded?.cwj());
|
|
318
380
|
}
|
|
381
|
+
/** Count the number of non-null values. Use in a projection with `groupByOp` to aggregate per group. */
|
|
319
382
|
count() {
|
|
320
383
|
return new AggregateOperation(
|
|
321
|
-
|
|
384
|
+
this.cwj(),
|
|
322
385
|
"COUNT" /* COUNT */,
|
|
323
386
|
this._displayName + " Count"
|
|
324
387
|
);
|
|
325
388
|
}
|
|
389
|
+
/** Sort this attribute in ascending order. Pass to `orderByOp` or a window function's `orderBy`. */
|
|
326
390
|
ascending() {
|
|
327
|
-
return new SortOperation(
|
|
391
|
+
return new SortOperation(this.cwj(), "ASC" /* ASC */);
|
|
328
392
|
}
|
|
393
|
+
/** Sort this attribute in descending order. Pass to `orderByOp` or a window function's `orderBy`. */
|
|
329
394
|
descending() {
|
|
330
|
-
return new SortOperation(
|
|
395
|
+
return new SortOperation(this.cwj(), "DESC" /* DESC */);
|
|
331
396
|
}
|
|
397
|
+
/** Filter to rows where this attribute has no value. */
|
|
332
398
|
isNull() {
|
|
333
|
-
return new IsNullOperation(
|
|
399
|
+
return new IsNullOperation(this.cwj());
|
|
334
400
|
}
|
|
401
|
+
/** Filter to rows where this attribute has a value. */
|
|
335
402
|
isNotNull() {
|
|
336
|
-
return new IsNotNullOperation(
|
|
403
|
+
return new IsNotNullOperation(this.cwj());
|
|
337
404
|
}
|
|
338
405
|
_windowSpec(partitionBy, orderBy) {
|
|
339
|
-
const
|
|
406
|
+
const pbArr = partitionBy === void 0 ? [] : Array.isArray(partitionBy) ? partitionBy : [partitionBy];
|
|
407
|
+
const pb = pbArr.map((x) => x instanceof _Attribute ? x.cwj() : x);
|
|
340
408
|
const ob = orderBy === void 0 ? [] : Array.isArray(orderBy) ? orderBy : [orderBy];
|
|
341
409
|
return new WindowSpecification(pb, ob);
|
|
342
410
|
}
|
|
411
|
+
/**
|
|
412
|
+
* Assign a rank to each row within the ordered window, following pandas `Series.rank` conventions.
|
|
413
|
+
*
|
|
414
|
+
* `method` controls tie-breaking (default `'min'`):
|
|
415
|
+
* - `'min'` — tied rows share the lowest rank; the next rank skips.
|
|
416
|
+
* - `'dense'` — like `'min'` but ranks are contiguous (no gaps).
|
|
417
|
+
* - `'first'` — each row gets a unique sequential integer (no ties).
|
|
418
|
+
* - `'max'` — only meaningful with `pct: true` (see below).
|
|
419
|
+
*
|
|
420
|
+
* When `pct: true` the result is a relative rank between 0 and 1:
|
|
421
|
+
* - `method: 'min'` (default) → fraction of values strictly below this row (PERCENT_RANK).
|
|
422
|
+
* - `method: 'max'` → fraction of values at or below this row (cumulative distribution).
|
|
423
|
+
*
|
|
424
|
+
* `partitionBy` restarts the ranking within each group of distinct values.
|
|
425
|
+
*/
|
|
343
426
|
rank(opts = {}) {
|
|
344
427
|
const { method = "min", pct = false, partitionBy, orderBy } = opts;
|
|
345
428
|
let func;
|
|
@@ -364,6 +447,11 @@ var Attribute = class {
|
|
|
364
447
|
}
|
|
365
448
|
return new WindowFunctionOperation(null, func, name, void 0, [], this._windowSpec(partitionBy, orderBy));
|
|
366
449
|
}
|
|
450
|
+
/**
|
|
451
|
+
* Split rows into `buckets` equal-sized quantile bins ordered by `orderBy`.
|
|
452
|
+
* Each row receives a bucket number from 1 (lowest) to `buckets` (highest).
|
|
453
|
+
* Named after `pandas.qcut`.
|
|
454
|
+
*/
|
|
367
455
|
qcut(buckets, opts = {}) {
|
|
368
456
|
return new WindowFunctionOperation(
|
|
369
457
|
null,
|
|
@@ -374,12 +462,17 @@ var Attribute = class {
|
|
|
374
462
|
this._windowSpec(opts.partitionBy, opts.orderBy)
|
|
375
463
|
);
|
|
376
464
|
}
|
|
465
|
+
/**
|
|
466
|
+
* Return the value of this attribute from `periods` rows earlier (positive) or later (negative)
|
|
467
|
+
* within the ordered window, following `pandas.Series.shift`.
|
|
468
|
+
* Rows with no neighbour at the given offset return `null` (or `fillValue` if provided).
|
|
469
|
+
*/
|
|
377
470
|
shift(periods = 1, opts = {}) {
|
|
378
471
|
const extraArgs = opts.fillValue !== void 0 ? [opts.fillValue] : [];
|
|
379
472
|
const func = periods >= 0 ? "LAG" /* LAG */ : "LEAD" /* LEAD */;
|
|
380
473
|
const label = periods >= 0 ? "Lag" : "Lead";
|
|
381
474
|
return new WindowFunctionOperation(
|
|
382
|
-
|
|
475
|
+
this.cwj(),
|
|
383
476
|
func,
|
|
384
477
|
label + " " + this._displayName,
|
|
385
478
|
Math.abs(periods),
|
|
@@ -387,9 +480,13 @@ var Attribute = class {
|
|
|
387
480
|
this._windowSpec(opts.partitionBy, opts.orderBy)
|
|
388
481
|
);
|
|
389
482
|
}
|
|
483
|
+
/**
|
|
484
|
+
* Return the first value of this attribute in the window frame.
|
|
485
|
+
* Use `partitionBy` to restart the frame for each group.
|
|
486
|
+
*/
|
|
390
487
|
first(opts = {}) {
|
|
391
488
|
return new WindowFunctionOperation(
|
|
392
|
-
|
|
489
|
+
this.cwj(),
|
|
393
490
|
"FIRST_VALUE" /* FIRST_VALUE */,
|
|
394
491
|
"First " + this._displayName,
|
|
395
492
|
void 0,
|
|
@@ -397,9 +494,13 @@ var Attribute = class {
|
|
|
397
494
|
this._windowSpec(opts.partitionBy, opts.orderBy)
|
|
398
495
|
);
|
|
399
496
|
}
|
|
497
|
+
/**
|
|
498
|
+
* Return the last value of this attribute in the window frame.
|
|
499
|
+
* Use `partitionBy` to restart the frame for each group.
|
|
500
|
+
*/
|
|
400
501
|
last(opts = {}) {
|
|
401
502
|
return new WindowFunctionOperation(
|
|
402
|
-
|
|
503
|
+
this.cwj(),
|
|
403
504
|
"LAST_VALUE" /* LAST_VALUE */,
|
|
404
505
|
"Last " + this._displayName,
|
|
405
506
|
void 0,
|
|
@@ -494,209 +595,233 @@ function parseDate(value) {
|
|
|
494
595
|
return d;
|
|
495
596
|
}
|
|
496
597
|
var DateAttribute = class extends Attribute {
|
|
497
|
-
constructor(displayName, columnName, columnDbType, owner, parent) {
|
|
498
|
-
super(displayName, columnName, columnDbType, owner, parent);
|
|
598
|
+
constructor(displayName, columnName, columnDbType, owner, parent, embedded) {
|
|
599
|
+
super(displayName, columnName, columnDbType, owner, parent, embedded);
|
|
499
600
|
}
|
|
601
|
+
/** Filter to rows where this date equals `value`. */
|
|
500
602
|
eq(value) {
|
|
501
603
|
return new ComparisonOperation(this.cwj(), "EQUAL" /* EQUAL */, new DateConstantOperation(parseDate(value)));
|
|
502
604
|
}
|
|
605
|
+
/** Filter to rows where this date does not equal `value`. */
|
|
503
606
|
ne(value) {
|
|
504
607
|
return new ComparisonOperation(this.cwj(), "NOT_EQUAL" /* NOT_EQUAL */, new DateConstantOperation(parseDate(value)));
|
|
505
608
|
}
|
|
609
|
+
/** Filter to rows where this date is after `value`. */
|
|
506
610
|
gt(value) {
|
|
507
611
|
return new ComparisonOperation(this.cwj(), "GREATER_THAN" /* GREATER_THAN */, new DateConstantOperation(parseDate(value)));
|
|
508
612
|
}
|
|
613
|
+
/** Filter to rows where this date is before `value`. */
|
|
509
614
|
lt(value) {
|
|
510
615
|
return new ComparisonOperation(this.cwj(), "LESS_THAN" /* LESS_THAN */, new DateConstantOperation(parseDate(value)));
|
|
511
616
|
}
|
|
617
|
+
/** Filter to rows where this date is on or after `value`. */
|
|
512
618
|
gte(value) {
|
|
513
619
|
return new ComparisonOperation(this.cwj(), "GREATER_THAN_OR_EQUAL_TO" /* GREATER_THAN_OR_EQUAL_TO */, new DateConstantOperation(parseDate(value)));
|
|
514
620
|
}
|
|
621
|
+
/** Filter to rows where this date is on or before `value`. */
|
|
515
622
|
lte(value) {
|
|
516
623
|
return new ComparisonOperation(this.cwj(), "LESS_THAN_OR_EQUAL_TO" /* LESS_THAN_OR_EQUAL_TO */, new DateConstantOperation(parseDate(value)));
|
|
517
624
|
}
|
|
625
|
+
/** Extract the four-digit calendar year. */
|
|
518
626
|
year() {
|
|
519
627
|
return new DateExtractOperation(this.cwj(), "YEAR" /* YEAR */, "Year " + this.displayName());
|
|
520
628
|
}
|
|
629
|
+
/** Extract the month number (1–12). */
|
|
521
630
|
month() {
|
|
522
631
|
return new DateExtractOperation(this.cwj(), "MONTH" /* MONTH */, "Month " + this.displayName());
|
|
523
632
|
}
|
|
633
|
+
/** Extract the day of the month (1–31). */
|
|
524
634
|
day() {
|
|
525
635
|
return new DateExtractOperation(this.cwj(), "DAY" /* DAY */, "Day " + this.displayName());
|
|
526
636
|
}
|
|
637
|
+
/** Extract the quarter (1–4). */
|
|
527
638
|
quarter() {
|
|
528
639
|
return new DateExtractOperation(this.cwj(), "QUARTER" /* QUARTER */, "Quarter " + this.displayName());
|
|
529
640
|
}
|
|
641
|
+
/** Extract the ISO week number (1–53). */
|
|
530
642
|
week() {
|
|
531
643
|
return new DateExtractOperation(this.cwj(), "WEEK" /* WEEK */, "Week " + this.displayName());
|
|
532
644
|
}
|
|
645
|
+
/** Extract the day of the week (0 = Sunday through 6 = Saturday). */
|
|
533
646
|
dayOfWeek() {
|
|
534
647
|
return new DateExtractOperation(this.cwj(), "DOW" /* DOW */, "Day Of Week " + this.displayName());
|
|
535
648
|
}
|
|
649
|
+
/** Add `n` days to this date. */
|
|
536
650
|
addDays(n) {
|
|
537
651
|
return new DateArithmeticOperation(this.cwj(), n, "DAY" /* DAY */, true, "Add Days " + this.displayName());
|
|
538
652
|
}
|
|
653
|
+
/** Add `n` months to this date. */
|
|
539
654
|
addMonths(n) {
|
|
540
655
|
return new DateArithmeticOperation(this.cwj(), n, "MONTH" /* MONTH */, true, "Add Months " + this.displayName());
|
|
541
656
|
}
|
|
657
|
+
/** Add `n` years to this date. */
|
|
542
658
|
addYears(n) {
|
|
543
659
|
return new DateArithmeticOperation(this.cwj(), n, "YEAR" /* YEAR */, true, "Add Years " + this.displayName());
|
|
544
660
|
}
|
|
661
|
+
/** Subtract `n` days from this date. */
|
|
545
662
|
subtractDays(n) {
|
|
546
663
|
return new DateArithmeticOperation(this.cwj(), n, "DAY" /* DAY */, false, "Subtract Days " + this.displayName());
|
|
547
664
|
}
|
|
665
|
+
/** Subtract `n` months from this date. */
|
|
548
666
|
subtractMonths(n) {
|
|
549
667
|
return new DateArithmeticOperation(this.cwj(), n, "MONTH" /* MONTH */, false, "Subtract Months " + this.displayName());
|
|
550
668
|
}
|
|
669
|
+
/** Subtract `n` years from this date. */
|
|
551
670
|
subtractYears(n) {
|
|
552
671
|
return new DateArithmeticOperation(this.cwj(), n, "YEAR" /* YEAR */, false, "Subtract Years " + this.displayName());
|
|
553
672
|
}
|
|
673
|
+
/** Number of whole days between this date and `other`. */
|
|
554
674
|
diffDays(other) {
|
|
555
675
|
return new DateDiffOperation(this.cwj(), other, "DAY" /* DAY */, "Diff Days " + this.displayName());
|
|
556
676
|
}
|
|
677
|
+
/** Number of whole months between this date and `other`. */
|
|
557
678
|
diffMonths(other) {
|
|
558
679
|
return new DateDiffOperation(this.cwj(), other, "MONTH" /* MONTH */, "Diff Months " + this.displayName());
|
|
559
680
|
}
|
|
681
|
+
/** Number of whole years between this date and `other`. */
|
|
560
682
|
diffYears(other) {
|
|
561
683
|
return new DateDiffOperation(this.cwj(), other, "YEAR" /* YEAR */, "Diff Years " + this.displayName());
|
|
562
684
|
}
|
|
563
685
|
};
|
|
564
686
|
var DateTimeAttribute = class extends Attribute {
|
|
565
|
-
constructor(displayName, columnName, columnDbType, owner, parent) {
|
|
566
|
-
super(displayName, columnName, columnDbType, owner, parent);
|
|
687
|
+
constructor(displayName, columnName, columnDbType, owner, parent, embedded) {
|
|
688
|
+
super(displayName, columnName, columnDbType, owner, parent, embedded);
|
|
567
689
|
}
|
|
690
|
+
/** Filter to rows where this timestamp equals `value`. */
|
|
568
691
|
eq(value) {
|
|
569
692
|
return new ComparisonOperation(this.cwj(), "EQUAL" /* EQUAL */, new DateTimeConstantOperation(parseDate(value)));
|
|
570
693
|
}
|
|
694
|
+
/** Filter to rows where this timestamp does not equal `value`. */
|
|
571
695
|
ne(value) {
|
|
572
696
|
return new ComparisonOperation(this.cwj(), "NOT_EQUAL" /* NOT_EQUAL */, new DateTimeConstantOperation(parseDate(value)));
|
|
573
697
|
}
|
|
698
|
+
/** Filter to rows where this timestamp is after `value`. */
|
|
574
699
|
gt(value) {
|
|
575
700
|
return new ComparisonOperation(this.cwj(), "GREATER_THAN" /* GREATER_THAN */, new DateTimeConstantOperation(parseDate(value)));
|
|
576
701
|
}
|
|
702
|
+
/** Filter to rows where this timestamp is before `value`. */
|
|
577
703
|
lt(value) {
|
|
578
704
|
return new ComparisonOperation(this.cwj(), "LESS_THAN" /* LESS_THAN */, new DateTimeConstantOperation(parseDate(value)));
|
|
579
705
|
}
|
|
706
|
+
/** Filter to rows where this timestamp is on or after `value`. */
|
|
580
707
|
gte(value) {
|
|
581
708
|
return new ComparisonOperation(this.cwj(), "GREATER_THAN_OR_EQUAL_TO" /* GREATER_THAN_OR_EQUAL_TO */, new DateTimeConstantOperation(parseDate(value)));
|
|
582
709
|
}
|
|
710
|
+
/** Filter to rows where this timestamp is on or before `value`. */
|
|
583
711
|
lte(value) {
|
|
584
712
|
return new ComparisonOperation(this.cwj(), "LESS_THAN_OR_EQUAL_TO" /* LESS_THAN_OR_EQUAL_TO */, new DateTimeConstantOperation(parseDate(value)));
|
|
585
713
|
}
|
|
714
|
+
/** Extract the four-digit calendar year. */
|
|
586
715
|
year() {
|
|
587
716
|
return new DateExtractOperation(this.cwj(), "YEAR" /* YEAR */, "Year " + this.displayName());
|
|
588
717
|
}
|
|
718
|
+
/** Extract the month number (1–12). */
|
|
589
719
|
month() {
|
|
590
720
|
return new DateExtractOperation(this.cwj(), "MONTH" /* MONTH */, "Month " + this.displayName());
|
|
591
721
|
}
|
|
722
|
+
/** Extract the day of the month (1–31). */
|
|
592
723
|
day() {
|
|
593
724
|
return new DateExtractOperation(this.cwj(), "DAY" /* DAY */, "Day " + this.displayName());
|
|
594
725
|
}
|
|
726
|
+
/** Extract the hour (0–23). */
|
|
595
727
|
hour() {
|
|
596
728
|
return new DateExtractOperation(this.cwj(), "HOUR" /* HOUR */, "Hour " + this.displayName());
|
|
597
729
|
}
|
|
730
|
+
/** Extract the minute (0–59). */
|
|
598
731
|
minute() {
|
|
599
732
|
return new DateExtractOperation(this.cwj(), "MINUTE" /* MINUTE */, "Minute " + this.displayName());
|
|
600
733
|
}
|
|
734
|
+
/** Extract the second (0–59). */
|
|
601
735
|
second() {
|
|
602
736
|
return new DateExtractOperation(this.cwj(), "SECOND" /* SECOND */, "Second " + this.displayName());
|
|
603
737
|
}
|
|
738
|
+
/** Extract the quarter (1–4). */
|
|
604
739
|
quarter() {
|
|
605
740
|
return new DateExtractOperation(this.cwj(), "QUARTER" /* QUARTER */, "Quarter " + this.displayName());
|
|
606
741
|
}
|
|
742
|
+
/** Extract the ISO week number (1–53). */
|
|
607
743
|
week() {
|
|
608
744
|
return new DateExtractOperation(this.cwj(), "WEEK" /* WEEK */, "Week " + this.displayName());
|
|
609
745
|
}
|
|
746
|
+
/** Extract the day of the week (0 = Sunday through 6 = Saturday). */
|
|
610
747
|
dayOfWeek() {
|
|
611
748
|
return new DateExtractOperation(this.cwj(), "DOW" /* DOW */, "Day Of Week " + this.displayName());
|
|
612
749
|
}
|
|
750
|
+
/** Add `n` days to this timestamp. */
|
|
613
751
|
addDays(n) {
|
|
614
752
|
return new DateArithmeticOperation(this.cwj(), n, "DAY" /* DAY */, true, "Add Days " + this.displayName());
|
|
615
753
|
}
|
|
754
|
+
/** Add `n` months to this timestamp. */
|
|
616
755
|
addMonths(n) {
|
|
617
756
|
return new DateArithmeticOperation(this.cwj(), n, "MONTH" /* MONTH */, true, "Add Months " + this.displayName());
|
|
618
757
|
}
|
|
758
|
+
/** Add `n` years to this timestamp. */
|
|
619
759
|
addYears(n) {
|
|
620
760
|
return new DateArithmeticOperation(this.cwj(), n, "YEAR" /* YEAR */, true, "Add Years " + this.displayName());
|
|
621
761
|
}
|
|
762
|
+
/** Add `n` hours to this timestamp. */
|
|
622
763
|
addHours(n) {
|
|
623
764
|
return new DateArithmeticOperation(this.cwj(), n, "HOUR" /* HOUR */, true, "Add Hours " + this.displayName());
|
|
624
765
|
}
|
|
766
|
+
/** Add `n` minutes to this timestamp. */
|
|
625
767
|
addMinutes(n) {
|
|
626
768
|
return new DateArithmeticOperation(this.cwj(), n, "MINUTE" /* MINUTE */, true, "Add Minutes " + this.displayName());
|
|
627
769
|
}
|
|
770
|
+
/** Add `n` seconds to this timestamp. */
|
|
628
771
|
addSeconds(n) {
|
|
629
772
|
return new DateArithmeticOperation(this.cwj(), n, "SECOND" /* SECOND */, true, "Add Seconds " + this.displayName());
|
|
630
773
|
}
|
|
774
|
+
/** Subtract `n` days from this timestamp. */
|
|
631
775
|
subtractDays(n) {
|
|
632
776
|
return new DateArithmeticOperation(this.cwj(), n, "DAY" /* DAY */, false, "Subtract Days " + this.displayName());
|
|
633
777
|
}
|
|
778
|
+
/** Subtract `n` months from this timestamp. */
|
|
634
779
|
subtractMonths(n) {
|
|
635
780
|
return new DateArithmeticOperation(this.cwj(), n, "MONTH" /* MONTH */, false, "Subtract Months " + this.displayName());
|
|
636
781
|
}
|
|
782
|
+
/** Subtract `n` years from this timestamp. */
|
|
637
783
|
subtractYears(n) {
|
|
638
784
|
return new DateArithmeticOperation(this.cwj(), n, "YEAR" /* YEAR */, false, "Subtract Years " + this.displayName());
|
|
639
785
|
}
|
|
786
|
+
/** Subtract `n` hours from this timestamp. */
|
|
640
787
|
subtractHours(n) {
|
|
641
788
|
return new DateArithmeticOperation(this.cwj(), n, "HOUR" /* HOUR */, false, "Subtract Hours " + this.displayName());
|
|
642
789
|
}
|
|
790
|
+
/** Subtract `n` minutes from this timestamp. */
|
|
643
791
|
subtractMinutes(n) {
|
|
644
792
|
return new DateArithmeticOperation(this.cwj(), n, "MINUTE" /* MINUTE */, false, "Subtract Minutes " + this.displayName());
|
|
645
793
|
}
|
|
794
|
+
/** Subtract `n` seconds from this timestamp. */
|
|
646
795
|
subtractSeconds(n) {
|
|
647
796
|
return new DateArithmeticOperation(this.cwj(), n, "SECOND" /* SECOND */, false, "Subtract Seconds " + this.displayName());
|
|
648
797
|
}
|
|
798
|
+
/** Number of whole days between this timestamp and `other`. */
|
|
649
799
|
diffDays(other) {
|
|
650
800
|
return new DateDiffOperation(this.cwj(), other, "DAY" /* DAY */, "Diff Days " + this.displayName());
|
|
651
801
|
}
|
|
802
|
+
/** Number of whole months between this timestamp and `other`. */
|
|
652
803
|
diffMonths(other) {
|
|
653
804
|
return new DateDiffOperation(this.cwj(), other, "MONTH" /* MONTH */, "Diff Months " + this.displayName());
|
|
654
805
|
}
|
|
806
|
+
/** Number of whole years between this timestamp and `other`. */
|
|
655
807
|
diffYears(other) {
|
|
656
808
|
return new DateDiffOperation(this.cwj(), other, "YEAR" /* YEAR */, "Diff Years " + this.displayName());
|
|
657
809
|
}
|
|
810
|
+
/** Number of whole hours between this timestamp and `other`. */
|
|
658
811
|
diffHours(other) {
|
|
659
812
|
return new DateDiffOperation(this.cwj(), other, "HOUR" /* HOUR */, "Diff Hours " + this.displayName());
|
|
660
813
|
}
|
|
814
|
+
/** Number of whole minutes between this timestamp and `other`. */
|
|
661
815
|
diffMinutes(other) {
|
|
662
816
|
return new DateDiffOperation(this.cwj(), other, "MINUTE" /* MINUTE */, "Diff Minutes " + this.displayName());
|
|
663
817
|
}
|
|
818
|
+
/** Number of whole seconds between this timestamp and `other`. */
|
|
664
819
|
diffSeconds(other) {
|
|
665
820
|
return new DateDiffOperation(this.cwj(), other, "SECOND" /* SECOND */, "Diff Seconds " + this.displayName());
|
|
666
821
|
}
|
|
667
822
|
};
|
|
668
823
|
|
|
669
|
-
// src/datafinder/finder.ts
|
|
670
|
-
var ExistsOperation = class extends RelationalOperationElement {
|
|
671
|
-
constructor(node) {
|
|
672
|
-
super();
|
|
673
|
-
this.node = node;
|
|
674
|
-
}
|
|
675
|
-
node;
|
|
676
|
-
andOp(other) {
|
|
677
|
-
return new LogicalOperation(this, "AND" /* AND */, other);
|
|
678
|
-
}
|
|
679
|
-
};
|
|
680
|
-
var NotExistsOperation = class extends RelationalOperationElement {
|
|
681
|
-
constructor(node) {
|
|
682
|
-
super();
|
|
683
|
-
this.node = node;
|
|
684
|
-
}
|
|
685
|
-
node;
|
|
686
|
-
andOp(other) {
|
|
687
|
-
return new LogicalOperation(this, "AND" /* AND */, other);
|
|
688
|
-
}
|
|
689
|
-
};
|
|
690
|
-
|
|
691
824
|
// src/datafinder/sql-generator.ts
|
|
692
|
-
var Alias = class {
|
|
693
|
-
constructor(element, name) {
|
|
694
|
-
this.element = element;
|
|
695
|
-
this.name = name;
|
|
696
|
-
}
|
|
697
|
-
element;
|
|
698
|
-
name;
|
|
699
|
-
};
|
|
700
825
|
var TableAlias = class {
|
|
701
826
|
constructor(table, alias) {
|
|
702
827
|
this.table = table;
|
|
@@ -724,22 +849,6 @@ var Join = class {
|
|
|
724
849
|
target;
|
|
725
850
|
filterOp;
|
|
726
851
|
};
|
|
727
|
-
var SelectOperation = class {
|
|
728
|
-
constructor(display, filter, orderBy = [], groupBy = [], limit, table) {
|
|
729
|
-
this.display = display;
|
|
730
|
-
this.filter = filter;
|
|
731
|
-
this.orderBy = orderBy;
|
|
732
|
-
this.groupBy = groupBy;
|
|
733
|
-
this.limit = limit;
|
|
734
|
-
this.table = table;
|
|
735
|
-
}
|
|
736
|
-
display;
|
|
737
|
-
filter;
|
|
738
|
-
orderBy;
|
|
739
|
-
groupBy;
|
|
740
|
-
limit;
|
|
741
|
-
table;
|
|
742
|
-
};
|
|
743
852
|
function sqlFormatDatetime(value) {
|
|
744
853
|
const pad = (n, w = 2) => String(n).padStart(w, "0");
|
|
745
854
|
return `'${value.getUTCFullYear()}-${pad(value.getUTCMonth() + 1)}-${pad(value.getUTCDate())} ${pad(value.getUTCHours())}:${pad(value.getUTCMinutes())}:${pad(value.getUTCSeconds())}'`;
|
|
@@ -871,6 +980,9 @@ function sqlOperationToString(operation) {
|
|
|
871
980
|
}
|
|
872
981
|
throw new TypeError("Unknown operation in sqlOperationToString: " + operation.constructor.name);
|
|
873
982
|
}
|
|
983
|
+
function embeddedOf(ref) {
|
|
984
|
+
return ref instanceof Attribute ? ref.embedded() : ref.embedded;
|
|
985
|
+
}
|
|
874
986
|
function findColumn(operation) {
|
|
875
987
|
if (operation instanceof UnaryOperation) return findColumn(operation.element);
|
|
876
988
|
if (operation instanceof ColumnWithJoin) return operation;
|
|
@@ -920,38 +1032,125 @@ function buildMilestoningFilterOperation(businessDate, processingDatetime, table
|
|
|
920
1032
|
if (ops.length === 1) return ops[0];
|
|
921
1033
|
return new LogicalOperation(ops[0], "AND" /* AND */, ops[1]);
|
|
922
1034
|
}
|
|
923
|
-
function
|
|
1035
|
+
function buildMilestoningFilterOperationForDateRange(businessDateFrom, businessDateTo, processingDatetime, table, joinNode) {
|
|
1036
|
+
const mc = table.milestoningColumns;
|
|
1037
|
+
const ops = [];
|
|
1038
|
+
const hasRange = businessDateFrom !== null && businessDateTo !== null;
|
|
1039
|
+
const processingOp = (m) => {
|
|
1040
|
+
const startAt = new DateTimeAttribute("start_at", m.startAtColumn.name, m.startAtColumn.type, m.startAtColumn.table.qualifiedName, joinNode);
|
|
1041
|
+
const endAt = new DateTimeAttribute("end_at", m.endAtColumn.name, m.endAtColumn.type, m.endAtColumn.table.qualifiedName, joinNode);
|
|
1042
|
+
return new LogicalOperation(startAt.lte(processingDatetime), "AND" /* AND */, openEndClause(endAt, processingDatetime, m.infiniteDatetime));
|
|
1043
|
+
};
|
|
1044
|
+
if (mc instanceof BiTemporalColumns) {
|
|
1045
|
+
if (hasRange) {
|
|
1046
|
+
const dateFrom = new DateAttribute("business_date_from", mc.businessDateFromColumn.name, mc.businessDateFromColumn.type, mc.businessDateFromColumn.table.qualifiedName, joinNode);
|
|
1047
|
+
const dateTo = new DateAttribute("business_date_to", mc.businessDateToColumn.name, mc.businessDateToColumn.type, mc.businessDateToColumn.table.qualifiedName, joinNode);
|
|
1048
|
+
ops.push(new LogicalOperation(dateFrom.lte(businessDateTo), "AND" /* AND */, openEndClause(dateTo, businessDateFrom, mc.infiniteDatetime)));
|
|
1049
|
+
}
|
|
1050
|
+
if (processingDatetime !== null) ops.push(processingOp(mc));
|
|
1051
|
+
} else if (mc instanceof BusinessDateAndProcessingTemporalColumns) {
|
|
1052
|
+
if (hasRange) {
|
|
1053
|
+
const businessAtt = new DateAttribute("business_date", mc.businessDateColumn.name, mc.businessDateColumn.type, mc.businessDateColumn.table.qualifiedName, joinNode);
|
|
1054
|
+
ops.push(new LogicalOperation(businessAtt.gte(businessDateFrom), "AND" /* AND */, businessAtt.lte(businessDateTo)));
|
|
1055
|
+
}
|
|
1056
|
+
if (processingDatetime !== null) ops.push(processingOp(mc));
|
|
1057
|
+
} else if (mc instanceof ProcessingTemporalColumns) {
|
|
1058
|
+
if (processingDatetime !== null) ops.push(processingOp(mc));
|
|
1059
|
+
} else if (mc instanceof SingleBusinessDateColumn && hasRange) {
|
|
1060
|
+
const businessAtt = new DateAttribute("business_date", mc.businessDateColumn.name, mc.businessDateColumn.type, mc.businessDateColumn.table.qualifiedName, joinNode);
|
|
1061
|
+
ops.push(new LogicalOperation(businessAtt.gte(businessDateFrom), "AND" /* AND */, businessAtt.lte(businessDateTo)));
|
|
1062
|
+
}
|
|
1063
|
+
if (ops.length === 0) return null;
|
|
1064
|
+
if (ops.length === 1) return ops[0];
|
|
1065
|
+
return new LogicalOperation(ops[0], "AND" /* AND */, ops[1]);
|
|
1066
|
+
}
|
|
1067
|
+
function walkRefs(op, visit, visitExists) {
|
|
1068
|
+
if (op === null || op === void 0) return;
|
|
1069
|
+
if (op instanceof Attribute || op instanceof ColumnWithJoin) {
|
|
1070
|
+
visit(op);
|
|
1071
|
+
} else if (op instanceof ExistsOperation || op instanceof NotExistsOperation) {
|
|
1072
|
+
visitExists?.(op.node);
|
|
1073
|
+
} else if (op instanceof AggregateOperation) {
|
|
1074
|
+
walkRefs(op.element, visit, visitExists);
|
|
1075
|
+
if (op.window) walkWindowSpec(op.window, visit, visitExists);
|
|
1076
|
+
} else if (op instanceof WindowFunctionOperation) {
|
|
1077
|
+
if (op.element) walkRefs(op.element, visit, visitExists);
|
|
1078
|
+
if (op.window) walkWindowSpec(op.window, visit, visitExists);
|
|
1079
|
+
} else if (op instanceof ScalarFunctionOperation || op instanceof DateExtractOperation || op instanceof DateArithmeticOperation || op instanceof DateDiffOperation || op instanceof IsNullOperation || op instanceof IsNotNullOperation) {
|
|
1080
|
+
walkRefs(op.element, visit, visitExists);
|
|
1081
|
+
} else if (op instanceof SortOperation) {
|
|
1082
|
+
walkRefs(op.column, visit, visitExists);
|
|
1083
|
+
} else if (op instanceof LogicalOperation || op instanceof ComparisonOperation) {
|
|
1084
|
+
walkRefs(op.left, visit, visitExists);
|
|
1085
|
+
walkRefs(op.right, visit, visitExists);
|
|
1086
|
+
}
|
|
1087
|
+
}
|
|
1088
|
+
function walkWindowSpec(window, visit, visitExists) {
|
|
1089
|
+
for (const p of window.partitionBy) walkRefs(p, visit, visitExists);
|
|
1090
|
+
for (const s of window.orderBy) walkRefs(s.column, visit, visitExists);
|
|
1091
|
+
}
|
|
1092
|
+
function buildJoinFilterFromProperties(node, filter, columnMap) {
|
|
1093
|
+
const ops = [];
|
|
1094
|
+
for (const [key, value] of Object.entries(filter)) {
|
|
1095
|
+
const entry = columnMap[key];
|
|
1096
|
+
if (entry === void 0) {
|
|
1097
|
+
throw new Error(`Unknown property '${key}' \u2014 valid properties are: ${Object.keys(columnMap).sort().join(", ")}`);
|
|
1098
|
+
}
|
|
1099
|
+
const [name, type, table] = entry;
|
|
1100
|
+
const col = new ColumnWithJoin(new Column(name, type, table), node);
|
|
1101
|
+
let constant;
|
|
1102
|
+
if (typeof value === "boolean") constant = new BooleanConstantOperation(value);
|
|
1103
|
+
else if (typeof value === "number") constant = Number.isInteger(value) ? new IntegerConstantOperation(value) : new FloatConstantOperation(value);
|
|
1104
|
+
else if (value instanceof Date) constant = type.toUpperCase() === "DATE" ? new DateConstantOperation(value) : new DateTimeConstantOperation(value);
|
|
1105
|
+
else constant = new StringConstantOperation(String(value));
|
|
1106
|
+
ops.push(new ComparisonOperation(col, "EQUAL" /* EQUAL */, constant));
|
|
1107
|
+
}
|
|
1108
|
+
return ops.reduce((acc, op) => new LogicalOperation(acc, "AND" /* AND */, op));
|
|
1109
|
+
}
|
|
1110
|
+
function withAncestors(nodes) {
|
|
1111
|
+
const ordered = /* @__PURE__ */ new Set();
|
|
1112
|
+
const add = (node) => {
|
|
1113
|
+
if (ordered.has(node)) return;
|
|
1114
|
+
if (node.parent !== void 0) add(node.parent);
|
|
1115
|
+
ordered.add(node);
|
|
1116
|
+
};
|
|
1117
|
+
for (const node of nodes) add(node);
|
|
1118
|
+
return [...ordered];
|
|
1119
|
+
}
|
|
1120
|
+
function buildQueryOperation(businessDate, processingDatetime, columns, table, op, orderBy = [], groupBy = [], limit, businessDateTo = null) {
|
|
924
1121
|
let filter = op;
|
|
1122
|
+
const milestoningFor = (t, node) => businessDateTo !== null ? buildMilestoningFilterOperationForDateRange(businessDate, businessDateTo, processingDatetime, t, node) : buildMilestoningFilterOperation(businessDate, processingDatetime, t, node);
|
|
925
1123
|
if (table instanceof MilestonedTable) {
|
|
926
|
-
const milestonedOp =
|
|
1124
|
+
const milestonedOp = milestoningFor(table);
|
|
927
1125
|
if (milestonedOp !== null) {
|
|
928
1126
|
filter = filter instanceof NoOperation ? milestonedOp : new LogicalOperation(filter, "AND" /* AND */, milestonedOp);
|
|
929
1127
|
}
|
|
930
1128
|
}
|
|
931
|
-
const requiredJoins =
|
|
932
|
-
const
|
|
933
|
-
|
|
934
|
-
if (
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
1129
|
+
const requiredJoins = /* @__PURE__ */ new Set();
|
|
1130
|
+
const collect = (ref) => {
|
|
1131
|
+
const parent = ref instanceof Attribute ? ref.parent() : ref.parent;
|
|
1132
|
+
if (parent !== void 0) requiredJoins.add(parent);
|
|
1133
|
+
};
|
|
1134
|
+
const collectNode = (node) => requiredJoins.add(node);
|
|
1135
|
+
for (const col of columns) walkRefs(col, collect, collectNode);
|
|
1136
|
+
for (const expr of groupBy) walkRefs(expr, collect, collectNode);
|
|
1137
|
+
for (const sort of orderBy) walkRefs(sort, collect, collectNode);
|
|
1138
|
+
walkRefs(op, collect, collectNode);
|
|
1139
|
+
const joinFilters = /* @__PURE__ */ new Map();
|
|
1140
|
+
for (const node of withAncestors(requiredJoins)) {
|
|
1141
|
+
let combined;
|
|
1142
|
+
if (Object.keys(node.join.filterKwargs).length > 0) {
|
|
1143
|
+
combined = buildJoinFilterFromProperties(node, node.join.filterKwargs, node.join.filterColumnMap);
|
|
940
1144
|
}
|
|
941
|
-
if (node !== void 0 && !requiredJoinIds.has(node)) {
|
|
942
|
-
requiredJoinIds.add(node);
|
|
943
|
-
requiredJoins.push(node);
|
|
944
|
-
}
|
|
945
|
-
}
|
|
946
|
-
for (const node of requiredJoins) {
|
|
947
1145
|
if (node.join.target instanceof MilestonedTable) {
|
|
948
|
-
const milestonedOp =
|
|
1146
|
+
const milestonedOp = milestoningFor(node.join.target, node);
|
|
949
1147
|
if (milestonedOp !== null) {
|
|
950
|
-
|
|
1148
|
+
combined = combined === void 0 ? milestonedOp : new LogicalOperation(combined, "AND" /* AND */, milestonedOp);
|
|
951
1149
|
}
|
|
952
1150
|
}
|
|
1151
|
+
if (combined !== void 0) joinFilters.set(node, combined);
|
|
953
1152
|
}
|
|
954
|
-
return new SelectOperation(columns, filter, orderBy, groupBy, limit, table);
|
|
1153
|
+
return new SelectOperation(columns, filter, orderBy, groupBy, limit, table, joinFilters);
|
|
955
1154
|
}
|
|
956
1155
|
var SQLQueryGenerator = class {
|
|
957
1156
|
_select = [];
|
|
@@ -965,8 +1164,12 @@ var SQLQueryGenerator = class {
|
|
|
965
1164
|
_tableAliasesByTable = /* @__PURE__ */ new Map();
|
|
966
1165
|
_addedJoinIds = /* @__PURE__ */ new Set();
|
|
967
1166
|
_rootTable;
|
|
1167
|
+
_elidableNodes = /* @__PURE__ */ new Set();
|
|
1168
|
+
_joinFilters = /* @__PURE__ */ new Map();
|
|
968
1169
|
generate(select) {
|
|
969
1170
|
this._rootTable = select.table;
|
|
1171
|
+
this._elidableNodes = this._computeElidableNodes(select);
|
|
1172
|
+
this._joinFilters = select.joinFilters;
|
|
970
1173
|
if (this._rootTable !== void 0) {
|
|
971
1174
|
this._from.add(this._tableAliasForTable(this._rootTable.qualifiedName, this._rootTable.qualifiedName));
|
|
972
1175
|
}
|
|
@@ -986,39 +1189,49 @@ var SQLQueryGenerator = class {
|
|
|
986
1189
|
this._limit = select.limit;
|
|
987
1190
|
}
|
|
988
1191
|
_attrToColString(attr) {
|
|
989
|
-
const
|
|
990
|
-
const ta = this._tableAliasForTable(
|
|
991
|
-
return ta.alias + "." +
|
|
1192
|
+
const { column, parent } = this._resolve(attr);
|
|
1193
|
+
const ta = this._tableAliasForTable(column.owner, parent ?? column.owner);
|
|
1194
|
+
return ta.alias + "." + column.name;
|
|
992
1195
|
}
|
|
993
1196
|
_collectRequiredJoins(op, out) {
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1197
|
+
walkRefs(op, (ref) => {
|
|
1198
|
+
const { parent } = this._resolve(ref);
|
|
1199
|
+
if (parent !== void 0) out.set(parent, parent);
|
|
1200
|
+
});
|
|
1201
|
+
}
|
|
1202
|
+
/**
|
|
1203
|
+
* Determine upfront which join nodes can be satisfied entirely by embedded (join-less) alternates:
|
|
1204
|
+
* a node is elidable when every reference to it has an embedded alternate. A reference without one
|
|
1205
|
+
* (e.g. a milestoning column) keeps the join for every reference to that node.
|
|
1206
|
+
*/
|
|
1207
|
+
_computeElidableNodes(select) {
|
|
1208
|
+
const refsByNode = /* @__PURE__ */ new Map();
|
|
1209
|
+
const record = (ref) => {
|
|
1210
|
+
const parent = ref instanceof Attribute ? ref.parent() : ref.parent;
|
|
1211
|
+
if (parent === void 0) return;
|
|
1212
|
+
const refs = refsByNode.get(parent);
|
|
1213
|
+
if (refs) refs.push(ref);
|
|
1214
|
+
else refsByNode.set(parent, [ref]);
|
|
1215
|
+
};
|
|
1216
|
+
for (const col of select.display) walkRefs(col, record);
|
|
1217
|
+
for (const expr of select.groupBy) walkRefs(expr, record);
|
|
1218
|
+
for (const sort of select.orderBy) walkRefs(sort, record);
|
|
1219
|
+
walkRefs(select.filter, record);
|
|
1220
|
+
const elidable = /* @__PURE__ */ new Set();
|
|
1221
|
+
for (const [node, refs] of refsByNode) {
|
|
1222
|
+
if (refs.every((ref) => embeddedOf(ref) !== void 0)) elidable.add(node);
|
|
1018
1223
|
}
|
|
1019
|
-
|
|
1020
|
-
|
|
1224
|
+
return elidable;
|
|
1225
|
+
}
|
|
1226
|
+
/** The (column, parent) a reference should resolve to, substituting its embedded alternate when its join is elided. */
|
|
1227
|
+
_resolve(ref) {
|
|
1228
|
+
const column = ref instanceof Attribute ? ref.column() : ref.column;
|
|
1229
|
+
const parent = ref instanceof Attribute ? ref.parent() : ref.parent;
|
|
1230
|
+
if (parent !== void 0 && this._elidableNodes.has(parent)) {
|
|
1231
|
+
const embedded = embeddedOf(ref);
|
|
1232
|
+
if (embedded !== void 0) return this._resolve(embedded);
|
|
1021
1233
|
}
|
|
1234
|
+
return { column, parent };
|
|
1022
1235
|
}
|
|
1023
1236
|
_rewriteWindowSpec(window) {
|
|
1024
1237
|
const partitionBy = window.partitionBy.map((p) => this._rewriteOperation(p));
|
|
@@ -1026,13 +1239,9 @@ var SQLQueryGenerator = class {
|
|
|
1026
1239
|
return new WindowSpecification(partitionBy, orderBy);
|
|
1027
1240
|
}
|
|
1028
1241
|
_rewriteOperation(op) {
|
|
1029
|
-
if (op instanceof Attribute) {
|
|
1030
|
-
const
|
|
1031
|
-
return new TableAliasColumn(
|
|
1032
|
-
}
|
|
1033
|
-
if (op instanceof ColumnWithJoin) {
|
|
1034
|
-
const ta = op.parent !== void 0 ? this._tableAliasForTable(op.column.owner, op.parent) : this._tableAliasForTable(op.column.owner, op.column.owner);
|
|
1035
|
-
return new TableAliasColumn(op.column, ta);
|
|
1242
|
+
if (op instanceof Attribute || op instanceof ColumnWithJoin) {
|
|
1243
|
+
const { column, parent } = this._resolve(op);
|
|
1244
|
+
return new TableAliasColumn(column, this._tableAliasForTable(column.owner, parent ?? column.owner));
|
|
1036
1245
|
}
|
|
1037
1246
|
if (op instanceof Column) {
|
|
1038
1247
|
const ta = this._tableAliasForTable(op.owner, op.owner);
|
|
@@ -1081,15 +1290,15 @@ var SQLQueryGenerator = class {
|
|
|
1081
1290
|
}
|
|
1082
1291
|
for (const col of cols) {
|
|
1083
1292
|
if (col instanceof Attribute) {
|
|
1084
|
-
const node =
|
|
1293
|
+
const { column, parent: node } = this._resolve(col);
|
|
1085
1294
|
let ta;
|
|
1086
1295
|
if (node !== void 0) {
|
|
1087
|
-
ta = this._tableAliasForTable(
|
|
1296
|
+
ta = this._tableAliasForTable(column.owner, node);
|
|
1088
1297
|
} else {
|
|
1089
|
-
ta = this._tableAliasForTable(
|
|
1298
|
+
ta = this._tableAliasForTable(column.owner, column.owner);
|
|
1090
1299
|
this._from.add(ta);
|
|
1091
1300
|
}
|
|
1092
|
-
this._select.push(new Alias(new TableAliasColumn(
|
|
1301
|
+
this._select.push(new Alias(new TableAliasColumn(column, ta), col.displayName()));
|
|
1093
1302
|
} else if (col instanceof WindowFunctionOperation) {
|
|
1094
1303
|
const rewritten = this._rewriteOperation(col);
|
|
1095
1304
|
let alias;
|
|
@@ -1104,7 +1313,7 @@ var SQLQueryGenerator = class {
|
|
|
1104
1313
|
}
|
|
1105
1314
|
this._select.push(new Alias(rewritten, alias));
|
|
1106
1315
|
} else if (col instanceof AggregateOperation) {
|
|
1107
|
-
const colNested = findColumn(col);
|
|
1316
|
+
const colNested = this._resolve(findColumn(col));
|
|
1108
1317
|
const node = colNested.parent;
|
|
1109
1318
|
let ta;
|
|
1110
1319
|
if (node !== void 0) {
|
|
@@ -1113,7 +1322,7 @@ var SQLQueryGenerator = class {
|
|
|
1113
1322
|
ta = this._tableAliasForTable(colNested.column.owner, colNested.column.owner);
|
|
1114
1323
|
this._from.add(ta);
|
|
1115
1324
|
}
|
|
1116
|
-
const alias = col.displayName ?? col.operator + " " +
|
|
1325
|
+
const alias = col.displayName ?? col.operator + " " + findColumn(col).column.name;
|
|
1117
1326
|
const rewrittenAgg = new AggregateOperation(
|
|
1118
1327
|
new TableAliasColumn(colNested.column, ta),
|
|
1119
1328
|
col.operator,
|
|
@@ -1122,7 +1331,7 @@ var SQLQueryGenerator = class {
|
|
|
1122
1331
|
);
|
|
1123
1332
|
this._select.push(new Alias(rewrittenAgg, alias));
|
|
1124
1333
|
} else if (col instanceof ScalarFunctionOperation) {
|
|
1125
|
-
const colNested = findColumn(col);
|
|
1334
|
+
const colNested = this._resolve(findColumn(col));
|
|
1126
1335
|
const node = colNested.parent;
|
|
1127
1336
|
let ta;
|
|
1128
1337
|
if (node !== void 0) {
|
|
@@ -1131,13 +1340,13 @@ var SQLQueryGenerator = class {
|
|
|
1131
1340
|
ta = this._tableAliasForTable(colNested.column.owner, colNested.column.owner);
|
|
1132
1341
|
this._from.add(ta);
|
|
1133
1342
|
}
|
|
1134
|
-
const alias = col.displayName ?? col.func + " " +
|
|
1343
|
+
const alias = col.displayName ?? col.func + " " + findColumn(col).column.name;
|
|
1135
1344
|
this._select.push(new Alias(
|
|
1136
1345
|
new ScalarFunctionOperation(new TableAliasColumn(colNested.column, ta), col.func, void 0, col.secondArg, col.extraArgs),
|
|
1137
1346
|
alias
|
|
1138
1347
|
));
|
|
1139
1348
|
} else if (col instanceof DateExtractOperation || col instanceof DateArithmeticOperation || col instanceof DateDiffOperation) {
|
|
1140
|
-
const colNested = findColumn(col);
|
|
1349
|
+
const colNested = this._resolve(findColumn(col));
|
|
1141
1350
|
const node = colNested.parent;
|
|
1142
1351
|
let ta;
|
|
1143
1352
|
if (node !== void 0) {
|
|
@@ -1146,7 +1355,7 @@ var SQLQueryGenerator = class {
|
|
|
1146
1355
|
ta = this._tableAliasForTable(colNested.column.owner, colNested.column.owner);
|
|
1147
1356
|
this._from.add(ta);
|
|
1148
1357
|
}
|
|
1149
|
-
const alias = col.displayName ??
|
|
1358
|
+
const alias = col.displayName ?? findColumn(col).column.name;
|
|
1150
1359
|
let aliasedOp;
|
|
1151
1360
|
if (col instanceof DateExtractOperation) {
|
|
1152
1361
|
aliasedOp = new DateExtractOperation(new TableAliasColumn(colNested.column, ta), col.part);
|
|
@@ -1174,7 +1383,9 @@ var SQLQueryGenerator = class {
|
|
|
1174
1383
|
const sc = new TableAliasColumn(left, srcTa);
|
|
1175
1384
|
const right = join.right;
|
|
1176
1385
|
const tc = new TableAliasColumn(right, this._tableAliasForTable(right.owner, node));
|
|
1177
|
-
this.
|
|
1386
|
+
const queryFilter = this._joinFilters.get(node);
|
|
1387
|
+
const filterOp = join.filter !== void 0 && queryFilter !== void 0 ? new LogicalOperation(join.filter, "AND" /* AND */, queryFilter) : join.filter ?? queryFilter;
|
|
1388
|
+
this._join.push(new Join(sc, tc, filterOp));
|
|
1178
1389
|
}
|
|
1179
1390
|
buildFilter(op) {
|
|
1180
1391
|
if (op instanceof NoOperation) return "";
|
|
@@ -1200,15 +1411,15 @@ var SQLQueryGenerator = class {
|
|
|
1200
1411
|
}
|
|
1201
1412
|
if (op instanceof ConstantOperation) return constantValueString(op);
|
|
1202
1413
|
if (op instanceof ColumnWithJoin) {
|
|
1203
|
-
const node = op
|
|
1414
|
+
const { column, parent: node } = this._resolve(op);
|
|
1204
1415
|
let ta;
|
|
1205
1416
|
if (node !== void 0) {
|
|
1206
|
-
ta = this._tableAliasForTable(
|
|
1417
|
+
ta = this._tableAliasForTable(column.owner, node);
|
|
1207
1418
|
this._addJoin(node);
|
|
1208
1419
|
} else {
|
|
1209
|
-
ta = this._tableAliasForTable(
|
|
1420
|
+
ta = this._tableAliasForTable(column.owner, column.owner);
|
|
1210
1421
|
}
|
|
1211
|
-
return ta.alias + "." +
|
|
1422
|
+
return ta.alias + "." + column.name;
|
|
1212
1423
|
}
|
|
1213
1424
|
if (op instanceof Column) {
|
|
1214
1425
|
const ta = this._tableAliasForTable(op.owner, op.owner);
|
|
@@ -1248,12 +1459,21 @@ function selectSqlToString(selectOperation) {
|
|
|
1248
1459
|
qg.generate(selectOperation);
|
|
1249
1460
|
return qg.buildQueryString();
|
|
1250
1461
|
}
|
|
1251
|
-
function toSql(businessDate, processingDatetime, columns, table, op, orderBy = [], groupBy = [], limit) {
|
|
1252
|
-
const selectOp = buildQueryOperation(businessDate, processingDatetime, columns, table, op, orderBy, groupBy, limit);
|
|
1462
|
+
function toSql(businessDate, processingDatetime, columns, table, op, orderBy = [], groupBy = [], limit, businessDateTo = null) {
|
|
1463
|
+
const selectOp = buildQueryOperation(businessDate, processingDatetime, columns, table, op, orderBy, groupBy, limit, businessDateTo);
|
|
1253
1464
|
return selectSqlToString(selectOp);
|
|
1254
1465
|
}
|
|
1255
1466
|
|
|
1256
1467
|
// src/datafinder/runner.ts
|
|
1468
|
+
var DEFAULT_TIMEOUT_MS = 6e4;
|
|
1469
|
+
var QueryTimeoutError = class extends Error {
|
|
1470
|
+
constructor(timeoutMs) {
|
|
1471
|
+
super(`Query exceeded ${timeoutMs}ms timeout`);
|
|
1472
|
+
this.timeoutMs = timeoutMs;
|
|
1473
|
+
this.name = "QueryTimeoutError";
|
|
1474
|
+
}
|
|
1475
|
+
timeoutMs;
|
|
1476
|
+
};
|
|
1257
1477
|
var _runner = null;
|
|
1258
1478
|
function registerRunner(runner) {
|
|
1259
1479
|
_runner = runner;
|
|
@@ -1266,21 +1486,24 @@ function getRunner() {
|
|
|
1266
1486
|
return _runner;
|
|
1267
1487
|
}
|
|
1268
1488
|
var FinderResult = class {
|
|
1269
|
-
constructor(_businessDate, _processingDatetime, _columns, _table, _op) {
|
|
1489
|
+
constructor(_businessDate, _processingDatetime, _columns, _table, _op, _businessDateTo = null) {
|
|
1270
1490
|
this._businessDate = _businessDate;
|
|
1271
1491
|
this._processingDatetime = _processingDatetime;
|
|
1272
1492
|
this._columns = _columns;
|
|
1273
1493
|
this._table = _table;
|
|
1274
1494
|
this._op = _op;
|
|
1495
|
+
this._businessDateTo = _businessDateTo;
|
|
1275
1496
|
}
|
|
1276
1497
|
_businessDate;
|
|
1277
1498
|
_processingDatetime;
|
|
1278
1499
|
_columns;
|
|
1279
1500
|
_table;
|
|
1280
1501
|
_op;
|
|
1502
|
+
_businessDateTo;
|
|
1281
1503
|
_orderBy = [];
|
|
1282
1504
|
_groupBy = [];
|
|
1283
1505
|
_limit;
|
|
1506
|
+
_timeoutMs = DEFAULT_TIMEOUT_MS;
|
|
1284
1507
|
orderByOp(...sorts) {
|
|
1285
1508
|
this._orderBy = sorts;
|
|
1286
1509
|
return this;
|
|
@@ -1293,6 +1516,11 @@ var FinderResult = class {
|
|
|
1293
1516
|
this._limit = n;
|
|
1294
1517
|
return this;
|
|
1295
1518
|
}
|
|
1519
|
+
/** Abort the query and throw QueryTimeoutError if it runs longer than `milliseconds` (default 60000). */
|
|
1520
|
+
timeout(milliseconds) {
|
|
1521
|
+
this._timeoutMs = milliseconds;
|
|
1522
|
+
return this;
|
|
1523
|
+
}
|
|
1296
1524
|
toSql() {
|
|
1297
1525
|
return toSql(
|
|
1298
1526
|
this._businessDate,
|
|
@@ -1302,7 +1530,8 @@ var FinderResult = class {
|
|
|
1302
1530
|
this._op,
|
|
1303
1531
|
this._orderBy,
|
|
1304
1532
|
this._groupBy,
|
|
1305
|
-
this._limit
|
|
1533
|
+
this._limit,
|
|
1534
|
+
this._businessDateTo
|
|
1306
1535
|
);
|
|
1307
1536
|
}
|
|
1308
1537
|
async toRows() {
|
|
@@ -1314,14 +1543,18 @@ var FinderResult = class {
|
|
|
1314
1543
|
this._op,
|
|
1315
1544
|
this._orderBy,
|
|
1316
1545
|
this._groupBy,
|
|
1317
|
-
this._limit
|
|
1546
|
+
this._limit,
|
|
1547
|
+
this._timeoutMs,
|
|
1548
|
+
this._businessDateTo
|
|
1318
1549
|
);
|
|
1319
1550
|
}
|
|
1320
1551
|
};
|
|
1321
1552
|
function convertDate(value) {
|
|
1322
1553
|
if (value === null) return null;
|
|
1323
1554
|
if (value instanceof Date) return value;
|
|
1324
|
-
|
|
1555
|
+
let normalized = value;
|
|
1556
|
+
if (/^\d{4}-\d{2}-\d{2}$/.test(value)) normalized = value + "T00:00:00Z";
|
|
1557
|
+
else if (/^\d{4}-\d{2}-\d{2}[ T]\d{2}:\d{2}(:\d{2}(\.\d+)?)?$/.test(value)) normalized = value.replace(" ", "T") + "Z";
|
|
1325
1558
|
const d = new Date(normalized);
|
|
1326
1559
|
if (isNaN(d.getTime())) throw new Error(`Cannot parse date: ${value}`);
|
|
1327
1560
|
return d;
|
|
@@ -1335,11 +1568,27 @@ function convertInputsAndSelect(businessDate, processingDatetime, columns, table
|
|
|
1335
1568
|
op
|
|
1336
1569
|
);
|
|
1337
1570
|
}
|
|
1571
|
+
function convertInputsAndSelectForDateRange(businessDateFrom, businessDateTo, processingDatetime, columns, table, op = new NoOperation()) {
|
|
1572
|
+
if (businessDateFrom == null) throw new Error("businessDateFrom is required for findForDateRange");
|
|
1573
|
+
if (businessDateTo == null) throw new Error("businessDateTo is required for findForDateRange");
|
|
1574
|
+
if (processingDatetime == null) throw new Error("processingValidAt is required for findForDateRange");
|
|
1575
|
+
return new FinderResult(
|
|
1576
|
+
convertDate(businessDateFrom),
|
|
1577
|
+
convertDate(processingDatetime),
|
|
1578
|
+
columns,
|
|
1579
|
+
table,
|
|
1580
|
+
op,
|
|
1581
|
+
convertDate(businessDateTo)
|
|
1582
|
+
);
|
|
1583
|
+
}
|
|
1338
1584
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1339
1585
|
0 && (module.exports = {
|
|
1586
|
+
DEFAULT_TIMEOUT_MS,
|
|
1340
1587
|
FinderResult,
|
|
1588
|
+
QueryTimeoutError,
|
|
1341
1589
|
clearRunner,
|
|
1342
1590
|
convertInputsAndSelect,
|
|
1591
|
+
convertInputsAndSelectForDateRange,
|
|
1343
1592
|
getRunner,
|
|
1344
1593
|
registerRunner
|
|
1345
1594
|
});
|