Skip to content

feat: support domains - #309

Open
iambilotta wants to merge 1 commit into
stripe:mainfrom
cocreiamo:feat/domain-support
Open

iambilotta wants to merge 1 commit into
stripe:mainfrom
cocreiamo:feat/domain-support

Conversation

@iambilotta

Copy link
Copy Markdown

Description

Adds domains to the schema model and to the diff.

  • GetDomains reads pg_type rows with typtype = 'd': base type (format_type with the typmod), default (pg_get_expr on typdefaultbin), NOT NULL, and the CHECK constraints (pg_get_constraintdef, sorted by name). NOT NULL is itself a constraint on Postgres 17+, so only contype = 'c' is read; typnotnull already carries it. Extension-owned domains are excluded, as for enums.
  • schema.Domain (BaseType, Default, NotNull, Constraints) is part of Schema and of its hash; Normalize sorts domains and their constraints.
  • domainSQLGenerator mirrors the enum generator: CREATE DOMAIN … [DEFAULT …] [NOT NULL] CONSTRAINT … CHECK … before anything that can use the domain, DROP DOMAIN after the last column that did, and in between ALTER DOMAIN for the default, NOT NULL, and constraints (a changed constraint is dropped and re-added under its name). Changing the base type returns ErrNotImplemented: a domain in use cannot be dropped and re-created, and Postgres has no ALTER DOMAIN … TYPE.
  • Column types referencing a domain already diff through format_type, so a column moving from text with a CHECK to a domain plans as ALTER COLUMN … SET DATA TYPE plus the constraint drop, and validates.

Motivation

Without domains in the model, plan validation fails as soon as a column takes a domain type (type "…" does not exist in the temporary database), which makes declarative schemas that use CREATE DOMAIN for value objects unusable with validation on. Found on a real catalog with 68 domains over 170 columns.

Testing

domain_cases_test.go: no-op; domain and table created in the same plan; domain dropped with its table; constraints, default and NOT NULL added, changed and dropped; a column moving from a checked text to a domain while the old domain is dropped; a base type change reported as not implemented. The schema fixture in internal/schema/schema_test.go gains a domain (hashes updated). Run with the Docker test runner on Postgres 17; make lint and make code_gen in the repository's own images.

🤖 Generated with Claude Code

https://claude.ai/code/session_014TKmA55WMHjNEb6DmYZfJX

Domains are fetched from pg_type (base type, default, NOT NULL and their CHECK constraints)
and diffed like enums: created before anything that can use them, altered in place
(default, NOT NULL, constraints dropped and re-added by name), dropped after the last
column that used them. Changing the base type is reported as not implemented, since a
domain in use cannot be dropped and re-created and Postgres has no ALTER DOMAIN ... TYPE.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
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