From 3f1340364236b22f5a2b505e359083494b276b95 Mon Sep 17 00:00:00 2001
From: kommih <haribabuk@fast.au.fujitsu.com>
Date: Mon, 8 Oct 2018 15:08:59 +1100
Subject: [PATCH 2/2] init fork API

API to create INIT_FORKNUM file with wrapper
table_create_init_fork.
---
 src/backend/access/heap/heapam_handler.c | 26 +++++++++++++++++++++++-
 src/backend/catalog/heap.c               | 24 ++--------------------
 src/backend/commands/tablecmds.c         |  4 ++--
 src/include/access/tableam.h             |  8 ++++++++
 src/include/catalog/heap.h               |  2 --
 5 files changed, 37 insertions(+), 27 deletions(-)

diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c
index 313ed319fc..87d3331ba1 100644
--- a/src/backend/access/heap/heapam_handler.c
+++ b/src/backend/access/heap/heapam_handler.c
@@ -33,6 +33,7 @@
 #include "catalog/indexing.h"
 #include "catalog/pg_am_d.h"
 #include "catalog/storage.h"
+#include "catalog/storage_xlog.h"
 #include "executor/executor.h"
 #include "pgstat.h"
 #include "storage/lmgr.h"
@@ -2240,6 +2241,28 @@ RelationSetNewRelfilenode(Relation relation, char persistence,
 	EOXactListAdd(relation);
 }
 
