Rindle docs and package mapSkip to main content

Module source_common

Module source_common 

Source
Expand description

Backend-agnostic source machinery, shared by the memory (BTree) and SQLite leaves. This module references no BTree, no rusqlite, AND no Node — it is generic over S: RowStream and deals only in rows (OwnedRow) and source changes (SourceChange). It is the seam the spec calls source_common (04 §4.6): the two leaves differ only in the concrete S they pass in.

A source emits rows, not nodes. The overlay splice, the start/constraint/ filter chain, the k-way merge, and the push/edit-split orchestration here all operate on rows. A row becomes a Node (row + lazily attached relationships) only at the connection boundaryGraph::fetch on a SourceConn wraps each emitted row in a leaf node on the read path, and the SourceConn’s push driver wraps each SourceChange into a node-bearing Change on the write path. Downstream joins then attach relationships. So the Node concept lives entirely above this module.

What lives here (faithful ports of memory-source.ts, which is the JS root even though 05/TableSource consume it verbatim):

The connection/overlay types (Connection, ConnectionFilters, Overlay, Overlays, RowPredicate) live here too because their shape is identical across backends (04 §4.1, §4.2).

Structs§

ConnTable
A source’s connection registry: the Connections plus a generational free-list, so a torn-down connection’s slot is RECYCLED rather than leaked under query churn (the source-side analogue of the graph arena’s node/storage reuse). Shared by both Source backends (the memory BTree leaf and the SQLite TableSource) so the reuse logic — and its stale-ConnId fail-fast — lives in exactly one place and the two backends cannot drift apart.
Connection
One connection (one downstream output). Self-joins make two. Mirrors Connection (memory-source.ts:75). IDENTICAL shape to 05’s so this module stays backend-agnostic. The mutable bits are Cell so they bump during a push without a &mut borrow held across a vend (foundations §6.2).
ConnectionFilters
The fully-pushed-down filter + the precomputed PK constraint. The memory leaf only evaluates predicate; pk_constraint is hoisted from the condition at connect time (the JS recomputes it per fetch via primaryKeyConstraintFrom Filters — we hoist since the condition is fixed per connection). fully_ applied mirrors SourceInput.fullyAppliedFilters (memory-source.ts:180).
Overlay
The single in-flight source change, epoch-tagged. Rows are OWNED (overlays are materialized — foundations §3.3). Mirrors Overlay (memory-source.ts:59); IDENTICAL to 05’s (it lives here).
Overlays
The narrowed add/remove pair fed to the splice (Overlays, memory-source.ts:64). Both owned.

Enums§

Operand
One side of a SqlCondition::Simple. A Column lowers to its quoted identifier (resolved from the schema at build time); a Literal lowers to a bound ? param (query-builder.ts valuePositionToSQL).
SqlCondition
A filter condition lowered to a backend-neutral AST — the input the SQLite leaf’s build_select_query walks to emit the SELECT WHERE (port of query-builder.ts NoSubqueryCondition, subqueries already stripped). Pure data, no rusqlite: the memory backend ignores it entirely (it filters via RowPredicate); only the SQLite leaf lowers it to SQL text, leaving the predicate to narrow only the (not-in-SQL) overlay rows. Column operands are already-resolved ColIds; a literal operand’s OwnedValue variant selects its SQLite storage form (the JS getJsTypetoSQLiteType).
SqlOp
Comparison / membership operators (query-builder.ts simpleConditionToSQL). Most lower to their raw SQL spelling verbatim; In/NotIn lower to a json_each(?) subquery over a JSON-array literal (query-builder.ts:196-205); the Like family appends ESCAPE '\' and Ilike lowers both sides through lower(...) (query-builder.ts likeConditionToSQL). Is/IsNot are the NULL-aware equality operators in the JS SimpleOperator set (ast.ts:37): they reach the WHERE verbatim (a user .where(c, 'IS', null), and the engine’s NOT EXISTSfield IS NOT literal rewrite, resolve-scalar-subqueries.ts:176). Distinct from the start-bound’s nullable-aware =/IS choice (§3.7), which is a SEPARATE code path keyed on column optionality, not a user operator.

Functions§

compare_rows_rev
reverse=falsecompare_rows(sort, a, b); reverse=true ⇒ its negation. Defined ONCE so the cursor seek direction, the overlay-add splice position, the remove-suppress equality, the start gate, and the k-way merge all agree.
compute_overlays
The full ordered narrowing pipeline: startAt → constraint → each non-empty multiConstraint → filter (computeOverlays, memory-source.ts:722). Pure — no leaf access. gate_sort/reverse are the connection comparator — the one the downstream start gate (generate_with_start) applies — NOT the scan’s constrained index sort (see overlays_for_start_at’s comparator invariant; the splice’s interleaving comparator is a separate parameter of generate_with_overlay).
generate_with_constraint
Trim trailing rows once the constraint stops matching — a break, NOT a filter (generateWithConstraint, memory-source.ts:505). Valid because the chosen index is sorted by the constraint columns first, so once the scan passes the last matching row every subsequent row fails (§3.1).
generate_with_filter
Drop rows failing the predicate (generateWithFilter, memory-source.ts:517).
generate_with_overlay
Drive a leaf cursor through the epoch-gated, narrowed, ordered overlay splice (generateWithOverlay, memory-source.ts:697). Generic over the leaf S: RowStream — the seam both backends feed. Two comparators, one per job: sort is the index comparator the splice interleaves under (the break-safety dependency, §3.1 — it must match the scan order of rows); gate_sort is the connection comparator the start_at narrowing compares under (it must match the downstream generate_with_start gate — see overlays_for_start_at’s comparator invariant). They coincide except on a constrained scan, where the index sort leads with the constraint columns. start_at, constraint, predicate, multi_constraints narrow the overlay only (the committed rows are filtered later by generate_with_filter).
generate_with_overlay_checked
generate_with_overlay_inner
Splice already-computed overlays into an ordered row stream. Exposed for direct testing (the JS generateWithOverlayInner suite). sort/reverse are the index comparator.
generate_with_overlay_inner_unordered
Splice already-computed overlays into an unordered row stream. Exposed for the JS generateWithOverlayInnerUnordered suite.
generate_with_overlay_unordered
Unordered variant of generate_with_overlay (generateWithOverlayUnordered, memory-source.ts:885): NO start, add injected eagerly, remove suppressed by PK. Narrowing is constraint → multiConstraint → predicate (no startAt).
generate_with_overlay_unordered_checked
generate_with_start
Skip rows until the start bound is reached, then pass the rest (generateWithStart, memory-source.ts:653). Uses the connection comparator (reverse-aware). start = None ⇒ pass-through.
merge_sorted_streams
K-way min-heap merge of pre-sorted row streams under the reverse-aware comparator. Drop-clean (early close drops every sub-stream — §5.5).
overlays_for_constraint
Drop an add/remove that does not match the constraint (overlaysForConstraint, memory-source.ts:821).
overlays_for_multi_constraint
Keep an add/remove iff it matches some entry of the multiConstraint (overlaysForMultiConstraint, memory-source.ts:787).
overlays_for_start_at
Drop an add/remove that sorts strictly before start_at (overlaysForStartAt, memory-source.ts:806). Reverse-aware.
try_gen_push_and_write_with_split_edit

Type Aliases§

RowPredicate
The in-memory predicate compiled from a connection’s pushed-down filter (createPredicate, owned by 07). Rc so a fetch can clone it into the returned lazy stream without holding a RefCell borrow on connection state across the vend (the cardinal rule — foundations §6.2). The memory leaf reads columns by ColId index; a bare &Row keeps this backend-agnostic.