[BUG] Constraint triggers generate invalid plans
@bplunkett-stripe is already working on this.
Since Jul 20, 2025.
Assessment
This issue has not been assessed yet.
Description
Describe the bug
Apologies if this is expected and should instead be a feature request instead. I can move this if that makes more sense.
I am using the library to automatically generate migrations programmatically. The schema makes use of constraint triggers which, when changed, result in an invalid plan that tries to use CREATE OR REPLACE CONSTRAINT TRIGGER which is not supported in Postgres.
I am currently working around this by ignoring the tool's validation and post-processing the plan to drop & re-create the trigger instead.
Expected behavior
A valid plan can be generated when constraint triggers are modified whether this is via a pair of DROP TRIGGER IF EXISTS... & CREATE CONSTRAINT TRIGGER... or other means.
To Reproduce
-
Start a postgres instance (
docker run --name test-pg -e POSTGRES_PASSWORD=postgres -v "$(pwd)/data:/var/lib/postgresql/data" -p 5432:5432 -d postgres) -
mkdir initial_schema after_schema -
touch initial_schema/schema.sql after_schema/schemal.sql -
Add the following to
initial_schema/schema.sql.CREATE FUNCTION test_fn() RETURNS trigger LANGUAGE plpgsql AS $_$ DECLARE msg TEXT := TG_ARGV[0]; BEGIN RAISE NOTICE '%', msg; RETURN NEW; END; $_$; CREATE TABLE foobar (id int); CREATE CONSTRAINT TRIGGER test_trigger AFTER INSERT OR UPDATE ON foobar DEFERRABLE INITIALLY DEFERRED FOR EACH ROW EXECUTE FUNCTION test_fn('hello'); -
Add the following to
after_schema/schemal.sql(note, just the parameter changed)CREATE FUNCTION test_fn() RETURNS trigger LANGUAGE plpgsql AS $_$ DECLARE msg TEXT := TG_ARGV[0]; BEGIN RAISE NOTICE '%', msg; RETURN NEW; END; $_$; CREATE TABLE foobar (id int); CREATE CONSTRAINT TRIGGER trigger_1 AFTER INSERT OR UPDATE ON foobar DEFERRABLE INITIALLY DEFERRED FOR EACH ROW EXECUTE FUNCTION test_fn('HI'); -
Apply the initial schema with
pg-schema-diff apply --dsn "postgres://postgres:test@localhost:5432/postgres" --schema-dir before_schema --allow-hazards HAS_UNTRACKABLE_DEPENDENCIES(click "Yes" when promoted) -
Generate a plan to migrate to the "after" schema with
pg-schema-diff plan --dsn "postgres://postgres:test@localhost:5432/postgres" --schema-dir after_schema
This generates the following output:
Error: generating plan: validating migration plan: running migration plan: executing migration statement: {CREATE OR REPLACE CONSTRAINT TRIGGER trigger_1 AFTER INSERT OR UPDATE ON public.foobar DEFERRABLE INITIALLY DEFERRED FOR EACH ROW EXECUTE FUNCTION test_fn('HI') 3s 3s []}: ERROR: CREATE OR REPLACE CONSTRAINT TRIGGER is not supported (SQLSTATE 0A000)
diff.Plan{
Statements: {
{
DDL: "CREATE OR REPLACE CONSTRAINT TRIGGER trigger_1 AFTER INSERT OR UPDATE ON public.foobar DEFERRABLE INITIALLY DEFERRED FOR EACH ROW EXECUTE FUNCTION test_fn('HI')",
Timeout: 3000000000,
LockTimeout: 3000000000,
Hazards: nil,
},
},
CurrentSchemaHash: "b9bb8afe1d961d34",
}
Context
pg-schema-diff version: v0.9.0
pg-schema-diff usage: CLI & LIBRARY
Postgres version: 17
- Dominant language
- Go
- Stars
- 884
- Forks
- 82
- PR merge metrics
- No merged PRs in 30d
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from stripe/pg-schema-diff
-
bug
Difficulty 1/5 Under an hour Newbie friendliness 76/100
stripe/pg-schema-diff#302 · 1 comment ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
stripe/pg-schema-diff#283 · 1 reaction ·
-
Difficulty 4/5 3-5 days Newbie friendliness 50/100
stripe/pg-schema-diff#301 ·
-
Is the repo active? Open
Difficulty 1/5 Under an hour Newbie friendliness 15/100
stripe/pg-schema-diff#289 · 7 reactions ·
-
Difficulty 3/5 1-2 days Newbie friendliness 76/100
stripe/pg-schema-diff#284 ·
All issues in stripe/pg-schema-diff
Similar issues
-
optimization optimization:agents-md-curator
Difficulty 2/5 1-3 hours Newbie friendliness 86/100
githubnext/gh-aw-cao#13143 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
blinklabs-io/bursa#904 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
yanet-platform/ipfw-go#129 ·
-
bug confmap/provider/googlesecretmanagerprovider needs triage
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
open-telemetry/opentelemetry-collector-contrib#51273 · 2 comments ·
-
bug: AI Gateway client filter lists "Unknown" twice when NULL and literal Unknown clients coexist Openbug
Difficulty 2/5 1-3 hours Newbie friendliness 90/100