packages feed

pgmq-migration-0.5.0.0: CHANGELOG.md

# Changelog for pgmq-migration

## 0.5.0.0 -- 2026-08-06

### Bug Fixes

Migration `0003-notify-crash-safety-and-locking.sql` re-creates three functions. It is
appended to the ledger; `0001` and `0002` are unchanged.

* Insert notifications no longer stop permanently after a PostgreSQL crash.
  `pgmq.notify_insert_throttle` is `UNLOGGED`, so crash recovery truncates it, and
  `pgmq.notify_queue_listeners` notified only when its throttle `UPDATE` matched a row.
  Zero updated rows had two causes — throttled, and row absent — and the trigger treated
  both as "stay quiet", so after a crash it fired, matched nothing, and silently never
  notified again until an application restart re-enabled notify. Sends succeeded and
  messages accumulated while listeners starved. A `NOT EXISTS` probe on the already-failed
  branch now tells the two cases apart and notifies unthrottled until the next reconcile
  restores the configured interval. The row is deliberately not re-inserted: the
  configured interval is the crash's data loss, and inventing one in the hot path would
  silently change throttling.
* Concurrent `pgmq.enable_notify_insert` calls for the same queue no longer race. Two
  replicas reconciling the same config at startup could both pass the function's internal
  `DROP TRIGGER IF EXISTS` — on a fresh queue it finds nothing and takes no lock — and the
  loser then blocked on the throttle row's unique constraint, resumed, and created a
  trigger that now existed, failing with SQLSTATE 42710 (duplicate_object) and taking down
  that replica's entire startup reconcile. Measured at roughly a 28% collision rate over
  200 concurrent iterations. The function now takes the per-queue advisory lock, as
  `pgmq.create` and `pgmq.create_partitioned` already do, which makes concurrent callers
  convergent.
* `pgmq.enable_notify_insert` coalesces a NULL `throttle_interval_ms` to the documented
  250 ms, so non-Haskell callers get the same guarantee the pgmq-hasql statement provides
  client-side.
* `pgmq.create_partitioned` is now re-entrant. The advisory lock serialized concurrent
  creators, but the second one still called `partman.create_parent` on a parent the first
  had just registered: its `CREATE TABLE IF NOT EXISTS` is a no-op while `create_parent`
  rejects an already-managed parent. Both `create_parent` calls are now guarded by a
  `part_config` probe.

### Other Changes

* The test suite derives the migration ledger from the plan rather than enumerating it
  positionally, so appending a migration no longer turns unrelated tests red. The ledger
  is spelled out once, in `testNativeComponent`.
* Added a pg_partman-gated re-entry test that reports its skip rather than passing
  silently when the extension is unavailable.

## 0.4.0.1 -- 2026-07-14

### Bug Fixes

* Add `SourceLedgerPolicy` and `pgmqHasqlMigrationSourceConfigWithPolicy`. Consumers whose
  predecessor `public.schema_migrations` table is intentionally shared can select
  `AllowUnselectedSourceRows`, inspect the adapter's unselected-row preflight, and import
  only PGMQ history. The existing `pgmqHasqlMigrationSourceConfig` remains strict, and both
  modes retain exact checksum and state-validator requirements for selected PGMQ rows.

## 0.4.0.0 -- 2026-07-14

### Breaking Changes

* Replace the `hasql-migration` command/session API with the native
  `pgmqMigrations :: Either DefinitionError MigrationComponent` API. `Pgmq.Migration` now
  exports only `pgmqMigrations`, `MigrationComponent`, and `DefinitionError`; consumers
  compose and run a `pg-migrate` plan instead of calling a runner in this package.
* Remove the migration operations `migrate`, `upgrade`, and `validate`, the migration
  metadata `getMigrations`, `version`, `migrations`, and `upgradeMigrations`, and the
  `hasql-migration` re-exports `MigrationCommand`, `MigrationError`, and
  `SchemaMigration`.
