Skip to content

9.40.0

Choose a tag to compare

@jeremydmiller jeremydmiller released this 04 Oct 16:24
· 8 commits to master since this release
bc2013f

Full notes: Upgrading to 9.40

No breaking changes. The whole 9.39.0 → 9.40.0 public surface was audited: nothing public was removed, and the one new interface member carries a default implementation.

⚠️ A host stop no longer waits out the advisory lock

#676 · #678

Weasel.Postgresql.AdvisoryLock.DisposeAsync released its locks one at a time, unbounded and unlogged. With session-scoped multiplexed locks plus lock monitoring, a host stop could take 60 or 120 seconds with nothing logged at all — Medallion's connection monitor parks a connection in a one-minute wait, and the last release on it fires no wake-up because the handle drops its monitoring registration before running pg_advisory_unlock.

Releases now run concurrently and the wait is bounded by the new AdvisoryLockOptions.ReleaseTimeout (default 5s), with any overrun logged.

This changes what DisposeAsync waits for — it now returns after the timeout with outstanding releases backgrounded. Nothing leaks, and it is strictly better than the old stall, but set ReleaseTimeout to Timeout.InfiniteTimeSpan (or any non-positive value) to opt out.

A creation script runs — and re-runs

#677 · #680 · #681 · #685 · #686 · #687

The migration path has deferred foreign keys to tables created later for a long time. The script path wrote objects in yield order, so the same model could migrate cleanly and emit a script that failed on its first constraint. ToDatabaseScript() and WriteScriptsByTypeAsync() now order objects and features by dependency — features too, because WriteScriptsByTypeAsync puts each in its own file, so there the feature order is the script order.

A second run then failed on the foreign key itself. Measured on all six providers; three were already right:

PostgreSQL now catches duplicate_object
Oracle now checks all_constraints
MySQL now declares the key inline in CREATE TABLE
SQL Server, Firebird, SQLite already guarded

MySQL's rendered CREATE TABLE changes shape: foreign keys move inside the parentheses and no trailing ALTER TABLE … ADD CONSTRAINT is emitted. Identical schema, delta detection unaffected — but if you assert on that text, it moved.

All creation-path only. Every WriteAddStatement is untouched, so no rendered migration changes.

ICommandBuilder.ParameterCount

#675 · #679 · #682 · #683

How many parameters the command being built already carries, so a caller rendering a value list can decide against Migrator.MaxParametersPerCommand instead of guessing. The budget belongs to the command, not the fragment, so a per-fragment threshold does not close the hole.

If you implement ICommandBuilder, you need change nothing. It has a default implementation returning ICommandBuilder.UnknownParameterCount (-1). Without that default this would have been a runtime break — the CLR refuses the type the first time a host loads it, which no build or restore reveals.

New public API

  • AdvisoryLockOptions.ReleaseTimeout
  • ICommandBuilder.ParameterCount / UnknownParameterCount
  • Weasel.Core.Migrations.ISchemaObjectWithDependencies — declare a creation-order dependency that is not a foreign key
  • Weasel.Core.Migrations.SchemaObjectOrdering.InDependencyOrder
  • ForeignKey.WriteGuardedAddStatement (PostgreSQL, Oracle), ForeignKey.WriteInlineDefinition / ToInlineDefinition (MySQL)