Commit 0f1690a
authored
fix: handle PostgreSQL identifier quoting in partial index predicate comparison (#5788)
## Description
Closes #5787
## Problem
After #5780, partial indexes with object literal `where` clauses are
still recreated on every migration when predicates contain multiple
conditions. PostgreSQL's `pg_get_expr()` returns unquoted identifiers
for lowercase column names (`postcode`), while Prisma generates quoted
identifiers (`"postcode"`). The AST comparison treats these as
different, causing needless drop+recreate cycles.
```sql
-- Prisma generates:
("deletedAt" IS NULL AND "postcode" IS NOT NULL)
-- pg_get_expr() returns:
((("deletedAt" IS NULL) AND (postcode IS NOT NULL)))
```
## Solution
Extend `exprs_semantically_eq` to treat quoted and unquoted identifiers
as equivalent when the unquoted form is a valid PostgreSQL identifier.
Uses `sqlparser` with `PostgreSqlDialect` to verify that the identifier
value can be safely used without quotes (i.e., it's not a reserved
keyword and follows identifier rules).
## Changes
- **PG `schema_differ.rs`** — Added identifier quoting comparison in
`exprs_semantically_eq`; checks if `"foo"` and `foo` refer to the same
column by re-parsing with `sqlparser`
- **`partial.rs`** — Regression test for object literal predicates with
`null` and `not: null` conditions
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Improved PostgreSQL schema comparison to more robustly treat
identifiers as equivalent across quote styles and within expressions.
* **Tests**
* Added an idempotency test for Postgres partial indexes using
object-literal filters with null and not-null conditions.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->1 parent ab73dcf commit 0f1690a
2 files changed
Lines changed: 44 additions & 6 deletions
File tree
- schema-engine
- connectors/sql-schema-connector/src/flavour/postgres
- sql-migration-tests/tests/migrations/indexes
Lines changed: 26 additions & 6 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
17 | 17 | | |
18 | 18 | | |
19 | 19 | | |
20 | | - | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
21 | 25 | | |
22 | 26 | | |
23 | 27 | | |
| |||
749 | 753 | | |
750 | 754 | | |
751 | 755 | | |
752 | | - | |
753 | | - | |
754 | | - | |
755 | | - | |
756 | | - | |
| 756 | + | |
757 | 757 | | |
758 | 758 | | |
759 | 759 | | |
| |||
792 | 792 | | |
793 | 793 | | |
794 | 794 | | |
| 795 | + | |
| 796 | + | |
| 797 | + | |
| 798 | + | |
| 799 | + | |
| 800 | + | |
| 801 | + | |
| 802 | + | |
| 803 | + | |
| 804 | + | |
| 805 | + | |
| 806 | + | |
| 807 | + | |
| 808 | + | |
795 | 809 | | |
796 | 810 | | |
797 | 811 | | |
| |||
801 | 815 | | |
802 | 816 | | |
803 | 817 | | |
| 818 | + | |
| 819 | + | |
| 820 | + | |
| 821 | + | |
| 822 | + | |
| 823 | + | |
804 | 824 | | |
805 | 825 | | |
806 | 826 | | |
| |||
Lines changed: 18 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1082 | 1082 | | |
1083 | 1083 | | |
1084 | 1084 | | |
| 1085 | + | |
| 1086 | + | |
| 1087 | + | |
| 1088 | + | |
| 1089 | + | |
| 1090 | + | |
| 1091 | + | |
| 1092 | + | |
| 1093 | + | |
| 1094 | + | |
| 1095 | + | |
| 1096 | + | |
| 1097 | + | |
| 1098 | + | |
| 1099 | + | |
| 1100 | + | |
| 1101 | + | |
| 1102 | + | |
0 commit comments