Conversation
Greptile SummaryThis PR fixes a role-mismatch bug (#303) in the Changes:
How the fix fits the codebase: The Confidence Score: 4/5
Important Files Changed
Sequence DiagramsequenceDiagram
participant User
participant PlanCmd as plan command
participant TargetDB as Target Database
participant EmbeddedPG as Embedded PostgreSQL
User->>PlanCmd: pgschema plan --user postgres --db mydb
PlanCmd->>TargetDB: Detect PostgreSQL version
TargetDB-->>PlanCmd: version (e.g. 17.x)
Note over PlanCmd,EmbeddedPG: BEFORE fix: Username hardcoded to "pgschema"<br/>AFTER fix: Username = config.User (e.g. "postgres")
PlanCmd->>EmbeddedPG: Start (Username=config.User)
PlanCmd->>EmbeddedPG: Apply new.sql (desired state)
Note over EmbeddedPG: ALTER DEFAULT PRIVILEGES FOR ROLE postgres<br/>Now works — "postgres" role exists as superuser
PlanCmd->>EmbeddedPG: Inspect desired state IR
EmbeddedPG-->>PlanCmd: desiredStateIR (roles match target DB)
PlanCmd->>TargetDB: Inspect current state IR
TargetDB-->>PlanCmd: currentStateIR
PlanCmd->>PlanCmd: diff(currentStateIR, desiredStateIR)
Note over PlanCmd: Role names match — no spurious REVOKE/GRANT generated
PlanCmd-->>User: Correct migration plan
Last reviewed commit: 9c7288e |
| embeddedConfig := &postgres.EmbeddedPostgresConfig{ | ||
| Version: pgVersion, | ||
| Database: "pgschema_temp", | ||
| Username: "pgschema", | ||
| Username: config.User, | ||
| Password: "pgschema", | ||
| } |
There was a problem hiding this comment.
No guard against empty config.User in programmatic use
CreateEmbeddedPostgresForPlan is an exported function, and config.User is passed directly as the embedded postgres Username. In the CLI path this is safe because PreRunE validates the --user flag. However, if this function is ever called programmatically with an empty config.User, the embedded-postgres library will either fail to start or silently fall back to a default username — breaking the role-matching invariant this fix establishes.
Consider adding a defensive guard before constructing embeddedConfig:
if config.User == "" {
return nil, fmt.Errorf("target database user must not be empty when creating embedded postgres")
}There was a problem hiding this comment.
Pull request overview
Updates the plan command’s embedded PostgreSQL setup to use the target database user so role ownership/default-privilege semantics match between desired/current state, addressing issue #303 around ALTER DEFAULT PRIVILEGES ... FOR ROLE ... when planning with embedded Postgres.
Changes:
- Use
config.User(target DB user) as the embedded Postgres superuser forplan. - Add a new
default_privilege/issue_303_for_rolefixture exercising explicitFOR ROLE. - Substantially rewrite/remove several
.claude/skills/*docs (unrelated to the bug fix).
Reviewed changes
Copilot reviewed 13 out of 13 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
cmd/plan/plan.go |
Uses target DB user for embedded Postgres in plan to align role references/ownership. |
testdata/diff/default_privilege/issue_303_for_role/old.sql |
Test fixture: initial state (no default privileges) and ensures demouser exists. |
testdata/diff/default_privilege/issue_303_for_role/new.sql |
Test fixture: desired state includes ALTER DEFAULT PRIVILEGES ... FOR ROLE testuser .... |
testdata/diff/default_privilege/issue_303_for_role/diff.sql |
Expected diff SQL for the new fixture. |
testdata/diff/default_privilege/issue_303_for_role/plan.sql |
Expected plan SQL output for the new fixture. |
testdata/diff/default_privilege/issue_303_for_role/plan.json |
Expected plan JSON output for the new fixture. |
testdata/diff/default_privilege/issue_303_for_role/plan.txt |
Expected human-readable plan output for the new fixture. |
.claude/skills/validate_db/SKILL.md |
Large rewrite of skill documentation. |
.claude/skills/run_tests/SKILL.md |
Large rewrite of skill documentation. |
.claude/skills/postgres_syntax/SKILL.md |
Large rewrite of skill documentation. |
.claude/skills/pg_dump/SKILL.md |
Large rewrite of skill documentation. |
.claude/skills/fix_bug/SKILL.md |
Large rewrite of skill documentation. |
.claude/skills/refactor-pass/SKILL.md |
Deletes the refactor-pass skill doc. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| Database: "pgschema_temp", | ||
| Username: "pgschema", | ||
| Username: config.User, | ||
| Password: "pgschema", |
There was a problem hiding this comment.
The behavior change (embedded DB username now derived from config.User) isn’t directly covered by a regression test that would have failed before this fix. Consider adding an integration test for plan that uses a desired-state file containing ALTER DEFAULT PRIVILEGES FOR ROLE <target user> ... (and creates any required roles), and asserts the plan command succeeds; this would fail when the embedded username was hardcoded to pgschema and pass with this change.
| Password: "pgschema", | |
| Password: config.Password, |
There was a problem hiding this comment.
The password suggestion is incorrect. The embedded postgres is a fresh local instance — its password is independent of the target database. The username matters because PostgreSQL uses it for role ownership attribution (pg_get_userbyid(defaclrole)). The password has no semantic meaning here; it is just auth to a throwaway instance.
Regarding test coverage: valid observation. The integration test uses sharedEmbeddedPG as the provider (bypassing CreateEmbeddedPostgresForPlan), so it would not have caught the hardcoded username directly. However, a true end-to-end test spinning up a separate embedded PG with a mismatched user would be complex and slow. The diff test verifies FOR ROLE works correctly at the IR level.
.claude/skills/validate_db/SKILL.md
Outdated
| --- | ||
| name: Validate with Database | ||
| description: Connect to live PostgreSQL database to validate schema assumptions, compare pg_dump vs pgschema output, and query system catalogs interactively | ||
| name: validate_db | ||
| description: Connect to live PostgreSQL database to validate schema assumptions, compare pg_dump vs pgschema output, and query system catalogs interactively. Use this skill whenever you need to test queries against a real database, verify how PostgreSQL stores or formats objects, debug introspection issues, or check version-specific behavior (PostgreSQL 14-18). | ||
| --- | ||
|
|
||
| # Validate with Database | ||
|
|
||
| Use this skill to connect to the test PostgreSQL database, validate assumptions about schema behavior, and cross-validate between pg_dump and pgschema implementations. | ||
| Connect to the test PostgreSQL database to validate assumptions, compare implementations, and test queries. |
There was a problem hiding this comment.
This PR includes a large, unrelated rewrite of the .claude/skills/* documentation (including deleting a skill file). Since the PR description is focused on the embedded-postgres username fix and a regression test for issue #303, consider splitting these doc/tooling changes into a separate PR to keep the change set minimal and easier to review/revert if needed.
There was a problem hiding this comment.
The skill documentation changes are from a prior commit on main (04a882d7) already merged. They are not part of this branch — likely a git diff artifact.
…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 <noreply@anthropic.com>
…Plan Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
9937ab6 to
9970824
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| 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; |
There was a problem hiding this comment.
This test uses GRANT ALL ON TABLES, which expands to a version-dependent privilege list (e.g., MAINTAIN is present in newer PostgreSQL versions but not older ones). Since CI runs the test suite across PG 14–18, the expected outputs in this fixture will likely fail on older versions. Prefer granting an explicit, version-stable subset of privileges (e.g., SELECT), and update the expected diff.sql / plan.* files accordingly (or add version-specific expectations/skips).
| 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; |
There was a problem hiding this comment.
Fixed in 691d56d. Changed to GRANT SELECT for cross-version stability.
…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 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Summary
plancommand used a hardcodedUsername: "pgschema", which causedALTER DEFAULT PRIVILEGES FOR ROLE postgresto fail because the "postgres" role didn't exist in the embedded instanceFOR ROLE, default privileges were attributed to the "pgschema" user instead of the target database user (e.g., "postgres"), causing a role mismatch that generated incorrect migration plans (revoke from one role, grant to another)config.User) as the embedded postgres username, ensuring role references match between desired and current stateFixes #303
Test plan
testdata/diff/default_privilege/issue_303_for_role/test case with explicitFOR ROLEin ALTER DEFAULT PRIVILEGESPGSCHEMA_TEST_FILTER="default_privilege/" go test -v ./internal/diff -run TestDiffFromFilesPGSCHEMA_TEST_FILTER="default_privilege/" go test -v ./cmd -run TestPlanAndApplyPGSCHEMA_TEST_FILTER="privilege/" go test -v ./cmd -run TestPlanAndApply🤖 Generated with Claude Code