Subject: [PATCH v1 1/2] Allow IndexScanDesc allocation in caller-specified context

From: amit <[email-masked]>
Date: Tue, 30 Oct 2018 16:56:17 +0900

---
 src/backend/access/index/genam.c         |  6 ++++--
 src/backend/access/index/indexam.c       | 21 +++++++++++++++------
 src/backend/commands/cluster.c           |  3 ++-
 src/backend/executor/execIndexing.c      |  3 ++-
 src/backend/executor/execReplication.c   |  2 +-
 src/backend/executor/nodeIndexonlyscan.c |  3 ++-
 src/backend/executor/nodeIndexscan.c     |  6 ++++--
 src/backend/utils/adt/selfuncs.c         |  4 ++--
 src/include/access/genam.h               |  3 ++-
 src/include/access/relscan.h             |  6 ++++++
 10 files changed, 40 insertions(+), 17 deletions(-)

diff --git a/src/backend/access/index/genam.c b/src/backend/access/index/genam.c
index 9d08775687..0744b00d15 100644
--- a/src/backend/access/index/genam.c
+++ b/src/backend/access/index/genam.c
@@ -370,7 +370,8 @@ systable_beginscan(Relation heapRelation,
 		}
 
 		sysscan->iscan = index_beginscan(heapRelation, irel,
-										 snapshot, nkeys, 0);
+										 snapshot, nkeys, 0,
+										 CurrentMemoryContext);
 		index_rescan(sysscan->iscan, key, nkeys, NULL, 0);
 		sysscan->scan = NULL;
 	}
@@ -572,7 +573,8 @@ systable_beginscan_ordered(Relation heapRelation,
 	}
 
 	sysscan->iscan = index_beginscan(heapRelation, indexRelation,
-									 snapshot, nkeys, 0);
+									 snapshot, nkeys, 0,
+									 CurrentMemoryContext);
 	index_rescan(sysscan->iscan, key, nkeys, NULL, 0);
 	sysscan->scan = NULL;
 
diff --git a/src/backend/access/index/indexam.c b/src/backend/access/index/indexam.c
index eade540ef5..b17ad9417b 100644
--- a/src/backend/access/index/indexam.c
+++ b/src/backend/access/index/indexam.c
@@ -125,7 +125,8 @@ do { \
 
 static IndexScanDesc index_beginscan_internal(Relation indexRelation,
 						 int nkeys, int norderbys, Snapshot snapshot,
-						 ParallelIndexScanDesc pscan, bool temp_snap);
+						 ParallelIndexScanDesc pscan, bool temp_snap,
+						 MemoryContext scan_cxt);

 /* ----------------------------------------------------------------
@@ -222,11 +223,13 @@ IndexScanDesc
 index_beginscan(Relation heapRelation,
 				Relation indexRelation,
 				Snapshot snapshot,
-				int nkeys, int norderbys)
+				int nkeys, int norderbys,
+				MemoryContext scan_cxt)
 {
 	IndexScanDesc scan;
 
-	scan = index_beginscan_internal(indexRelation, nkeys, norderbys, snapshot, NULL, false);
+	scan = index_beginscan_internal(indexRelation, nkeys, norderbys, snapshot,
+									NULL, false, scan_cxt);
 
 	/*
 	 * Save additional parameters into the scandesc.  Everything else was set
@@ -251,7 +254,8 @@ index_beginscan_bitmap(Relation indexRelation,
 {
 	IndexScanDesc scan;
 
-	scan = index_beginscan_internal(indexRelation, nkeys, 0, snapshot, NULL, false);
+	scan = index_beginscan_internal(indexRelation, nkeys, 0, snapshot,
+									NULL, false, CurrentMemoryContext);
 
 	/*
 	 * Save additional parameters into the scandesc.  Everything else was set
@@ -268,9 +272,11 @@ index_beginscan_bitmap(Relation indexRelation,
 static IndexScanDesc
 index_beginscan_internal(Relation indexRelation,
 						 int nkeys, int norderbys, Snapshot snapshot,
-						 ParallelIndexScanDesc pscan, bool temp_snap)
+						 ParallelIndexScanDesc pscan, bool temp_snap,
+						 MemoryContext scan_cxt)
 {
 	IndexScanDesc scan;
+	MemoryContext oldcxt;
 
 	RELATION_CHECKS;
 	CHECK_REL_PROCEDURE(ambeginscan);
@@ -286,11 +292,14 @@ index_beginscan_internal(Relation indexRelation,
 	/*
 	 * Tell the AM to open a scan.
 	 */
