Skip to content

fix(postgres): use the utf8_ci_ai index collation for _uid and _document lookups - #996

Open
HarshMN2345 wants to merge 1 commit into
mainfrom
fix/postgres-uid-collation
Open

HarshMN2345 wants to merge 1 commit into
mainfrom
fix/postgres-uid-collation

Conversation

@HarshMN2345

Copy link
Copy Markdown
Member

Refs appwrite/appwrite#14075

The Postgres _uid and _perms unique indexes are built with COLLATE utf8_ci_ai, but lookups compared with the column default collation, so the indexes could never be used and every lookup by ID was a sequential scan.

This adds two collation hooks to SQL (empty by default, so MariaDB/MySQL/SQLite SQL is unchanged) and uses them for _uid / _document matches in getDocument (incl. FOR UPDATE), getSequences, updateDocument(s), upsertDocuments, increaseDocumentAttribute, deleteDocument(s) and Query::equal('$id', ...). Shared tables build the _perms index on _document without the collation, so _document matches stay as they are there.

Side effect: on Postgres, getDocument and equal('$id') now match IDs case-insensitively, as on MariaDB and in line with the case-insensitive _uid uniqueness.

Verification (PostgreSQL 18.3, 300k rows, plans from auto_explain on the library's own queries): before, every one of these paths ran Seq Scan / Parallel Seq Scan on the collection, _metadata and (non-shared) _perms. After, they all run Index Scan using ..._uid / ..._ukey, in both shared and non-shared mode. Postgres e2e suites: the failures are the same environment-related ones as on main, and the tests that only failed in the full run pass when run on their own.

The _uid and permissions unique indexes are built with the utf8_ci_ai
collation, but lookups compared with the column default collation, so
Postgres could never use them and every lookup by ID was a sequential
scan. Compare with the index collation through adapter hooks that are
empty for the other SQL adapters.
@coderabbitai

coderabbitai Bot commented Oct 5, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 43 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

⚙️ Run configuration
  • Configuration used: Repository: utopia-php/database/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 600f8554-66ec-4c21-be6c-aefcbb45902c
📥 Commits

Reviewing files that changed from the base of the PR and between 1c99c21 and 7681c9e.

📒 Files selected for processing (2)
  • src/Database/Adapter/Postgres.php
  • src/Database/Adapter/SQL.php
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

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