+/*
+ * Set up an init fork for an unlogged table so that it can be correctly
+ * reinitialized on restart.  An immediate sync is required even if the
+ * page has been logged, because the write did not go through
+ * shared_buffers and therefore a concurrent checkpoint may have moved
+ * the redo pointer past our xlog record.  Recovery may as well remove it
+ * while replaying, for example, XLOG_DBASE_CREATE or XLOG_TBLSPC_CREATE
+ * record. Therefore, logging is necessary even if wal_level=minimal.
+ */
+static void
+heap_create_init_fork(Relation rel)
+{
+	Assert(rel->rd_rel->relkind == RELKIND_RELATION ||
+		   rel->rd_rel->relkind == RELKIND_MATVIEW ||
+		   rel->rd_rel->relkind == RELKIND_TOASTVALUE);
+	RelationOpenSmgr(rel);
+	smgrcreate(rel->rd_smgr, INIT_FORKNUM, false);
+	log_smgrcreate(&rel->rd_smgr->smgr_rnode.node, INIT_FORKNUM);
+	smgrimmedsync(rel->rd_smgr, INIT_FORKNUM);
+}
+
+
 static const TableAmRoutine heapam_methods = {
 	.type = T_TableAmRoutine,
 
@@ -2289,7 +2312,8 @@ static const TableAmRoutine heapam_methods = {
 
 	.index_validate_scan = validate_index_heapscan,
 
-	.SetNewFileNode = RelationSetNewRelfilenode
+	.SetNewFileNode = RelationSetNewRelfilenode,
+	.CreateInitFork = heap_create_init_fork
 };
 
 const TableAmRoutine *
diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 38b368f916..8e7c8ce684 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -32,6 +32,7 @@
 #include "access/htup_details.h"
 #include "access/multixact.h"
 #include "access/sysattr.h"
+#include "access/tableam.h"
 #include "access/transam.h"
 #include "access/xact.h"
 #include "access/xlog.h"
@@ -1425,7 +1426,7 @@ heap_create_with_catalog(const char *relname,
 	 */
 	if (relpersistence == RELPERSISTENCE_UNLOGGED &&
 		relkind != RELKIND_PARTITIONED_TABLE)
-		heap_create_init_fork(new_rel_desc);
+		table_create_init_fork(new_rel_desc);
 
 	/*
 	 * ok, the relation has been cataloged, so close our relations and return
@@ -1437,27 +1438,6 @@ heap_create_with_catalog(const char *relname,
 	return relid;
 }
 
-/*
- * Set up an init fork for an unlogged table so that it can be correctly
- * reinitialized on restart.  An immediate sync is required even if the
- * page has been logged, because the write did not go through
- * shared_buffers and therefore a concurrent checkpoint may have moved
- * the redo pointer past our xlog record.  Recovery may as well remove it
- * while replaying, for example, XLOG_DBASE_CREATE or XLOG_TBLSPC_CREATE
- * record. Therefore, logging is necessary even if wal_level=minimal.
- */
-void
-heap_create_init_fork(Relation rel)
-{
-	Assert(rel->rd_rel->relkind == RELKIND_RELATION ||
-		   rel->rd_rel->relkind == RELKIND_MATVIEW ||
-		   rel->rd_rel->relkind == RELKIND_TOASTVALUE);
-	RelationOpenSmgr(rel);
-	smgrcreate(rel->rd_smgr, INIT_FORKNUM, false);
-	log_smgrcreate(&rel->rd_smgr->smgr_rnode.node, INIT_FORKNUM);
-	smgrimmedsync(rel->rd_smgr, INIT_FORKNUM);
-}
-
 /*
  *		RelationRemoveInheritance
  *
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 6db214309e..e107afc786 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -1647,7 +1647,7 @@ ExecuteTruncateGuts(List *explicit_rels, List *relids, List *relids_logged,
 			table_set_new_filenode(rel, rel->rd_rel->relpersistence,
 									  RecentXmin, minmulti);
 			if (rel->rd_rel->relpersistence == RELPERSISTENCE_UNLOGGED)
-				heap_create_init_fork(rel);
+				table_create_init_fork(rel);
 
 			heap_relid = RelationGetRelid(rel);
 			toast_relid = rel->rd_rel->reltoastrelid;
@@ -1661,7 +1661,7 @@ ExecuteTruncateGuts(List *explicit_rels, List *relids, List *relids_logged,
 				table_set_new_filenode(rel, rel->rd_rel->relpersistence,
 										  RecentXmin, minmulti);
 				if (rel->rd_rel->relpersistence == RELPERSISTENCE_UNLOGGED)
-					heap_create_init_fork(rel);
+					table_create_init_fork(rel);
 				heap_close(rel, NoLock);
 			}
 
diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h
index 4d5b11c294..f3e36368db 100644
--- a/src/include/access/tableam.h
+++ b/src/include/access/tableam.h
@@ -196,6 +196,7 @@ typedef bool (*SampleScanNextTuple_function)(TableScanDesc scan, struct SampleSc
 
 typedef void (*SetNewFileNode_function)(Relation relation, char persistence,
 										TransactionId freezeXid, MultiXactId minmulti);
+typedef void (*CreateInitFork_function)(Relation rel);
 
 /*
  * API struct for a table AM.  Note this must be allocated in a
@@ -255,6 +256,7 @@ typedef struct TableAmRoutine
 	IndexValidateScan_function index_validate_scan;
 
 	SetNewFileNode_function	SetNewFileNode;
+	CreateInitFork_function CreateInitFork;
 }			TableAmRoutine;
 
 static inline const TupleTableSlotOps*
@@ -754,6 +756,12 @@ table_set_new_filenode(Relation relation, char persistence,
 									freezeXid, minmulti);
 }
 
+static inline void
+table_create_init_fork(Relation relation)
+{
+	relation->rd_tableamroutine->CreateInitFork(relation);
+}
+
 extern BlockNumber table_parallelscan_nextpage(TableScanDesc scan);
 extern void table_parallelscan_startblock_init(TableScanDesc scan);
 extern Size table_parallelscan_estimate(Snapshot snapshot);
diff --git a/src/include/catalog/heap.h b/src/include/catalog/heap.h
index 4584b3473c..c0e706ecc9 100644
--- a/src/include/catalog/heap.h
+++ b/src/include/catalog/heap.h
@@ -77,8 +77,6 @@ extern Oid heap_create_with_catalog(const char *relname,
 						 Oid relrewrite,
 						 ObjectAddress *typaddress);
 
-extern void heap_create_init_fork(Relation rel);
-
 extern void heap_drop_with_catalog(Oid relid);
 
 extern void heap_truncate(List *relids);
-- 
2.18.0.windows.1