* Remove the following exposed modules. Their contents were either predecessor migration
  command lists or the `hasql-migration` runner plumbing, both of which the native
  component replaces:
  * `Pgmq.Migration.Migrations`
  * `Pgmq.Migration.Migrations.V1_10_0_to_V1_10_1`
  * `Pgmq.Migration.Migrations.V1_10_1_to_V1_11_0`
  * `Pgmq.Migration.Migrations.V1_11_0`
  * `Pgmq.Migration.Sessions`
  * `Pgmq.Migration.Statements`
  * `Pgmq.Migration.Transactions`
* An existing ledger written by a previous release of this package must be imported
  through the direct or the explicitly opted-in equivalent-history route (see below)
  before the native runner takes over. The native runner does not read the old
  `public.schema_migrations` table on its own.
* Require the `pg-migrate` 1.1 family (`pg-migrate`, `pg-migrate-embed`, and
  `pg-migrate-import-hasql-migration`), up from 1.0. That release reshapes types this
  package's callers handle directly: `HistoryImportReport` becomes a multi-field record,
  `CleanupFailed` carries a primary error plus a `NonEmpty CleanupIssue`, and `SqlError`
  and `HistoryValidationError` gain constructors that exhaustive matches must cover.

### New Features

* Add the exposed module `Pgmq.Migration.History.HasqlMigration`, which maps a
  predecessor `hasql-migration` ledger onto the native baseline. It exports
  `AlternativeHistoryPolicy`, `pgmqHasqlMigrationMappings`, and
  `pgmqHasqlMigrationSourceConfig`.
  * `DirectFullInstallHistory` imports a `pgmq_v1.11.0` full-install ledger, verified by
    reproducing the exact base64 MD5 recorded in `public.schema_migrations`.
  * `EquivalentTwoStepUpgradeHistory` imports a `v1.10.0 -> v1.10.1 -> v1.11.0` upgrade
    ledger. It is never selected implicitly, and is additionally guarded by the read-only
    PGMQ 1.11 schema contract.
* Add the exposed module `Pgmq.Migration.SchemaContract`, exporting
  `pgmqV1_11StateValidator` and `pgmqV1_11StateEvidenceKey`. The validator checks the PGMQ
  1.11 schemas, tables, columns, constraints, types, and functions that pgmq-hs depends on
  without modifying database state.
* Append `0002-schema-management-comment` as an observable native-runner canary after the
  imported historical baseline. It is non-destructive: it only sets a `COMMENT ON SCHEMA
  pgmq`, so the first native-only upgrade is provable after either import route.

### Other Changes

* Load `Database.PostgreSQL.Migrate.Embed.RecompilePlugin` in the manifest-embedding
  module. GHC 9.12 offers Template Haskell no way to depend on the migrations directory
  itself, so adding or removing a SQL file could otherwise reuse a stale object file and
  skip strict manifest membership validation. This forces the module to recompile whenever
  GHC runs over the package. Note that a build where *only* SQL files changed can still be
  short-circuited by `cabal`'s own up-to-date check before GHC is invoked.

## 0.3.0.0 -- 2026-05-31

* Version bump only — coordinated release with pgmq-effectful 0.3.0.0.
  No source-level changes since 0.2.0.0.

## 0.2.0.0 -- 2026-04-23

* Version bump only — coordinated release with pgmq-effectful 0.2.0.0.
  No source-level changes since 0.1.3.0.

## 0.1.3.0 -- 2026-03-12

### Other Changes

* Update repository homepage URL to shinzui/pgmq-hs

## 0.1.2.0 -- 2026-03-03

### Other Changes

* Vendor upstream pgmq SQL via git subtree, replacing hand-written SQL files
* SQL is now embedded from `vendor/pgmq/pgmq-extension/sql/` instead of local `database/` directory

## 0.1.1.0 -- 2026-02-23

### New Features

* Support for PGMQ v1.11.0 schema installation
* Incremental migration from v1.10.0 to v1.11.0 (topic routing, batch topic sends, throttle management)

## 0.1.0.0 -- 2026-02-21

* Initial release
* Support for PGMQ v1.9.0 schema installation
* Support for PGMQ v1.10.0 schema installation
* Incremental migration support (v1.9.0 to v1.10.0 upgrade path)