You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The other half of #685. That ticket fixed adopting a stock-created
file: an existing sqlite_autoindex_* is now recovered and maintained.
This one fixes producing one.
CREATE TABLE with a declared composite PRIMARY KEY or UNIQUE
constraint currently creates no sqlite_autoindex_* b-tree and no sqlite_master row for it. Stock SQLite then reads the DDL, expects the
index, does not find it, and reports "database disk image is malformed
(11)" on any write or integrity_check.
So a table this crate creates with a declared composite key is not a
valid SQLite database, which is a direct hit on the crate's headline
byte-compatibility claim.
Recorded today in src/codegen/stmt/insert.rs's module doc:
A composite PRIMARY KEY(...)/UNIQUE(...)table constraint with no
backing CREATE INDEX/on-disk index (this codebase doesn't
auto-create sqlite_autoindex_* entries yet) has no real index to seek
against, so it still isn't enforced — that's a CREATE TABLE-side gap,
not an INSERT-codegen one.
#685 closed the INSERT-codegen half. This is the CREATE TABLE half.
Scope
src/codegen/ddl/ — CREATE TABLE must, for each constraint that
SQLite would give an autoindex:
allocate an index b-tree root page;
write a sqlite_master row with type = 'index', name = sqlite_autoindex_<table>_<n>, tbl_name = <table>, the new
root page, and sql = NULL;
Different blast radius. #685 touches the schema reader and refuses
unsafe writes; this touches DDL codegen and the freelist/page
allocator. #685 is what unblocks the SQE integration, because SQE's
warehouse files are created by C SQLite and only read and written by
this crate — it never creates them.
Complexity
Estimate: medium Reasoning: The numbering rule and its tests already exist from #685. The work is DDL codegen: allocating a root page per autoindex,
emitting the sqlite_master rows with a NULL sql, and keeping the
whole thing inside one transaction so a partial CREATE TABLE cannot
leave a table with some of its indexes. Populating the index is trivial
for a fresh empty table.
Acceptance Criteria
A table created here with a composite PRIMARY KEY passes the
oracle's PRAGMA integrity_check and accepts oracle writes
No "database disk image is malformed (11)" from the oracle on any
created shape
sqlite_master rows match the oracle's byte-for-byte, including sql IS NULL
Round trip: create here, write with the oracle, read back here
Rowid-alias and WITHOUT ROWID tables gain no autoindex
A failed CREATE TABLE leaves no partial index behind
Description
The other half of #685. That ticket fixed adopting a stock-created
file: an existing
sqlite_autoindex_*is now recovered and maintained.This one fixes producing one.
CREATE TABLEwith a declared compositePRIMARY KEYorUNIQUEconstraint currently creates no
sqlite_autoindex_*b-tree and nosqlite_masterrow for it. Stock SQLite then reads the DDL, expects theindex, does not find it, and reports "database disk image is malformed
(11)" on any write or
integrity_check.So a table this crate creates with a declared composite key is not a
valid SQLite database, which is a direct hit on the crate's headline
byte-compatibility claim.
Recorded today in
src/codegen/stmt/insert.rs's module doc:#685 closed the INSERT-codegen half. This is the
CREATE TABLEhalf.Scope
src/codegen/ddl/—CREATE TABLEmust, for each constraint thatSQLite would give an autoindex:
sqlite_masterrow withtype = 'index',name = sqlite_autoindex_<table>_<n>,tbl_name = <table>, the newroot page, and
sql = NULL;implements in
ddl_reader::autoindex_key_lists— declaration order,column-level constraints included, rowid-alias and
WITHOUT ROWIDprimary keys skipped and consuming no number, redundant constraints
collapsed.
The rule is already written and tested; this ticket consumes it rather
than re-deriving it.
Why it is separate from #685
Different blast radius. #685 touches the schema reader and refuses
unsafe writes; this touches DDL codegen and the freelist/page
allocator. #685 is what unblocks the SQE integration, because SQE's
warehouse files are created by C SQLite and only read and written by
this crate — it never creates them.
Complexity
Estimate: medium
Reasoning: The numbering rule and its tests already exist from
#685. The work is DDL codegen: allocating a root page per autoindex,
emitting the
sqlite_masterrows with a NULLsql, and keeping thewhole thing inside one transaction so a partial
CREATE TABLEcannotleave a table with some of its indexes. Populating the index is trivial
for a fresh empty table.
Acceptance Criteria
PRIMARY KEYpasses theoracle's
PRAGMA integrity_checkand accepts oracle writescreated shape
sqlite_masterrows match the oracle's byte-for-byte, includingsql IS NULLWITHOUT ROWIDtables gain no autoindexCREATE TABLEleaves no partial index behindRefs: 010/Req-8, #685