diff --git a/docs/superpowers/specs/2026-07-30-stability-hardening-design.md b/docs/superpowers/specs/2026-07-30-stability-hardening-design.md index 026d378..43d1529 100644 --- a/docs/superpowers/specs/2026-07-30-stability-hardening-design.md +++ b/docs/superpowers/specs/2026-07-30-stability-hardening-design.md @@ -110,9 +110,9 @@ re-test with a newer Nim runtime, or a minimal repro filed upstream). ## Proposed next phases (not started) -- **B2. Split `query/executor.nim`** (5,398 lines) into focused modules - (DML, DDL, select pipeline, transactions). Now safe to do: the full suite - guards behavior. Large diff, mechanical. +- **B2. Split `query/executor.nim`** (5,398 lines) — **DONE**: split into 15 + modules under `query/exec/`, `executor.nim` down to 1,578 lines, full suite + green (650 checks). - **C. Features** — real Raft network transport, persistence for graph/FTS/columnar engines, benchmark validation. - **ORC (blocked):** re-test `tests/orc_repro.py` against a newer Nim runtime; diff --git a/src/barabadb/query/exec/README.md b/src/barabadb/query/exec/README.md index 3caf2e2..336861e 100644 --- a/src/barabadb/query/exec/README.md +++ b/src/barabadb/query/exec/README.md @@ -1,8 +1,9 @@ # Executor package (`query/exec/`) -The original `executor.nim` was a ~5.8k-line god object. Shared pieces live here; -`../executor.nim` remains the main execution engine and **re-exports** this package -so existing `import barabadb/query/executor` keeps working. +The original `executor.nim` was a ~5.8k-line god object. It is now split into +focused modules here (1,578 lines remain); `../executor.nim` keeps statement +dispatch (`executeQueryImpl`), DDL, and transactions, and **re-exports** this +package so existing `import barabadb/query/executor` keeps working. ## Modules @@ -11,19 +12,36 @@ so existing `import barabadb/query/executor` keeps working. | `types.nim` | `ExecutionContext`, `TableDef`, `Row`, `ExecResult`, … | | `values.nim` | Null/string conversion, row payload parse/escape, SQL escapes | | `schema.nim` | Durable catalog (`_schema:tables:*`), restore, index rebuild | +| `context.nim` | Execution-context lifecycle, per-connection cloning, AST→SQL serializer for VIEW DDL | +| `helpers.nim` | Join strategy, vector parsing, correlated-table helpers | +| `params.nim` | Parameter binding — placeholder substitution, statement column metadata | +| `migrations.nim` | Migration storage — lock keys, applied/record keys, checksums (internal, not re-exported) | +| `eval.nim` | Expression evaluation (`evalExpr` and legacy variants), hybrid vector+FTS search | +| `lower.nim` | AST → IR lowering (`lowerExpr` / `lowerSelect`) | +| `rls.nim` | Row-Level Security — privilege checks and policy evaluation | +| `scan.nim` | Table scans — full scans and point reads against the LSM store | +| `dml.nim` | DML row operations — INSERT/UPDATE/DELETE row-level execution | +| `fk.nim` | Foreign-key enforcement — referential checks and cascade actions | +| `triggers.nim` | Trigger firing, `validateType`, `validateConstraints`, `applyDefaultValues` | +| `window.nim` | Window-function computation, star-row expansion | +| `plan_exec.nim` | IR plan walker (`executePlan`) — filters, projections, aggregates, joins, pivot/unpivot, graph traversal | ## Import rules -- **No cycles:** `types` → nothing in `exec/`; `values` → `types`; `schema` → `types` + `values`. -- `executor.nim` imports all three and `export`s them. +- **No cycles.** Bottom-up dependency order: + `types` → `values` → `schema` → `context`/`helpers`/`params`/`migrations` → + `eval` → `lower` → `rls` → `scan` → `dml`/`fk` → `triggers` → `window` → + `plan_exec` → `executor.nim`. +- `executor.nim` imports all modules and `export`s them (except `migrations`). - Prefer adding new shared helpers under `exec/` instead of growing `executor.nim`. -## Sensible next extractions (not done yet) +## Recursion hooks -1. `dml.nim` — `execScan` / `execInsert` / `execUpdate` / `execDelete` (needs eval/triggers hooks) -2. `rls.nim` — row-level security + privileges -3. `lower.nim` — AST → IR (`lowerExpr` / `lowerSelect`) -4. `plan_exec.nim` — IR plan walker / window functions -5. `hybrid.nim` — hybrid vector+FTS search helpers +Nim forbids circular imports, but subqueries, hybrid search, NL→SQL, and +trigger bodies are genuine recursion points between modules: they must call +back into `executePlan`, `execScan`, or the private `executeQueryImpl`, all of +which live in (or above) `executor.nim`. Those back-edges go through proc-var +hooks, wired at module scope in `executor.nim`: -Keep statement dispatch (`executeQueryImpl`) in `executor.nim` until those land. +- `eval.executePlanHook`, `eval.execScanHook`, `eval.executeQueryHook` — in `eval.nim` +- `triggers.executeQueryHook` — in `triggers.nim`