From ca3e363fdd064f7b2ea667aee79f038fa9143510 Mon Sep 17 00:00:00 2001
From: Hari Babu <kommi.haribabu@gmail.com>
Date: Wed, 20 Dec 2017 18:19:26 +1100
Subject: [PATCH 09/11] BulkInsertState is moved into storage

Added Get, free and release bulkinsertstate functions
to operate with bulkinsertstate that is provided by
the storage.
---
 src/backend/access/heap/heapam.c         |  2 +-
 src/backend/access/heap/heapam_storage.c |  4 ++++
 src/backend/access/storage/storageam.c   | 23 +++++++++++++++++++++++
 src/backend/commands/copy.c              |  8 ++++----
 src/backend/commands/createas.c          |  6 +++---
 src/backend/commands/matview.c           |  6 +++---
 src/backend/commands/tablecmds.c         |  6 +++---
 src/include/access/heapam.h              |  4 +---
 src/include/access/storage_common.h      |  3 +++
 src/include/access/storageam.h           |  4 ++++
 src/include/access/storageamapi.h        |  7 +++++++
 11 files changed, 56 insertions(+), 17 deletions(-)

diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c
index 90bbed9900..04d9fabd9a 100644
--- a/src/backend/access/heap/heapam.c
+++ b/src/backend/access/heap/heapam.c
@@ -2328,7 +2328,7 @@ GetBulkInsertState(void)
 	bistate = (BulkInsertState) palloc(sizeof(BulkInsertStateData));
 	bistate->strategy = GetAccessStrategy(BAS_BULKWRITE);
 	bistate->current_buf = InvalidBuffer;
-	return bistate;
+	return (void *)bistate;
 }
 
 /*
diff --git a/src/backend/access/heap/heapam_storage.c b/src/backend/access/heap/heapam_storage.c
index ea2b640693..b89069bf74 100644
--- a/src/backend/access/heap/heapam_storage.c
+++ b/src/backend/access/heap/heapam_storage.c
@@ -327,5 +327,9 @@ heapam_storage_handler(PG_FUNCTION_ARGS)
 	amroutine->tuple_get_latest_tid = heap_get_latest_tid;
 	amroutine->relation_sync = heap_sync;
 
+	amroutine->getbulkinsertstate = GetBulkInsertState;
+	amroutine->freebulkinsertstate = FreeBulkInsertState;
+	amroutine->releasebulkinsertstate = ReleaseBulkInsertStatePin;
+
 	PG_RETURN_POINTER(amroutine);
 }
diff --git a/src/backend/access/storage/storageam.c b/src/backend/access/storage/storageam.c
index f14673e88e..d884b3633c 100644
--- a/src/backend/access/storage/storageam.c
+++ b/src/backend/access/storage/storageam.c
@@ -378,3 +378,26 @@ storage_sync(Relation rel)
 {
 	rel->rd_stamroutine->relation_sync(rel);
 }
+
+/*
+ * -------------------
+ * storage Bulk Insert functions
+ * -------------------
+ */
+BulkInsertState
+storage_getbulkinsertstate(Relation rel)
+{
+	return rel->rd_stamroutine->getbulkinsertstate();
+}
+
+void
+storage_freebulkinsertstate(Relation rel, BulkInsertState bistate)
+{
+	rel->rd_stamroutine->freebulkinsertstate(bistate);
+}
+
+void
+storage_releasebulkinsertstate(Relation rel, BulkInsertState bistate)
+{
+	rel->rd_stamroutine->releasebulkinsertstate(bistate);
+}
diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c
index 42803c687b..a4a8f52284 100644
--- a/src/backend/commands/copy.c
+++ b/src/backend/commands/copy.c
@@ -2297,7 +2297,7 @@ CopyFrom(CopyState cstate)
 	ErrorContextCallback errcallback;
 	CommandId	mycid = GetCurrentCommandId(true);
 	int			hi_options = 0; /* start with default heap_insert options */
-	BulkInsertState bistate;
+	void       *bistate;
 	uint64		processed = 0;
 	bool		useHeapMultiInsert;
 	int			nBufferedTuples = 0;
@@ -2553,7 +2553,7 @@ CopyFrom(CopyState cstate)
 	values = (Datum *) palloc(tupDesc->natts * sizeof(Datum));
 	nulls = (bool *) palloc(tupDesc->natts * sizeof(bool));
 
