Skip to content

fix: preserve full-replay history and improve SQL test planning - #801

Merged
kvlonge merged 14 commits into
mainfrom
fix/sql-test-chain-scaling
Sep 24, 2026
Merged

kvlonge merged 14 commits into
mainfrom
fix/sql-test-chain-scaling

Conversation

@kvlonge

@kvlonge kvlonge commented Sep 24, 2026

Copy link
Copy Markdown
Contributor

Why

Full replay could replace an incremental table with only its recent cursor window, silently losing history. SQL-test chains could grow exponentially, and duplicate planning implementations caused inconsistent behavior.

Changes

  • Preserve full history for replay_on_change full, including runtime-resolved and microbatch bounds; show resolved replay ranges.
  • Use one native SQL-test planner and renderer, render shared upstream models once, and omit execution-plan payloads from compile-only responses.
  • Compare model tests on explicitly listed expected columns by name, with clear unknown-column and missing-mock errors.
  • Accept formatter file paths and preserve leading CTE comments.
  • Support multiple and kind-prefixed lineage targets, directional selector expansion, and exclusions.

Verification

  • DuckDB CLI regressions cover full-history replay against a fresh-build oracle, SQL-test chains and partial expectations, repeat-compile diagnostics, formatting, and lineage.
  • Focused Rust tests, clippy, Python tests, and bounded independent review with both findings fixed.
  • Performance fingerprints updated for intentional compiled-SQL changes; verification results recorded in the delivery summary.

…d comparison implementation

The Python SQL-test planner and comparison renderer duplicated the native
implementation used by compile, and the Python textual chain inlined every
upstream model once per dependency path.

- Native planning now returns each test's chain and assertion steps, model
  names and warnings, with optional rendered SQL, in one batch call.
- plan/build/test build SqlTestPlanEntry from the native plan; Python keeps
  fixture validation and plan metadata only.
- Comparison SQL, difference samples, compile target files and runtime
  artifacts all render natively, using the SQL-analysis dialect for CTE
  lifting.
- Each distinct missing mock is reported once per test instead of once per
  dependency path or chain step.
- Textual assertion fallbacks lift their chain CTEs to the top level.
- Remove the Python assembly, analysis assembly, comparison helpers and
  dead wrappers.
Native plan output carried every chain step's full upstream closure, so
long unmocked chains produced step payloads quadratic in chain length.

- Populate resolvedSql, liftedCtes and comparisonBodySql only for steps
  with an expected CTE or an assertion that reads the step's actual CTE,
  using one shared rendered-step helper for planner and renderer.
- Skip empty steps when building manifest test compiled_code.
- Add a long-chain regression test bounding step SQL by the rendered SQL
  and proving unrendered step SQL cannot change the rendered comparison.
SQL unit tests compared whole rows by position, so an __expected__ CTE had
to list every model column in model order.

- The native planner reads each expected CTE's column list syntactically
  (projection names, VALUES alias lists, first set-operation branch) with
  the SQL-analysis dialect, keeping authored identifier spelling. It works
  without SQL analysis and falls back to full-row comparison when the list
  is not explicit.
- Comparison counts and difference samples project both sides to the listed
  columns; the actual row count still counts every actual row.
- With SQL analysis and authoritative model columns, unknown expected
  columns fail statically before connecting. Otherwise a failed comparison
  probes the actual step's columns with a zero-row query and reports the
  missing columns as T005 instead of the warehouse error.
- Document the rule in the agent testing skill references.
Planner ERROR warnings for a SQL test, such as a reference with no mock,
were only visible through `sqb test --inspect`.

- `plan_sql_tests` now turns a test's distinct ERROR-severity planning
  messages into fixture diagnostics, so `sqb test`, `sqb build` and
  `sqb test --inspect` stop with the existing "Invalid SQL test fixtures"
  error before execution. WARNING-severity warnings are unchanged.
- Compile artifact planning reports the same messages as S000 test-phase
  compile diagnostics from the single native batch call. They count in the
  compile summary, appear in --json, and make compile exit 1. Tests with
  planning errors are not stored in the SQL-test artifact cache, so warm
  compiles report them again.
@kvlonge
kvlonge enabled auto-merge (squash) September 24, 2026 07:23
@kvlonge
kvlonge merged commit d616759 into main Sep 24, 2026
28 checks passed
@kvlonge
kvlonge deleted the fix/sql-test-chain-scaling branch September 24, 2026 07:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant