Fix incorrect output from gin_desc().
authorFujii Masao <fujii@postgresql.org>
Mon, 5 Dec 2016 11:29:41 +0000 (20:29 +0900)
committerFujii Masao <fujii@postgresql.org>
Mon, 5 Dec 2016 11:29:41 +0000 (20:29 +0900)
Previously gin_desc() displayed incorrect output "unknown action 0"
for XLOG_GIN_INSERT and XLOG_GIN_VACUUM_DATA_LEAF_PAGE records with
valid actions. The cause of this problem was that gin_desc() wrongly
used XLogRecGetData() to extract data from those records.
Since they were registered by XLogRegisterBufData(), gin_desc() should
have used XLogRecGetBlockData(), instead, like gin_redo().
Also there were other differences about how to treat XLOG_GIN_INSERT
record between gin_desc() and gin_redo().

This commit fixes gin_desc() routine so that it treats those records
in the same way as gin_redo().

Batch-patch to 9.5 where WAL record format was revamped and
XLogRegisterBufData() was added.

Reported-By: Andres Freund
Reviewed-By: Tom Lane
Discussion: <20160509194645.7lewnpw647zegx2m@alap3.anarazel.de>

src/backend/access/rmgrdesc/gindesc.c

index db832a5f789cf01eb3d0d41aeb0ca5a37cb33df2..b058d493f7721642575338374f11241eb5465ca6 100644 (file)
@@ -87,13 +87,13 @@ gin_desc(StringInfo buf, XLogReaderState *record)
        case XLOG_GIN_INSERT:
            {
                ginxlogInsert *xlrec = (ginxlogInsert *) rec;
-               char       *payload = rec + sizeof(ginxlogInsert);
 
                appendStringInfo(buf, "isdata: %c isleaf: %c",
                              (xlrec->flags & GIN_INSERT_ISDATA) ? 'T' : 'F',
                             (xlrec->flags & GIN_INSERT_ISLEAF) ? 'T' : 'F');
                if (!(xlrec->flags & GIN_INSERT_ISLEAF))
                {
+                   char       *payload = rec + sizeof(ginxlogInsert);
                    BlockNumber leftChildBlkno;
                    BlockNumber rightChildBlkno;
 
@@ -104,27 +104,27 @@ gin_desc(StringInfo buf, XLogReaderState *record)
                    appendStringInfo(buf, " children: %u/%u",
                                     leftChildBlkno, rightChildBlkno);
                }
-               if (!(xlrec->flags & GIN_INSERT_ISDATA))
-                   appendStringInfo(buf, " isdelete: %c",
-                   (((ginxlogInsertEntry *) payload)->isDelete) ? 'T' : 'F');
-               else if (xlrec->flags & GIN_INSERT_ISLEAF)
-               {
-                   ginxlogRecompressDataLeaf *insertData =
-                   (ginxlogRecompressDataLeaf *) payload;
-
-                   if (XLogRecHasBlockImage(record, 0))
-                       appendStringInfoString(buf, " (full page image)");
-                   else
-                       desc_recompress_leaf(buf, insertData);
-               }
+               if (XLogRecHasBlockImage(record, 0))
+                   appendStringInfoString(buf, " (full page image)");
                else
                {
-                   ginxlogInsertDataInternal *insertData = (ginxlogInsertDataInternal *) payload;
+                   char       *payload = XLogRecGetBlockData(record, 0, NULL);
 
-                   appendStringInfo(buf, " pitem: %u-%u/%u",
-                            PostingItemGetBlockNumber(&insertData->newitem),
-                        ItemPointerGetBlockNumber(&insertData->newitem.key),
-                      ItemPointerGetOffsetNumber(&insertData->newitem.key));
+                   if (!(xlrec->flags & GIN_INSERT_ISDATA))
+                       appendStringInfo(buf, " isdelete: %c",
+                        (((ginxlogInsertEntry *) payload)->isDelete) ? 'T' : 'F');
+                   else if (xlrec->flags & GIN_INSERT_ISLEAF)
+                       desc_recompress_leaf(buf, (ginxlogRecompressDataLeaf *) payload);
+                   else
+                   {
+                       ginxlogInsertDataInternal *insertData =
+                           (ginxlogInsertDataInternal *) payload;
+
+                       appendStringInfo(buf, " pitem: %u-%u/%u",
+                                        PostingItemGetBlockNumber(&insertData->newitem),
+                                        ItemPointerGetBlockNumber(&insertData->newitem.key),
+                                        ItemPointerGetOffsetNumber(&insertData->newitem.key));
+                   }
                }
            }
            break;
@@ -144,12 +144,15 @@ gin_desc(StringInfo buf, XLogReaderState *record)
            break;
        case XLOG_GIN_VACUUM_DATA_LEAF_PAGE:
            {
-               ginxlogVacuumDataLeafPage *xlrec = (ginxlogVacuumDataLeafPage *) rec;
-
                if (XLogRecHasBlockImage(record, 0))
                    appendStringInfoString(buf, " (full page image)");
                else
+               {
+                   ginxlogVacuumDataLeafPage *xlrec =
+                       (ginxlogVacuumDataLeafPage *) XLogRecGetBlockData(record, 0, NULL);
+
                    desc_recompress_leaf(buf, &xlrec->data);
+               }
            }
            break;
        case XLOG_GIN_DELETE_PAGE: