fix: skip partition-clone child triggers in dump (#472)#487
Conversation
Greptile SummaryThis PR fixes two related trigger-inspection bugs: (1) partition-clone child triggers (
Confidence Score: 5/5Safe to merge — both fixes are narrowly scoped catalog filter/rendering changes with no destructive side effects, and regression tests cover both scenarios. The No files require special attention. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[GetTriggersForSchema query] --> B{t.tgisinternal?}
B -- true --> C[Skip - internal trigger]
B -- false --> D{t.tgparentid = 0?}
D -- "false: non-zero parent" --> E[Skip - partition-clone child added by this PR]
D -- "true: top-level trigger" --> F[LATERAL: set_config search_path to trigger schema added by this PR]
F --> G[pg_get_triggerdef with deterministic schema context]
G --> H[Emit trigger row]
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
A[GetTriggersForSchema query] --> B{t.tgisinternal?}
B -- true --> C[Skip - internal trigger]
B -- false --> D{t.tgparentid = 0?}
D -- "false: non-zero parent" --> E[Skip - partition-clone child added by this PR]
D -- "true: top-level trigger" --> F[LATERAL: set_config search_path to trigger schema added by this PR]
F --> G[pg_get_triggerdef with deterministic schema context]
G --> H[Emit trigger row]
Reviews (1): Last reviewed commit: "fix: skip partition-clone child triggers..." | Re-trigger Greptile |
There was a problem hiding this comment.
Pull request overview
This PR updates pgschema’s trigger inspection to align with pg_dump by skipping partition-cloned child triggers (pg_trigger.tgparentid != 0), preventing bogus CREATE OR REPLACE TRIGGER ... ON <partition_child> output and downstream failures when partitions are ignored. It also changes how trigger definitions are rendered to be deterministic by forcing search_path before calling pg_get_triggerdef.
Changes:
- Filter trigger inspection to only dump top-level (non-cloned) triggers via
t.tgparentid = 0. - Render trigger definitions under a forced
search_pathto avoid schema-qualification drift inWHENclauses (idempotent plan/apply). - Add a dump regression fixture + integration test for issue #472, plus an integration coverage case for trigger
WHENenum casts.
Reviewed changes
Copilot reviewed 7 out of 8 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| testdata/dump/issue_472_partition_clone_trigger/raw.sql | Adds a minimal repro schema for partition-cloned triggers. |
| testdata/dump/issue_472_partition_clone_trigger/pgschema.sql | Expected pgschema output for the new regression case. |
| testdata/dump/issue_472_partition_clone_trigger/pgdump.sql | pg_dump-produced input used to seed the regression database. |
| testdata/dump/issue_472_partition_clone_trigger/manifest.json | Documents the regression fixture purpose and links issue #472. |
| ir/queries/queries.sql | Updates trigger query to (a) force deterministic rendering and (b) skip tgparentid != 0 clones. Also includes a sequence query adjustment. |
| ir/queries/queries.sql.go | Regenerates sqlc output to match the updated SQL queries. |
| cmd/issue_449_integration_test.go | Extends repeat-plan idempotency coverage to include trigger WHEN enum casts (issue #481). |
| cmd/dump/dump_integration_test.go | Adds an integration test runner for the new issue #472 dump fixture. |
Files not reviewed (1)
- ir/queries/queries.sql.go: Generated file
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
A FOR EACH ROW trigger on a partitioned table causes PostgreSQL to clone the trigger onto every partition child, creating one extra pg_trigger row per partition with tgparentid != 0 (and tgisinternal = false). pg_dump never emits these clones; only the top-level trigger on the partitioned parent (tgparentid = 0) is dumpable. pgschema dump emitted all of them, producing a bogus CREATE OR REPLACE TRIGGER ... ON <child> statement. This broke pgschema's own plan with "relation does not exist" when the child partition was excluded via .pgschemaignore, mirroring the #409/#460 internal per-partition FK constraint problem. Filter trigger rows with t.tgparentid = 0 in the inspector query, matching pg_dump and the existing FK-constraint treatment. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
0e1fca2 to
f565e90
Compare
Summary
A
FOR EACH ROWtrigger on a partitioned table causes PostgreSQL to clone the trigger onto every partition child, creating one extrapg_triggerrow per partition withtgparentid != 0(andtgisinternal = false).pg_dumpnever emits these clones — only the top-level trigger on the partitioned parent (tgparentid = 0).pgschema's trigger inspector query filtered only
tgisinternal, so the clones slipped through and were dumped as standaloneCREATE OR REPLACE TRIGGER ... ON <child>statements. When the child partitions were excluded via.pgschemaignore, the resulting desired-state file failed pgschema's ownplanwithrelation "<child>" does not exist.This is the trigger analog of the internal per-partition FK constraint problem fixed in #409/#460. The fix adds
AND t.tgparentid = 0to the trigger query inir/queries, matchingpg_dumpand the existing FK-constraint treatment.tgparentidexists since PostgreSQL 13, so all supported versions (14–18) are covered.Verified against a live PostgreSQL 17/18 catalog: the parent trigger has
tgisinternal=f, tgparentid=0; the cloned child trigger hastgisinternal=f, tgparentid!=0.Fixes #472
Test plan
Added dump regression
testdata/dump/issue_472_partition_clone_trigger/(partitionedledgerwith a row-level trigger). Before the fix, dump emitted a duplicatetrg_rolluponledger_2026_06; after, only the parent trigger is emitted.Both pass;
go build ./...clean.🤖 Generated with Claude Code