Skip to content

test: SQE's catalog as a consumer fixture family, and four ratchets it exposed (013/Req-6) - #704

Open
dpsiderius wants to merge 1 commit into
mainfrom
test/013-sqe-consumer-corpus
Open

dpsiderius wants to merge 1 commit into
mainfrom
test/013-sqe-consumer-corpus

Conversation

@dpsiderius

@dpsiderius dpsiderius commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

Why

Spec 013 Requirement 6 asks for an acceptance family built from the
consumer's real statements rather than invented SQL. SQE's Iceberg catalog
is that consumer: CREATE TABLE IF NOT EXISTS, a four-parameter INSERT,
a SELECT ... UNION, LIMIT 1 probes, a conditional UPDATE whose
rows-affected count is an optimistic-concurrency signal, and a DELETE.

What

The catalog workload as a corpus fixture family, diffed against the pinned
3.53.4 oracle: 2 passing tests and 4 #[ignore]d ratchets that this
exercise exposed, each naming the ticket that flips it — #687, #696, #697,
#698.

The ratchets are the point. They are not aspirational stubs; each one fails
today for a reason we can name, and un-#[ignore]ing it is an acceptance
criterion on the ticket it cites.

Scope note

This is Phase 7a — SQE's own named-unique-index workaround, which passes
now and proves the API. Phase 7b, the family running spec 013's literal
DDL, cannot pass until #687 and #697 land, and is deliberately not in this
PR. Requirement 6's Implementation line says which is which.

Verification

Full suite and corpus green; make lint clean on both clippy passes;
make check-assurance with no dead links. Verified from a detached clean
worktree.

spend: trivial budget, matched.

Independent of #703/#705 — can merge in any order.

Refs: 013/Req-6, #695, #687, #696, #697, #698

🤖 Generated with Claude Code

…t exposed (#695)

Spec 013 Requirement 6 says acceptance for the embedding API is spec
004's harness rather than a new one: "a consumer statement set becomes a
fixture family, diffed against pinned `sqlite3`... The first family is
*SQE*'s catalog". This is that family, and running it end to end found
four bugs that exit codes alone hid — all ten statements returned rc=0
while the resulting file was corrupt.

Not in the spike, deliberately. ADR-0008: spike code is disposed, the
evidence survives, and "test material is committed as acceptance corpus
for the real implementation — the ratchet". Spikes also do not run in CI
(`make test-spikes` lists 001-009; `ci.yml` mentions none), so a
regression guard kept there would rot unnoticed. The spike remains the
right place to *measure* — it has a counting allocator and a
worker-thread harness this suite cannot easily reproduce — but not to
guard.

Two tests pass, and they are the substantive claim:

- `catalog_queries_match_the_oracle` — SQE's read path. Existence probes
  with `LIMIT 1` that hit and miss, a namespace `UNION`, point lookups
  on the composite key, aggregates. Byte-identical to the oracle.
- `catalog_writes_match_the_oracle_and_leave_a_valid_file` — the
  compare-and-swap SQE builds its optimistic concurrency on (a
  conditional `UPDATE` that matches, then the same one as a no-op), plus
  a `DELETE`. Rows agree with the oracle *and* `PRAGMA integrity_check`
  on the file we wrote comes back `ok`. That second assertion is the one
  that bites: it is what caught #685, and it caught #687 here.

Four are `#[ignore]`d with the ticket that flips them, each written to
pass once fixed:

- **#687** `declared_composite_pk_creates_a_valid_file`. A table *we*
  create with a declared composite `PRIMARY KEY` is malformed to the
  oracle immediately, before any write, because no `sqlite_autoindex_*`
  is emitted. #685 fixed adopting a stock-created file; this is the same
  gap in the direction we control, and it is why `catalog.sql` uses a
  named `CREATE UNIQUE INDEX` — that is not a test simplification, it is
  the workaround spec 013 records SQE having adopted.
  `catalog_declared_pk.sql` is the schema SQE wants back.
- **#697** `catalog_ddl_is_idempotent`. SQE runs its DDL on every
  startup; the second run appends a duplicate `sqlite_master` row and
  leaks a root page. Verified pre-existing on `main`, not caused by
  #685.
- **#696** `a_column_named_key_is_usable`. 89 keywords we reserve that
  SQLite's `parse.y:272` `%fallback ID` treats as identifiers.
- **#698** `catalog_sql_file_runs_verbatim`. A statement beginning with a
  SQL comment is a parse error, so the fixture's own header comment made
  the file unusable — which is why the passing tests feed our side a
  comment-stripped copy while the oracle always gets the file verbatim.
  That crutch disappears when #698 closes.

The oracle is fed over stdin rather than `argv`, because a leading `--`
is read as a CLI option by `sqlite3` — worth stating, since testing it
the obvious way produces a failure that says nothing about SQL.

Verified: 1572 unit, 390 corpus (388 + 2 passing, 4 ignored), 15
sqllogictest, `make lint` clean both clippy passes,
`make check-mod-files`, assurance 86/86 and 276/276 with no dead links.

Refs: 013/Req-6, #687, #695, #696, #697, #698

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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