fix: strip double-quotes from extracted sequence name in SERIAL ownership detection#469
Conversation
…ship detection
When a sequence has a mixed-case quoted name, the nextval() default expression
stores it as nextval('schema."SeqName"'::regclass). The existing two-pass
REGEXP_REPLACE extracted 'SeqName' with double-quotes still present, causing
the col_table JOIN to compare '"SeqName"' against 'SeqName' (as stored in
pg_sequences) — the join always failed for such sequences.
Add a third REGEXP_REPLACE pass that strips leading/trailing double-quotes
from the extracted sequence name so the col_table JOIN matches correctly.
With this fix, OwnedByTable is correctly populated for quoted SERIAL sequences,
the skip condition fires, and pgschema no longer emits a standalone
CREATE SEQUENCE alongside the SERIAL-generated one — eliminating the _seq1
drift on fresh database deploys.
Greptile SummaryThis PR updates sequence ownership detection for quoted SERIAL sequence defaults. The main changes are:
Confidence Score: 3/5This should be fixed before merging.
Important Files Changed
Reviews (1): Last reviewed commit: "fix: strip double-quotes from extracted ..." | Re-trigger Greptile |
After stripping outer quotes, a sequence name like My"Seq is stored in column_default as My""Seq (PostgreSQL SQL identifier escaping). Without unescaping, the col_table JOIN still fails for such names. Add REPLACE(..., '""', '"') as a final pass to unescape doubled quotes, as suggested in code review.
The previous regex '^[^.]*\.' splits at the first dot, which breaks for quoted schemas containing a dot (e.g. "foo.bar"). Replace with a quote-aware alternative that matches either a full quoted identifier followed by a dot, or an unquoted prefix followed by a dot.
|
Pls add a test case to validate this fix |
There was a problem hiding this comment.
Pull request overview
Fixes SERIAL sequence ownership detection for mixed-case / quoted sequence names so pgschema doesn’t emit redundant standalone CREATE SEQUENCE statements (which can lead to _seq1 duplicates on fresh deploys).
Changes:
- Updates
GetSequencesForSchema’snextval(...)parsing to strip schema prefixes that may be quoted and to remove surrounding double-quotes from the extracted sequence name. - Normalizes escaped quotes (
""→") to match the unquotedpg_sequences.sequencenamejoin key. - Applies the same SQL change to both the source SQL and the sqlc-generated Go query constant.
Reviewed changes
Copilot reviewed 1 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
ir/queries/queries.sql |
Adjusts the sequence-name extraction logic from column_default to correctly join mixed-case quoted sequence names to pg_sequences. |
ir/queries/queries.sql.go |
Regenerates/updates the sqlc output so the runtime query matches the updated SQL source. |
Files not reviewed (1)
- ir/queries/queries.sql.go: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…tection
Adds a query-level test that directly calls GetSequencesForSchema and
asserts OwnedByTable/OwnedByColumn are populated for a SERIAL column
with a mixed-case name ("orderId"). The pg_depend ownership edge is
removed via OWNED BY NONE to force the column_default parsing fallback
— the path that was broken before this fix.
Without the fix, the test fails with:
OwnedByTable = "", want "orders"
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
LGTM |
Problem
When a sequence has a mixed-case quoted name (e.g.
"MyTable_myCol_seq"), thenextval()column default stores it as:nextval('schema."MyTable_myCol_seq"'::regclass)
The existing two-pass
REGEXP_REPLACEingetSequencesForSchemaextracted the name with double-quotes still attached —"MyTable_myCol_seq"— and thecol_tableJOIN compared this againstMyTable_myCol_seq(as stored unquoted inpg_sequences). The join always failed for such sequences, leavingOwnedByTableempty.With
OwnedByTableempty, the skip condition indiff.gonever fired, so pgschema emitted a standaloneCREATE SEQUENCEfor sequences already handled bySERIAL, causing PostgreSQL to create a duplicate with a_seq1suffix on every fresh database deploy.Fix
Add a third
REGEXP_REPLACEpass that strips leading/trailing double-quotes from the extracted sequence name before the JOIN. This makes the JOIN match correctly,OwnedByTableis populated, the skip condition fires, and no standaloneCREATE SEQUENCEis emitted for SERIAL-backed sequences.Testing
Verified on a schema with ~90 mixed-case SERIAL sequences across multiple tables:
DROP SEQUENCEoperations on every second apply