From ee59bb8639459373080b3b30904aca4484857bb0 Mon Sep 17 00:00:00 2001
From: Kuntal Ghosh <kuntal.ghosh@enterprisedb.com>
Date: Tue, 28 Feb 2017 10:51:27 +0530
Subject: [PATCH] wal_consistency_checking for hash index

This patch implements the feature of wal consistency checking for
hash index. It includes a hash_mask function to mask the hash pages
before performing any consistency check.
---
 src/backend/access/hash/hash_xlog.c | 37 +++++++++++++++++++++++++++++++++++++
 src/include/access/hash_xlog.h      |  1 +
 src/include/access/rmgrlist.h       |  2 +-
 3 files changed, 39 insertions(+), 1 deletion(-)

diff --git a/src/backend/access/hash/hash_xlog.c b/src/backend/access/hash/hash_xlog.c
index aff9b53..9c86036 100644
--- a/src/backend/access/hash/hash_xlog.c
+++ b/src/backend/access/hash/hash_xlog.c
@@ -14,6 +14,7 @@
  */
 #include "postgres.h"
 
+#include "access/bufmask.h"
 #include "access/hash.h"
 #include "access/hash_xlog.h"
 #include "access/xlogutils.h"
@@ -972,3 +973,39 @@ hash_redo(XLogReaderState *record)
 			elog(PANIC, "hash_redo: unknown op code %u", info);
 	}
 }
+
+/*
+ * Mask a Hash page before performing consistency checks on it.
+ */
+void
+hash_mask(char *pagedata, BlockNumber blkno)
+{
+	Page		page = (Page) pagedata;
+	HashPageOpaque		opaque;
+
+	mask_page_lsn(page);
+
+	mask_page_hint_bits(page);
+	mask_unused_space(page);
+
+	opaque = (HashPageOpaque) PageGetSpecialPointer(page);
+
+	if (opaque->hasho_flag & LH_UNUSED_PAGE)
+	{
+		/*
+		 * Mask everything on a UNUSED page.
+		 */
+		mask_page_content(page);
+	}
+	else if ((opaque->hasho_flag & LH_BUCKET_PAGE) ||
+						(opaque->hasho_flag & LH_OVERFLOW_PAGE))
+	{
+		/*
+		 * In btree bucket and overflow pages, it is possible to modify the
+		 * LP_FLAGS without emitting any WAL record. Hence, mask the line
+		 * pointer flags.
+		 * See hashgettuple() for details.
+		 */
+		mask_lp_flags(page);
+	}
+}
diff --git a/src/include/access/hash_xlog.h b/src/include/access/hash_xlog.h
index 8400022..6620dee 100644
--- a/src/include/access/hash_xlog.h
+++ b/src/include/access/hash_xlog.h
@@ -253,5 +253,6 @@ typedef struct xl_hash_init_bitmap_page
 extern void hash_redo(XLogReaderState *record);
 extern void hash_desc(StringInfo buf, XLogReaderState *record);
 extern const char *hash_identify(uint8 info);
+extern void hash_mask(char *pagedata, BlockNumber blkno);
 
 #endif   /* HASH_XLOG_H */
diff --git a/src/include/access/rmgrlist.h b/src/include/access/rmgrlist.h
index b892aea..2f43c19 100644
--- a/src/include/access/rmgrlist.h
+++ b/src/include/access/rmgrlist.h
@@ -37,7 +37,7 @@ PG_RMGR(RM_STANDBY_ID, "Standby", standby_redo, standby_desc, standby_identify,
 PG_RMGR(RM_HEAP2_ID, "Heap2", heap2_redo, heap2_desc, heap2_identify, NULL, NULL, heap_mask)
 PG_RMGR(RM_HEAP_ID, "Heap", heap_redo, heap_desc, heap_identify, NULL, NULL, heap_mask)
 PG_RMGR(RM_BTREE_ID, "Btree", btree_redo, btree_desc, btree_identify, NULL, NULL, btree_mask)
-PG_RMGR(RM_HASH_ID, "Hash", hash_redo, hash_desc, hash_identify, NULL, NULL, NULL)
+PG_RMGR(RM_HASH_ID, "Hash", hash_redo, hash_desc, hash_identify, NULL, NULL, hash_mask)
 PG_RMGR(RM_GIN_ID, "Gin", gin_redo, gin_desc, gin_identify, gin_xlog_startup, gin_xlog_cleanup, gin_mask)
 PG_RMGR(RM_GIST_ID, "Gist", gist_redo, gist_desc, gist_identify, gist_xlog_startup, gist_xlog_cleanup, gist_mask)
 PG_RMGR(RM_SEQ_ID, "Sequence", seq_redo, seq_desc, seq_identify, NULL, NULL, seq_mask)
-- 
1.8.3.1

