Skip to content

fix: change summary_messages/lineage/context_items FK from RESTRICT to CASCADE/SET NULL#254

Open
Eugene9D wants to merge 1 commit intoMartian-Engineering:mainfrom
Eugene9D:fix/summary-messages-cascade-delete
Open

fix: change summary_messages/lineage/context_items FK from RESTRICT to CASCADE/SET NULL#254
Eugene9D wants to merge 1 commit intoMartian-Engineering:mainfrom
Eugene9D:fix/summary-messages-cascade-delete

Conversation

@Eugene9D
Copy link
Copy Markdown

@Eugene9D Eugene9D commented Apr 3, 2026

Problem

summary_messages.message_id uses ON DELETE RESTRICT, but SQLite defaults to PRAGMA foreign_keys=0. This means message deletes silently succeed and leave orphaned rows in summary_messages pointing at non-existent message_ids.

Same issue affects summary_lineage.parent_summary_id and context_items.message_id/summary_id.

On a production database (~607MB, 58K messages, 1098 summaries), orphaned summary_messages rows accumulated silently over weeks.

Fix

Table Column Before After Rationale
summary_messages message_id RESTRICT CASCADE Link row has no meaning without source message
summary_lineage parent_summary_id RESTRICT CASCADE Lineage row is meaningless without parent
context_items message_id RESTRICT SET NULL Preserve context row, null out dead ref
context_items summary_id RESTRICT SET NULL Preserve context row, null out dead ref

Migration for existing databases

Adds migrateForeignKeyCascade() — idempotent table rebuild that:

  1. Checks current FK action via PRAGMA foreign_key_list
  2. Only rebuilds if RESTRICT is still present
  3. Filters orphans during INSERT INTO ... SELECT (cleans existing orphans)
  4. Rebuilds indexes

Testing

Applied locally on a 607MB production LCM database:

  • Before: orphaned summary_messages rows accumulating
  • After: 0 orphans, all 1098 summaries intact, CASCADE verified via PRAGMA foreign_key_list

…o CASCADE/SET NULL

Summary_messages used ON DELETE RESTRICT for message_id FK, but SQLite
defaults to PRAGMA foreign_keys=0, so deletes silently succeed and
leave orphaned rows in summary_messages pointing at non-existent
message_ids.

Changes:
- summary_messages.message_id: RESTRICT → CASCADE
  (when a message is deleted, its link rows auto-delete)
- summary_lineage.parent_summary_id: RESTRICT → CASCADE
  (when a parent summary is deleted, lineage rows auto-delete)
- context_items.message_id/summary_id: RESTRICT → SET NULL
  (preserve the context row but null out the dead reference)
- Add migrateForeignKeyCascade() for existing databases
  (idempotent table rebuild, cleans orphans during migration)
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