* Decode XLOG_HEAP2_MULTI_INSERT_insert record into multiple tuplebufs. * * Currently MULTI_INSERT will always contain the full tuples. */
| 1063 | * Currently MULTI_INSERT will always contain the full tuples. |
| 1064 | */ |
| 1065 | static void |
| 1066 | DecodeMultiInsert(LogicalDecodingContext *ctx, XLogRecordBuffer *buf) |
| 1067 | { |
| 1068 | XLogReaderState *r = buf->record; |
| 1069 | xl_heap_multi_insert *xlrec; |
| 1070 | int i; |
| 1071 | char *data; |
| 1072 | char *tupledata; |
| 1073 | Size tuplelen; |
| 1074 | RelFileNode rnode; |
| 1075 | |
| 1076 | xlrec = (xl_heap_multi_insert *) XLogRecGetData(r); |
| 1077 | |
| 1078 | /* |
| 1079 | * Ignore insert records without new tuples. This happens when a |
| 1080 | * multi_insert is done on a catalog or on a non-persistent relation. |
| 1081 | */ |
| 1082 | if (!(xlrec->flags & XLH_INSERT_CONTAINS_NEW_TUPLE)) |
| 1083 | return; |
| 1084 | |
| 1085 | /* only interested in our database */ |
| 1086 | XLogRecGetBlockTag(r, 0, &rnode, NULL, NULL); |
| 1087 | if (rnode.dbNode != ctx->slot->data.database) |
| 1088 | return; |
| 1089 | |
| 1090 | /* output plugin doesn't look for this origin, no need to queue */ |
| 1091 | if (FilterByOrigin(ctx, XLogRecGetOrigin(r))) |
| 1092 | return; |
| 1093 | |
| 1094 | /* |
| 1095 | * We know that this multi_insert isn't for a catalog, so the block should |
| 1096 | * always have data even if a full-page write of it is taken. |
| 1097 | */ |
| 1098 | tupledata = XLogRecGetBlockData(r, 0, &tuplelen); |
| 1099 | Assert(tupledata != NULL); |
| 1100 | |
| 1101 | data = tupledata; |
| 1102 | for (i = 0; i < xlrec->ntuples; i++) |
| 1103 | { |
| 1104 | ReorderBufferChange *change; |
| 1105 | xl_multi_insert_tuple *xlhdr; |
| 1106 | int datalen; |
| 1107 | ReorderBufferTupleBuf *tuple; |
| 1108 | HeapTupleHeader header; |
| 1109 | |
| 1110 | change = ReorderBufferGetChange(ctx->reorder); |
| 1111 | change->action = REORDER_BUFFER_CHANGE_INSERT; |
| 1112 | change->origin_id = XLogRecGetOrigin(r); |
| 1113 | |
| 1114 | memcpy(&change->data.tp.relnode, &rnode, sizeof(RelFileNode)); |
| 1115 | |
| 1116 | xlhdr = (xl_multi_insert_tuple *) SHORTALIGN(data); |
| 1117 | data = ((char *) xlhdr) + SizeOfMultiInsertTuple; |
| 1118 | datalen = xlhdr->datalen; |
| 1119 | |
| 1120 | change->data.tp.newtuple = |
| 1121 | ReorderBufferGetTupleBuf(ctx->reorder, datalen); |
| 1122 |
no test coverage detected