Skip to content

feat(corpus): names holding double quotes - #16

Merged
jasdeepkhalsa merged 1 commit into
mainfrom
feat/quoted-identifiers
Oct 8, 2026
Merged

jasdeepkhalsa merged 1 commit into
mainfrom
feat/quoted-identifiers

Conversation

@jasdeepkhalsa

Copy link
Copy Markdown
Member

Adds quoted_identifiers to the migrations corpus: a table, its columns, a check and a unique constraint, an index, a view, an enum type, a policy and comments, each named with a double quote in it.

A name written between plain quotes without its own quotes doubled is a syntax error that fails the whole migration. DBDiff wrote column, constraint, type and policy names that way, and SupaForge did the same in its own policy SQL. Both are fixed in their own PRs; this case keeps both covered from now on, through DBDiff's corpus round trips and SupaForge's scenario suite.

The corpus tests pass on PostgreSQL 17. DBDiff's corpus round trip of the new case fails before its fix and passes after it, with both renderers.

🤖 Generated with Claude Code

A table, its columns, a check and a unique constraint, an index, a view,
an enum type, a policy and comments, each named with a double quote in
it. Each must be written with its quotes doubled; one written between
plain quotes is a syntax error that fails the whole migration.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@jasdeepkhalsa
jasdeepkhalsa merged commit 106a478 into main Oct 8, 2026
6 checks passed
jasdeepkhalsa added a commit to DBDiff/DBDiff that referenced this pull request Oct 8, 2026
…view's grants (#254)

Three fixes found by retesting against Supabase and plain PostgreSQL.
Each has tests that fail before the fix and pass after it.

## Names holding a double quote
Column, constraint, type, collation and policy names were written
between plain quotes, so `Col "c"` became `"Col "c""`: a syntax error
that fails the whole migration. Every renderer now goes through one
`PostgresSchemaHelper::ident()`, which doubles the quotes.

- `tests/Unit/QuotedIdentifiersTest.php` pins each renderer.
- pg-conformance gains a `quoted_identifiers` migration case
(akalsoftware/pg-conformance#16), so the corpus round trip covers it end to
end once it is released and bumped here. Locally, that case fails before
this fix and passes after it, with both renderers.

## The same view on another major version
PostgreSQL 16 and later print a stored view without the table qualifiers
15 writes (`SELECT id` against `SELECT vt.id`). Every unchanged view
therefore read as changed between a 15 and a 17 database, and was
dropped and recreated.

When the servers' major versions differ, the source's definition is now
also rendered on the target, in a transaction that is rolled back, and
compared there. A real change is still reported.

- `tests/CrossVersionPostgresTest.php` covers views, join views,
materialized views, checks, policies and partial indexes.
- It needs a second server (`DB_HOST_POSTGRES_OTHER`,
`DB_PORT_POSTGRES_OTHER`) and skips without one.
- A new **Cross-version** CI job runs it between PostgreSQL 15 and 17,
in both directions.

## A replaced view keeps its grants
A changed view is dropped and created again, which discarded its grants.
On a database with default privileges, the new view picked those up
instead: on Supabase, everything to `anon` and `authenticated`.

The UP now puts back the source's grants and the DOWN the target's,
revoking what creation added first. A view stood aside for a column type
change already worked this way. That logic is now `GrantSQL::restore()`,
shared by both. `tests/ViewGrantsRoundTripPostgresTest.php` covers views
and materialized views.

## Testing
Run locally against PostgreSQL 17, with the corpus taken from the
pg-conformance branch:

| Suite | Result |
|---|---|
| Unit | 1042 OK |
| Corpus, pg_dump renderer | 153 OK |
| Corpus, built-in renderer | 153 OK |
| Postgres, pg_dump renderer | 208 OK (the 12 cross-version tests skip
there) |
| Postgres, built-in renderer | 208 OK (the same 12 skip) |
| Cross-version, 15 → 17 | 12 OK |
| Cross-version, 17 → 15 | 12 OK |

🤖 Generated with [Claude Code](https://claude.com/claude-code)
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