Skip to content

Require full unique indexes for lookup tables - #915

Open
workstonedai-collab wants to merge 1 commit into
simonw:mainfrom
workstonedai-collab:fix/lookup-full-unique-index
Open

workstonedai-collab wants to merge 1 commit into
simonw:mainfrom
workstonedai-collab:fix/lookup-full-unique-index

Conversation

@workstonedai-collab

@workstonedai-collab workstonedai-collab commented Oct 24, 2026 •

Copy link
Copy Markdown

Fixes #914.

Problem

Table.lookup() checked only whether an index covered the lookup columns. A non-unique index could therefore be mistaken for the required uniqueness constraint, and a partial unique index could be treated as equivalent to a full unique index. This could allow duplicate lookup rows.

Behavior

  • Before: an ordinary or partial index could prevent lookup() from creating the required full unique index.
  • After: lookup() reuses an existing full unique index on exactly the lookup columns, or creates one when needed.
  • Existing indexes are preserved.
  • If existing data violates the required uniqueness constraint, the unique-index creation fails with sqlite3.IntegrityError before any rows are changed.

This change is limited to Table.lookup() unique-index detection and creation. It makes no broad performance or indexing claims and is independent of #913; both are based on the same upstream commit.

Validation

Validation was run by Codex:

  • Existing lookup tests, new regression tests, and three standalone probes: 18 passed.
  • Repository lookup tests: 15 passed after the fix (4 failed before the fix).
  • Full suite: 1502 passed, 16 skipped, 33 warnings.
  • mypy: 10 source files passed.
  • Black, flake8, and diff checks passed.

Implementation and tests: MiniMax. Review and validation: Codex.


📚 Documentation preview 📚: https://sqlite-utils--915.org.readthedocs.build/en/915/

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.

lookup() treats ordinary and partial indexes as unique lookup constraints

1 participant