Skip to content

Comments

fix: auto-detect schema from dump file header for plan/apply (#296)#312

Closed
tianzhou wants to merge 1 commit intomainfrom
fix/issue-296-schema-auto-detect
Closed

fix: auto-detect schema from dump file header for plan/apply (#296)#312
tianzhou wants to merge 1 commit intomainfrom
fix/issue-296-schema-auto-detect

Conversation

@tianzhou
Copy link
Contributor

Summary

  • Dump output now includes -- Dumped from schema: <name> metadata in the header
  • Plan and apply commands auto-detect the target schema from this header when --schema is not explicitly set
  • Prevents accidental cross-schema operations (e.g., dumping vehicle schema then applying without --schema vehicle would previously default to public and drop public tables)

Fixes #296

Changes

  • internal/dump/formatter.go: Added -- Dumped from schema: <name> line to dump header
  • cmd/util/schema_detect.go: New utility to parse schema name from dump file header
  • cmd/plan/plan.go: Auto-detect schema from file when --schema is not explicitly set
  • cmd/apply/apply.go: Same auto-detection for apply command
  • internal/diff/header.go: Removed dead GenerateDumpHeader function (duplicate of formatter's method)
  • cmd/dump/dump_integration_test.go: Updated test normalization to handle new header line

Behavior

  • If --schema is explicitly set, it is always used (no change)
  • If --schema is not set and the dump file has -- Dumped from schema: X, uses X
  • If --schema is not set and the dump file has no schema header (old format), defaults to public (backward compatible)
  • Auto-detection prints a message to stderr: Auto-detected schema 'vehicle' from dump file

Test plan

  • Unit tests for schema detection utility (cmd/util/schema_detect_test.go)
  • Dump integration tests pass (Employee, TenantSchemas)
  • All diff tests pass (TestDiffFromFiles)
  • Integration tests pass (TestPlanAndApply — create_table, migrate, dependency categories)
  • Full CI test suite

🤖 Generated with Claude Code

When dumping a non-public schema (e.g., vehicle), the dump output now
includes a "-- Dumped from schema: <name>" metadata line. The plan and
apply commands read this header and auto-detect the target schema when
--schema is not explicitly set, preventing accidental cross-schema
operations that could drop tables from the wrong schema.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings February 22, 2026 07:04
@greptile-apps
Copy link

greptile-apps bot commented Feb 22, 2026

Greptile Summary

Adds schema auto-detection to prevent accidental cross-schema operations by embedding schema metadata in dump headers and parsing it during plan/apply commands.

  • Added -- Dumped from schema: <name> metadata line to dump file headers
  • Created new utility (cmd/util/schema_detect.go) to parse schema from dump headers by scanning first 20 lines
  • Modified plan and apply commands to auto-detect schema when --schema flag is not explicitly set
  • Maintains backward compatibility: defaults to public schema when header is missing (old dump format)
  • Removed duplicate GenerateDumpHeader function from internal/diff/header.go
  • Updated test normalization to filter out new schema header line for cross-version comparisons

Confidence Score: 5/5

  • This PR is safe to merge with minimal risk
  • Well-designed feature with comprehensive unit tests, clean implementation, proper backward compatibility, and clear separation of concerns
  • No files require special attention

Important Files Changed

Filename Overview
cmd/util/schema_detect.go New utility to parse schema from dump file header, well-tested and straightforward
cmd/plan/plan.go Added schema auto-detection logic, cleanly implemented with proper flag checking
cmd/apply/apply.go Added schema auto-detection logic, mirrors plan.go implementation
internal/dump/formatter.go Added schema metadata line to dump header for auto-detection

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[dump command] -->|writes| B[SQL file with schema header]
    B -->|"-- Dumped from schema: X"| C{plan/apply command}
    C -->|--schema flag set?| D[Use explicit schema]
    C -->|--schema NOT set| E[DetectSchemaFromFile]
    E -->|header found| F[Use detected schema X]
    E -->|header NOT found| G[Default to 'public']
    F --> H[Execute plan/apply with schema X]
    D --> H
    G --> H
Loading

Last reviewed commit: 8cb2e74

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds schema metadata to pgschema dump output and uses it to auto-select the correct target schema during plan/apply when --schema isn’t explicitly provided, preventing accidental operations against the default public schema.

Changes:

  • Add -- Dumped from schema: <name> to the dump header.
  • Introduce a schema-detection utility that parses the schema from a dump file header.
  • Update plan and apply to use the detected schema when --schema is not set, and adjust dump integration test normalization accordingly.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
internal/dump/formatter.go Emits schema metadata in the dump header for downstream consumers.
cmd/util/schema_detect.go Adds a small helper to detect schema from the dump header.
cmd/util/schema_detect_test.go Adds unit tests for schema header parsing.
cmd/plan/plan.go Uses detected schema (when available) as the effective schema for planning.
cmd/apply/apply.go Uses detected schema (when available) as the effective schema for apply.
internal/diff/header.go Removes the old dump header generator (now unused).
cmd/dump/dump_integration_test.go Updates normalization to ignore the new schema header line in comparisons.
Comments suppressed due to low confidence (1)

internal/diff/header.go:2

  • This file is now empty (only a package declaration). Since GenerateDumpHeader was removed, consider deleting the file entirely to avoid a confusing empty source file in the diff package.
package diff


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +41 to +52
name: "quoted schema name",
content: `--
-- pgschema database dump
--

-- Dumped from database version PostgreSQL 17.7
-- Dumped by pgschema version 1.7.1
-- Dumped from schema: my_schema

`,
expected: "my_schema",
},
Copy link

Copilot AI Feb 22, 2026

Choose a reason for hiding this comment

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

This test case is labeled "quoted schema name" but the content uses an unquoted identifier (my_schema). Rename the case to reflect what it actually covers, or update the fixture to include a truly quoted schema name (e.g., "MySchema") and assert the intended behavior.

Copilot uses AI. Check for mistakes.
Comment on lines +27 to +35
func detectSchemaFromReader(r io.Reader) (string, error) {
scanner := bufio.NewScanner(r)
for i := 0; i < 20 && scanner.Scan(); i++ {
line := scanner.Text()
if strings.HasPrefix(line, schemaHeaderPrefix) {
return strings.TrimSpace(line[len(schemaHeaderPrefix):]), nil
}
}
return "", scanner.Err()
Copy link

Copilot AI Feb 22, 2026

Choose a reason for hiding this comment

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

detectSchemaFromReader uses bufio.Scanner without increasing the buffer size. Scanner will return ErrTooLong if it encounters a line >64K, which can happen in SQL files (e.g., large function bodies or comments on a single line), causing schema detection to error. Consider increasing the scanner buffer (scanner.Buffer) or using a bufio.Reader to read lines so header parsing is robust.

Copilot uses AI. Check for mistakes.
Comment on lines +104 to +111
// Auto-detect schema from dump file if --schema was not explicitly set
effectiveSchema := planSchema
if !cmd.Flags().Changed("schema") && planFile != "" {
if detected, err := util.DetectSchemaFromFile(planFile); err == nil && detected != "" {
effectiveSchema = detected
fmt.Fprintf(os.Stderr, "Auto-detected schema '%s' from dump file\n", detected)
}
}
Copy link

Copilot AI Feb 22, 2026

Choose a reason for hiding this comment

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

Schema auto-detection ignores errors from DetectSchemaFromFile. If header parsing fails (e.g., due to a scanning error), this silently falls back to the default schema, which undermines the safety goal of preventing cross-schema operations. Consider surfacing a warning to stderr when err != nil, or failing fast with a message instructing the user to pass --schema explicitly.

Copilot uses AI. Check for mistakes.
Comment on lines +271 to +274
if detected, err := util.DetectSchemaFromFile(applyFile); err == nil && detected != "" {
effectiveSchema = detected
fmt.Fprintf(os.Stderr, "Auto-detected schema '%s' from dump file\n", detected)
}
Copy link

Copilot AI Feb 22, 2026

Choose a reason for hiding this comment

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

Schema auto-detection ignores errors from DetectSchemaFromFile. If header parsing fails, apply will silently continue using the default schema, which can reintroduce the cross-schema risk this change is meant to prevent. Consider warning on detection errors or requiring --schema when detection fails.

Suggested change
if detected, err := util.DetectSchemaFromFile(applyFile); err == nil && detected != "" {
effectiveSchema = detected
fmt.Fprintf(os.Stderr, "Auto-detected schema '%s' from dump file\n", detected)
}
detected, err := util.DetectSchemaFromFile(applyFile)
if err != nil {
return fmt.Errorf("failed to auto-detect schema from dump file %q: %w (please specify --schema explicitly)", applyFile, err)
}
if detected == "" {
return fmt.Errorf("schema could not be auto-detected from dump file %q; please specify --schema explicitly", applyFile)
}
effectiveSchema = detected
fmt.Fprintf(os.Stderr, "Auto-detected schema '%s' from dump file\n", detected)

Copilot uses AI. Check for mistakes.
@tianzhou
Copy link
Contributor Author

Closing this PR — after further analysis, the reported behavior is working as designed.

pgschema produces schema-agnostic dumps by design. The same dump file can be applied to any schema (public, tenant1, vehicle, etc.). This means --schema must be specified on plan and apply when targeting non-public schemas.

The issue was a missing --schema vehicle flag on the apply command. See the comment on #296 for details.

@tianzhou tianzhou closed this Feb 22, 2026
@tianzhou tianzhou deleted the fix/issue-296-schema-auto-detect branch February 22, 2026 07:14
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.

How to get it to work with multiple schemas?

1 participant