Repository navigation
9.46.0
Four fixes. Three are cases where Weasel reported or did the wrong thing while every check said the schema was fine; the fourth reached anyone publishing trimmed or natively compiled. See the 9.46 notes.
Nothing public was removed and no signature changed. One member was added to Migrator, with a default implementation, so existing subclasses keep working.
PostgreSQL
-
A half-built concurrent partitioned index can be finished (#718, contributed by @lahma). A concurrent index on a partitioned table that stopped partway through — a uniqueness violation, a cancelled build, a process that died between a build and its attach — could never be finished. Weasel already read the invalid parent as drift and rebuilt it by dropping it first, but dropping a partitioned index removes only the children attached to it, and the child of the partition the run stopped at was never attached. So the rebuild asked for the same name again and failed with
42P07: relation "…" already exists, on every run, because nothing ever removed the leftover. Each partition's step now begins with aDROP INDEX CONCURRENTLY IF EXISTSfor that child, so a database stuck in this state finishes the index on its next apply. -
Advisory lock holders are read from the current database only (#719 / #725).
AdvisoryLock.FindHolderAsyncqueriedpg_lockswithout scoping it to a database. An advisory lock is taken on the acquiring session's database — two databases on one server hold the same id independently, andpg_try_advisory_lockfor an id a neighbour holds returnstrue— whilepg_locksis server-wide. So the read reported a lock as held, with a pid and an application name, for a lock this node could have taken. Database-per-tenant deployments and parallel test lanes share a server and reuse lock ids, so they hit it by construction.Weasel.SqlServernever had this; its equivalent read already filtered onDB_ID().
Firebird
- A catalog read that raced a rewrite is read again (#723 / #728). Firebird keeps a view's, routine's and trigger's source in a BLOB, and a catalog row carries only the BLOB's id; the client fetches the blob in a later round trip. A concurrent
CREATE OR ALTERreplaces the record version the id came from, and the blob can be collected before that fetch —BLOB not found, error 335544382, for something no reader did wrong. It is a read failure, not a statement failure, which is why Firebird's existing statement retry never covered it: a statement never produces this error.MigratorgainedIsConcurrentIntrospectionFailureandSchemaMigration.DetermineAsync(conn, migrator, …)now re-reads the whole set, up to three attempts with a jittered backoff. Every other provider answersfalse, so nothing else changes.
Weasel.Core
- No more trim warning (#724, contributed by @lahma).
MultiCommandDataReader.GetFieldType(int)overrodeDbDataReader.GetFieldType(int)without repeating the base method's[return: DynamicallyAccessedMembers(…)], so a trimmed or natively published application that keeps the type reportedIL2093— surfacing asIL2104: Assembly 'Weasel.Core' produced trim warnings. Any application running a compiled batch throughCommandBuilderExtensions.ExecuteReaderAsynckeeps it, whichever database it talks to. Found through Quartz.NET's trim canary (quartznet/quartznet#4129).
What changes for you
- Generated PostgreSQL DDL for a concurrent index on a partitioned table carries new statements — a
DROP INDEX CONCURRENTLY IF EXISTS <schema>.<child>;per partition. Update expected text if you assert on it. Nothing changes for a non-partitioned index, or a partitioned index built non-concurrently. AdvisoryLock.FindHolderAsyncreturnsnullwhere it used to name a holder in another database. That answer was wrong, but tooling that treated any non-null result as "someone holds this" will now correctly see the lock as free.Migratorhas a new virtual,IsConcurrentIntrospectionFailure(Exception), defaulting tofalse. Existing subclasses compile and behave exactly as before.- A Firebird migration may make up to three introspection attempts instead of one. Anything that is not
BLOB not foundstill surfaces on the first attempt.
Two internal CI fixes also landed with no effect on the packages: #720 removed a Postgres matrix leg that tested nothing, and #721 put Weasel.CommandLine.Tests into a workflow — it had been run by none.