pgdesign v0.26.0 /internal/model
On this page

Package model provides the resolved intermediate representation for pgdesign, the canonical in-memory schema that all downstream packages consume.

#internal/model

#internal/model

Package model provides the resolved intermediate representation for pgdesign, the canonical in-memory schema that all downstream packages consume.

Adding a new schema object type (e.g., domain, sequence, composite type):

1. parse/types.go — raw TOML struct for the new object 2. parse/parse.go — parse function to populate the raw struct 3. model/model.go — model struct + field on Schema 4. model/build.go — resolve function (type resolution, dependency wiring) 5. validate/validate.go — validation checks (E-codes) 6. generate/generate.go — DDL generation section 7. sql/sql.go — DDL helper functions (CREATE, ALTER, DROP) 8. diff/diff.go — diff fields + comparison (use matchObjects[T]) 9. migrate/generate.go — migration op generation 10. migrate/sql_gen.go — op-to-SQL rendering 11. migrate/parse_migration.go — TOML serialization (tomlDDL fields) 12. risk/risk.go — risk classification for new ops 13. introspect/introspect.go — pg_catalog query 14. introspect/export.go — TOML export 15. generate/d2.go — diagram rendering (optional) 16. generate/doc.go — documentation output (optional)

#TowardReferencing

Go go
const TowardReferencing WalkDirection = iota

TowardReferencing follows Reverse edges: from a referenced table into the tables whose FKs point at it. This is the direction ON DELETE actions propagate at runtime (deleting a referenced row mutates rows in the referencing tables).

#TowardReferenced

Go go
const TowardReferenced

TowardReferenced follows Forward edges: from a referencing table out to the tables it references (toward the potential delete origins whose DELETE would write into the start table).

#BuildOption

Go go
type BuildOption func(*buildOptions)

