From 62639ae2ea5f59349e4d45376a05c2e9e21de292 Mon Sep 17 00:00:00 2001 From: Tianzhou Date: Wed, 4 Mar 2026 07:29:19 -0800 Subject: [PATCH 1/3] fix: use target database user for embedded postgres in plan command (#303) The embedded postgres used a hardcoded "pgschema" username, causing ALTER DEFAULT PRIVILEGES FOR ROLE to fail when the target database user differed. Now uses the target database user so role references match. Co-Authored-By: Claude Opus 4.6 --- cmd/plan/plan.go | 8 ++++++-- .../issue_303_for_role/diff.sql | 1 + .../issue_303_for_role/new.sql | 10 ++++++++++ .../issue_303_for_role/old.sql | 9 +++++++++ .../issue_303_for_role/plan.json | 20 +++++++++++++++++++ .../issue_303_for_role/plan.sql | 1 + .../issue_303_for_role/plan.txt | 12 +++++++++++ 7 files changed, 59 insertions(+), 2 deletions(-) create mode 100644 testdata/diff/default_privilege/issue_303_for_role/diff.sql create mode 100644 testdata/diff/default_privilege/issue_303_for_role/new.sql create mode 100644 testdata/diff/default_privilege/issue_303_for_role/old.sql create mode 100644 testdata/diff/default_privilege/issue_303_for_role/plan.json create mode 100644 testdata/diff/default_privilege/issue_303_for_role/plan.sql create mode 100644 testdata/diff/default_privilege/issue_303_for_role/plan.txt diff --git a/cmd/plan/plan.go b/cmd/plan/plan.go index 81b74f69..7e13a211 100644 --- a/cmd/plan/plan.go +++ b/cmd/plan/plan.go @@ -209,11 +209,15 @@ func CreateDesiredStateProvider(config *PlanConfig) (postgres.DesiredStateProvid // CreateEmbeddedPostgresForPlan creates a temporary embedded PostgreSQL instance // for validating the desired state schema. The instance should be stopped by the caller. func CreateEmbeddedPostgresForPlan(config *PlanConfig, pgVersion postgres.PostgresVersion) (*postgres.EmbeddedPostgres, error) { - // Start embedded PostgreSQL with matching version + // Start embedded PostgreSQL with matching version. + // Use the target database username so that role references match between + // the desired state (embedded) and current state (target database). + // This ensures ALTER DEFAULT PRIVILEGES FOR ROLE works correctly + // and that implicit owner roles match the target database. (issue #303) embeddedConfig := &postgres.EmbeddedPostgresConfig{ Version: pgVersion, Database: "pgschema_temp", - Username: "pgschema", + Username: config.User, Password: "pgschema", } embeddedPG, err := postgres.StartEmbeddedPostgres(embeddedConfig) diff --git a/testdata/diff/default_privilege/issue_303_for_role/diff.sql b/testdata/diff/default_privilege/issue_303_for_role/diff.sql new file mode 100644 index 00000000..41281214 --- /dev/null +++ b/testdata/diff/default_privilege/issue_303_for_role/diff.sql @@ -0,0 +1 @@ +ALTER DEFAULT PRIVILEGES FOR ROLE testuser IN SCHEMA public GRANT DELETE, INSERT, MAINTAIN, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON TABLES TO demouser; diff --git a/testdata/diff/default_privilege/issue_303_for_role/new.sql b/testdata/diff/default_privilege/issue_303_for_role/new.sql new file mode 100644 index 00000000..5b744567 --- /dev/null +++ b/testdata/diff/default_privilege/issue_303_for_role/new.sql @@ -0,0 +1,10 @@ +-- Create roles for testing +DO $$ +BEGIN + IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'demouser') THEN + CREATE ROLE demouser; + END IF; +END $$; + +-- Grant default privileges with explicit FOR ROLE (issue #303) +ALTER DEFAULT PRIVILEGES FOR ROLE testuser IN SCHEMA public GRANT ALL ON TABLES TO demouser; diff --git a/testdata/diff/default_privilege/issue_303_for_role/old.sql b/testdata/diff/default_privilege/issue_303_for_role/old.sql new file mode 100644 index 00000000..510ca931 --- /dev/null +++ b/testdata/diff/default_privilege/issue_303_for_role/old.sql @@ -0,0 +1,9 @@ +-- Create roles for testing +DO $$ +BEGIN + IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'demouser') THEN + CREATE ROLE demouser; + END IF; +END $$; + +-- No default privileges configured diff --git a/testdata/diff/default_privilege/issue_303_for_role/plan.json b/testdata/diff/default_privilege/issue_303_for_role/plan.json new file mode 100644 index 00000000..b3e221e7 --- /dev/null +++ b/testdata/diff/default_privilege/issue_303_for_role/plan.json @@ -0,0 +1,20 @@ +{ + "version": "1.0.0", + "pgschema_version": "1.7.3", + "created_at": "1970-01-01T00:00:00Z", + "source_fingerprint": { + "hash": "965b1131737c955e24c7f827c55bd78e4cb49a75adfd04229e0ba297376f5085" + }, + "groups": [ + { + "steps": [ + { + "sql": "ALTER DEFAULT PRIVILEGES FOR ROLE testuser IN SCHEMA public GRANT DELETE, INSERT, MAINTAIN, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON TABLES TO demouser;", + "type": "default_privilege", + "operation": "create", + "path": "default_privileges.testuser.TABLES.demouser" + } + ] + } + ] +} diff --git a/testdata/diff/default_privilege/issue_303_for_role/plan.sql b/testdata/diff/default_privilege/issue_303_for_role/plan.sql new file mode 100644 index 00000000..41281214 --- /dev/null +++ b/testdata/diff/default_privilege/issue_303_for_role/plan.sql @@ -0,0 +1 @@ +ALTER DEFAULT PRIVILEGES FOR ROLE testuser IN SCHEMA public GRANT DELETE, INSERT, MAINTAIN, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON TABLES TO demouser; diff --git a/testdata/diff/default_privilege/issue_303_for_role/plan.txt b/testdata/diff/default_privilege/issue_303_for_role/plan.txt new file mode 100644 index 00000000..db814d48 --- /dev/null +++ b/testdata/diff/default_privilege/issue_303_for_role/plan.txt @@ -0,0 +1,12 @@ +Plan: 1 to add. + +Summary by type: + default privileges: 1 to add + +Default privileges: + + demouser + +DDL to be executed: +-------------------------------------------------- + +ALTER DEFAULT PRIVILEGES FOR ROLE testuser IN SCHEMA public GRANT DELETE, INSERT, MAINTAIN, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON TABLES TO demouser; From 99708244ebb1d5595b12920bfd32630e69719c9b Mon Sep 17 00:00:00 2001 From: Tianzhou Date: Wed, 4 Mar 2026 07:47:04 -0800 Subject: [PATCH 2/3] fix: add guard against empty config.User in CreateEmbeddedPostgresForPlan Co-Authored-By: Claude Opus 4.6 --- cmd/plan/plan.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cmd/plan/plan.go b/cmd/plan/plan.go index 7e13a211..b2623fdb 100644 --- a/cmd/plan/plan.go +++ b/cmd/plan/plan.go @@ -209,6 +209,10 @@ func CreateDesiredStateProvider(config *PlanConfig) (postgres.DesiredStateProvid // CreateEmbeddedPostgresForPlan creates a temporary embedded PostgreSQL instance // for validating the desired state schema. The instance should be stopped by the caller. func CreateEmbeddedPostgresForPlan(config *PlanConfig, pgVersion postgres.PostgresVersion) (*postgres.EmbeddedPostgres, error) { + if config.User == "" { + return nil, fmt.Errorf("target database user must not be empty when creating embedded postgres") + } + // Start embedded PostgreSQL with matching version. // Use the target database username so that role references match between // the desired state (embedded) and current state (target database). From 691d56d4ad6c368aa6c14e619bc9d2da2af35875 Mon Sep 17 00:00:00 2001 From: Tianzhou Date: Wed, 4 Mar 2026 08:19:05 -0800 Subject: [PATCH 3/3] fix: use GRANT SELECT instead of GRANT ALL in test for cross-version compat GRANT ALL expands to include MAINTAIN on PG17+ but not on PG14-16, which would cause test failures in CI across PostgreSQL versions. Co-Authored-By: Claude Opus 4.6 --- testdata/diff/default_privilege/issue_303_for_role/diff.sql | 2 +- testdata/diff/default_privilege/issue_303_for_role/new.sql | 2 +- testdata/diff/default_privilege/issue_303_for_role/plan.json | 2 +- testdata/diff/default_privilege/issue_303_for_role/plan.sql | 2 +- testdata/diff/default_privilege/issue_303_for_role/plan.txt | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/testdata/diff/default_privilege/issue_303_for_role/diff.sql b/testdata/diff/default_privilege/issue_303_for_role/diff.sql index 41281214..cbdf338b 100644 --- a/testdata/diff/default_privilege/issue_303_for_role/diff.sql +++ b/testdata/diff/default_privilege/issue_303_for_role/diff.sql @@ -1 +1 @@ -ALTER DEFAULT PRIVILEGES FOR ROLE testuser IN SCHEMA public GRANT DELETE, INSERT, MAINTAIN, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON TABLES TO demouser; +ALTER DEFAULT PRIVILEGES FOR ROLE testuser IN SCHEMA public GRANT SELECT ON TABLES TO demouser; diff --git a/testdata/diff/default_privilege/issue_303_for_role/new.sql b/testdata/diff/default_privilege/issue_303_for_role/new.sql index 5b744567..2b475a8e 100644 --- a/testdata/diff/default_privilege/issue_303_for_role/new.sql +++ b/testdata/diff/default_privilege/issue_303_for_role/new.sql @@ -7,4 +7,4 @@ BEGIN END $$; -- Grant default privileges with explicit FOR ROLE (issue #303) -ALTER DEFAULT PRIVILEGES FOR ROLE testuser IN SCHEMA public GRANT ALL ON TABLES TO demouser; +ALTER DEFAULT PRIVILEGES FOR ROLE testuser IN SCHEMA public GRANT SELECT ON TABLES TO demouser; diff --git a/testdata/diff/default_privilege/issue_303_for_role/plan.json b/testdata/diff/default_privilege/issue_303_for_role/plan.json index b3e221e7..e4adfddc 100644 --- a/testdata/diff/default_privilege/issue_303_for_role/plan.json +++ b/testdata/diff/default_privilege/issue_303_for_role/plan.json @@ -9,7 +9,7 @@ { "steps": [ { - "sql": "ALTER DEFAULT PRIVILEGES FOR ROLE testuser IN SCHEMA public GRANT DELETE, INSERT, MAINTAIN, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON TABLES TO demouser;", + "sql": "ALTER DEFAULT PRIVILEGES FOR ROLE testuser IN SCHEMA public GRANT SELECT ON TABLES TO demouser;", "type": "default_privilege", "operation": "create", "path": "default_privileges.testuser.TABLES.demouser" diff --git a/testdata/diff/default_privilege/issue_303_for_role/plan.sql b/testdata/diff/default_privilege/issue_303_for_role/plan.sql index 41281214..cbdf338b 100644 --- a/testdata/diff/default_privilege/issue_303_for_role/plan.sql +++ b/testdata/diff/default_privilege/issue_303_for_role/plan.sql @@ -1 +1 @@ -ALTER DEFAULT PRIVILEGES FOR ROLE testuser IN SCHEMA public GRANT DELETE, INSERT, MAINTAIN, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON TABLES TO demouser; +ALTER DEFAULT PRIVILEGES FOR ROLE testuser IN SCHEMA public GRANT SELECT ON TABLES TO demouser; diff --git a/testdata/diff/default_privilege/issue_303_for_role/plan.txt b/testdata/diff/default_privilege/issue_303_for_role/plan.txt index db814d48..d9bf7a20 100644 --- a/testdata/diff/default_privilege/issue_303_for_role/plan.txt +++ b/testdata/diff/default_privilege/issue_303_for_role/plan.txt @@ -9,4 +9,4 @@ Default privileges: DDL to be executed: -------------------------------------------------- -ALTER DEFAULT PRIVILEGES FOR ROLE testuser IN SCHEMA public GRANT DELETE, INSERT, MAINTAIN, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON TABLES TO demouser; +ALTER DEFAULT PRIVILEGES FOR ROLE testuser IN SCHEMA public GRANT SELECT ON TABLES TO demouser;