From 58b1bcd28991a1be04d13783e1c46a1ebf5de51c Mon Sep 17 00:00:00 2001
From: Kommi <haribabuk@fast.au.fujitsu.com>
Date: Fri, 24 Aug 2018 11:21:34 +1000
Subject: [PATCH 2/2] check-world fixes

---
 contrib/amcheck/verify_nbtree.c        |  1 +
 contrib/pg_visibility/pg_visibility.c  |  5 +++--
 contrib/pgstattuple/pgstatapprox.c     | 10 +++++++++-
 contrib/pgstattuple/pgstattuple.c      |  9 ++++++++-
 src/backend/executor/execMain.c        | 11 +----------
 src/backend/executor/execTuples.c      | 22 ++++++++++++++++++++++
 src/backend/executor/nodeModifyTable.c | 12 ++++++++++--
 src/include/executor/tuptable.h        |  1 +
 8 files changed, 55 insertions(+), 16 deletions(-)

diff --git a/contrib/amcheck/verify_nbtree.c b/contrib/amcheck/verify_nbtree.c
index 04102dd3df..cb4294af7d 100644
--- a/contrib/amcheck/verify_nbtree.c
+++ b/contrib/amcheck/verify_nbtree.c
@@ -25,6 +25,7 @@
 
 #include "access/htup_details.h"
 #include "access/nbtree.h"
+#include "access/tableam.h"
 #include "access/transam.h"
 #include "access/xact.h"
 #include "catalog/index.h"
diff --git a/contrib/pg_visibility/pg_visibility.c b/contrib/pg_visibility/pg_visibility.c
index dce5262e34..88ca4fd2af 100644
--- a/contrib/pg_visibility/pg_visibility.c
+++ b/contrib/pg_visibility/pg_visibility.c
@@ -563,12 +563,13 @@ collect_corrupt_items(Oid relid, bool all_visible, bool all_frozen)
 
 	rel = relation_open(relid, AccessShareLock);
 
+	/* Only some relkinds have a visibility map */
+	check_relation_relkind(rel);
+
 	if (rel->rd_rel->relam != HEAP_TABLE_AM_OID)
 		ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
 						errmsg("only heap AM is supported")));
 
-	/* Only some relkinds have a visibility map */
-	check_relation_relkind(rel);
 
 	nblocks = RelationGetNumberOfBlocks(rel);
 
diff --git a/contrib/pgstattuple/pgstatapprox.c b/contrib/pgstattuple/pgstatapprox.c
index e805981bb9..6aee2ce8ac 100644
--- a/contrib/pgstattuple/pgstatapprox.c
+++ b/contrib/pgstattuple/pgstatapprox.c
@@ -12,6 +12,7 @@
  */
 #include "postgres.h"
 
+#include "access/tableam.h"
 #include "access/transam.h"
 #include "access/visibilitymap.h"
 #include "access/xact.h"
@@ -69,6 +70,7 @@ statapprox_heap(Relation rel, output_type *stat)
 	Buffer		vmbuffer = InvalidBuffer;
 	BufferAccessStrategy bstrategy;
 	TransactionId OldestXmin;
+	TupleTableSlot *slot;
 
 	OldestXmin = GetOldestXmin(rel, PROCARRAY_FLAGS_VACUUM);
 	bstrategy = GetAccessStrategy(BAS_BULKREAD);
@@ -76,6 +78,8 @@ statapprox_heap(Relation rel, output_type *stat)
 	nblocks = RelationGetNumberOfBlocks(rel);
 	scanned = 0;
 
