Skip to content

fix: CREATE TABLE emits sqlite_autoindex_* for declared composite keys (#687) - #716

Open
dpsiderius wants to merge 2 commits into
fix/686-rowid-alias-bfrom
fix/687-emit-autoindex
Open

dpsiderius wants to merge 2 commits into
fix/686-rowid-alias-bfrom
fix/687-emit-autoindex

Conversation

@dpsiderius

Copy link
Copy Markdown
Contributor

Stacked on #686 (fix/686-rowid-alias-b) — merge that first.

What

CREATE TABLE now allocates a root page and writes a sqlite_master row
(type='index', name=sqlite_autoindex_<table>_<n>, sql IS NULL) for
each constraint SQLite would autoindex — a declared composite PRIMARY KEY or UNIQUE — using the numbering rule #685 already derived, all
inside one transaction. MasterEntry::sql became Option<String> so
NULL can be represented (all call sites updated).

Before/after (measured against the pinned oracle)

Before: a table this crate created with a declared composite key made
stock sqlite3 report "database disk image is malformed (11)" on any
write or integrity_check. After: integrity_check reports ok, the
oracle can INSERT into the table, and a duplicate composite key is
correctly rejected — matching the sqlite_master row shape SQLite itself
produces.

Known gap, out of scope, flagged not fixed: WITHOUT ROWID table
storage is independently broken (stored as an ordinary rowid b-tree, not
an index b-tree) — unrelated to autoindexing. The WITHOUT ROWID test in
this PR skips integrity_check for that reason and only asserts the
autoindex-count claim this ticket owns.

Test plan

  • Oracle-diffed: sqlite_master row shape, integrity_check, oracle
    INSERT after our CREATE, our INSERT enforcing uniqueness on an
    existing autoindex, rowid-alias/WITHOUT ROWID getting no autoindex.
  • make test, make lint, make test-corpus, make check-mvl-limit, make check-mod-files, make assurance all pass.

Refs: 001/Req-*, #685
Closes #687

spend: matched estimate

#687)

CREATE TABLE with a declared composite PRIMARY KEY/UNIQUE constraint
created no autoindex b-tree or sqlite_master row, so the oracle
answered any write or integrity_check on such a table with "database
disk image is malformed (11)". Opcode::CreateTable now allocates a
root page and a sql IS NULL sqlite_master row for every constraint
schema::autoindex_key_lists (already written and tested by #685) says
stock SQLite would autoindex, all inside the CreateTable exec's own
write. Rowid-alias and WITHOUT ROWID primary keys still consume no
number.

btree::MasterEntry::sql is now Option<String> so a NULL sql column can
be represented -- previously always Value::Text, even for an empty
string, which the autoindex row's NULL requirement needed.

Refs: 010/Req-8, #685
#716 made CREATE TABLE emit sqlite_autoindex_* b-trees and
sqlite_master rows for declared composite PRIMARY KEY/UNIQUE
constraints, closing #687. The insert.rs module doc still claimed
this codebase doesn't auto-create those entries and that the
constraint isn't enforced — both now false. Verified on this
branch: a composite-PK table created here rejects a duplicate key
through our own engine (SQLite result code 2067), and the pinned
3.53.4 oracle opens the file, reports PRAGMA integrity_check ok, and
independently rejects the same duplicate. Grepped src/ and
.openspec/ for the same claim in other doc comments/specs; found no
other stale instance (spec 010's write-up already reflects the fix
via its "Closed by #687" note, and the delete.rs/update.rs comments
describe a different, still-real case — an on-disk autoindex whose
columns can't be recovered from DDL).

spend: well under estimate (doc-only, single comment block)
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.

fix: CREATE TABLE does not emit sqlite_autoindex_* for declared composite keys (oracle calls the file malformed)

1 participant