Skip to content

Comments

Support RENAME VALUE for PostgreSQL ENUM types#1065

Merged
gfx merged 3 commits intosqldef:masterfrom
178inaba:feature/enum-rename-value
Dec 27, 2025
Merged

Support RENAME VALUE for PostgreSQL ENUM types#1065
gfx merged 3 commits intosqldef:masterfrom
178inaba:feature/enum-rename-value

Conversation

@178inaba
Copy link
Contributor

Summary

This PR adds support for renaming PostgreSQL ENUM values using the @renamed annotation, following the same pattern as column, table, and index renaming.

Features

  • Support ALTER TYPE ... RENAME VALUE generation (PostgreSQL 10+)
  • Both block comments (/* @renamed from=old_value */) and line comments (-- @renamed from=old_value) are supported
  • Works with schema-qualified types (e.g., myschema.status)
  • Can be combined with ADD VALUE for simultaneous rename and add operations

Example

CREATE TYPE status AS ENUM (
  'active',
  'waiting' /* @renamed from=pending */,
  'inactive'
);

Generates:

ALTER TYPE "public"."status" RENAME VALUE 'pending' TO 'waiting';

Implementation Details

  • Added EnumValue struct with renamedFrom field (using Ident type for consistency with column/table/index)
  • Implemented tokenizer-based comment extraction (extractEnumValueComments) following the same pattern as extractColumnComments
  • Updated generateDDLsForCreateType to handle RENAME VALUE before ADD VALUE

Test Plan

  • make build passes
  • make test-all-flavors passes (except mssqldef due to SQL Server connection)
  • make format passes
  • make lint passes
  • make vulncheck - no vulnerabilities found
  • make modernize passes

Test Cases Added

  • RenameEnumValue - Basic rename with block comment
  • RenameEnumValueLineComment - Rename with line comment
  • RenameMultipleEnumValues - Renaming multiple values at once
  • RenameAndAddEnumValue - Combining rename with add
  • RenameEnumValueWithSchema - Schema-qualified type rename

Add support for renaming enum values using @renamed annotation:
- CREATE TYPE status AS ENUM ('waiting' /* @renamed from=pending */);
- Generates: ALTER TYPE status RENAME VALUE 'pending' TO 'waiting';

Requires PostgreSQL 10+.
Replace regex-based parseEnumValuesWithRename with tokenizer-based
extractEnumValueComments for consistency with extractColumnComments.
Match the pattern used by Table, Column, and Index for consistency.
@codecov
Copy link

codecov bot commented Dec 26, 2025

Codecov Report

❌ Patch coverage is 93.02326% with 6 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
schema/parser.go 90.90% 3 Missing and 3 partials ⚠️
Files with missing lines Coverage Δ
schema/ast.go 96.11% <ø> (ø)
schema/generator.go 80.94% <100.00%> (+0.08%) ⬆️
schema/parser.go 91.41% <90.90%> (-0.05%) ⬇️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

}

// stripQuotes removes surrounding single quotes from a string if present
func stripQuotes(s string) string {
Copy link
Contributor

Choose a reason for hiding this comment

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

Is it really needed? I can't believe enum vares are stored with quotes.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thank you for the review!

Good question! The parser explicitly adds quotes around enum values in parser/parser.y at lines 4123 and 4127:

$$ = append($$, "'" + $1 + "'")

sqldef/parser/parser.y

Lines 4119 to 4128 in ba33464

enum_values:
STRING
{
$$ = make([]string, 0, 4)
$$ = append($$, "'" + $1 + "'")
}
| enum_values ',' STRING
{
$$ = append($1, "'" + $3 + "'")
}

So enum values are stored as 'active', 'pending', etc. with surrounding quotes. The stripQuotes function removes these quotes to generate correct SQL like:

ALTER TYPE "public"."status" RENAME VALUE 'pending' TO 'waiting';

Without it, we would get double quotes:

ALTER TYPE "public"."status" RENAME VALUE ''pending'' TO ''waiting'';

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We could also fix parser.y to not add quotes. In that case, the following changes would be needed:

File Line Change
parser/parser.y 4123, 4127 Remove quote addition
parser/node.go 897 Add quotes when outputting
schema/generator.go 2756 Add quotes when outputting
schema/generator.go 2371, 2381, 2399-2410 Remove stripQuotes function and calls

Total: 5 locations across 3 files.

I'm happy to make this change in this PR if you prefer. Please let me know which approach you'd like me to take.

Copy link
Contributor

Choose a reason for hiding this comment

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

Wow! It is surprising.

That parser behavior is totally wrong, and should be fixed.

Would be nice if you can fix the behavir in a separate PR. I'm waiting the next release until that fix.

@gfx
Copy link
Contributor

gfx commented Dec 26, 2025

Thank you for your contribution. I'm about to merge this PR, but can you check it a comment I've left?

@gfx gfx added this pull request to the merge queue Dec 27, 2025
Merged via the queue into sqldef:master with commit 8f1712a Dec 27, 2025
26 checks passed
@sqldef-bot sqldef-bot bot mentioned this pull request Dec 27, 2025
@178inaba 178inaba deleted the feature/enum-rename-value branch December 27, 2025 09:38
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.

2 participants