diff options
Diffstat (limited to 'src/backend/replication/logical/decode.c')
-rw-r--r-- | src/backend/replication/logical/decode.c | 19 |
1 files changed, 16 insertions, 3 deletions
diff --git a/src/backend/replication/logical/decode.c b/src/backend/replication/logical/decode.c index 3a6d6ffab1a..09a334232e1 100644 --- a/src/backend/replication/logical/decode.c +++ b/src/backend/replication/logical/decode.c @@ -653,6 +653,7 @@ DecodeUpdate(LogicalDecodingContext *ctx, XLogRecordBuffer *buf) xl_heap_update *xlrec; ReorderBufferChange *change; char *data; + size_t remlen = r->xl_len; xlrec = (xl_heap_update *) buf->record_data; @@ -666,6 +667,7 @@ DecodeUpdate(LogicalDecodingContext *ctx, XLogRecordBuffer *buf) /* caution, remaining data in record is not aligned */ data = buf->record_data + SizeOfHeapUpdate; + remlen -= SizeOfHeapUpdate; if (xlrec->flags & XLOG_HEAP_CONTAINS_NEW_TUPLE) { @@ -677,6 +679,7 @@ DecodeUpdate(LogicalDecodingContext *ctx, XLogRecordBuffer *buf) memcpy(&xlhdr, data, sizeof(xlhdr)); data += offsetof(xl_heap_header_len, header); + remlen -= offsetof(xl_heap_header_len, header); datalen = xlhdr.t_len + SizeOfHeapHeader; tuplelen = xlhdr.t_len; @@ -687,8 +690,10 @@ DecodeUpdate(LogicalDecodingContext *ctx, XLogRecordBuffer *buf) DecodeXLogTuple(data, datalen, change->data.tp.newtuple); /* skip over the rest of the tuple header */ data += SizeOfHeapHeader; + remlen -= SizeOfHeapHeader; /* skip over the tuple data */ data += xlhdr.t_len; + remlen -= xlhdr.t_len; } if (xlrec->flags & XLOG_HEAP_CONTAINS_OLD) @@ -699,10 +704,17 @@ DecodeUpdate(LogicalDecodingContext *ctx, XLogRecordBuffer *buf) memcpy(&xlhdr, data, sizeof(xlhdr)); data += offsetof(xl_heap_header_len, header); + remlen -= offsetof(xl_heap_header_len, header); - /* t_len is inconsistent with other cases, see log_heap_update */ - tuplelen = xlhdr.t_len - offsetof(HeapTupleHeaderData, t_bits); - datalen = tuplelen + SizeOfHeapHeader; + /* + * NB: Even though xl_heap_header_len contains the tuple's length, + * it's length field is not wide enough. Use the whole record length + * minus the new tuple's length instead. We can't remove the record + * length from the WAL record format in 9.4 due to compatibility + * concerns - later versions don't have it anyway. + */ + datalen = remlen; + tuplelen = datalen - SizeOfHeapHeader; change->data.tp.oldtuple = ReorderBufferGetTupleBuf(ctx->reorder, tuplelen); @@ -710,6 +722,7 @@ DecodeUpdate(LogicalDecodingContext *ctx, XLogRecordBuffer *buf) DecodeXLogTuple(data, datalen, change->data.tp.oldtuple); #ifdef NOT_USED data += datalen; + remlen -= datalen; #endif } |