Fix: idx_group_keys_root migration creates index on missing column

The Phase 2f `canonical_root_post_id` column was added to both the
CREATE TABLE block (for fresh DBs) and a conditional ALTER TABLE (for
upgrading DBs). The matching CREATE INDEX, however, was inlined in the
CREATE TABLE block — which runs BEFORE the ALTER. On an upgrading DB
with the v0.6.1 schema, CREATE TABLE IF NOT EXISTS is a no-op against
the existing (old) table, so the table still lacks the column when the
index statement runs and SQLite bails with "Error code 1: SQL error or
missing database" at offset 74.

Caught on the v0.6.2 anchor deploy — the anchor died right after start
because its v0.6.1 DB couldn't apply migrations.

Fix: remove the index from the CREATE TABLE block; run an unconditional
`CREATE INDEX IF NOT EXISTS idx_group_keys_root ...` in the migration
section, after the conditional ALTER has added the column. Idempotent
in both paths — fresh DB (column from CREATE TABLE) and upgrading DB
(column from ALTER).

121 / 121 core tests pass.
This commit is contained in:
Scott Reimers 2026-04-23 00:00:06 -04:00
parent de6aa06acf
commit 88dfbd26f4

View file

@ -287,7 +287,10 @@ impl Storage {
canonical_root_post_id BLOB
);
CREATE INDEX IF NOT EXISTS idx_group_keys_circle ON group_keys(circle_name);
CREATE INDEX IF NOT EXISTS idx_group_keys_root ON group_keys(canonical_root_post_id);
-- idx_group_keys_root is created in the migration block below, after
-- ALTER TABLE has ensured the canonical_root_post_id column exists
-- on upgraded DBs (CREATE TABLE IF NOT EXISTS is a no-op against an
-- older schema, so the column may still be missing at this point).
CREATE TABLE IF NOT EXISTS group_member_keys (
group_id BLOB NOT NULL,
member BLOB NOT NULL,
@ -658,10 +661,18 @@ impl Storage {
)?.query_row([], |row| row.get::<_, i64>(0))?;
if has_canonical_root == 0 {
self.conn.execute_batch(
"ALTER TABLE group_keys ADD COLUMN canonical_root_post_id BLOB DEFAULT NULL;
CREATE INDEX IF NOT EXISTS idx_group_keys_root ON group_keys(canonical_root_post_id);"
"ALTER TABLE group_keys ADD COLUMN canonical_root_post_id BLOB DEFAULT NULL;"
)?;
}
// Ensure the root-lookup index exists on every startup. IF NOT EXISTS
// makes this idempotent; runs for both fresh DBs (where CREATE TABLE
// above populated the column) and just-upgraded DBs (where the ALTER
// above did). Before this fix, the index was inlined in the CREATE
// TABLE block and tried to reference a column that didn't exist yet
// on upgrading DBs.
self.conn.execute_batch(
"CREATE INDEX IF NOT EXISTS idx_group_keys_root ON group_keys(canonical_root_post_id);"
)?;
// Add device_role column to peers if missing (Active CDN replication)
let has_device_role = self.conn.prepare(