+	slot = MakeSingleTupleTableSlot(RelationGetDescr(rel), TTS_TYPE_BUFFER);
+
 	for (blkno = 0; blkno < nblocks; blkno++)
 	{
 		Buffer		buf;
@@ -153,13 +157,15 @@ statapprox_heap(Relation rel, output_type *stat)
 			tuple.t_len = ItemIdGetLength(itemid);
 			tuple.t_tableOid = RelationGetRelid(rel);
 
+			ExecStoreTuple(&tuple,slot,buf,false);
+
 			/*
 			 * We follow VACUUM's lead in counting INSERT_IN_PROGRESS tuples
 			 * as "dead" while DELETE_IN_PROGRESS tuples are "live".  We don't
 			 * bother distinguishing tuples inserted/deleted by our own
 			 * transaction.
 			 */
-			switch (rel->rd_tableamroutine->snapshot_satisfiesVacuum(&tuple, OldestXmin, buf))
+			switch (rel->rd_tableamroutine->snapshot_satisfiesVacuum(slot, OldestXmin))
 			{
 				case HEAPTUPLE_LIVE:
 				case HEAPTUPLE_DELETE_IN_PROGRESS:
@@ -210,6 +216,8 @@ statapprox_heap(Relation rel, output_type *stat)
 		ReleaseBuffer(vmbuffer);
 		vmbuffer = InvalidBuffer;
 	}
+
+	ExecDropSingleTupleTableSlot(slot);
 }
 
 /*
diff --git a/contrib/pgstattuple/pgstattuple.c b/contrib/pgstattuple/pgstattuple.c
index 53fdff6c2c..5965ecbcf8 100644
--- a/contrib/pgstattuple/pgstattuple.c
+++ b/contrib/pgstattuple/pgstattuple.c
@@ -28,6 +28,7 @@
 #include "access/hash.h"
 #include "access/nbtree.h"
 #include "access/relscan.h"
+#include "access/tableam.h"
 #include "catalog/namespace.h"
 #include "catalog/pg_am.h"
 #include "funcapi.h"
@@ -326,12 +327,14 @@ pgstat_heap(Relation rel, FunctionCallInfo fcinfo)
 	Buffer		buffer;
 	pgstattuple_type stat = {0};
 	SnapshotData SnapshotDirty;
+	TupleTableSlot *slot;
 	TableAmRoutine *method = rel->rd_tableamroutine;
 
 	/* Disable syncscan because we assume we scan from block zero upwards */
 	scan = table_beginscan_strat(rel, SnapshotAny, 0, NULL, true, false);
 	InitDirtySnapshot(SnapshotDirty);
 
+	slot = MakeSingleTupleTableSlot(RelationGetDescr(rel), TTS_TYPE_BUFFER);
 	pagescan = tableam_get_heappagescandesc(scan);
 	nblocks = pagescan->rs_nblocks; /* # blocks to be scanned */
 
@@ -343,7 +346,10 @@ pgstat_heap(Relation rel, FunctionCallInfo fcinfo)
 		/* must hold a buffer lock to call HeapTupleSatisfiesVisibility */
 		LockBuffer(scan->rs_cbuf, BUFFER_LOCK_SHARE);
 
-		if (HeapTupleSatisfiesVisibility(method, tuple, &SnapshotDirty, scan->rs_cbuf))
+		/* FIXME: change to get the slot directly, instead of tuple */
+		ExecStoreTuple(tuple, slot, scan->rs_cbuf, false);
+
+		if (HeapTupleSatisfiesVisibility(method, slot, &SnapshotDirty))
 		{
 			stat.tuple_len += tuple->t_len;
 			stat.tuple_count++;
@@ -393,6 +399,7 @@ pgstat_heap(Relation rel, FunctionCallInfo fcinfo)
 	relation_close(rel, AccessShareLock);
 
 	stat.table_len = (uint64) nblocks * BLCKSZ;
+	ExecDropSingleTupleTableSlot(slot);
 
 	return build_pgstattuple_type(&stat, fcinfo);
 }
diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c
index 1237e809f3..e349a22e94 100644
--- a/src/backend/executor/execMain.c
+++ b/src/backend/executor/execMain.c
@@ -2765,16 +2765,7 @@ EvalPlanQualFetchRowMarks(EPQState *epqstate)
 			if (isNull)
 				continue;
 
