Skip to content

v0.2.0

Latest

Choose a tag to compare

@Kiran01bm Kiran01bm released this 30 Aug 06:09
· 6 commits to main since this release
v0.2.0
127f158

Desired-state execution grows a library front door and learns to create the table it is converging toward — declaring a brand-new table on a fresh database now works end to end under the engine's proof discipline.

Highlights

Greenfield CREATE TABLE through the declarative front door

  • A desired file whose table does not exist yet now converges — the engine proves the name is free (CheckTableAbsent, read against pg_class so a missing privilege can never masquerade as absence), proves the role holds CREATE on the schema, then runs the CREATE TABLE and its index builds as brief bounded steps under the usual lock_timeout / statement_timeout budgets. A rerun converges to an empty plan. (#60, #62, #63)
  • Refusals are typed and land before anything runs — an occupied name (relation or standalone type) is the new create-collision reason; a privilege gap is insufficient-privileges; PARTITION OF, INHERITS, LIKE, OF, and IF NOT EXISTS shapes refuse with unsupported-statement. (#63)
  • Plan order states execution order — desired-file statements are ordered at parse (the CREATE TABLE first, indexes keeping input order after it) everywhere the file replays: the greenfield plan, the create path's steps, and the scratch-schema introspection that derives a diff once the table exists. (#63)

Library-level desired-state execution

  • migrate.RunDesired converges one live table onto its parsed desired schema: derive the convergence plan, admit it as a whole (table existence, destructive guard, routed dispositions, optional ExpectedFingerprint pin), then run each planned statement back through the same migrate.Run pipeline with fresh introspection and classification, stopping at the first refusal or failure. The result carries the plan, per-statement verdicts, and an aggregate outcome with committed-prefix detail. (#49, #53)
  • Two new refusal reasons: destructive-change (the plan discards live structure — desired-state execution never runs it) and plan-fingerprint-mismatch (the plan derived at execution time is not the pinned reviewed plan). Library-only for now — the migrate --desired CLI verb follows separately. (#53)

Classification and resolution fixes

  • Alter attempts pin search_path to the target schema (then public) whenever the statement is schema-qualified — the same resolution the create path and introspection use, so unqualified secondary names (a column's type, an expression's function) can no longer silently bind a same-named object in public. (#63)
  • ALTER COLUMN ... DROP NOT NULL now classifies as destructive — dropping NOT NULL discards the same guarantee as dropping the equivalent constraint; DROP DEFAULT deliberately stays non-destructive. (#53)

Upgrade notes

  • A greenfield desired plan now executes where it previously refused — automation branching on the old unsupported-statement refusal for a not-yet-existing table sees the create run instead.
  • Callers relying on ambient search_path resolution must qualify secondary names — alter attempts on a schema-qualified statement now resolve unqualified secondary names (a column's type, an expression's function) in the target schema, not the session's search_path.
  • ALTER COLUMN ... DROP NOT NULL now reports destructive: true in plan reports, and desired-state execution refuses it like any other drop. DROP DEFAULT deliberately stays non-destructive.
  • Refusal-reason vocabulary additions: create-collision, destructive-change, plan-fingerprint-mismatch. A consumer enumerating the closed set should re-sync.

Docs

Contributors

Full changelog: v0.1.0...v0.2.0