# 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)