+	oldcxt = MemoryContextSwitchTo(scan_cxt);
 	scan = indexRelation->rd_amroutine->ambeginscan(indexRelation, nkeys,
 													norderbys);
 	/* Initialize information for parallel scan. */
 	scan->parallel_scan = pscan;
 	scan->xs_temp_snap = temp_snap;
+	scan->xs_scan_cxt = scan_cxt;
+	MemoryContextSwitchTo(oldcxt);
 
 	return scan;
 }
@@ -504,7 +513,7 @@ index_beginscan_parallel(Relation heaprel, Relation indexrel, int nkeys,
 	snapshot = RestoreSnapshot(pscan->ps_snapshot_data);
 	RegisterSnapshot(snapshot);
 	scan = index_beginscan_internal(indexrel, nkeys, norderbys, snapshot,
-									pscan, true);
+									pscan, true, CurrentMemoryContext);
 
 	/*
 	 * Save additional parameters into the scandesc.  Everything else was set
diff --git a/src/backend/commands/cluster.c b/src/backend/commands/cluster.c
index 68be470977..2c5c23a145 100644
--- a/src/backend/commands/cluster.c
+++ b/src/backend/commands/cluster.c
@@ -926,7 +926,8 @@ copy_heap_data(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex, bool verbose,
 	if (OldIndex != NULL && !use_sort)
 	{
 		heapScan = NULL;
-		indexScan = index_beginscan(OldHeap, OldIndex, SnapshotAny, 0, 0);
+		indexScan = index_beginscan(OldHeap, OldIndex, SnapshotAny, 0, 0,
+									CurrentMemoryContext);
 		index_rescan(indexScan, NULL, 0, NULL, 0);
 	}
 	else
diff --git a/src/backend/executor/execIndexing.c b/src/backend/executor/execIndexing.c
index 9927ad70e6..74d15e6b43 100644
--- a/src/backend/executor/execIndexing.c
+++ b/src/backend/executor/execIndexing.c
@@ -719,7 +719,8 @@ check_exclusion_or_unique_constraint(Relation heap, Relation index,
 retry:
 	conflict = false;
 	found_self = false;
-	index_scan = index_beginscan(heap, index, &DirtySnapshot, indnkeyatts, 0);
+	index_scan = index_beginscan(heap, index, &DirtySnapshot, indnkeyatts, 0,
+								 CurrentMemoryContext);
 	index_rescan(index_scan, scankeys, indnkeyatts, NULL, 0);
 
 	while ((tup = index_getnext(index_scan,
diff --git a/src/backend/executor/execReplication.c b/src/backend/executor/execReplication.c
index 25ba93e03c..432785c7d1 100644
--- a/src/backend/executor/execReplication.c
+++ b/src/backend/executor/execReplication.c
@@ -132,7 +132,7 @@ RelationFindReplTupleByIndex(Relation rel, Oid idxoid,
 	InitDirtySnapshot(snap);
 	scan = index_beginscan(rel, idxrel, &snap,
 						   IndexRelationGetNumberOfKeyAttributes(idxrel),
-						   0);
+						   0, CurrentMemoryContext);
 
 	/* Build scan key. */
 	build_replindex_scan_key(skey, rel, idxrel, searchslot);
diff --git a/src/backend/executor/nodeIndexonlyscan.c b/src/backend/executor/nodeIndexonlyscan.c
index daedf342f7..8b654a9eee 100644
--- a/src/backend/executor/nodeIndexonlyscan.c
+++ b/src/backend/executor/nodeIndexonlyscan.c
@@ -91,7 +91,8 @@ IndexOnlyNext(IndexOnlyScanState *node)
 								   node->ioss_RelationDesc,
 								   estate->es_snapshot,
 								   node->ioss_NumScanKeys,