-	bistate = GetBulkInsertState();
+	bistate = storage_getbulkinsertstate(resultRelInfo->ri_RelationDesc);
 	econtext = GetPerTupleExprContext(estate);
 
 	/* Set up callback to identify error line number */
@@ -2633,7 +2633,7 @@ CopyFrom(CopyState cstate)
 			 */
 			if (prev_leaf_part_index != leaf_part_index)
 			{
-				ReleaseBulkInsertStatePin(bistate);
+				storage_releasebulkinsertstate(resultRelInfo->ri_RelationDesc, bistate);
 				prev_leaf_part_index = leaf_part_index;
 			}
 
@@ -2818,7 +2818,7 @@ CopyFrom(CopyState cstate)
 	/* Done, clean up */
 	error_context_stack = errcallback.previous;
 
-	FreeBulkInsertState(bistate);
+	storage_freebulkinsertstate(resultRelInfo->ri_RelationDesc, bistate);
 
 	MemoryContextSwitchTo(oldcontext);
 
diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c
index 9e6fb8740b..2ddebcec3d 100644
--- a/src/backend/commands/createas.c
+++ b/src/backend/commands/createas.c
@@ -60,7 +60,7 @@ typedef struct
 	ObjectAddress reladdr;		/* address of rel, for ExecCreateTableAs */
 	CommandId	output_cid;		/* cmin to insert in output tuples */
 	int			hi_options;		/* heap_insert performance options */
-	BulkInsertState bistate;	/* bulk insert state */
+	void       *bistate;		/* bulk insert state */
 } DR_intorel;
 
 /* utility functions for CTAS definition creation */
@@ -570,7 +570,7 @@ intorel_startup(DestReceiver *self, int operation, TupleDesc typeinfo)
 	 */
 	myState->hi_options = HEAP_INSERT_SKIP_FSM |
 		(XLogIsNeeded() ? 0 : HEAP_INSERT_SKIP_WAL);
-	myState->bistate = GetBulkInsertState();
+	myState->bistate = storage_getbulkinsertstate(intoRelationDesc);
 
 	/* Not using WAL requires smgr_targblock be initially invalid */
 	Assert(RelationGetTargetBlock(intoRelationDesc) == InvalidBlockNumber);
@@ -619,7 +619,7 @@ intorel_shutdown(DestReceiver *self)
 {
 	DR_intorel *myState = (DR_intorel *) self;
 
-	FreeBulkInsertState(myState->bistate);
+	storage_freebulkinsertstate(myState->rel, myState->bistate);
 
 	/* If we skipped using WAL, must heap_sync before commit */
 	if (myState->hi_options & HEAP_INSERT_SKIP_WAL)
diff --git a/src/backend/commands/matview.c b/src/backend/commands/matview.c
index 936ea9b9e5..ab44049e3a 100644
--- a/src/backend/commands/matview.c
+++ b/src/backend/commands/matview.c
@@ -52,7 +52,7 @@ typedef struct
 	Relation	transientrel;	/* relation to write to */
 	CommandId	output_cid;		/* cmin to insert in output tuples */
 	int			hi_options;		/* heap_insert performance options */
-	BulkInsertState bistate;	/* bulk insert state */
+	void       *bistate;		/* bulk insert state */
 } DR_transientrel;
 
 static int	matview_maintenance_depth = 0;
@@ -479,7 +479,7 @@ transientrel_startup(DestReceiver *self, int operation, TupleDesc typeinfo)
 	myState->hi_options = HEAP_INSERT_SKIP_FSM | HEAP_INSERT_FROZEN;
 	if (!XLogIsNeeded())
 		myState->hi_options |= HEAP_INSERT_SKIP_WAL;
-	myState->bistate = GetBulkInsertState();
+	myState->bistate = storage_getbulkinsertstate(transientrel);
 
 	/* Not using WAL requires smgr_targblock be initially invalid */
 	Assert(RelationGetTargetBlock(transientrel) == InvalidBlockNumber);
@@ -522,7 +522,7 @@ transientrel_shutdown(DestReceiver *self)
 {
 	DR_transientrel *myState = (DR_transientrel *) self;
 
-	FreeBulkInsertState(myState->bistate);
+	storage_freebulkinsertstate(myState->transientrel, myState->bistate);
 
 	/* If we skipped using WAL, must heap_sync before commit */
 	if (myState->hi_options & HEAP_INSERT_SKIP_WAL)
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 28874a27ae..90c41b4847 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -4384,7 +4384,7 @@ ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap, LOCKMODE lockmode)
 	ListCell   *l;
 	EState	   *estate;
 	CommandId	mycid;
