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
type Config structConfig 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
func DefaultConfig() ConfigDefaultConfig returns the increment-A defaults: small multi-schema models with a handful of tables and columns each.
#Generator
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
func Draw(t *rapid.T, cfg Config) []*parse.RawSchemaDraw is a convenience for property tests: it draws one model from the generator built for cfg.
#GeneratePair
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
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
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).