You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/rfcs/arbitrary-boolean-expressions-with-subqueries.md
+36-1Lines changed: 36 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -7,7 +7,7 @@ contributors:
7
7
- ilia
8
8
- kev
9
9
created: 2026-01-27
10
-
last_updated: 2026-01-27
10
+
last_updated: 2026-02-10
11
11
prd: N/A
12
12
prd_version: N/A
13
13
---
@@ -376,6 +376,40 @@ This handles all race conditions:
376
376
| Value enters in txn T, exits in txn T+1 while query running | Same — `moved_out_tags` records hash from T+1's move-out; T's query results filtered |
377
377
| Same hash at different positions (`x IN sq1 OR x IN sq2`) | Position-aware filtering only checks the triggering position |
378
378
| Partial exit from multi-value query ([A, B] queried, A exits) | Per-row filtering: row with A skipped, row with B kept |
379
+
|`find_position_for_sublink` re-derivation picks wrong position (same subquery in both IN and NOT IN) | Pre-existing TODO, low practical risk — requires identical subquery text in both positive and negated form. Fix: thread already-known position through instead of re-deriving. |
380
+
381
+
##### Dual tag format: snapshot files vs wire/API
382
+
383
+
Snapshot file tags (used for `moved_out_tags` filtering) use a **different format** from the
384
+
wire/API tags sent to clients:
385
+
386
+
-**Wire format** (in JSON headers, sent to clients): slash-delimited strings per disjunct —
387
+
e.g. `"hash1/hash2/"`, `"//hash3"`. One string per disjunct, positions within a disjunct
388
+
separated by `/`. Unchanged from the design above. Clients use these for their own
389
+
tag-based inclusion tracking.
390
+
-**Snapshot file format** (internal, used for filtering): flat list of per-position hashes —
391
+
one hash per DNF position, no delimiters. `Enum.at(tags, position)` directly yields the
392
+
hash for that position. These tags never leave the server.
393
+
394
+
**Why the flat format is sufficient**: since `moved_out_tags` is now position-aware (tracking
395
+
`{position, tags_to_skip}` instead of just `tags_to_skip`), filtering only needs to check
396
+
the hash at a single position index. No string splitting or multi-position comparison is
397
+
needed. The flat list is effectively a position-indexed array.
398
+
399
+
**Worked example** — shape `WHERE x IN sq1 OR x IN sq2`, tag_structure `[[x], [x]]`:
0 commit comments