BuildOption customizes model construction. Options are the extension point for build inputs that come from OUTSIDE the schema TOML (e.g. the project's [imports] declarations, which live in pgdesign.toml). Existing callers pass no options and get the same behavior as before.

#FKEdge

Go go
type FKEdge struct

FKEdge represents a single foreign key relationship between two tables. Both endpoints carry their schema so the edge is unambiguous across schemas; the FromTable/ToTable fields remain the bare table names (codegen and workload use them for type/identifier derivation), and TableKey combines them into the graph's canonical (schema, name) map key.

#FKGraph

Go go
type FKGraph struct

FKGraph is a pre-computed graph of foreign key relationships across all tables. Every map is keyed by TableKey(schema, name).

#WalkDirection

Go go
type WalkDirection int

WalkDirection selects which way WalkCascade traverses FK edges.

#FKNodeProjection

Go go
type FKNodeProjection struct

FKNodeProjection is one table node in an FKGraphProjection: its (schema, name) identity plus the constraint fan counts.

#FKEdgeProjection

Go go
type FKEdgeProjection struct

FKEdgeProjection is one FK edge in an FKGraphProjection. It mirrors FKEdge, including the schema qualification of both endpoints and the Imported flag, so the projection is a faithful, self-describing snapshot.

#FKGraphProjection

Go go
type FKGraphProjection struct

FKGraphProjection is a deterministic, (schema, name)-keyed, JSON-able snapshot of an FKGraph. It is EXCLUDED from schema identity (the graph is a derived structure, never a declared one — FKGraph itself is json:"-"), but it is carried in the API payload so consumers can read the resolved relationship graph without re-deriving it. Nodes and edges are sorted, so json.Marshal of a projection is stable regardless of the source graph's map iteration order.

#NamedTransition

Go go
type NamedTransition struct

NamedTransition holds a single named state machine transition with its metadata. Used by codegen to generate per-transition methods.

#SMTransitionMap

Go go
type SMTransitionMap struct

SMTransitionMap holds the allowed transitions for a state machine type. Keys are source state names, values are the set of reachable target states.

#SMState

Go go
type SMState struct

SMState is a single state of a state-machine type. Its declaration order is SEMANTIC (it becomes the enum label order in the generated CREATE TYPE ... AS ENUM), so the collection is never reordered.

#SMTransition

Go go
type SMTransition struct

SMTransition is a single named transition of a state-machine type. The transition collection is a CANONICAL-ONLY set (declaration order is not observable); From is a source-state SET.

#StateMachine

Go go
type StateMachine struct

StateMachine is the first-class model representation of a state-machine type definition. It carries the full transition graph WITH comments — the identity content that has no home in the derived StateMachineTransitions duplicate or in the state-name Enum. Populated during Build() from the semtype registry for every state-machine type in use. This is the identity carrier for state-machine types (encoded as a first-class object by internal/enc); the state names additionally materialize into a model Enum for DDL generation.

#Schema

Go go
type Schema struct

Schema is the top-level resolved schema.

#View

Go go
type View struct

View represents a resolved view definition.

#MaterializedView

Go go
type MaterializedView struct

MaterializedView represents a resolved materialized view definition.

#Table

Go go
type Table struct

Table represents a resolved table definition.

#Column

Go go
type Column struct

Column represents a resolved column definition.

#FK

Go go
type FK struct

FK represents a resolved foreign key constraint.

#Index

Go go
type Index struct

Index represents a resolved index definition.

#UniqueConstraint

Go go
type UniqueConstraint struct

UniqueConstraint represents a unique constraint.

#CheckConstraint

Go go
type CheckConstraint struct

CheckConstraint represents a check constraint.

#ExclusionElement

Go go
type ExclusionElement struct

ExclusionElement represents a single element in an exclusion constraint.

#ExclusionConstraint

Go go
type ExclusionConstraint struct

ExclusionConstraint represents an exclusion constraint.

#Policy

Go go
type Policy struct

Policy represents a row-level security (RLS) policy.

#Trigger

Go go
type Trigger struct

Trigger represents a user-defined trigger on a table.

#Enum

Go go
type Enum struct

Enum represents a resolved enum type.

#Sequence

Go go
type Sequence struct

Sequence represents a standalone PostgreSQL sequence.

#FunctionArg

Go go
type FunctionArg struct

FunctionArg represents a single argument to a function or procedure.

#Function

Go go
type Function struct

Function represents a resolved function or procedure definition.

#Domain

Go go
type Domain struct

Domain represents a resolved PostgreSQL domain type.

#CompositeField

Go go
type CompositeField struct

CompositeField represents a single field in a composite type.

#CompositeType

Go go
type CompositeType struct

CompositeType represents a resolved PostgreSQL composite type.

#PartitionSpec

Go go
type PartitionSpec struct

PartitionSpec represents partitioning configuration.

#MaintenanceConfig

Go go
type MaintenanceConfig struct

MaintenanceConfig represents maintenance configuration for a table.

#WithImports

Go go
func WithImports(imports map[string]string) BuildOption

WithImports supplies the project's declared import aliases (alias -> target PG schema) so alias:table FK references resolve at build time (roadmap 7.1).

#WithImportedTables

Go go
func WithImportedTables(tables []Table) BuildOption

WithImportedTables supplies the REFERENCE tables decoded from the vendored import surface (roadmap 7.3). They populate Schema.ImportedTables and are unioned into TablesByName and the FKGraph so imported-FK targets resolve, but are kept out of Schema.Tables so every Tables-iterating consumer is fail-closed by omission.

#Build

Go go
func Build(raw *parse.RawSchema, reg *semtype.Registry, opts ...BuildOption) (*Schema, diagnostic.Diagnostics)

Build constructs a resolved Schema from raw parse output and a type registry. It returns the schema (possibly partial) and any diagnostics encountered.

#BuildMulti

Go go
func BuildMulti(raws []*parse.RawSchema, reg *semtype.Registry, opts ...BuildOption) (*Schema, diagnostic.Diagnostics)

BuildMulti constructs a resolved Schema from multiple raw schemas and a type registry. Tables, enums, and extensions from all schemas are merged into one Schema. Each table's Schema field is set from its source RawSchema's meta.schema. The returned Schema.Name is empty (multi-schema has no single name).

#IsStateMachineColumn

Go go
func IsStateMachineColumn(col Column, reg *semtype.Registry) bool

IsStateMachineColumn returns true if the column's semantic type is a state machine.

#TableKey

Go go
func TableKey(schema, name string) string

TableKey is THE canonical map key for a table across the model package. TablesByName, the FKGraph adjacency maps (Forward/Reverse/FanIn/FanOut), the topological sort, and group resolution all key on it. The rule is a single function of (schema, name): "." when a schema is present, and the bare "" when the schema is empty.

This reconciles the two historical conventions — TablesByName's leading-dot ".name" form for empty schemas and the FKGraph's schema-blind bare names — into one rule, so a table has exactly one identity everywhere and same-named tables in different schemas never collide in the graph.

#FKGraphFromProjection

Go go
func FKGraphFromProjection(p FKGraphProjection) *FKGraph

FKGraphFromProjection reconstructs an FKGraph from a projection. Forward and Reverse are rebuilt from the edge list (keyed by TableKey); FanIn/FanOut are taken from the node records. Project∘FKGraphFromProjection∘Project is the identity on the projection (round-trip stable).

#StrPtr

Go go
func StrPtr(s string) *string

StrPtr returns a pointer to the given string. Used for constructing struct literals with *string fields.

#Int64Ptr

Go go
func Int64Ptr(v int64) *int64

Int64Ptr returns a pointer to the given int64. Used for constructing struct literals with *int64 fields.

#Float64Ptr

Go go
func Float64Ptr(v float64) *float64

Float64Ptr returns a pointer to the given float64. Used for constructing struct literals with *float64 fields.

#Schema.Canonicalize

Go go
func (s *Schema) Canonicalize()

Canonicalize is the shared finalize routine that puts a resolved Schema into canonical form. It is invoked by Build, BuildMulti, Introspect, and the FilterByGroups/FilterBySource filters so that every schema — regardless of origin (TOML declaration order or introspect ORDER BY) — serializes to the same bytes.

It performs three kinds of work:

1. Ordering. Per-table collections (FKs, indexes, uniques, checks, exclusions, policies, triggers), materialized-view indexes, top-level type collections (enums, domains, composite types, sequences), and Extensions are sorted alphabetically. Tables, views, materialized views, and functions are ordered topologically with an alphabetical tie-break. Columns, enum values, composite-type fields, function args, partition key columns, FK column correspondence, and index key-column order are SOURCE-ORDERED and never sorted — their order is semantic.

2. Derived structures. TablesByName and the FKGraph are rebuilt from the (now canonical) tables. Callers that mutate the table set — the group and source filters — rely on this to avoid carrying a stale graph.

3. Expression normalization (roadmap 1.2, activating full L1(a)). N-normalizes every expression-bearing field into the IR (defaults, CHECK expressions, index/exclusion predicates, policy USING/WITH CHECK, generated-column expressions, domain CHECK/default). This is what makes enc(a) = enc(b) iff a ≈_syn b hold over expressions, not just structure. N is best-effort total: an expression that does not parse (user SQL can be partial) is left VERBATIM (trimmed) rather than erroring, so schemas that Build accepted before still Build.

Canonicalize is idempotent: running it twice yields the same result.

#FKGraph.WalkCascade

Go go
func (g *FKGraph) WalkCascade(start string, dir WalkDirection, maxDepth int, follow func(edge FKEdge, firstHop bool) bool, visit func(path []FKEdge))

WalkCascade explores every simple path out of start, following FK edges in the given direction. start is a TableKey(schema, name) key. maxDepth bounds the path length: when maxDepth > 0 the walk never extends a path beyond maxDepth edges; maxDepth <= 0 means unbounded. follow reports whether an edge may be traversed; firstHop is true for edges directly attached to start. visit is invoked at every step with the full edge path from start (len(path) >= 1); the slice is reused between calls, so callers must copy it if they retain it. Cycles are cut by never revisiting a table already on the current path. Exploring all simple paths is worst-case exponential, but FK graphs are small and sparse in practice.

#FKGraph.CascadeDepth

Go go
func (g *FKGraph) CascadeDepth(table string) int

CascadeDepth returns the length of the longest ON DELETE CASCADE chain triggered by deleting rows from the given table. table is a TableKey(schema, name) key.

#FKGraph.CascadeBreadth

Go go
func (g *FKGraph) CascadeBreadth(table string) int

CascadeBreadth returns the total count of distinct tables whose rows are deleted when rows are deleted from the given table (transitively, via CASCADE edges). Does NOT count the starting table. table is a TableKey(schema, name) key.

#FKGraph.CascadeChain

Go go
func (g *FKGraph) CascadeChain(table string) []string

CascadeChain returns the distinct tables affected by deleting rows from the given table, in first-reached DFS order, as TableKey(schema, name) keys. The argument is likewise a TableKey key. Does NOT include the starting table. Returns nil if no cascade edges exist.

#Schema.ReferencedTableKeys

Go go
func (s *Schema) ReferencedTableKeys() map[string]bool

ReferencedTableKeys returns the set of TableKey(schema, name) keys that are the target of at least one FK declared by an owned table. This is THE single union-aware orphan-detection helper (roadmap 7.3) consumed by both W002 (internal/validate) and C103 (cmd/pgdesign) — replacing the two divergent raw-string scans that keyed on fk.RefSchema+"."+fk.RefTable and so could mismatch the TableKey convention (leading-dot vs bare for empty schemas) and bypassed the import union. Each FK target is resolved through TableByName (the union of owned and imported tables) so an imported-FK target keys correctly and never causes a spuriously-orphaned local table; unresolved targets fall back to the raw (schema, name) key so a dangling FK is still counted as an incoming reference (E204 reports the dangling ref separately).

#Schema.BuildFKGraph

Go go
func (s *Schema) BuildFKGraph()

BuildFKGraph constructs the FK graph from all tables. Safe to call multiple times; rebuilds each time. Called automatically by Build() and BuildMulti().

#FKGraph.Project

Go go
func (g *FKGraph) Project() FKGraphProjection

Project produces the deterministic projection of the graph. Edges are read from Forward (the authoritative edge set — every edge appears exactly once there) and sorted; nodes are the union of edge endpoints, each carrying its FanIn/FanOut from the graph.

#Schema.TableOrder

Go go
func (s *Schema) TableOrder() []Table

TableOrder returns tables in dependency order (topo-sorted). Cycle group tables appear after their non-cyclic dependencies.

#Schema.TableByName

Go go
func (s *Schema) TableByName(schema, name string) *Table

TableByName looks up a table by schema and name.

#Schema.FilterByGroups

Go go
func (s *Schema) FilterByGroups(groupNames []string) *Schema

FilterByGroups returns a shallow copy of the schema containing only tables that belong to at least one of the named groups. Other schema fields (enums, views, etc.) are preserved as-is. If groupNames is empty, the original schema is returned unchanged.

#Schema.FilterBySource

Go go
func (s *Schema) FilterBySource(sources []string) *Schema

FilterBySource returns a shallow copy of the schema containing only tables whose SourceFile basename matches one of the given source filenames. Other schema fields (enums, domains, views, etc.) are preserved as-is — types pass through because codegen needs them regardless of which source file defined them. If sources is empty, the original schema is returned unchanged.

#Table.HasIndexCovering

Go go
func (t *Table) HasIndexCovering(columns []string) bool

HasIndexCovering returns true if any index's leading columns cover all of the given columns (prefix coverage).

#Table.CandidateKeys

Go go
func (t *Table) CandidateKeys() [][]string

CandidateKeys computes candidate keys from the table's functional dependencies. The result is cached after the first call.

Search