DELETEs on tables whose replica identity includes a user-defined enum column, extends the fix to enum arrays and domains over enums, and stops a single failing query from taking its whole batch down with it. Pipelines replicating tables with enum primary keys should read the upgrade notes: the target may already have diverged.
Replicated Deletes on Enum Primary Keys
PR #1038, by @kvch. EveryDELETE replicated to a table whose replica identity contained a user-defined enum column failed with unable to encode []interface {}{...} into text format for unknown type. Consecutive same-table deletes are coalesced into a single statement that binds one array parameter per identity column, and pgx has no codec for a database-specific enum array OID — so the statement never left the client. Scalar enum values are plain strings and encode fine, which is why INSERT and UPDATE were unaffected and only deletes broke. Identity values for these columns are now sent as text[] and cast back on the target.
This is the replication counterpart of the snapshot fix in v1.2.3 (PR #1035), which covered only the bulk-ingest COPY path.
Enum Arrays and Domains Over Enums
The cast target is resolved from the target catalog — the enum itself, reached through the array element type and the domain base type — rather than from the column type carried by the replication stream. Casting to the column’s declared type is not equivalent: the enum comparison operators are polymorphic overanyenum, which does not accept a domain. This also fixes deletes on a domain-over-enum identity column, which previously failed on every path, including the per-row form that predates delete coalescing.
Failure Containment
A client-side encoding failure carries no SQLSTATE, so it was classified as an internal error: the whole send failed rather than the one offending query being dropped, and withignore_send_errors: true the entire batch was discarded — including co-batched writes to unrelated tables. Such failures are now recognized as deterministic and query-attributable, so only the failing query is dropped and the rest of the batch proceeds. They are also no longer retried; with the default retry policy (no attempt or elapsed-time bound) a deterministic encoding failure would otherwise retry indefinitely.
Two related fixes ship alongside: a transaction retried after a transient failure no longer reports already-committed queries as needing a retry, and the DATALOSS warning for a dropped query now records the cause and the affected schema and table.
Upgrade
No configuration changes are required, and the SQL emitted for tables without enum identity columns is unchanged. ⚠️ If you replicate tables with enum primary keys, the target may already have diverged: before this release those deletes failed permanently, and withignore_send_errors: true the surrounding batch was dropped with it. Upgrading fixes future deletes but does not reconcile rows that were missed — check for rows on the target that no longer exist on the source, and re-snapshot the affected tables if needed.
Operators who would rather halt than let the target diverge can set strict_mode, which stops the pipeline on any query that would otherwise be dropped. Note that it has no effect while ignore_send_errors is true, as that swallows the error first.
Support
- Issues: https://github.com/xataio/pgstream/issues
- Documentation: https://github.com/xataio/pgstream/tree/main/docs
- Discussions: https://github.com/xataio/pgstream/discussions