diff --git a/contrib/test_decoding/expected/ddl.out b/contrib/test_decoding/expected/ddl.out index 8e8eb596526..a3ed9a5cbf9 100644 --- a/contrib/test_decoding/expected/ddl.out +++ b/contrib/test_decoding/expected/ddl.out @@ -196,6 +196,21 @@ ORDER BY 1,2; 20467 | table public.tr_etoomuch: DELETE: id[integer]:1 | table public.tr_etoomuch: UPDATE: id[integer]:9999 data[integer]:-9999 (3 rows) +-- check updates of primary keys work correctly +BEGIN; +CREATE TABLE spoolme AS SELECT g.i FROM generate_series(1, 5000) g(i); +UPDATE tr_etoomuch SET id = -id WHERE id = 5000; +DELETE FROM spoolme; +DROP TABLE spoolme; +COMMIT; +SELECT data +FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1') +WHERE data ~ 'UPDATE'; + data +------------------------------------------------------------------------------------------------------------- + table public.tr_etoomuch: UPDATE: old-key: id[integer]:5000 new-tuple: id[integer]:-5000 data[integer]:5000 +(1 row) + /* * check whether we decode subtransactions correctly in relation with each * other diff --git a/contrib/test_decoding/sql/ddl.sql b/contrib/test_decoding/sql/ddl.sql index 7357902e590..8e3dae62931 100644 --- a/contrib/test_decoding/sql/ddl.sql +++ b/contrib/test_decoding/sql/ddl.sql @@ -114,6 +114,18 @@ FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', GROUP BY substring(data, 1, 24) ORDER BY 1,2; +-- check updates of primary keys work correctly +BEGIN; +CREATE TABLE spoolme AS SELECT g.i FROM generate_series(1, 5000) g(i); +UPDATE tr_etoomuch SET id = -id WHERE id = 5000; +DELETE FROM spoolme; +DROP TABLE spoolme; +COMMIT; + +SELECT data +FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1') +WHERE data ~ 'UPDATE'; + /* * check whether we decode subtransactions correctly in relation with each * other diff --git a/src/backend/replication/logical/reorderbuffer.c b/src/backend/replication/logical/reorderbuffer.c index 5b434ac825f..22b83ab6ad0 100644 --- a/src/backend/replication/logical/reorderbuffer.c +++ b/src/backend/replication/logical/reorderbuffer.c @@ -2266,19 +2266,6 @@ ReorderBufferRestoreChange(ReorderBuffer *rb, ReorderBufferTXN *txn, case REORDER_BUFFER_CHANGE_UPDATE: /* fall through */ case REORDER_BUFFER_CHANGE_DELETE: - if (change->data.tp.newtuple) - { - Size len = offsetof(ReorderBufferTupleBuf, data) - +((ReorderBufferTupleBuf *) data)->tuple.t_len - - offsetof(HeapTupleHeaderData, t_bits); - - change->data.tp.newtuple = ReorderBufferGetTupleBuf(rb); - memcpy(change->data.tp.newtuple, data, len); - change->data.tp.newtuple->tuple.t_data = - &change->data.tp.newtuple->header; - data += len; - } - if (change->data.tp.oldtuple) { Size len = offsetof(ReorderBufferTupleBuf, data) @@ -2291,6 +2278,19 @@ ReorderBufferRestoreChange(ReorderBuffer *rb, ReorderBufferTXN *txn, &change->data.tp.oldtuple->header; data += len; } + + if (change->data.tp.newtuple) + { + Size len = offsetof(ReorderBufferTupleBuf, data) + +((ReorderBufferTupleBuf *) data)->tuple.t_len + - offsetof(HeapTupleHeaderData, t_bits); + + change->data.tp.newtuple = ReorderBufferGetTupleBuf(rb); + memcpy(change->data.tp.newtuple, data, len); + change->data.tp.newtuple->tuple.t_data = + &change->data.tp.newtuple->header; + data += len; + } break; case REORDER_BUFFER_CHANGE_INTERNAL_SNAPSHOT: {