fix: validate extension schema consistency between plan and target databases (#518) - #544
Conversation
…tabases (#518) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Greptile SummaryThe PR adds fail-fast validation for extension installation-schema consistency when an external plan database is used.
Confidence Score: 5/5The PR appears safe to merge; no actionable changed-code defect remains. The new validation is reached by both plan and file-based apply paths, uses the established database connection configuration, closes failure-path resources, and consistently rejects the extension mismatch it was designed to prevent. Important Files Changed
Sequence DiagramsequenceDiagram
participant Command as plan/apply
participant Target as Target DB
participant Provider as CreateDesiredStateProvider
participant PlanDB as External plan DB
Command->>Target: Detect PostgreSQL major version
Command->>Provider: Create provider
Provider->>Target: Query extension schemas
Provider->>PlanDB: Connect and verify major version
Provider->>PlanDB: Query extension schemas
alt Shared extension schemas match
PlanDB-->>Command: External provider
else Shared extension schema differs
PlanDB-->>Command: Extension schema mismatch error
end
Reviews (1): Last reviewed commit: "fix: validate extension schema consisten..." | Re-trigger Greptile |
There was a problem hiding this comment.
Pull request overview
Adds a fail-fast guard for --plan-host workflows to prevent generating incorrect migration plans when the same PostgreSQL extension is installed into different schemas on the plan vs target databases (e.g., extension-owned types resolving as public.vector vs domain.vector).
Changes:
- Query target DB
pg_extensionschemas and pass them into the external plan DB provider. - Validate that extensions present on both plan + target DBs are installed in the same schema; otherwise return a clear error.
- Add an integration test covering extension schema mismatch and subsequent remediation.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| internal/postgres/external.go | Adds extension-schema validation for external plan DBs plus helper(s) to query extension install schemas. |
| cmd/plan/plan.go | Collects target extension schema map and wires it into external provider creation. |
| cmd/plan/external_db_integration_test.go | Adds integration test ensuring mismatched extension schemas fail provider creation and matching schemas succeed. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.
Suppressed comments (2)
cmd/plan/plan.go:205
- This now queries pg_extension on the target database even when no external plan DB is being used (PlanDBHost == ""). That adds an extra catalog query on every plan/apply run and can be avoided by only fetching extensions when the external plan DB path is selected.
// Detect target database PostgreSQL version (needed for both embedded and external)
// and its extension installation schemas (needed for the external database's
// extension schema consistency check, issue #518) in a single connection.
pgVersion, targetExtensions, err := postgres.DetectPostgresVersionAndExtensionsFromDB(
config.Host,
cmd/plan/plan.go:204
- CreateDesiredStateProvider now calls DetectPostgresVersionAndExtensionsFromDB, so failures can come from querying extensions as well as version detection. The current wrapped error text below still says "failed to detect PostgreSQL version", which can be misleading when the underlying cause is extension introspection.
pgVersion, targetExtensions, err := postgres.DetectPostgresVersionAndExtensionsFromDB(
Summary
When using an external plan database (
--plan-host), an extension installed in a different schema on the plan database than on the target (e.g. pgvector'svectorinpublicvsdomain) makes extension-owned types resolve to different schema-qualified names on the two sides. This silently produced a wrong plan: spuriousALTER COLUMN TYPE, orCREATE TABLEDDL referencing a schema that doesn't exist on the target.This adds a fail-fast validation mirroring the existing major-version check: when creating the external database provider, pgschema now queries
pg_extensionon both databases and errors clearly if any extension installed on both sides lives in different schemas. Extensions present on only one side are unaffected — if the desired state needs a missing extension, applying it to the plan database already fails loudly with the existing hint.Both
planandapplygo throughCreateDesiredStateProvider, so both commands get the guard.Fixes #518
Test plan
Added
TestExternalDatabase_ExtensionSchemaMismatchincmd/plan/external_db_integration_test.go: installscitextinto schemaextson the target andpublicon the plan database, asserts provider creation fails with an error naming the extension and both schemas, then moves the extension to the matching schema and asserts creation succeeds.go test -v ./cmd/plan -run TestExternalDatabase🤖 Generated with Claude Code