@milaboratories/pl-model-common 1.41.2 → 1.43.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/drivers/index.d.ts +4 -4
- package/dist/drivers/ls.d.ts +1 -1
- package/dist/drivers/pframe/driver.d.ts +2 -2
- package/dist/drivers/pframe/index.d.ts +4 -4
- package/dist/drivers/pframe/pframe.d.ts +1 -1
- package/dist/drivers/pframe/query/index.d.ts +2 -2
- package/dist/drivers/pframe/query/query_common.d.ts +229 -22
- package/dist/drivers/pframe/query/query_common.d.ts.map +1 -1
- package/dist/drivers/pframe/query/query_data.d.ts +9 -7
- package/dist/drivers/pframe/query/query_data.d.ts.map +1 -1
- package/dist/drivers/pframe/query/query_spec.d.ts +9 -7
- package/dist/drivers/pframe/query/query_spec.d.ts.map +1 -1
- package/dist/drivers/pframe/query/utils.cjs +12 -3
- package/dist/drivers/pframe/query/utils.cjs.map +1 -1
- package/dist/drivers/pframe/query/utils.d.ts.map +1 -1
- package/dist/drivers/pframe/query/utils.js +12 -3
- package/dist/drivers/pframe/query/utils.js.map +1 -1
- package/dist/drivers/pframe/spec_driver.d.ts +11 -1
- package/dist/drivers/pframe/spec_driver.d.ts.map +1 -1
- package/dist/drivers/pframe/table_calculate.d.ts +1 -1
- package/dist/index.d.ts +5 -5
- package/dist/services/service_declarations.cjs +4 -2
- package/dist/services/service_declarations.cjs.map +1 -1
- package/dist/services/service_declarations.js +4 -2
- package/dist/services/service_declarations.js.map +1 -1
- package/package.json +4 -4
- package/src/drivers/pframe/query/query_common.ts +256 -27
- package/src/drivers/pframe/query/query_data.ts +33 -12
- package/src/drivers/pframe/query/query_spec.ts +29 -11
- package/src/drivers/pframe/query/utils.test.ts +24 -8
- package/src/drivers/pframe/query/utils.ts +21 -3
- package/src/drivers/pframe/spec_driver.ts +12 -1
- package/src/services/service_declarations.ts +2 -0
|
@@ -61,8 +61,9 @@ export type NumericUnaryOperand =
|
|
|
61
61
|
* - `mul` - Multiplication: left * right
|
|
62
62
|
* - `div` - Division: left / right (division by zero returns Infinity or NaN)
|
|
63
63
|
* - `mod` - Modulo: left % right
|
|
64
|
+
* - `power` - Exponentiation: left ** right
|
|
64
65
|
*/
|
|
65
|
-
export type NumericBinaryOperand = "add" | "sub" | "mul" | "div" | "mod";
|
|
66
|
+
export type NumericBinaryOperand = "add" | "sub" | "mul" | "div" | "mod" | "power";
|
|
66
67
|
|
|
67
68
|
/**
|
|
68
69
|
* Numeric comparison operation kinds.
|
|
@@ -83,16 +84,16 @@ export type NumericComparisonOperand = "eq" | "ne" | "lt" | "le" | "gt" | "ge";
|
|
|
83
84
|
// ============ Geometric Types ============
|
|
84
85
|
|
|
85
86
|
/**
|
|
86
|
-
* 2D point coordinates.
|
|
87
|
+
* 2D point coordinates as an `[x, y]` tuple.
|
|
88
|
+
*
|
|
89
|
+
* Used for geometric operations like point-in-polygon tests. The wire
|
|
90
|
+
* form is a tuple (matching Rust's `(f64, f64)` serialisation), not an
|
|
91
|
+
* object with `x` / `y` fields.
|
|
87
92
|
*
|
|
88
|
-
* Used for geometric operations like point-in-polygon tests.
|
|
89
93
|
* Common use case: flow cytometry gating where points are tested
|
|
90
94
|
* against user-defined polygon regions.
|
|
91
95
|
*/
|
|
92
|
-
export type Point2D =
|
|
93
|
-
x: number;
|
|
94
|
-
y: number;
|
|
95
|
-
};
|
|
96
|
+
export type Point2D = [number, number];
|
|
96
97
|
|
|
97
98
|
// ============ Constant Expression ============
|
|
98
99
|
|
|
@@ -148,17 +149,20 @@ export interface ExprIsNull<I> {
|
|
|
148
149
|
* **Output**: Same type as input/replacement.
|
|
149
150
|
* **Null handling**: If input is null, returns replacement; otherwise returns input.
|
|
150
151
|
*
|
|
152
|
+
* The Rust runtime also accepts the legacy `"ifNull"` tag as a serde
|
|
153
|
+
* alias; new code should emit `"fillNull"`.
|
|
154
|
+
*
|
|
151
155
|
* @template I - The expression type (for recursion)
|
|
152
156
|
*
|
|
153
157
|
* @example
|
|
154
158
|
* // Replace null values with 0
|
|
155
|
-
* { type: '
|
|
159
|
+
* { type: 'fillNull', input: columnRef, replacement: { type: 'constant', value: 0 } }
|
|
156
160
|
*
|
|
157
161
|
* // Replace null strings with 'unknown'
|
|
158
|
-
* { type: '
|
|
162
|
+
* { type: 'fillNull', input: nameColumn, replacement: { type: 'constant', value: 'unknown' } }
|
|
159
163
|
*/
|
|
160
|
-
export interface
|
|
161
|
-
type: "
|
|
164
|
+
export interface ExprFillNull<I> {
|
|
165
|
+
type: "fillNull";
|
|
162
166
|
/** Value to check for null */
|
|
163
167
|
input: I;
|
|
164
168
|
/** Replacement value if input is null */
|
|
@@ -475,8 +479,154 @@ export interface ExprIsIn<I, T extends string | number> {
|
|
|
475
479
|
input: I;
|
|
476
480
|
/** Set of allowed values */
|
|
477
481
|
set: T[];
|
|
482
|
+
/** If true, the predicate is inverted (true for values NOT in `set`). */
|
|
483
|
+
negate: boolean;
|
|
478
484
|
}
|
|
479
485
|
|
|
486
|
+
/**
|
|
487
|
+
* Type cast expression.
|
|
488
|
+
*
|
|
489
|
+
* Converts the input value to a different column value type. Mirrors
|
|
490
|
+
* SQL `CAST(input AS U)`.
|
|
491
|
+
*
|
|
492
|
+
* **Input**: any expression.
|
|
493
|
+
* **Output**: a value of `targetType`.
|
|
494
|
+
* **Null handling**: null in → null out.
|
|
495
|
+
*
|
|
496
|
+
* @template I - The expression type (for recursion)
|
|
497
|
+
*/
|
|
498
|
+
export interface ExprCast<I> {
|
|
499
|
+
type: "cast";
|
|
500
|
+
/** Expression to cast. */
|
|
501
|
+
input: I;
|
|
502
|
+
/** Target column value type. */
|
|
503
|
+
targetType: ColumnValueType;
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
/**
|
|
507
|
+
* A single `when → then` case in a {@link ExprConditional} expression.
|
|
508
|
+
*
|
|
509
|
+
* @template I - The expression type (for recursion)
|
|
510
|
+
*/
|
|
511
|
+
export interface ExprConditionalCase<I> {
|
|
512
|
+
/** Boolean predicate that selects this branch. */
|
|
513
|
+
when: I;
|
|
514
|
+
/** Value produced when `when` evaluates to true. */
|
|
515
|
+
then: I;
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
/**
|
|
519
|
+
* Conditional (CASE WHEN) expression.
|
|
520
|
+
*
|
|
521
|
+
* Evaluates `cases` in order; the value of the first case whose `when`
|
|
522
|
+
* is true is returned. If no case matches, `otherwise` is used (or
|
|
523
|
+
* null when omitted).
|
|
524
|
+
*
|
|
525
|
+
* **Result type**: the type of the first case's `then`; subsequent
|
|
526
|
+
* `then`s and `otherwise` are cast to it.
|
|
527
|
+
*
|
|
528
|
+
* @template I - The expression type (for recursion)
|
|
529
|
+
*
|
|
530
|
+
* @example
|
|
531
|
+
* {
|
|
532
|
+
* type: 'conditional',
|
|
533
|
+
* cases: [
|
|
534
|
+
* { when: gtTwenty, then: { type: 'constant', value: 'high' } },
|
|
535
|
+
* { when: gtTen, then: { type: 'constant', value: 'mid' } }
|
|
536
|
+
* ],
|
|
537
|
+
* otherwise: { type: 'constant', value: 'low' }
|
|
538
|
+
* }
|
|
539
|
+
*/
|
|
540
|
+
export interface ExprConditional<I> {
|
|
541
|
+
type: "conditional";
|
|
542
|
+
/** Cases evaluated in order; first matching wins. At least one. */
|
|
543
|
+
cases: [ExprConditionalCase<I>, ...ExprConditionalCase<I>[]];
|
|
544
|
+
/** Fallback value when no case matches. */
|
|
545
|
+
otherwise?: I;
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
// ============ Disabled — type defined in pframes-rs, runtime not wired yet ============
|
|
549
|
+
//
|
|
550
|
+
// `isInPolygon` and `aggregation` are defined in the Rust query model
|
|
551
|
+
// (`packages/bridge/src/query/expressions/`) but the DataFusion backend
|
|
552
|
+
// returns errors when it tries to evaluate them (filter.rs:276 / :340).
|
|
553
|
+
// Until those stubs land, exposing the TS types here would let block
|
|
554
|
+
// authors construct queries the runtime cannot execute. Re-enable in
|
|
555
|
+
// lock-step with the Rust executor.
|
|
556
|
+
|
|
557
|
+
// export interface ExprIsInPolygon<I> {
|
|
558
|
+
// type: "isInPolygon";
|
|
559
|
+
// x: I;
|
|
560
|
+
// y: I;
|
|
561
|
+
// polygon: [Point2D, ...Point2D[]];
|
|
562
|
+
// negate: boolean;
|
|
563
|
+
// }
|
|
564
|
+
|
|
565
|
+
// export type AggregationKind =
|
|
566
|
+
// | "sum"
|
|
567
|
+
// | "avg"
|
|
568
|
+
// | "count"
|
|
569
|
+
// | "min"
|
|
570
|
+
// | "max"
|
|
571
|
+
// | "first"
|
|
572
|
+
// | "last"
|
|
573
|
+
// | "stddev"
|
|
574
|
+
// | "variance"
|
|
575
|
+
// | "median";
|
|
576
|
+
|
|
577
|
+
// export interface ExprAggregation<I, A, C> {
|
|
578
|
+
// type: "aggregation";
|
|
579
|
+
// kind: AggregationKind;
|
|
580
|
+
// input: I;
|
|
581
|
+
// over?: [QuerySelector<A, C>, ...QuerySelector<A, C>[]];
|
|
582
|
+
// }
|
|
583
|
+
|
|
584
|
+
/** Ranking function kind. */
|
|
585
|
+
export type RankingKind = "rank" | "denseRank" | "rowNumber";
|
|
586
|
+
|
|
587
|
+
/**
|
|
588
|
+
* Ranking expression (always a window function).
|
|
589
|
+
*
|
|
590
|
+
* Orders rows by `orderBy` within each partition and assigns ranks
|
|
591
|
+
* according to `kind`. Output is always `Long`.
|
|
592
|
+
*
|
|
593
|
+
* @template I - The expression type (for recursion)
|
|
594
|
+
* @template A - Axis selector type
|
|
595
|
+
* @template C - Column selector type
|
|
596
|
+
*/
|
|
597
|
+
export interface ExprRanking<I, A, C> {
|
|
598
|
+
type: "ranking";
|
|
599
|
+
/** Ranking semantics. */
|
|
600
|
+
kind: RankingKind;
|
|
601
|
+
/** Expression to order by within each partition. */
|
|
602
|
+
orderBy: I;
|
|
603
|
+
/** If true (default), sort ascending; if false, descending. */
|
|
604
|
+
ascending?: boolean;
|
|
605
|
+
/** Partition specification — at least one entry when supplied. */
|
|
606
|
+
partitionBy?: [QuerySelector<A, C>, ...QuerySelector<A, C>[]];
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
// ============ Disabled — type defined in pframes-rs, runtime not wired yet ============
|
|
610
|
+
//
|
|
611
|
+
// `cumulative` is defined in the Rust query model but the DataFusion
|
|
612
|
+
// backend returns an error (filter.rs:387). Re-enable in lock-step
|
|
613
|
+
// with the Rust executor.
|
|
614
|
+
|
|
615
|
+
// export type CumulativeOperand =
|
|
616
|
+
// | "cumulativeSum"
|
|
617
|
+
// | "cumulativeMin"
|
|
618
|
+
// | "cumulativeMax"
|
|
619
|
+
// | "cumulativeAvg";
|
|
620
|
+
|
|
621
|
+
// export interface ExprCumulative<I, A, C> {
|
|
622
|
+
// type: "cumulative";
|
|
623
|
+
// operand: CumulativeOperand;
|
|
624
|
+
// input: I;
|
|
625
|
+
// orderBy: I;
|
|
626
|
+
// ascending?: boolean;
|
|
627
|
+
// partitionBy?: [QuerySelector<A, C>, ...QuerySelector<A, C>[]];
|
|
628
|
+
// }
|
|
629
|
+
|
|
480
630
|
// ============ Reference Expression Types ============
|
|
481
631
|
|
|
482
632
|
/**
|
|
@@ -583,6 +733,15 @@ export interface QueryColumnSelector<C> {
|
|
|
583
733
|
id: C;
|
|
584
734
|
}
|
|
585
735
|
|
|
736
|
+
/**
|
|
737
|
+
* Axis-or-column selector — mirrors the Rust `Selector<AxisSelector,
|
|
738
|
+
* ColumnSelector>` enum
|
|
739
|
+
* (`packages/bridge/src/query/query_sort.rs`). Used for the
|
|
740
|
+
* `partitionBy` / `over` fields of window expressions where either an
|
|
741
|
+
* axis or a column can drive the partition.
|
|
742
|
+
*/
|
|
743
|
+
export type QuerySelector<A, C> = QueryAxisSelector<A> | QueryColumnSelector<C>;
|
|
744
|
+
|
|
586
745
|
/**
|
|
587
746
|
* Left outer join query operation.
|
|
588
747
|
*
|
|
@@ -684,8 +843,8 @@ export interface QuerySliceAxes<Q, A> {
|
|
|
684
843
|
* type: 'sort',
|
|
685
844
|
* input: dataQuery,
|
|
686
845
|
* sortBy: [
|
|
687
|
-
* { expression: { type: 'columnRef', value: 'score' }, ascending: false, nullsFirst:
|
|
688
|
-
* { expression: { type: 'axisRef', value: { name: 'name' } }, ascending: true, nullsFirst:
|
|
846
|
+
* { expression: { type: 'columnRef', value: 'score' }, ascending: false, nullsFirst: false },
|
|
847
|
+
* { expression: { type: 'axisRef', value: { name: 'name' } }, ascending: true, nullsFirst: false }
|
|
689
848
|
* ]
|
|
690
849
|
* }
|
|
691
850
|
*/
|
|
@@ -702,9 +861,8 @@ export interface QuerySort<Q, E> {
|
|
|
702
861
|
* Null placement control:
|
|
703
862
|
* - true: nulls sort before non-null values
|
|
704
863
|
* - false: nulls sort after non-null values
|
|
705
|
-
* - null: use default behavior (typically nulls last)
|
|
706
864
|
*/
|
|
707
|
-
nullsFirst:
|
|
865
|
+
nullsFirst: boolean;
|
|
708
866
|
}[];
|
|
709
867
|
}
|
|
710
868
|
|
|
@@ -799,37 +957,57 @@ export interface QueryInlineColumn<T> {
|
|
|
799
957
|
/**
|
|
800
958
|
* Sparse to dense column query operation.
|
|
801
959
|
*
|
|
802
|
-
*
|
|
803
|
-
*
|
|
960
|
+
* Densifies a sparse column over the Cartesian product of distinct
|
|
961
|
+
* axis values: `axes` partitions the column's own axes into two sets
|
|
962
|
+
* (the listed axes on one side, the rest on the other); both sides
|
|
963
|
+
* contribute their distinct values, and the cross product fills in
|
|
964
|
+
* the missing tuples (null on rows that have no underlying value).
|
|
804
965
|
*
|
|
805
|
-
* **Use case**:
|
|
806
|
-
*
|
|
966
|
+
* **Use case**: graph-maker and other UI surfaces that need a dense
|
|
967
|
+
* grid to plot.
|
|
807
968
|
*
|
|
808
969
|
* **Behavior**:
|
|
809
|
-
* -
|
|
810
|
-
* -
|
|
811
|
-
*
|
|
970
|
+
* - Output axes = input axes (no axes are added).
|
|
971
|
+
* - Missing axis-tuple combinations become null in the output (or
|
|
972
|
+
* filled later via `pl7.app/graph/isDenseAxis` /
|
|
973
|
+
* `treatAbsentValuesAs` annotations).
|
|
812
974
|
*
|
|
813
975
|
* @template C - Column reference type
|
|
976
|
+
* @template A - Axis selector type (named selectors at the spec layer,
|
|
977
|
+
* numeric axis indices at the data layer)
|
|
814
978
|
* @template SO - Spec override type
|
|
815
979
|
*
|
|
816
980
|
* @example
|
|
817
|
-
* //
|
|
981
|
+
* // Spec layer: name the axis to expand across.
|
|
818
982
|
* {
|
|
819
983
|
* type: 'sparseToDenseColumn',
|
|
820
984
|
* column: 'col_abc123',
|
|
821
|
-
*
|
|
985
|
+
* axes: [{ name: 'sample' }],
|
|
822
986
|
* specOverride: { ... } // optional spec modifications
|
|
823
987
|
* }
|
|
988
|
+
*
|
|
989
|
+
* @example
|
|
990
|
+
* // Data layer: the same query after spec→data lowering.
|
|
991
|
+
* {
|
|
992
|
+
* type: 'sparseToDenseColumn',
|
|
993
|
+
* column: 'col_abc123',
|
|
994
|
+
* axes: [0],
|
|
995
|
+
* specOverride: { ... }
|
|
996
|
+
* }
|
|
824
997
|
*/
|
|
825
|
-
export interface QuerySparseToDenseColumn<C, SO> {
|
|
998
|
+
export interface QuerySparseToDenseColumn<C, A, SO> {
|
|
826
999
|
type: "sparseToDenseColumn";
|
|
827
1000
|
/** Column reference (ID or full column object depending on context) */
|
|
828
1001
|
column: C;
|
|
829
1002
|
/** Optional override for the column specification */
|
|
830
1003
|
specOverride?: SO;
|
|
831
|
-
/**
|
|
832
|
-
|
|
1004
|
+
/**
|
|
1005
|
+
* Axes that participate in the cartesian-product densification.
|
|
1006
|
+
* Named selectors at the spec layer; resolved to numeric axis
|
|
1007
|
+
* indices during spec→data lowering. The Rust runtime also accepts
|
|
1008
|
+
* the legacy field name `axesIndices` as a serde alias.
|
|
1009
|
+
*/
|
|
1010
|
+
axes: [A, ...A[]];
|
|
833
1011
|
}
|
|
834
1012
|
|
|
835
1013
|
/**
|
|
@@ -928,3 +1106,54 @@ export interface QueryLinkerJoin<L, JE extends QueryJoinEntry<unknown>> {
|
|
|
928
1106
|
/** Rest side — one or more subqueries joined with the linker (at least one). */
|
|
929
1107
|
secondary: JE[];
|
|
930
1108
|
}
|
|
1109
|
+
|
|
1110
|
+
/**
|
|
1111
|
+
* `transformColumns` mode.
|
|
1112
|
+
*
|
|
1113
|
+
* - `"append"` — existing columns pass through; the new columns are
|
|
1114
|
+
* appended.
|
|
1115
|
+
* - `"replace"` — only the listed columns are kept; everything else is
|
|
1116
|
+
* dropped.
|
|
1117
|
+
*
|
|
1118
|
+
* The Rust runtime accepts the legacy `"add"` tag as a serde alias;
|
|
1119
|
+
* new code should emit `"append"`.
|
|
1120
|
+
*/
|
|
1121
|
+
export type TransformColumnsMode = "append" | "replace";
|
|
1122
|
+
|
|
1123
|
+
/**
|
|
1124
|
+
* Single column entry for {@link QueryTransformColumns}.
|
|
1125
|
+
*
|
|
1126
|
+
* @template E - Expression type
|
|
1127
|
+
* @template SO - Spec override type (typically `PColumnIdAndSpec` at
|
|
1128
|
+
* the spec layer, or layer-specific id+typespec at the data layer)
|
|
1129
|
+
*/
|
|
1130
|
+
export interface TransformColumnEntry<E, SO> {
|
|
1131
|
+
/** Expression computing the column values. */
|
|
1132
|
+
expression: E;
|
|
1133
|
+
/**
|
|
1134
|
+
* Optional spec override. If omitted, the runtime auto-derives the
|
|
1135
|
+
* column's spec from the host's input and the expression.
|
|
1136
|
+
* `valueType` is always inferred from the expression.
|
|
1137
|
+
*/
|
|
1138
|
+
specOverride?: SO;
|
|
1139
|
+
}
|
|
1140
|
+
|
|
1141
|
+
/**
|
|
1142
|
+
* Transform-columns query operation.
|
|
1143
|
+
*
|
|
1144
|
+
* Computes one or more derived columns from `input`. Axes are
|
|
1145
|
+
* preserved.
|
|
1146
|
+
*
|
|
1147
|
+
* @template Q - Input query type
|
|
1148
|
+
* @template E - Expression type
|
|
1149
|
+
* @template SO - Spec override type
|
|
1150
|
+
*/
|
|
1151
|
+
export interface QueryTransformColumns<Q, E, SO> {
|
|
1152
|
+
type: "transformColumns";
|
|
1153
|
+
/** Input query. */
|
|
1154
|
+
input: Q;
|
|
1155
|
+
/** `"append"` to add new columns; `"replace"` to keep only listed columns. */
|
|
1156
|
+
mode: TransformColumnsMode;
|
|
1157
|
+
/** Derived columns to compute (at least one). */
|
|
1158
|
+
columns: [TransformColumnEntry<E, SO>, ...TransformColumnEntry<E, SO>[]];
|
|
1159
|
+
}
|
|
@@ -1,22 +1,25 @@
|
|
|
1
1
|
import type { PObjectId } from "../../../pool";
|
|
2
2
|
import type {
|
|
3
3
|
ExprAxisRef,
|
|
4
|
+
ExprCast,
|
|
4
5
|
ExprColumnRef,
|
|
5
|
-
|
|
6
|
-
ExprNumericComparison,
|
|
6
|
+
ExprConditional,
|
|
7
7
|
ExprConstant,
|
|
8
|
+
ExprFillNull,
|
|
8
9
|
ExprIsIn,
|
|
9
10
|
ExprIsNull,
|
|
10
|
-
ExprIfNull,
|
|
11
11
|
ExprLogicalUnary,
|
|
12
12
|
ExprLogicalVariadic,
|
|
13
|
+
ExprNumericBinary,
|
|
14
|
+
ExprNumericComparison,
|
|
15
|
+
ExprNumericUnary,
|
|
16
|
+
ExprRanking,
|
|
13
17
|
ExprStringContains,
|
|
14
18
|
ExprStringContainsFuzzy,
|
|
15
19
|
ExprStringEquals,
|
|
16
20
|
ExprStringRegex,
|
|
17
|
-
|
|
21
|
+
InferBooleanExpressionUnion,
|
|
18
22
|
QueryColumn,
|
|
19
|
-
QuerySparseToDenseColumn,
|
|
20
23
|
QueryFilter,
|
|
21
24
|
QueryInlineColumn,
|
|
22
25
|
QueryJoinEntry,
|
|
@@ -24,9 +27,10 @@ import type {
|
|
|
24
27
|
QueryOuterJoin,
|
|
25
28
|
QuerySliceAxes,
|
|
26
29
|
QuerySort,
|
|
30
|
+
QuerySparseToDenseColumn,
|
|
27
31
|
QuerySymmetricJoin,
|
|
32
|
+
QueryTransformColumns,
|
|
28
33
|
TypeSpec,
|
|
29
|
-
InferBooleanExpressionUnion,
|
|
30
34
|
} from "./query_common";
|
|
31
35
|
|
|
32
36
|
/**
|
|
@@ -64,7 +68,11 @@ export type DataQueryColumn = QueryColumn;
|
|
|
64
68
|
/** @see QueryInlineColumn */
|
|
65
69
|
export type DataQueryInlineColumn = QueryInlineColumn<ColumnIdAndTypeSpec>;
|
|
66
70
|
/** @see QuerySparseToDenseColumn */
|
|
67
|
-
export type DataQuerySparseToDenseColumn = QuerySparseToDenseColumn<
|
|
71
|
+
export type DataQuerySparseToDenseColumn = QuerySparseToDenseColumn<
|
|
72
|
+
PObjectId,
|
|
73
|
+
number,
|
|
74
|
+
ColumnIdAndTypeSpec
|
|
75
|
+
>;
|
|
68
76
|
/** @see QuerySymmetricJoin */
|
|
69
77
|
export type DataQuerySymmetricJoin = QuerySymmetricJoin<DataQueryJoinEntry>;
|
|
70
78
|
/** @see QueryOuterJoin */
|
|
@@ -93,6 +101,12 @@ export type DataQuerySliceAxes = QuerySliceAxes<DataQuery, number>;
|
|
|
93
101
|
export type DataQuerySort = QuerySort<DataQuery, DataQueryExpression>;
|
|
94
102
|
/** @see QueryFilter */
|
|
95
103
|
export type DataQueryFilter = QueryFilter<DataQuery, DataQueryBooleanExpression>;
|
|
104
|
+
/** @see QueryTransformColumns */
|
|
105
|
+
export type DataQueryTransformColumns = QueryTransformColumns<
|
|
106
|
+
DataQuery,
|
|
107
|
+
DataQueryExpression,
|
|
108
|
+
ColumnIdAndTypeSpec
|
|
109
|
+
>;
|
|
96
110
|
|
|
97
111
|
/**
|
|
98
112
|
* Union of all data layer query types.
|
|
@@ -102,8 +116,8 @@ export type DataQueryFilter = QueryFilter<DataQuery, DataQueryBooleanExpression>
|
|
|
102
116
|
*
|
|
103
117
|
* Includes:
|
|
104
118
|
* - Leaf nodes: column, inlineColumn, sparseToDenseColumn
|
|
105
|
-
* - Join operations: innerJoin, fullJoin, outerJoin
|
|
106
|
-
* - Transformations: sliceAxes, sort, filter
|
|
119
|
+
* - Join operations: innerJoin, fullJoin, outerJoin, linkerJoin
|
|
120
|
+
* - Transformations: sliceAxes, sort, filter, transformColumns
|
|
107
121
|
*/
|
|
108
122
|
export type DataQuery =
|
|
109
123
|
| DataQueryColumn
|
|
@@ -114,7 +128,8 @@ export type DataQuery =
|
|
|
114
128
|
| DataQueryLinkerJoin
|
|
115
129
|
| DataQuerySliceAxes
|
|
116
130
|
| DataQuerySort
|
|
117
|
-
| DataQueryFilter
|
|
131
|
+
| DataQueryFilter
|
|
132
|
+
| DataQueryTransformColumns;
|
|
118
133
|
|
|
119
134
|
/** @see ExprAxisRef */
|
|
120
135
|
export type DataExprAxisRef = ExprAxisRef<number>;
|
|
@@ -133,10 +148,16 @@ export type DataQueryExpression =
|
|
|
133
148
|
| ExprStringRegex<DataQueryExpression>
|
|
134
149
|
| ExprStringContainsFuzzy<DataQueryExpression>
|
|
135
150
|
| ExprIsNull<DataQueryExpression>
|
|
136
|
-
|
|
|
151
|
+
| ExprFillNull<DataQueryExpression>
|
|
137
152
|
| ExprLogicalUnary<DataQueryExpression>
|
|
138
153
|
| ExprLogicalVariadic<DataQueryExpression>
|
|
139
154
|
| ExprIsIn<DataQueryExpression, string>
|
|
140
|
-
| ExprIsIn<DataQueryExpression, number
|
|
155
|
+
| ExprIsIn<DataQueryExpression, number>
|
|
156
|
+
// | ExprIsInPolygon<DataQueryExpression> -- runtime not wired (see query_common.ts)
|
|
157
|
+
| ExprCast<DataQueryExpression>
|
|
158
|
+
| ExprConditional<DataQueryExpression>
|
|
159
|
+
// | ExprAggregation<DataQueryExpression, number, number> -- runtime not wired
|
|
160
|
+
| ExprRanking<DataQueryExpression, number, number>;
|
|
161
|
+
// | ExprCumulative<DataQueryExpression, number, number> -- runtime not wired
|
|
141
162
|
|
|
142
163
|
export type DataQueryBooleanExpression = InferBooleanExpressionUnion<DataQueryExpression>;
|
|
@@ -1,22 +1,25 @@
|
|
|
1
1
|
import type { PObjectId } from "../../../pool";
|
|
2
2
|
import type {
|
|
3
3
|
ExprAxisRef,
|
|
4
|
+
ExprCast,
|
|
4
5
|
ExprColumnRef,
|
|
5
|
-
|
|
6
|
-
ExprNumericComparison,
|
|
6
|
+
ExprConditional,
|
|
7
7
|
ExprConstant,
|
|
8
|
+
ExprFillNull,
|
|
8
9
|
ExprIsIn,
|
|
9
10
|
ExprIsNull,
|
|
10
|
-
ExprIfNull,
|
|
11
11
|
ExprLogicalUnary,
|
|
12
12
|
ExprLogicalVariadic,
|
|
13
|
+
ExprNumericBinary,
|
|
14
|
+
ExprNumericComparison,
|
|
15
|
+
ExprNumericUnary,
|
|
16
|
+
ExprRanking,
|
|
13
17
|
ExprStringContains,
|
|
14
18
|
ExprStringContainsFuzzy,
|
|
15
19
|
ExprStringEquals,
|
|
16
20
|
ExprStringRegex,
|
|
17
|
-
|
|
21
|
+
InferBooleanExpressionUnion,
|
|
18
22
|
QueryColumn,
|
|
19
|
-
QuerySparseToDenseColumn,
|
|
20
23
|
QueryFilter,
|
|
21
24
|
QueryInlineColumn,
|
|
22
25
|
QueryJoinEntry,
|
|
@@ -24,8 +27,9 @@ import type {
|
|
|
24
27
|
QueryOuterJoin,
|
|
25
28
|
QuerySliceAxes,
|
|
26
29
|
QuerySort,
|
|
30
|
+
QuerySparseToDenseColumn,
|
|
27
31
|
QuerySymmetricJoin,
|
|
28
|
-
|
|
32
|
+
QueryTransformColumns,
|
|
29
33
|
} from "./query_common";
|
|
30
34
|
import type { Domain, PColumnIdAndSpec, SingleAxisSelector } from "../spec";
|
|
31
35
|
|
|
@@ -55,6 +59,7 @@ export type SpecQueryInlineColumn = QueryInlineColumn<PColumnIdAndSpec>;
|
|
|
55
59
|
/** @see QuerySparseToDenseColumn */
|
|
56
60
|
export type SpecQuerySparseToDenseColumn<C = PObjectId> = QuerySparseToDenseColumn<
|
|
57
61
|
C,
|
|
62
|
+
SingleAxisSelector,
|
|
58
63
|
PColumnIdAndSpec
|
|
59
64
|
>;
|
|
60
65
|
/** @see QuerySymmetricJoin */
|
|
@@ -82,6 +87,12 @@ export type SpecQuerySliceAxes<C = PObjectId> = QuerySliceAxes<SpecQuery<C>, Sin
|
|
|
82
87
|
export type SpecQuerySort<C = PObjectId> = QuerySort<SpecQuery<C>, SpecQueryExpression>;
|
|
83
88
|
/** @see QueryFilter */
|
|
84
89
|
export type SpecQueryFilter<C = PObjectId> = QueryFilter<SpecQuery<C>, SpecQueryBooleanExpression>;
|
|
90
|
+
/** @see QueryTransformColumns */
|
|
91
|
+
export type SpecQueryTransformColumns<C = PObjectId> = QueryTransformColumns<
|
|
92
|
+
SpecQuery<C>,
|
|
93
|
+
SpecQueryExpression,
|
|
94
|
+
PColumnIdAndSpec
|
|
95
|
+
>;
|
|
85
96
|
|
|
86
97
|
/**
|
|
87
98
|
* Union of all spec layer query types.
|
|
@@ -95,8 +106,8 @@ export type SpecQueryFilter<C = PObjectId> = QueryFilter<SpecQuery<C>, SpecQuery
|
|
|
95
106
|
*
|
|
96
107
|
* Includes:
|
|
97
108
|
* - Leaf nodes: column, inlineColumn, sparseToDenseColumn
|
|
98
|
-
* - Join operations: innerJoin, fullJoin, outerJoin
|
|
99
|
-
* - Transformations: sliceAxes, sort, filter
|
|
109
|
+
* - Join operations: innerJoin, fullJoin, outerJoin, linkerJoin
|
|
110
|
+
* - Transformations: sliceAxes, sort, filter, transformColumns
|
|
100
111
|
*/
|
|
101
112
|
export type SpecQuery<C = PObjectId> =
|
|
102
113
|
| SpecQueryColumn<C>
|
|
@@ -107,7 +118,8 @@ export type SpecQuery<C = PObjectId> =
|
|
|
107
118
|
| SpecQueryLinkerJoin<C>
|
|
108
119
|
| SpecQuerySliceAxes<C>
|
|
109
120
|
| SpecQuerySort<C>
|
|
110
|
-
| SpecQueryFilter<C
|
|
121
|
+
| SpecQueryFilter<C>
|
|
122
|
+
| SpecQueryTransformColumns<C>;
|
|
111
123
|
|
|
112
124
|
/** @see ExprAxisRef */
|
|
113
125
|
export type SpecExprAxisRef = ExprAxisRef<SingleAxisSelector>;
|
|
@@ -126,10 +138,16 @@ export type SpecQueryExpression =
|
|
|
126
138
|
| ExprStringRegex<SpecQueryExpression>
|
|
127
139
|
| ExprStringContainsFuzzy<SpecQueryExpression>
|
|
128
140
|
| ExprIsNull<SpecQueryExpression>
|
|
129
|
-
|
|
|
141
|
+
| ExprFillNull<SpecQueryExpression>
|
|
130
142
|
| ExprLogicalUnary<SpecQueryExpression>
|
|
131
143
|
| ExprLogicalVariadic<SpecQueryExpression>
|
|
132
144
|
| ExprIsIn<SpecQueryExpression, string>
|
|
133
|
-
| ExprIsIn<SpecQueryExpression, number
|
|
145
|
+
| ExprIsIn<SpecQueryExpression, number>
|
|
146
|
+
// | ExprIsInPolygon<SpecQueryExpression> -- runtime not wired (see query_common.ts)
|
|
147
|
+
| ExprCast<SpecQueryExpression>
|
|
148
|
+
| ExprConditional<SpecQueryExpression>
|
|
149
|
+
// | ExprAggregation<SpecQueryExpression, SingleAxisSelector, PObjectId> -- runtime not wired
|
|
150
|
+
| ExprRanking<SpecQueryExpression, SingleAxisSelector, PObjectId>;
|
|
151
|
+
// | ExprCumulative<SpecQueryExpression, SingleAxisSelector, PObjectId> -- runtime not wired
|
|
134
152
|
|
|
135
153
|
export type SpecQueryBooleanExpression = InferBooleanExpressionUnion<SpecQueryExpression>;
|
|
@@ -27,9 +27,17 @@ describe("traverseQuerySpec", () => {
|
|
|
27
27
|
});
|
|
28
28
|
|
|
29
29
|
it("transforms sparseToDenseColumn leaf", () => {
|
|
30
|
-
const q: Q = {
|
|
30
|
+
const q: Q = {
|
|
31
|
+
type: "sparseToDenseColumn",
|
|
32
|
+
column: "a",
|
|
33
|
+
axes: [{ name: "s" }, { name: "g" }],
|
|
34
|
+
} as Q;
|
|
31
35
|
const result = traverseQuerySpec(q, { column: (c) => `${c}!` });
|
|
32
|
-
expect(result).toEqual({
|
|
36
|
+
expect(result).toEqual({
|
|
37
|
+
type: "sparseToDenseColumn",
|
|
38
|
+
column: "a!",
|
|
39
|
+
axes: [{ name: "s" }, { name: "g" }],
|
|
40
|
+
});
|
|
33
41
|
});
|
|
34
42
|
|
|
35
43
|
it("passes inlineColumn through unchanged", () => {
|
|
@@ -107,7 +115,11 @@ describe("traverseQuerySpec", () => {
|
|
|
107
115
|
type: "sort",
|
|
108
116
|
input: col("a"),
|
|
109
117
|
sortBy: [
|
|
110
|
-
{
|
|
118
|
+
{
|
|
119
|
+
expression: { type: "columnRef", value: pid("id1") },
|
|
120
|
+
ascending: true,
|
|
121
|
+
nullsFirst: false,
|
|
122
|
+
},
|
|
111
123
|
],
|
|
112
124
|
} as Q;
|
|
113
125
|
const result = traverseQuerySpec(q, { column: (c) => c.toUpperCase() });
|
|
@@ -115,7 +127,7 @@ describe("traverseQuerySpec", () => {
|
|
|
115
127
|
type: "sort",
|
|
116
128
|
input: { type: "column", column: "A" },
|
|
117
129
|
sortBy: [
|
|
118
|
-
{ expression: { type: "columnRef", value: "id1" }, ascending: true, nullsFirst:
|
|
130
|
+
{ expression: { type: "columnRef", value: "id1" }, ascending: true, nullsFirst: false },
|
|
119
131
|
],
|
|
120
132
|
});
|
|
121
133
|
});
|
|
@@ -197,7 +209,11 @@ describe("collectSpecQueryColumns", () => {
|
|
|
197
209
|
});
|
|
198
210
|
|
|
199
211
|
it("collects from sparseToDenseColumn", () => {
|
|
200
|
-
const q: Q = {
|
|
212
|
+
const q: Q = {
|
|
213
|
+
type: "sparseToDenseColumn",
|
|
214
|
+
column: "s",
|
|
215
|
+
axes: [{ name: "s" }],
|
|
216
|
+
} as Q;
|
|
201
217
|
expect(collectSpecQueryColumns(q)).toEqual(["s"]);
|
|
202
218
|
});
|
|
203
219
|
|
|
@@ -258,17 +274,17 @@ describe("sortSpecQuery", () => {
|
|
|
258
274
|
});
|
|
259
275
|
});
|
|
260
276
|
|
|
261
|
-
it("sorts sparseToDenseColumn
|
|
277
|
+
it("sorts sparseToDenseColumn axes", () => {
|
|
262
278
|
const q: SpecQuery = {
|
|
263
279
|
type: "sparseToDenseColumn",
|
|
264
280
|
column: pid("a"),
|
|
265
|
-
|
|
281
|
+
axes: [{ name: "z" }, { name: "x" }, { name: "y" }],
|
|
266
282
|
} as SpecQuery;
|
|
267
283
|
const result = sortSpecQuery(q);
|
|
268
284
|
expect(result).toEqual({
|
|
269
285
|
type: "sparseToDenseColumn",
|
|
270
286
|
column: "a",
|
|
271
|
-
|
|
287
|
+
axes: [{ name: "x" }, { name: "y" }, { name: "z" }],
|
|
272
288
|
});
|
|
273
289
|
});
|
|
274
290
|
|