-			elog(ERROR, "frak, need to implement ROW_MARK_COPY");
-#ifdef FIXME
-			// FIXME: this should just deform the tuple and store it as a
-			// virtual one.
-			tuple = table_tuple_by_datum(erm->relation, datum, erm->relid);
-
-			/* store tuple */
-			EvalPlanQualSetTuple(epqstate, erm->rti, tuple);
-#endif
-
+			ExecForceStoreHeapTupleDatum(datum, slot);
 		}
 	}
 }
diff --git a/src/backend/executor/execTuples.c b/src/backend/executor/execTuples.c
index 59ccc1a626..046f7b23dc 100644
--- a/src/backend/executor/execTuples.c
+++ b/src/backend/executor/execTuples.c
@@ -1385,6 +1385,28 @@ ExecForceStoreHeapTuple(HeapTuple tuple,
 
 }
 
+void
+ExecForceStoreHeapTupleDatum(Datum data, TupleTableSlot *slot)
+{
+	HeapTuple	tuple;
+	HeapTupleHeader td;
+	MemoryContext oldContext;
+
+	td = DatumGetHeapTupleHeader(data);
+
+	tuple = (HeapTuple) palloc(HEAPTUPLESIZE + HeapTupleHeaderGetDatumLength(td));
+	tuple->t_len = HeapTupleHeaderGetDatumLength(td);
+	tuple->t_self = td->t_ctid;
+	tuple->t_data = (HeapTupleHeader) ((char *) tuple + HEAPTUPLESIZE);
+	memcpy((char *) tuple->t_data, (char *) td, tuple->t_len);
+
+	ExecClearTuple(slot);
+
+	heap_deform_tuple(tuple, slot->tts_tupleDescriptor,
+					  slot->tts_values, slot->tts_isnull);
+	ExecStoreVirtualTuple(slot);
+}
+
 /* --------------------------------
  *		ExecStoreMinimalTuple
  *
diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c
index 14ca3b976e..d7d79f845c 100644
--- a/src/backend/executor/nodeModifyTable.c
+++ b/src/backend/executor/nodeModifyTable.c
@@ -609,7 +609,7 @@ ExecDelete(ModifyTableState *mtstate,
 		   bool canSetTag,
 		   bool changingPart,
 		   bool *tupleDeleted,
-		   TupleTableSlot **epqslot)
+		   TupleTableSlot **epqreturnslot)
 {
 	ResultRelInfo *resultRelInfo;
 	Relation	resultRelationDesc;
@@ -634,7 +634,7 @@ ExecDelete(ModifyTableState *mtstate,
 		bool		dodelete;
 
 		dodelete = ExecBRDeleteTriggers(estate, epqstate, resultRelInfo,
-										tupleid, oldtuple, epqslot);
+										tupleid, oldtuple, epqreturnslot);
 
 		if (!dodelete)			/* "do nothing" */
 			return NULL;
@@ -727,6 +727,14 @@ ldelete:;
 					/* Tuple no more passing quals, exiting... */
 					return NULL;
 				}
+
+				/**/
+				if (epqreturnslot)
+				{
+					*epqreturnslot = epqslot;
+					return NULL;
+				}
+
 				goto ldelete;
 			}
 		}
diff --git a/src/include/executor/tuptable.h b/src/include/executor/tuptable.h
index dec3e87a1e..4e49304ba7 100644
--- a/src/include/executor/tuptable.h
+++ b/src/include/executor/tuptable.h
@@ -313,6 +313,7 @@ extern TupleTableSlot *ExecStoreMinimalTuple(MinimalTuple mtup,
 
 extern void ExecForceStoreHeapTuple(HeapTuple tuple,
 			   TupleTableSlot *slot);
+extern void ExecForceStoreHeapTupleDatum(Datum data, TupleTableSlot *slot);
 
 extern TupleTableSlot *ExecStoreVirtualTuple(TupleTableSlot *slot);
 extern TupleTableSlot *ExecStoreAllNullTuple(TupleTableSlot *slot);
-- 
2.18.0.windows.1

