aboutsummaryrefslogtreecommitdiff
path: root/src/backend/replication/logical/decode.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/replication/logical/decode.c')
-rw-r--r--src/backend/replication/logical/decode.c19
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
}