Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions cmd/pg-schema-diff/plan_cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ type (
dataPackNewTables bool
disablePlanValidation bool
noConcurrentIndexOps bool
skipPrivileges bool

statementTimeoutModifiers []string
lockTimeoutModifiers []string
Expand Down Expand Up @@ -227,6 +228,8 @@ func createPlanOptionsFlags(cmd *cobra.Command) *planOptionsFlags {
"database with an identical schema to the original, asserting that the generated plan actually migrates the schema to the desired target.")
cmd.Flags().BoolVar(&flags.noConcurrentIndexOps, "no-concurrent-index-ops", false, "If set, will disable the use of CONCURRENTLY in CREATE INDEX and DROP INDEX statements. "+
"This may result in longer lock times and potential downtime during migrations.")
cmd.Flags().BoolVar(&flags.skipPrivileges, "skip-privileges", false, "If set, will skip diffing of table privileges (GRANT/REVOKE). "+
"This is useful when privileges on partitioned tables cause plan generation to fail.")

timeoutModifierFlagVar(cmd, &flags.statementTimeoutModifiers, "statement", "t")
timeoutModifierFlagVar(cmd, &flags.lockTimeoutModifiers, "lock", "l")
Expand Down Expand Up @@ -329,6 +332,9 @@ func parsePlanOptions(p planOptionsFlags) (planOptions, error) {
if p.noConcurrentIndexOps {
opts = append(opts, diff.WithNoConcurrentIndexOps())
}
if p.skipPrivileges {
opts = append(opts, diff.WithSkipTablePrivileges())
}

var statementTimeoutModifiers []timeoutModifier
for _, s := range p.statementTimeoutModifiers {
Expand Down
16 changes: 16 additions & 0 deletions pkg/diff/plan_generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ type (
getSchemaOpts []schema.GetSchemaOpt
randReader io.Reader
noConcurrentIndexOps bool
skipTablePrivileges bool
}

PlanOpt func(opts *planOptions)
Expand Down Expand Up @@ -113,6 +114,16 @@ func WithNoConcurrentIndexOps() PlanOpt {
}
}

// WithSkipTablePrivileges configures plan generation to ignore table privilege differences.
// This is useful when privileges on partitioned tables cause plan generation to fail with
// "privileges on partitions: not implemented", or when privilege changes should not be
// included in the migration plan.
func WithSkipTablePrivileges() PlanOpt {
return func(opts *planOptions) {
opts.skipTablePrivileges = true
}
}

// Generate generates a migration plan to migrate the database to the target schema
//
// Parameters:
Expand Down Expand Up @@ -153,6 +164,11 @@ func Generate(
return Plan{}, fmt.Errorf("getting new schema: %w", err)
}

if planOptions.skipTablePrivileges {
currentSchema = clearTablePrivileges(currentSchema)
newSchema = clearTablePrivileges(newSchema)
}

statements, err := generateMigrationStatements(currentSchema, newSchema, planOptions)
if err != nil {
return Plan{}, fmt.Errorf("generating plan statements: %w", err)
Expand Down