pgdesign v0.26.0 /internal/modelgen
On this page

Package modelgen is a pure rapid-based random generator of valid pgdesign models, supplying structured inputs for the property tests of the kernel laws.

#internal/modelgen

#internal/modelgen

Package modelgen is a pure random generator of VALID pgdesign models, built on pgregory.net/rapid so shrinking is structural and comes for free with the combinators. It is L9's input source: the property tests that check the kernel's laws consume generated models rather than a handful of hand-built fixtures (the seed package generates row DATA and cannot serve this role).

This is increment A of the staged generator (roadmap 1.6): flat models only — multiple schemas, tables with snake_case names, typed builtin columns drawn from the real semtype builtin registry, mandatory table comments, and a surrogate primary key per table. It deliberately generates NO foreign keys, NO custom types, NO views or functions, and NO expressions; those fragments arrive in later increments alongside the consumers that need them.

Oracle doctrine: well-formedness invariants (snake_case names, comments, resolvable types, a valid PK) are constructed by design; broader policy invariants are left to generate-then-validate-reject so their distributions stay wide. The oracle itself (modelgen_test.go) is validate — generated models must Build + Canonicalize cleanly AND pass validate with zero errors, with the extension and type registries populated.

modelgen is test-support infrastructure: it is imported only by property tests, never by the production CLI, which keeps the rapid dependency out of shipped binaries.

#Config

Go go
type Config struct

Config controls the shape of generated models. Increment A covers flat tables; every field is additive so later increments (FKs, type closures, state machines, injective / bridge-proven fragments) extend this struct rather than reshape it.

#DefaultConfig

Go go
func DefaultConfig() Config

DefaultConfig returns the increment-A defaults: small multi-schema models with a handful of tables and columns each.

#Generator

Go go
func Generator(cfg Config) *rapid.Generator[[]*parse.RawSchema]

Generator returns a rapid generator of valid flat models as a slice of per-schema RawSchema values, ready for model.BuildMulti. Because it is a rapid.Generator, it composes into larger generators and shrinks structurally.

#Draw

Go go
func Draw(t *rapid.T, cfg Config) []*parse.RawSchema

Draw is a convenience for property tests: it draws one model from the generator built for cfg.

#GeneratePair

Go go
func GeneratePair(cfg Config) *rapid.Generator[[2][]*parse.RawSchema]

GeneratePair draws a MODEL PAIR (a, b) for L10's round-trip property: b is a's model mutated by structural edits — tables and columns added and dropped — that keep every SHARED column's type FIXED. That invariant is what makes the pair applyable: diff(a,b) lowers only to table and column add/drop ops, never a column-type-change ALTER (which would need a USING cast that empty-table apply cannot always satisfy). Both a and b are independently valid models. Groups are forced off for the pair so the diff stays focused on table/column DDL.

#DrawPair

Go go
func DrawPair(t *rapid.T, cfg Config) (a, b []*parse.RawSchema)

DrawPair is a convenience for property tests: it draws one model pair from the pair generator built for cfg.

#ExamplePair

Go go
func ExamplePair(cfg Config, seed int) (a, b []*parse.RawSchema)

ExamplePair draws a DETERMINISTIC model pair for the given seed, without a rapid.T — the entry point DB-gated tests use to iterate a bounded number of generated pairs in a plain loop (rapid's Example gives reproducible samples).

Search