Skip to content

feat: map PostgreSQL enum columns to generated Java enums - #52

Merged
omer-cengel merged 2 commits into
masterfrom
feature/postgresql-enum-types
Sep 28, 2026
Merged

omer-cengel merged 2 commits into
masterfrom
feature/postgresql-enum-types

Conversation

@omer-cengel

Copy link
Copy Markdown
Member

Summary

Columns of a PostgreSQL enum type used to be recorded as an unsupported type, so any query that read or bound them failed. sqlcj now models CREATE TYPE ... AS ENUM and ALTER TYPE ... ADD VALUE from the schema sources in order, and generates one top-level Java enum per enum type a query uses. Its constants keep PostgreSQL's exact labels and sort order, and every repository in the package shares it.

Changes

  • Schema: CREATE TYPE <name> AS ENUM (...) adds an enum type. ALTER TYPE <name> ADD VALUE [IF NOT EXISTS] '<label>' [BEFORE | AFTER '<neighbour>'] appends the label or inserts it next to its neighbour, and IF NOT EXISTS with an existing label changes nothing. Repeated types or labels, and unknown types or neighbours, are rejected with dedicated diagnostics.
  • A non-array column whose declared type names a declared enum, matched case-insensitively, becomes an enum column in CREATE TABLE, ADD COLUMN, and ALTER COLUMN TYPE. Renames and nullability changes keep its enum type, and a label added later applies to columns declared earlier.
  • Analysis carries the enum type into result columns and parameters. A placeholder index repeated across an enum and another type, or across two enums, is rejected, and the diagnostic names each enum by its PostgreSQL name.
  • Generation: each enum type a query reads or binds produces one top-level public enum in java.package, named in upper camel case, with one constant per label (label words upper-cased and joined with _), label(), and fromLabel(String). Arguments are bound as UntypedText around the constant's label, so null stays SQL NULL, and columns are read with getString and fromLabel.
  • Two entries that define one used enum differently, enums whose Java names are equal ignoring case, an enum colliding with another generated type, and a label that cannot form a Java constant all fail before any output is written.
  • Enum files are listed in the output manifest and deleted once no entry uses them.
  • Documentation covers the type mapping, the enum DDL, the generated enum API, the naming rules, and the diagnostics.

Scope and non-goals

  • Other ALTER TYPE actions (such as RENAME TO and RENAME VALUE), DROP TYPE, and composite, range, or shell CREATE TYPE stay rejected.
  • Arrays of an enum type stay recorded as unsupported types.
  • Schema-qualified enum type names are not resolved.
  • The runtime is unchanged: enum labels bind through the existing UntypedText mechanism.

@omer-cengel
omer-cengel merged commit 5c97445 into master Sep 28, 2026
6 checks passed
@omer-cengel
omer-cengel deleted the feature/postgresql-enum-types branch September 28, 2026 22:02
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