-								   node->ioss_NumOrderByKeys);
+								   node->ioss_NumOrderByKeys,
+								   CurrentMemoryContext);
 
 		node->ioss_ScanDesc = scandesc;
 
diff --git a/src/backend/executor/nodeIndexscan.c b/src/backend/executor/nodeIndexscan.c
index ba7821b0e2..750b455e66 100644
--- a/src/backend/executor/nodeIndexscan.c
+++ b/src/backend/executor/nodeIndexscan.c
@@ -114,7 +114,8 @@ IndexNext(IndexScanState *node)
 								   node->iss_RelationDesc,
 								   estate->es_snapshot,
 								   node->iss_NumScanKeys,
-								   node->iss_NumOrderByKeys);
+								   node->iss_NumOrderByKeys,
+								   CurrentMemoryContext);
 
 		node->iss_ScanDesc = scandesc;
 
@@ -220,7 +221,8 @@ IndexNextWithReorder(IndexScanState *node)
 								   node->iss_RelationDesc,
 								   estate->es_snapshot,
 								   node->iss_NumScanKeys,
-								   node->iss_NumOrderByKeys);
+								   node->iss_NumOrderByKeys,
+								   CurrentMemoryContext);
 
 		node->iss_ScanDesc = scandesc;
 
diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c
index e0ece74bb9..16f7cc3641 100644
--- a/src/backend/utils/adt/selfuncs.c
+++ b/src/backend/utils/adt/selfuncs.c
@@ -5582,7 +5582,7 @@ get_actual_variable_range(PlannerInfo *root, VariableStatData *vardata,
 				 */
 				index_scan = index_beginscan(heapRel, indexRel,
 											 &SnapshotNonVacuumable,
-											 1, 0);
+											 1, 0, CurrentMemoryContext);
 				index_rescan(index_scan, scankeys, 1, NULL, 0);
 
 				/* Fetch first tuple in sortop's direction */
@@ -5615,7 +5615,7 @@ get_actual_variable_range(PlannerInfo *root, VariableStatData *vardata,
 			{
 				index_scan = index_beginscan(heapRel, indexRel,
 											 &SnapshotNonVacuumable,
-											 1, 0);
+											 1, 0, CurrentMemoryContext);
 				index_rescan(index_scan, scankeys, 1, NULL, 0);
 
 				/* Fetch first tuple in reverse direction */
diff --git a/src/include/access/genam.h b/src/include/access/genam.h
index 534fac7bf2..676eb2b752 100644
--- a/src/include/access/genam.h
+++ b/src/include/access/genam.h
@@ -140,7 +140,8 @@ extern bool index_insert(Relation indexRelation,
 extern IndexScanDesc index_beginscan(Relation heapRelation,
 				Relation indexRelation,
 				Snapshot snapshot,
-				int nkeys, int norderbys);
+				int nkeys, int norderbys,
+				MemoryContext scan_cxt);
 extern IndexScanDesc index_beginscan_bitmap(Relation indexRelation,
 					   Snapshot snapshot,
 					   int nkeys);
diff --git a/src/include/access/relscan.h b/src/include/access/relscan.h
index e5289b8aa7..169435d746 100644
--- a/src/include/access/relscan.h
+++ b/src/include/access/relscan.h
@@ -139,6 +139,12 @@ typedef struct IndexScanDescData
 
 	/* parallel index scan information, in shared memory */
 	ParallelIndexScanDesc parallel_scan;
+
+	/*
+	 * The context under which memory for this struct and its members are
+	 * allocated.
+	 */
+	MemoryContext	xs_scan_cxt;
 }			IndexScanDescData;
 
 /* Generic structure for parallel scans */
-- 
2.11.0

--------------5253696EAEF276D5B6588979
Content-Type: text/plain; charset=UTF-8;
 name="v1-0002-Add-a-MemoryContext-arg-to-check_exclusion_or_uni.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
 filename*0="v1-0002-Add-a-MemoryContext-arg-to-check_exclusion_or_uni.pa";
 filename*1="tch"