Skip to content

Commit 75c1921

Browse files
committed
Adjust tuple data lookup logic in multi-insert logical decoding
As of now, logical decoding of a multi-insert has been scanning all xl_multi_insert_tuple entries only if XLH_INSERT_CONTAINS_NEW_TUPLE was getting set in the record. This is not an issue on HEAD as multi-insert records are not used for system catalogs, but the logical decoding logic includes all the code necessary to handle that properly, except that the code missed to iterate correctly over all xl_multi_insert_tuple entries when the flag is not set. Hence, when trying to use multi-insert for system catalogs, an assertion would be triggered. An upcoming patch is going to make use of multi-insert for system catalogs, and this fixes the logic to make sure that all entries are scanned correctly without softening the existing assertions. Reported-by: Daniel Gustafsson Author: Michael Paquier Reviewed-by: Daniel Gustafsson Discussion: https://postgr.es/m/[email protected]
1 parent efc77cf commit 75c1921

File tree

1 file changed

+12
-6
lines changed

1 file changed

+12
-6
lines changed

src/backend/replication/logical/decode.c

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -900,7 +900,12 @@ DecodeMultiInsert(LogicalDecodingContext *ctx, XLogRecordBuffer *buf)
900900
if (FilterByOrigin(ctx, XLogRecGetOrigin(r)))
901901
return;
902902

903+
/*
904+
* As multi_insert is not used for catalogs yet, the block should always
905+
* have data even if a full-page write of it is taken.
906+
*/
903907
tupledata = XLogRecGetBlockData(r, 0, &tuplelen);
908+
Assert(tupledata != NULL);
904909

905910
data = tupledata;
906911
for (i = 0; i < xlrec->ntuples; i++)
@@ -916,6 +921,10 @@ DecodeMultiInsert(LogicalDecodingContext *ctx, XLogRecordBuffer *buf)
916921

917922
memcpy(&change->data.tp.relnode, &rnode, sizeof(RelFileNode));
918923

924+
xlhdr = (xl_multi_insert_tuple *) SHORTALIGN(data);
925+
data = ((char *) xlhdr) + SizeOfMultiInsertTuple;
926+
datalen = xlhdr->datalen;
927+
919928
/*
920929
* CONTAINS_NEW_TUPLE will always be set currently as multi_insert
921930
* isn't used for catalogs, but better be future proof.
@@ -927,10 +936,6 @@ DecodeMultiInsert(LogicalDecodingContext *ctx, XLogRecordBuffer *buf)
927936
{
928937
HeapTupleHeader header;
929938

930-
xlhdr = (xl_multi_insert_tuple *) SHORTALIGN(data);
931-
data = ((char *) xlhdr) + SizeOfMultiInsertTuple;
932-
datalen = xlhdr->datalen;
933-
934939
change->data.tp.newtuple =
935940
ReorderBufferGetTupleBuf(ctx->reorder, datalen);
936941

@@ -953,8 +958,6 @@ DecodeMultiInsert(LogicalDecodingContext *ctx, XLogRecordBuffer *buf)
953958
memcpy((char *) tuple->tuple.t_data + SizeofHeapTupleHeader,
954959
(char *) data,
955960
datalen);
956-
data += datalen;
957-
958961
header->t_infomask = xlhdr->t_infomask;
959962
header->t_infomask2 = xlhdr->t_infomask2;
960963
header->t_hoff = xlhdr->t_hoff;
@@ -973,6 +976,9 @@ DecodeMultiInsert(LogicalDecodingContext *ctx, XLogRecordBuffer *buf)
973976

974977
ReorderBufferQueueChange(ctx->reorder, XLogRecGetXid(r),
975978
buf->origptr, change);
979+
980+
/* move to the next xl_multi_insert_tuple entry */
981+
data += datalen;
976982
}
977983
Assert(data == tupledata + tuplelen);
978984
}

0 commit comments

Comments
 (0)