Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions test/rfl/agg/count_distinct_extras.rfl
Original file line number Diff line number Diff line change
Expand Up @@ -87,12 +87,14 @@
;; 9) Spot-check a single-group count to confirm distinct-counting
;; semantics on the I32 serial arm (not just row count).
;; Group 0 sees rows 0 and 51000 → v = 0 and 51000%7 = 5 → 2 distinct.
(at (at (select {n: (count (distinct v)) from: Tcd-i32 by: g}) 'n) 0) -- 2
;; 51000 groups in unspecified order, so pin g==0 with where:.
(at (at (select {n: (count (distinct v)) from: Tcd-i32 by: g where: (== g 0)}) 'n) 0) -- 2

;; 10) Spot-check the F64 arm — group 0 sees rows 0 & 51000; both v=0.0
;; (51000 % 6 == 0), so a single distinct value. Confirms the F64
;; arm's NaN / -0.0 normalisation doesn't blow up on plain 0.0.
(at (at (select {n: (count (distinct v)) from: Tcd-f64 by: g}) 'n) 0) -- 1
;; 51000 groups in unspecified order, so pin g==0 with where:.
(at (at (select {n: (count (distinct v)) from: Tcd-f64 by: g where: (== g 0)}) 'n) 0) -- 1

;; ────────── has_nulls fallback (group.c L1204-1227) ──────────
;; Build a null-bearing I64 column: cast a small null-bearing prefix
Expand Down
7 changes: 4 additions & 3 deletions test/rfl/agg/pearson_corr.rfl
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,10 @@
;; Group B: y = 6-x → r = -1.0
;; The SIGNED coefficient must be returned per group — squaring it here
;; (a former workaround) collapsed +1 and -1 to 1.0 and hid the by-group
;; sign bug. Assert r directly so the sign is exercised.
(at (at (select {r: (pearson_corr x y) by: g from: Tq9}) 'r) 0) -- 1.0
(at (at (select {r: (pearson_corr x y) by: g from: Tq9}) 'r) 1) -- -1.0
;; sign bug. Group emit order is hash-bucket order (differs across ASan /
;; coverage builds), so assert the {+1.0, -1.0} pair order-independently.
(min (at (select {r: (pearson_corr x y) by: g from: Tq9}) 'r)) -- -1.0
(max (at (select {r: (pearson_corr x y) by: g from: Tq9}) 'r)) -- 1.0
;; r² parity: pow(r,2) is +1.0 for both groups (squaring discards sign).
(at (at (select {r2: (pow (pearson_corr x y) 2) by: g from: Tq9}) 'r2) 1) -- 1.0

Expand Down
63 changes: 34 additions & 29 deletions test/rfl/agg/per_group_holistic.rfl
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,12 @@
(count (select {m: (med v) by: g from: Tmed})) -- 3
(sum (at (select {m: (med v) by: g from: Tmed}) 'm)) -- 140.0
(type (at (select {m: (med v) by: g from: Tmed}) 'm)) -- 'F64
;; per-group value checks (sum alone can mask a value swap): groups
;; emit in first-appearance order [0 1 2] → medians [30.0 10.0 100.0].
(at (at (select {m: (med v) by: g from: Tmed}) 'm) 0) -- 30.0
(at (at (select {m: (med v) by: g from: Tmed}) 'm) 1) -- 10.0
(at (at (select {m: (med v) by: g from: Tmed}) 'm) 2) -- 100.0
;; per-group value checks (sum alone can mask a value swap): group emit
;; order is hash-bucket order (unspecified), so assert the SORTED set of
;; per-group medians {10 30 100} instead of pinned positions.
(asc (at (select {m: (med v) by: g from: Tmed}) 'm)) -- [10.0 30.0 100.0]
;; pin the distinguishing single-element group (g=2 → [100]) with where:.
(at (at (select {m: (med v) by: g from: Tmed where: (== g 2)}) 'm) 0) -- 100.0


;; ─── median per group: F64 value ────────────────────────────────────
Expand Down Expand Up @@ -73,9 +74,10 @@
(sum (at (select {m: (med v) by: [id1 id2] from: Tmm}) 'm)) -- 130.0
;; per-group values (sum 130 = 10+40+40+40 — the lone (A,X) group at
;; 10.0 is what distinguishes a correct scatter from one that mis-bins).
;; Group order is first-appearance [(A,X)(A,Y)(B,X)(B,Y)] → [10 40 40 40].
(at (at (select {m: (med v) by: [id1 id2] from: Tmm}) 'm) 0) -- 10.0
(at (at (select {m: (med v) by: [id1 id2] from: Tmm}) 'm) 3) -- 40.0
;; Group order is hash-bucket order (unspecified), so assert the sorted
;; multiset {10 40 40 40} and pin the lone (A,X) group with where:.
(asc (at (select {m: (med v) by: [id1 id2] from: Tmm}) 'm)) -- [10.0 40.0 40.0 40.0]
(at (at (select {m: (med v) by: [id1 id2] from: Tmm where: (and (== id1 'A) (== id2 'X))}) 'm) 0) -- 10.0


;; ─── top-K / bot-K per group via SYM key (LIST-cell path) ───────────
Expand Down Expand Up @@ -118,9 +120,10 @@
;; top-2 sum = (5.5+3.5) + (7.5+2.5) + (9.5+8.5) = 9 + 10 + 18 = 37.0
(sum (raze (at (select {t: (top v 2) by: k from: Ttopf}) 't))) -- 37.0
;; per-cell element check (sum can mask which values land in which cell):
;; group A cell = [5.5 3.5] descending; assert its largest element.
(at (at (at (select {t: (top v 2) by: k from: Ttopf}) 't) 0) 0) -- 5.5
(at (at (at (select {t: (top v 2) by: k from: Ttopf}) 't) 0) 1) -- 3.5
;; group A cell = [5.5 3.5] descending. Cell position is hash-bucket order,
;; so pin group A with where: to assert its top-2 cell deterministically.
(at (at (at (select {t: (top v 2) by: k from: Ttopf where: (== k 'A)}) 't) 0) 0) -- 5.5
(at (at (at (select {t: (top v 2) by: k from: Ttopf where: (== k 'A)}) 't) 0) 1) -- 3.5


;; ─── variance / stddev per group: canonical Wikipedia fixture ───────
Expand Down Expand Up @@ -228,14 +231,11 @@
(count Tms2r) -- 4
(sum (at Tms2r 'm)) -- 106.0
;; per-group medians are {25 26 27 28} — close, contiguous values a sum
;; check (106) cannot disambiguate from a permutation. NOTE: this 2-key
;; med+stddev fast path emits groups in hash-bucket order
;; [(B,Y)(A,Y)(B,X)(A,X)] → [28 26 27 25], NOT first-appearance; pin the
;; values at the keyed positions so a wrong per-group median is caught.
(at (at Tms2r 'm) 0) -- 28.0
(at (at Tms2r 'm) 3) -- 25.0
(at (at Tms2r 'id1) 0) -- 'B
(at (at Tms2r 'id2) 0) -- 'Y
;; check (106) cannot disambiguate from a permutation. Group emit order is
;; hash-bucket order and differs across ASan / coverage builds, so assert the
;; SORTED set of medians instead of pinned positions — this still catches a
;; wrong per-group median value, order-independently.
(asc (at Tms2r 'm)) -- [25.0 26.0 27.0 28.0]
(< (abs (- (sum (at Tms2r 's)) (* 4.0 12.909944487358056))) 0.000001) -- true


Expand Down Expand Up @@ -307,13 +307,17 @@
(count (select {m: (med v) by: [g h] from: Tmmi})) -- 4
(sum (at (select {m: (med v) by: [g h] from: Tmmi}) 'm)) -- 115.0
(sum (at (select {v: (var_pop v) by: [g h] from: Tmmi}) 'v)) -- 375.0
;; per-group value checks (group order first-appearance
;; [(0,0)(0,1)(1,0)(1,1)] → med [5 10 30 70], var_pop [0 0 100 275]).
;; per-group value checks. Group emit order is hash-bucket order
;; (unspecified), so assert the sorted multisets and pin discriminating
;; groups with where: on both keys. med {5 10 30 70}, var_pop {0 0 100 275}.
(asc (at (select {m: (med v) by: [g h] from: Tmmi}) 'm)) -- [5.0 10.0 30.0 70.0]
(asc (at (select {v: (var_pop v) by: [g h] from: Tmmi}) 'v)) -- [0.0 0.0 100.0 275.0]
;; The (1,1) group [60 80 100 60] is the discriminating one: median 70
;; (mean-of-two-middles: sort 60,60,80,100 → (60+80)/2), var_pop 275.
(at (at (select {m: (med v) by: [g h] from: Tmmi}) 'm) 3) -- 70.0
(at (at (select {v: (var_pop v) by: [g h] from: Tmmi}) 'v) 2) -- 100.0
(at (at (select {v: (var_pop v) by: [g h] from: Tmmi}) 'v) 3) -- 275.0
(at (at (select {m: (med v) by: [g h] from: Tmmi where: (and (== g 1) (== h 1))}) 'm) 0) -- 70.0
(at (at (select {v: (var_pop v) by: [g h] from: Tmmi where: (and (== g 1) (== h 1))}) 'v) 0) -- 275.0
;; (1,0) group [20 40] → var_pop 100.
(at (at (select {v: (var_pop v) by: [g h] from: Tmmi where: (and (== g 1) (== h 0))}) 'v) 0) -- 100.0


;; ─── ties: median of duplicate-only group equals that value ─────────
Expand Down Expand Up @@ -366,11 +370,12 @@
(== (count (at (select {m: (last s) by: k from: Wt}) 'm)) 200) -- true
;; result columns keep the STR type (not truncated to a fixed-width int)
(type (at (select {m: (min s) by: k from: Wt}) 'm)) -- 'STR
;; group 0 holds rows 0,200,400,... → string "0" is the lexicographic min,
;; and within that group first is "0", last is "5800".
(at (at (select {m: (min s) by: k from: Wt}) 'm) 0) -- "0"
(at (at (select {m: (first s) by: k from: Wt}) 'm) 0) -- "0"
(at (at (select {m: (last s) by: k from: Wt}) 'm) 0) -- "5800"
;; group k=0 holds rows 0,200,400,... → string "0" is the lexicographic min,
;; and within that group first is "0", last is "5800". Group position is
;; hash-bucket order (unspecified) across 200 groups, so pin k=0 with where:.
(at (at (select {m: (min s) by: k from: Wt where: (== k 0)}) 'm) 0) -- "0"
(at (at (select {m: (first s) by: k from: Wt where: (== k 0)}) 'm) 0) -- "0"
(at (at (select {m: (last s) by: k from: Wt where: (== k 0)}) 'm) 0) -- "5800"
;; GUID per-group first agrees with the scalar reducer on the same slice
(set Wg (guid Wn))
(set Wtg (table [g k] (list Wg Wk)))
Expand Down
10 changes: 7 additions & 3 deletions test/rfl/arith/top_bot.rfl
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,13 @@
;; Closes q8: top-N per group via the eval-level scatter.
(set Tg (table [g v] (list [A A A B B C C C C] [3 1 5 2 7 4 9 6 8])))
;; Group A → top 2 = [5 3]; B → [7 2]; C → [9 8].
(at (at (select {top2: (top v 2) by: g from: Tg}) 'top2) 0) -- [5 3]
(at (at (select {top2: (top v 2) by: g from: Tg}) 'top2) 1) -- [7 2]
(at (at (select {top2: (top v 2) by: g from: Tg}) 'top2) 2) -- [9 8]
;; by-group result order is unspecified (hash bucket order), so pin each
;; group with where: rather than indexing a fixed position.
(at (at (select {top2: (top v 2) by: g where: (== g 'A) from: Tg}) 'top2) 0) -- [5 3]
(at (at (select {top2: (top v 2) by: g where: (== g 'B) from: Tg}) 'top2) 0) -- [7 2]
(at (at (select {top2: (top v 2) by: g where: (== g 'C) from: Tg}) 'top2) 0) -- [9 8]
;; order-independent set check across all groups.
(asc (raze (at (select {top2: (top v 2) by: g from: Tg}) 'top2))) -- [2 3 5 7 8 9]

;; Multi-key per-group bot.
(set Tg2 (table [g h v] (list [A A A B B B] [X Y X X Y Y] [1 2 3 4 5 6])))
Expand Down
10 changes: 6 additions & 4 deletions test/rfl/integration/canonical_h2o.rfl
Original file line number Diff line number Diff line change
Expand Up @@ -125,10 +125,12 @@
(set Tq8f (table [id v] (list [A A A B B C C C C] [3.0 1.0 5.0 2.0 7.0 4.0 9.0 6.0 8.0])))
(type (at (at (select {t: (top v 2) by: id from: Tq8f}) 't) 0)) -- 'F64
;; K > grp_cnt → cell shorter than K (matches standalone topk_take_vec)
;; Tq8 group B has 2 rows {2,7}; K=3 → cell length 2
(count (at (at (select {t: (top v3 3) by: id6 from: Tq8}) 't) 1)) -- 2
;; K=1 → 1-element cell, equivalent to (max v3) wrapped in a vec
(at (at (select {t: (top v3 1) by: id6 from: Tq8}) 't) 0) -- [5]
;; Tq8 group B has 2 rows {2,7}; K=3 → cell length 2. by-group order is
;; unspecified, so pin group B with where: instead of a fixed index.
(count (at (at (select {t: (top v3 3) by: id6 where: (== id6 'B) from: Tq8}) 't) 0)) -- 2
;; K=1 → 1-element cell, equivalent to (max v3) wrapped in a vec.
;; Pin group A (max {3,1,5} = 5) rather than indexing position 0.
(at (at (select {t: (top v3 1) by: id6 where: (== id6 'A) from: Tq8}) 't) 0) -- [5]

;; ─── Composite-key correctness regression for the atom_eq fix ─────
;;
Expand Down
8 changes: 5 additions & 3 deletions test/rfl/integration/fused_group_parity.rfl
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,11 @@
;; (== 0N 0)=false, (!= 0N 0)=true in src/ops/cmp.c ray_neq_fn), NOT a
;; bug. g=0 keeps {1,2}→c=2 ; g=1 keeps {null,4,5}→c=3 ; sum 5.
(sum (at (select {c: (count v) from: Tn where: (!= v 0) by: g}) 'c)) -- 5
;; cross-check the per-group counts directly
(at (at (select {c: (count v) from: Tn where: (!= v 0) by: g}) 'c) 0) -- 2
(at (at (select {c: (count v) from: Tn where: (!= v 0) by: g}) 'c) 1) -- 3
;; cross-check the per-group counts directly. by-group order is
;; unspecified, so pin each group with an extra predicate rather than
;; indexing a fixed position.
(at (at (select {c: (count v) from: Tn where: (and (!= v 0) (== g 0)) by: g}) 'c) 0) -- 2
(at (at (select {c: (count v) from: Tn where: (and (!= v 0) (== g 1)) by: g}) 'c) 0) -- 3

;; A nullable agg-input column must aggregate null-aware; a stored
;; sentinel for the null would otherwise be summed as a real value.
Expand Down
8 changes: 5 additions & 3 deletions test/rfl/mem/heap_coverage.rfl
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,8 @@ FV1 -- [1.5 2.5 3.5]
(set GT (table [g v] (list (% (til 100000) 1000) (til 100000))))
(count (select {s: (sum v) from: GT by: g})) -- 1000
;; group g==0 holds v in {0,1000,..,99000}: 1000*(0+..+99) = 4950000.
(at (at (select {s: (sum v) from: GT by: g}) 's) 0) -- 4950000
;; by-group order over 1000 groups is unspecified, so pin g==0 with where:.
(at (at (select {s: (sum v) from: GT by: g where: (== g 0)}) 's) 0) -- 4950000

;; ════════════════════════════════════════════════════════════════════════════
;; 9. Lazy-graph release (heap.c:511-518, 615, 710-713).
Expand Down Expand Up @@ -356,8 +357,9 @@ FV1 -- [1.5 2.5 3.5]
(set GT2 (table [g v] (list (% (til 200000) 5000) (til 200000))))
(count (select {s: (sum v) from: GT2 by: g})) -- 5000
;; group g==0 holds v in {0,5000,..,195000}: 5000*(0+..+39) = 3900000.
;; Pin it so an arena-block overflow can't scramble the aggregated payload.
(at (at (select {s: (sum v) from: GT2 by: g}) 's) 0) -- 3900000
;; by-group order over 5000 groups is unspecified; pin g==0 with where:
;; so an arena-block overflow can't scramble the aggregated payload.
(at (at (select {s: (sum v) from: GT2 by: g where: (== g 0)}) 's) 0) -- 3900000

;; ════════════════════════════════════════════════════════════════════════════
;; 12. ray_heap_init no-op when already initialized (heap.c:1106).
Expand Down
37 changes: 18 additions & 19 deletions test/rfl/null/grouped_agg_null_correctness.rfl
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,18 @@
(at (at (select {a: (avg v) from: T by: g}) 'a) 0) -- 2.3333333333333335

;; ----- All-null group MIN returns typed null, not DBL_MAX / 0 -----
;; by-group result order is hash-bucket order (unspecified), so pin each
;; group with where: instead of indexing a fixed position.
(set Tn (table [v g] (list [0N 0N 5 6] [0 0 1 1])))
(set Rn (select {m: (min v) from: Tn by: g}))
(nil? (at (at Rn 'm) 0)) -- true
(at (at Rn 'm) 1) -- 5
(nil? (at (at (select {m: (min v) from: Tn by: g where: (== g 0)}) 'm) 0)) -- true
(at (at (select {m: (min v) from: Tn by: g where: (== g 1)}) 'm) 0) -- 5

;; ----- All-null group MAX returns typed null -----
(nil? (at (at (select {m: (max v) from: Tn by: g}) 'm) 0)) -- true
(nil? (at (at (select {m: (max v) from: Tn by: g where: (== g 0)}) 'm) 0)) -- true

;; ----- All-null group FIRST/LAST return typed null -----
(nil? (at (at (select {f: (first v) from: Tn by: g}) 'f) 0)) -- true
(nil? (at (at (select {l: (last v) from: Tn by: g}) 'l) 0)) -- true
(nil? (at (at (select {f: (first v) from: Tn by: g where: (== g 0)}) 'f) 0)) -- true
(nil? (at (at (select {l: (last v) from: Tn by: g where: (== g 0)}) 'l) 0)) -- true

;; ----- FIRST/LAST skip null prefix/suffix (first/last non-null semantics) -----
(set Tp (table [v g] (list [0N 0N 7 8] [0 0 0 0])))
Expand All @@ -29,27 +30,25 @@

;; ----- F64 equivalents — same accumulator paths, NaN-skip variant -----
(set Tf (table [v g] (list (as 'F64 [0N 0N 3.0 4.0]) [0 0 1 1])))
(nil? (at (at (select {m: (min v) from: Tf by: g}) 'm) 0)) -- true
(at (at (select {m: (min v) from: Tf by: g}) 'm) 1) -- 3.0
(nil? (at (at (select {m: (max v) from: Tf by: g}) 'm) 0)) -- true
(nil? (at (at (select {f: (first v) from: Tf by: g}) 'f) 0)) -- true
(nil? (at (at (select {l: (last v) from: Tf by: g}) 'l) 0)) -- true
(nil? (at (at (select {m: (min v) from: Tf by: g where: (== g 0)}) 'm) 0)) -- true
(at (at (select {m: (min v) from: Tf by: g where: (== g 1)}) 'm) 0) -- 3.0
(nil? (at (at (select {m: (max v) from: Tf by: g where: (== g 0)}) 'm) 0)) -- true
(nil? (at (at (select {f: (first v) from: Tf by: g where: (== g 0)}) 'f) 0)) -- true
(nil? (at (at (select {l: (last v) from: Tf by: g where: (== g 0)}) 'l) 0)) -- true

;; ----- F64 AVG divisor excludes NaN-tagged null rows -----
(set Tfa (table [v g] (list (as 'F64 [1.0 2.0 0N 4.0]) [0 0 0 0])))
(at (at (select {a: (avg v) from: Tfa by: g}) 'a) 0) -- 2.3333333333333335

;; ----- PROD on all-null group returns typed null (not 0 or initial seed) -----
(set Tprod (table [v g] (list [0N 0N 2 3] [0 0 1 1])))
(set Rprod (select {p: (prod v) from: Tprod by: g}))
(nil? (at (at Rprod 'p) 0)) -- true
(at (at Rprod 'p) 1) -- 6
(nil? (at (at (select {p: (prod v) from: Tprod by: g where: (== g 0)}) 'p) 0)) -- true
(at (at (select {p: (prod v) from: Tprod by: g where: (== g 1)}) 'p) 0) -- 6

;; ----- PROD on F64 all-null group returns typed null (no NaN bleed) -----
(set Tprf (table [v g] (list (as 'F64 [0N 0N 2.0 3.0]) [0 0 1 1])))
(set Rprf (select {p: (prod v) from: Tprf by: g}))
(nil? (at (at Rprf 'p) 0)) -- true
(at (at Rprf 'p) 1) -- 6.0
(nil? (at (at (select {p: (prod v) from: Tprf by: g where: (== g 0)}) 'p) 0)) -- true
(at (at (select {p: (prod v) from: Tprf by: g where: (== g 1)}) 'p) 0) -- 6.0

;; ----- Mixed null and non-null rows: PROD multiplies only non-null values -----
(set Tprx (table [v g] (list [2 0N 3 0N 5] [0 0 0 0 0])))
Expand All @@ -71,5 +70,5 @@
;; ----- STDDEV/VAR on a group with insufficient non-null rows is null -----
;; Population variance needs ≥1 non-null; sample variance needs ≥2.
(set Tv (table [v g] (list [0N 0N 1 2 3] [0 0 1 1 1])))
(nil? (at (at (select {s: (stddev v) from: Tv by: g}) 's) 0)) -- true
(nil? (at (at (select {s: (var v) from: Tv by: g}) 's) 0)) -- true
(nil? (at (at (select {s: (stddev v) from: Tv by: g where: (== g 0)}) 's) 0)) -- true
(nil? (at (at (select {s: (var v) from: Tv by: g where: (== g 0)}) 's) 0)) -- true
15 changes: 9 additions & 6 deletions test/rfl/ops/fuse_branch_cov.rfl
Original file line number Diff line number Diff line change
Expand Up @@ -81,14 +81,17 @@
;; ════════════════════════════════════════════════════════════════════════
(set Tg (table [k v] (list ['A 'B 'A 'B 'C] [1 2 3 4 5])))
;; group by k, sum v, with an element-wise agg input (v*2).
;; groups A,B,C in first-appearance order: A=(1+3)*2=8, B=(2+4)*2=12, C=5*2=10.
;; per group: A=(1+3)*2=8, B=(2+4)*2=12, C=5*2=10.
(sum (at (select {s: (sum (* v 2)) by: k from: Tg}) 's)) -- 30
;; per-group values (not just the total) — a wrong grouping that still
;; totals 30 would slip past the (sum ...) check above.
(at (at (select {s: (sum (* v 2)) by: k from: Tg}) 's) 0) -- 8
(at (at (select {s: (sum (* v 2)) by: k from: Tg}) 's) 1) -- 12
(at (at (select {s: (sum (* v 2)) by: k from: Tg}) 's) 2) -- 10
(at (at (select {s: (sum (* v 2)) by: k from: Tg}) 'k) 0) -- 'A
;; totals 30 would slip past the (sum ...) check above. by-group order
;; is unspecified (hash bucket order), so pin each key with where:.
(at (at (select {s: (sum (* v 2)) by: k where: (== k 'A) from: Tg}) 's) 0) -- 8
(at (at (select {s: (sum (* v 2)) by: k where: (== k 'B) from: Tg}) 's) 0) -- 12
(at (at (select {s: (sum (* v 2)) by: k where: (== k 'C) from: Tg}) 's) 0) -- 10
(at (at (select {s: (sum (* v 2)) by: k where: (== k 'A) from: Tg}) 'k) 0) -- 'A
;; order-independent set check across all groups.
(asc (at (select {s: (sum (* v 2)) by: k from: Tg}) 's)) -- [8 10 12]
;; sorted select — exercises OP_SORT column child counting.
;; v column is [1 2 3 4 5]; projecting it preserves row order.
(at (at (select {v: v from: Tg}) 'v) 0) -- 1
Expand Down
Loading
Loading