Skip to content

Schema change: create_enum and add_enum_value - #10

Merged
swsarancodes merged 2 commits into
mainfrom
feat/schema-change-enums
Oct 25, 2026
Merged

swsarancodes merged 2 commits into
mainfrom
feat/schema-change-enums

Conversation

@swsarancodes

Copy link
Copy Markdown
Owner

What changed

Two plan operations for enum types.

  • create_enum (type name, labels): CREATE TYPE … AS ENUM (…) in one step that locks nothing; the undo is DROP TYPE. A column can use the new type later in the same plan, and its default has to be one of the labels (PostgreSQL cannot be asked about a type that does not exist yet, so the compiler checks it itself). Refused: a name taken by a type or by a table (the two share a namespace), repeated labels, a label over 63 bytes, a schema that does not exist.
  • add_enum_value (type name, label, optionally before or after an existing label): ALTER TYPE … ADD VALUE IF NOT EXISTS … in a step of its own, so later steps can use the label. Says so when the label is already there (including one an earlier step of the same plan added); refuses an unknown type, a type that is not an enum, an unknown neighbour, and both positions. The notes say a label can never be removed again and that no table that uses the type is locked or rewritten.
  • A new probe reads whether a type exists, whether it is an enum and its labels in order. The planner no longer treats the type name of an enum operation as a table to read. Type names are compared without the schema when one side has none (public.mood and mood), because PostgreSQL leaves the schema out of a type on the search path; without that the comparison after a run would report a difference that is not one.
  • The planner prompt, the plan normalizer, the structured-output schema and the plan list in the UI know both operations; the "values was ignored" note now points at create_enum.

How it was checked

  • 6 new unit tests plus extended type-name tests; the repo suite passes (1,760 tests) and both type-checks are clean. OpenAI accepts the schema (npm run check:openai).
  • Two scenarios in scripts/schema-change-pg.ts: create an enum, add a column of that type with a default, then add a label after another (labels in order, existing rows read the default, the new label can be used); and add a label before another to an enum that exists. The probe is checked against an enum, a type that is not there and a table's row type. Lock levels and the predicted end state are checked like every scenario. npm run test:schema-pg:versions passes on PostgreSQL 12, 13, 14, 15, 16, 17 and 18.

Reviewer notes

  • Not included: removing or renaming a label, dropping an enum type, converting a column to or from an enum, a safe column rename.

create_enum makes an enum type in a step that locks nothing; a column can use it later in the same plan, and its default has to be one of its labels (PostgreSQL cannot be asked about a type that does not exist yet). add_enum_value adds a label at the end or before or after another, with ADD VALUE IF NOT EXISTS, in a step of its own so later steps can use the label; it says when the label is already there and refuses an unknown type, a type that is not an enum, an unknown neighbour or both positions. A new probe reads whether a type exists, whether it is an enum and its labels in order. Type names are compared without the schema when one side has none, because PostgreSQL leaves the schema out of a type on the search path.
One creates an enum, adds a column of that type with a default and then a label after another, and checks the labels in order, the default on existing rows and that the new label can be used; one adds a label before another to an enum that exists. The probe is checked against an enum, a type that is not there and a table's row type.
@swsarancodes
swsarancodes merged commit 253ef64 into main Oct 25, 2026
1 check failed
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.

1 participant