From 95523a7153f5822fe926800f0219897b36007b96 Mon Sep 17 00:00:00 2001
From: Hari Babu <kommi.haribabu@gmail.com>
Date: Thu, 29 Mar 2018 16:59:20 +1100
Subject: [PATCH 09/14] BulkInsertState is added into table AM

Added Get, free and release bulkinsertstate functions
to operate with bulkinsertstate that is provided by
the heap access method.
---
 src/backend/access/heap/heapam.c         |  2 +-
 src/backend/access/heap/heapam_handler.c |  4 ++++
 src/backend/access/table/tableam.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/tableam.h             |  4 ++++
 src/include/access/tableam_common.h      |  3 +++
 src/include/access/tableamapi.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 daf74bed93..2b3e4f428c 100644
--- a/src/backend/access/heap/heapam.c
+++ b/src/backend/access/heap/heapam.c
@@ -2331,7 +2331,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_handler.c b/src/backend/access/heap/heapam_handler.c
index 769febcd15..ba49551a07 100644
--- a/src/backend/access/heap/heapam_handler.c
+++ b/src/backend/access/heap/heapam_handler.c
@@ -384,5 +384,9 @@ heap_tableam_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/table/tableam.c b/src/backend/access/table/tableam.c
index 4991f62e1e..25db521dca 100644
--- a/src/backend/access/table/tableam.c
+++ b/src/backend/access/table/tableam.c
@@ -389,3 +389,26 @@ table_sync(Relation rel)
 {
 	rel->rd_tableamroutine->relation_sync(rel);
 }
+
+/*
+ * -------------------
+ * storage Bulk Insert functions
+ * -------------------
+ */
+BulkInsertState
+table_getbulkinsertstate(Relation rel)
+{
+	return rel->rd_tableamroutine->getbulkinsertstate();
+}
+
+void
+table_freebulkinsertstate(Relation rel, BulkInsertState bistate)
+{
+	rel->rd_tableamroutine->freebulkinsertstate(bistate);
+}
+
+void
+table_releasebulkinsertstate(Relation rel, BulkInsertState bistate)
+{
+	rel->rd_tableamroutine->releasebulkinsertstate(bistate);
+}
diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c
index ab27d28588..39cb9c0c08 100644
--- a/src/backend/commands/copy.c
+++ b/src/backend/commands/copy.c
@@ -2292,7 +2292,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;
@@ -2517,7 +2517,7 @@ CopyFrom(CopyState cstate)
 	values = (Datum *) palloc(tupDesc->natts * sizeof(Datum));
 	nulls = (bool *) palloc(tupDesc->natts * sizeof(bool));
 
-	bistate = GetBulkInsertState();
+	bistate = table_getbulkinsertstate(resultRelInfo->ri_RelationDesc);
 	econtext = GetPerTupleExprContext(estate);
 
 	/* Set up callback to identify error line number */
@@ -2597,7 +2597,7 @@ CopyFrom(CopyState cstate)
 			 */
 			if (prev_leaf_part_index != leaf_part_index)
 			{
-				ReleaseBulkInsertStatePin(bistate);
+				table_releasebulkinsertstate(resultRelInfo->ri_RelationDesc, bistate);
 				prev_leaf_part_index = leaf_part_index;
 			}
 
@@ -2778,7 +2778,7 @@ CopyFrom(CopyState cstate)
 	/* Done, clean up */
 	error_context_stack = errcallback.previous;
 
-	FreeBulkInsertState(bistate);
+	table_freebulkinsertstate(resultRelInfo->ri_RelationDesc, bistate);
 
 	MemoryContextSwitchTo(oldcontext);
 
diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c
index 9c531b7f28..c2d0a14d45 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 = table_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);
+	table_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 28b2f485b0..e17e2cd808 100644
--- a/src/backend/commands/matview.c
+++ b/src/backend/commands/matview.c
@@ -53,7 +53,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;
@@ -466,7 +466,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 = table_getbulkinsertstate(transientrel);
 
 	/* Not using WAL requires smgr_targblock be initially invalid */
 	Assert(RelationGetTargetBlock(transientrel) == InvalidBlockNumber);
@@ -509,7 +509,7 @@ transientrel_shutdown(DestReceiver *self)
 {
 	DR_transientrel *myState = (DR_transientrel *) self;
 
-	FreeBulkInsertState(myState->bistate);
+	table_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 5ebb183731..fd197d9042 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -4453,7 +4453,7 @@ ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap, LOCKMODE lockmode)
 	ListCell   *l;
 	EState	   *estate;
 	CommandId	mycid;
-	BulkInsertState bistate;
+	void       *bistate;
 	int			hi_options;
 	ExprState  *partqualstate = NULL;
 
@@ -4479,7 +4479,7 @@ ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap, LOCKMODE lockmode)
 	if (newrel)
 	{
 		mycid = GetCurrentCommandId(true);
-		bistate = GetBulkInsertState();
+		bistate = table_getbulkinsertstate(newrel);
 
 		hi_options = HEAP_INSERT_SKIP_FSM;
 		if (!XLogIsNeeded())
@@ -4754,7 +4754,7 @@ ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap, LOCKMODE lockmode)
 	heap_close(oldrel, NoLock);
 	if (newrel)
 	{
-		FreeBulkInsertState(bistate);
+		table_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 8d1263d0ae..f9a0602b86 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/tableam.h b/src/include/access/tableam.h
index 9be26fb86d..1027bcfba8 100644
--- a/src/include/access/tableam.h
+++ b/src/include/access/tableam.h
@@ -118,4 +118,8 @@ extern void table_get_latest_tid(Relation relation,
 
 extern void table_sync(Relation rel);
 
+extern BulkInsertState table_getbulkinsertstate(Relation rel);
+extern void table_freebulkinsertstate(Relation rel, BulkInsertState bistate);
+extern void table_releasebulkinsertstate(Relation rel, BulkInsertState bistate);
+
 #endif		/* TABLEAM_H */
diff --git a/src/include/access/tableam_common.h b/src/include/access/tableam_common.h
index e5cc461bd8..3c2ce82df3 100644
--- a/src/include/access/tableam_common.h
+++ b/src/include/access/tableam_common.h
@@ -39,6 +39,9 @@ typedef enum
 	HEAPTUPLE_DELETE_IN_PROGRESS	/* deleting xact is still in progress */
 } HTSV_Result;
 
+typedef struct BulkInsertStateData *BulkInsertState;
+
+
 /*
  * slot table AM routine functions
  */
diff --git a/src/include/access/tableamapi.h b/src/include/access/tableamapi.h
index b32a4bff83..adc3057eca 100644
--- a/src/include/access/tableamapi.h
+++ b/src/include/access/tableamapi.h
@@ -81,6 +81,9 @@ typedef TableTuple(*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 TableScanDesc (*ScanBegin_function) (Relation relation,
 											Snapshot snapshot,
@@ -154,6 +157,10 @@ typedef struct TableAmRoutine
 
 	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.16.1.windows.4