-	BulkInsertState bistate;
+	void       *bistate;
 	int			hi_options;
 	ExprState  *partqualstate = NULL;
 
@@ -4410,7 +4410,7 @@ ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap, LOCKMODE lockmode)
 	if (newrel)
 	{
 		mycid = GetCurrentCommandId(true);
-		bistate = GetBulkInsertState();
+		bistate = storage_getbulkinsertstate(newrel);
 
 		hi_options = HEAP_INSERT_SKIP_FSM;
 		if (!XLogIsNeeded())
@@ -4685,7 +4685,7 @@ ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap, LOCKMODE lockmode)
 	heap_close(oldrel, NoLock);
 	if (newrel)
 	{
-		FreeBulkInsertState(bistate);
+		storage_freebulkinsertstate(newrel, bistate);
 
 		/* If we skipped writing WAL, then we need to sync the heap. */
 		if (hi_options & HEAP_INSERT_SKIP_WAL)
diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h
index 0501bb7bb0..99b8cf67d8 100644
--- a/src/include/access/heapam.h
+++ b/src/include/access/heapam.h
@@ -31,8 +31,6 @@
 #define HEAP_INSERT_FROZEN		0x0004
 #define HEAP_INSERT_SPECULATIVE 0x0008
 
-typedef struct BulkInsertStateData *BulkInsertState;
-
 /*
  * Possible lock modes for a tuple.
  */
@@ -148,7 +146,7 @@ extern void heap_get_latest_tid(Relation relation, Snapshot snapshot,
 extern void setLastTid(const ItemPointer tid);
 
 extern BulkInsertState GetBulkInsertState(void);
-extern void FreeBulkInsertState(BulkInsertState);
+extern void FreeBulkInsertState(BulkInsertState bistate);
 extern void ReleaseBulkInsertStatePin(BulkInsertState bistate);
 
 extern Oid heap_insert(Relation relation, HeapTuple tup, CommandId cid,
diff --git a/src/include/access/storage_common.h b/src/include/access/storage_common.h
index 0c43ae4310..2d0b1a3ccd 100644
--- a/src/include/access/storage_common.h
+++ b/src/include/access/storage_common.h
@@ -28,6 +28,9 @@
 /* A physical tuple coming from a storage AM scan */
 typedef void *StorageTuple;
 
+typedef struct BulkInsertStateData *BulkInsertState;
+
+
 /*
  * slot storage routine functions
  */
diff --git a/src/include/access/storageam.h b/src/include/access/storageam.h
index e1d01193d3..8ced6c6a1f 100644
--- a/src/include/access/storageam.h
+++ b/src/include/access/storageam.h
@@ -116,4 +116,8 @@ extern void storage_get_latest_tid(Relation relation,
 
 extern void storage_sync(Relation rel);
 
+extern BulkInsertState storage_getbulkinsertstate(Relation rel);
+extern void storage_freebulkinsertstate(Relation rel, BulkInsertState bistate);
+extern void storage_releasebulkinsertstate(Relation rel, BulkInsertState bistate);
+
 #endif
diff --git a/src/include/access/storageamapi.h b/src/include/access/storageamapi.h
index d626115b51..d79aad71df 100644
--- a/src/include/access/storageamapi.h
+++ b/src/include/access/storageamapi.h
@@ -80,6 +80,9 @@ typedef StorageTuple(*TupleFromDatum_function) (Datum data, Oid tableoid);
 
 typedef void (*RelationSync_function) (Relation relation);
 
+typedef BulkInsertState (*GetBulkInsertState_function) (void);
+typedef void (*FreeBulkInsertState_function) (BulkInsertState bistate);
+typedef void (*ReleaseBulkInsertState_function) (BulkInsertState bistate);
 
 typedef StorageScanDesc(*ScanBegin_function) (Relation relation,
 											  Snapshot snapshot,
@@ -151,6 +154,10 @@ typedef struct StorageAmRoutine
 
 	RelationSync_function relation_sync;	/* heap_sync */
 
+	GetBulkInsertState_function getbulkinsertstate;
+	FreeBulkInsertState_function freebulkinsertstate;
+	ReleaseBulkInsertState_function releasebulkinsertstate;
+
 	/* Operations on relation scans */
 	ScanBegin_function scan_begin;
 	ScanGetParallelheapscandesc_function scan_get_parallelheapscandesc;
-- 
2.15.0.windows.1

