Skip to content

fix: validate extension schema consistency between plan and target databases (#518) - #544

Merged
tianzhou merged 3 commits into
mainfrom
fix/issue-518-extension-schema-check
Aug 15, 2026
Merged

fix: validate extension schema consistency between plan and target databases (#518)#544
tianzhou merged 3 commits into
mainfrom
fix/issue-518-extension-schema-check

Conversation

@tianzhou

Copy link
Copy Markdown
Contributor

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's vector in public vs domain) makes extension-owned types resolve to different schema-qualified names on the two sides. This silently produced a wrong plan: spurious ALTER COLUMN TYPE, or CREATE TABLE DDL 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_extension on 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 plan and apply go through CreateDesiredStateProvider, so both commands get the guard.

Fixes #518

Test plan

Added TestExternalDatabase_ExtensionSchemaMismatch in cmd/plan/external_db_integration_test.go: installs citext into schema exts on the target and public on 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

…tabases (#518)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Copilot AI lite review requested due to automatic review settings August 15, 2026 05:02
@greptile-apps

greptile-apps Bot commented Aug 15, 2026

Copy link
Copy Markdown

Greptile Summary

The PR adds fail-fast validation for extension installation-schema consistency when an external plan database is used.

  • Queries extension names and schemas from the target database before creating the external provider.
  • Compares extensions shared by the target and plan databases and reports deterministic mismatch errors.
  • Adds integration coverage for mismatching and subsequently aligned extension schemas.

Confidence Score: 5/5

The 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

Filename Overview
cmd/plan/plan.go Collects target extension metadata for external-provider creation using the existing target connection contract.
internal/postgres/external.go Adds deterministic shared-extension schema validation and metadata-query helpers with connection cleanup.
cmd/plan/external_db_integration_test.go Verifies provider creation fails for a schema mismatch and succeeds after schemas are aligned.

Sequence Diagram

sequenceDiagram
    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
Loading

Reviews (1): Last reviewed commit: "fix: validate extension schema consisten..." | Re-trigger Greptile

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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_extension schemas 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.

Comment thread internal/postgres/external.go Outdated
Comment thread cmd/plan/plan.go Outdated
tianzhou and others added 2 commits August 15, 2026 13:11
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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(

@tianzhou
tianzhou merged commit e4b4b9d into main Aug 15, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Extension-owned type schema mismatch causes false-positive diffs (pgvector, etc.)

2 participants