From 1b1463ab6e3b3677f416ccec7b4b7d28f5c89fbb Mon Sep 17 00:00:00 2001
From: Melanie Plageman <melanieplageman@gmail.com>
Date: Mon, 13 Dec 2021 17:17:22 -0500
Subject: [PATCH v4 2/2] Check allowedModes when creating tuplestores

As stated in src/backend/utils/fmgr/README, tuplestores
"must be created with randomAccess = true if SFRM_Materialize_Random is
set in allowedModes, but it can (and preferably should) be created with
randomAccess = false if not"

Previously, many func-api callers of tuplestore_begin_heap() passed a
constant value instead of checking allowedModes. This commit passes true
or false based on if SFRM_Materialize_Random is set in allowedModes to
MakeFuncResultTuplestore() (which wraps tuplestore_begin_heap() for
func-api callers).
---
 src/backend/access/transam/xlogfuncs.c         | 3 ++-
 src/backend/commands/event_trigger.c           | 7 +++++--
 src/backend/commands/extension.c               | 9 ++++++---
 src/backend/replication/logical/logicalfuncs.c | 3 ++-
 src/backend/replication/logical/origin.c       | 3 ++-
 src/backend/replication/slotfuncs.c            | 3 ++-
 src/backend/replication/walsender.c            | 3 ++-
 src/backend/storage/ipc/shmem.c                | 3 ++-
 src/backend/utils/adt/varlena.c                | 3 ++-
 src/backend/utils/misc/guc.c                   | 3 ++-
 src/backend/utils/misc/pg_config.c             | 3 ++-
 11 files changed, 29 insertions(+), 14 deletions(-)

diff --git a/src/backend/access/transam/xlogfuncs.c b/src/backend/access/transam/xlogfuncs.c
index 2407628db2..cf64639de2 100644
--- a/src/backend/access/transam/xlogfuncs.c
+++ b/src/backend/access/transam/xlogfuncs.c
@@ -181,7 +181,8 @@ pg_stop_backup_v2(PG_FUNCTION_ARGS)
 	per_query_ctx = rsinfo->econtext->ecxt_per_query_memory;
 	oldcontext = MemoryContextSwitchTo(per_query_ctx);
 
-	tupstore = MakeFuncResultTuplestore(fcinfo, &tupdesc, true);
+	tupstore = MakeFuncResultTuplestore(fcinfo, &tupdesc, (bool)
+			rsinfo->allowedModes & SFRM_Materialize_Random);
 	rsinfo->returnMode = SFRM_Materialize;
 	rsinfo->setResult = tupstore;
 	rsinfo->setDesc = tupdesc;
diff --git a/src/backend/commands/event_trigger.c b/src/backend/commands/event_trigger.c
index f1ea6a8796..be8d1f0d14 100644
--- a/src/backend/commands/event_trigger.c
+++ b/src/backend/commands/event_trigger.c
@@ -1310,7 +1310,9 @@ pg_event_trigger_dropped_objects(PG_FUNCTION_ARGS)
 	per_query_ctx = rsinfo->econtext->ecxt_per_query_memory;
 	oldcontext = MemoryContextSwitchTo(per_query_ctx);
 
-	tupstore = MakeFuncResultTuplestore(fcinfo, &tupdesc, true);
+	tupstore = MakeFuncResultTuplestore(fcinfo, &tupdesc, (bool)
+			rsinfo->allowedModes & SFRM_Materialize_Random);
+
 	rsinfo->returnMode = SFRM_Materialize;
 	rsinfo->setResult = tupstore;
 	rsinfo->setDesc = tupdesc;
@@ -1854,7 +1856,8 @@ pg_event_trigger_ddl_commands(PG_FUNCTION_ARGS)
 	per_query_ctx = rsinfo->econtext->ecxt_per_query_memory;
 	oldcontext = MemoryContextSwitchTo(per_query_ctx);
 
-	tupstore = MakeFuncResultTuplestore(fcinfo, &tupdesc, true);
+	tupstore = MakeFuncResultTuplestore(fcinfo, &tupdesc, (bool)
+			rsinfo->allowedModes & SFRM_Materialize_Random);
 	rsinfo->returnMode = SFRM_Materialize;
 	rsinfo->setResult = tupstore;
 	rsinfo->setDesc = tupdesc;
diff --git a/src/backend/commands/extension.c b/src/backend/commands/extension.c
index ae4899e007..75c06432b3 100644
--- a/src/backend/commands/extension.c
+++ b/src/backend/commands/extension.c
@@ -1933,7 +1933,8 @@ pg_available_extensions(PG_FUNCTION_ARGS)
 	per_query_ctx = rsinfo->econtext->ecxt_per_query_memory;
 	oldcontext = MemoryContextSwitchTo(per_query_ctx);
 
-	tupstore = MakeFuncResultTuplestore(fcinfo, &tupdesc, true);
+	tupstore = MakeFuncResultTuplestore(fcinfo, &tupdesc, (bool)
+			rsinfo->allowedModes & SFRM_Materialize_Random);
 	rsinfo->returnMode = SFRM_Materialize;
 	rsinfo->setResult = tupstore;
 	rsinfo->setDesc = tupdesc;
@@ -2027,7 +2028,8 @@ pg_available_extension_versions(PG_FUNCTION_ARGS)
 	per_query_ctx = rsinfo->econtext->ecxt_per_query_memory;
 	oldcontext = MemoryContextSwitchTo(per_query_ctx);
 
-	tupstore = MakeFuncResultTuplestore(fcinfo, &tupdesc, true);
+	tupstore = MakeFuncResultTuplestore(fcinfo, &tupdesc, (bool)
+			rsinfo->allowedModes & SFRM_Materialize_Random);
 	rsinfo->returnMode = SFRM_Materialize;
 	rsinfo->setResult = tupstore;
 	rsinfo->setDesc = tupdesc;
@@ -2298,7 +2300,8 @@ pg_extension_update_paths(PG_FUNCTION_ARGS)
 	per_query_ctx = rsinfo->econtext->ecxt_per_query_memory;
 	oldcontext = MemoryContextSwitchTo(per_query_ctx);
 
-	tupstore = MakeFuncResultTuplestore(fcinfo, &tupdesc, true);
+	tupstore = MakeFuncResultTuplestore(fcinfo, &tupdesc, (bool)
+			rsinfo->allowedModes & SFRM_Materialize_Random);
 	rsinfo->returnMode = SFRM_Materialize;
 	rsinfo->setResult = tupstore;
 	rsinfo->setDesc = tupdesc;
diff --git a/src/backend/replication/logical/logicalfuncs.c b/src/backend/replication/logical/logicalfuncs.c
index b8bd1e5bcb..693e5e0a53 100644
--- a/src/backend/replication/logical/logicalfuncs.c
+++ b/src/backend/replication/logical/logicalfuncs.c
@@ -188,7 +188,8 @@ pg_logical_slot_get_changes_guts(FunctionCallInfo fcinfo, bool confirm, bool bin
 		}
 	}
 
-	p->tupstore = MakeFuncResultTuplestore(fcinfo, &p->tupdesc, true);
+	p->tupstore = MakeFuncResultTuplestore(fcinfo, &p->tupdesc, (bool)
+			rsinfo->allowedModes & SFRM_Materialize_Random);
 	rsinfo->returnMode = SFRM_Materialize;
 	rsinfo->setResult = p->tupstore;
 	rsinfo->setDesc = p->tupdesc;
diff --git a/src/backend/replication/logical/origin.c b/src/backend/replication/logical/origin.c
index 620d8795b8..8ec3decf90 100644
--- a/src/backend/replication/logical/origin.c
+++ b/src/backend/replication/logical/origin.c
@@ -1494,7 +1494,8 @@ pg_show_replication_origin_status(PG_FUNCTION_ARGS)
 	per_query_ctx = rsinfo->econtext->ecxt_per_query_memory;
 	oldcontext = MemoryContextSwitchTo(per_query_ctx);
 
-	tupstore = MakeFuncResultTuplestore(fcinfo, &tupdesc, true);
+	tupstore = MakeFuncResultTuplestore(fcinfo, &tupdesc, (bool)
+			rsinfo->allowedModes & SFRM_Materialize_Random);
 
 	rsinfo->returnMode = SFRM_Materialize;
 	rsinfo->setResult = tupstore;
diff --git a/src/backend/replication/slotfuncs.c b/src/backend/replication/slotfuncs.c
index b05371d8b6..e76bbbf47d 100644
--- a/src/backend/replication/slotfuncs.c
+++ b/src/backend/replication/slotfuncs.c
@@ -248,7 +248,8 @@ pg_get_replication_slots(PG_FUNCTION_ARGS)
 	per_query_ctx = rsinfo->econtext->ecxt_per_query_memory;
 	oldcontext = MemoryContextSwitchTo(per_query_ctx);
 
-	tupstore = MakeFuncResultTuplestore(fcinfo, &tupdesc, true);
+	tupstore = MakeFuncResultTuplestore(fcinfo, &tupdesc, (bool)
+			rsinfo->allowedModes & SFRM_Materialize_Random);
 	rsinfo->returnMode = SFRM_Materialize;
 	rsinfo->setResult = tupstore;
 	rsinfo->setDesc = tupdesc;
diff --git a/src/backend/replication/walsender.c b/src/backend/replication/walsender.c
index 92a05b7447..62416a4ac8 100644
--- a/src/backend/replication/walsender.c
+++ b/src/backend/replication/walsender.c
@@ -3404,7 +3404,8 @@ pg_stat_get_wal_senders(PG_FUNCTION_ARGS)
 	per_query_ctx = rsinfo->econtext->ecxt_per_query_memory;
 	oldcontext = MemoryContextSwitchTo(per_query_ctx);
 
-	tupstore = MakeFuncResultTuplestore(fcinfo, &tupdesc, true);
+	tupstore = MakeFuncResultTuplestore(fcinfo, &tupdesc, (bool)
+			rsinfo->allowedModes & SFRM_Materialize_Random);
 	rsinfo->returnMode = SFRM_Materialize;
 	rsinfo->setResult = tupstore;
 	rsinfo->setDesc = tupdesc;
diff --git a/src/backend/storage/ipc/shmem.c b/src/backend/storage/ipc/shmem.c
index 2b882bdd28..95f5ddd81d 100644
--- a/src/backend/storage/ipc/shmem.c
+++ b/src/backend/storage/ipc/shmem.c
@@ -550,7 +550,8 @@ pg_get_shmem_allocations(PG_FUNCTION_ARGS)
 	per_query_ctx = rsinfo->econtext->ecxt_per_query_memory;
 	oldcontext = MemoryContextSwitchTo(per_query_ctx);
 
-	tupstore = MakeFuncResultTuplestore(fcinfo, &tupdesc, true);
+	tupstore = MakeFuncResultTuplestore(fcinfo, &tupdesc, (bool)
+			rsinfo->allowedModes & SFRM_Materialize_Random);
 	rsinfo->returnMode = SFRM_Materialize;
 	rsinfo->setResult = tupstore;
 	rsinfo->setDesc = tupdesc;
diff --git a/src/backend/utils/adt/varlena.c b/src/backend/utils/adt/varlena.c
index 62f320a12d..162f9f19d0 100644
--- a/src/backend/utils/adt/varlena.c
+++ b/src/backend/utils/adt/varlena.c
@@ -4856,7 +4856,8 @@ text_to_table(PG_FUNCTION_ARGS)
 
 	tstate.astate = NULL;
 	tstate.tupdesc = CreateTupleDescCopy(rsi->expectedDesc);
-	tstate.tupstore = MakeFuncResultTuplestore(fcinfo, NULL, true);
+	tstate.tupstore = MakeFuncResultTuplestore(fcinfo, NULL, (bool)
+			rsi->allowedModes & SFRM_Materialize_Random);
 
 	MemoryContextSwitchTo(old_cxt);
 
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index fddec33a47..8aa8eba8d1 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -10117,7 +10117,8 @@ show_all_file_settings(PG_FUNCTION_ARGS)
 					   TEXTOID, -1, 0);
 
 	/* Build a tuplestore to return our results in */
-	tupstore = MakeFuncResultTuplestore(fcinfo, NULL, true);
+	tupstore = MakeFuncResultTuplestore(fcinfo, NULL, (bool)
+			rsinfo->allowedModes & SFRM_Materialize_Random);
 	rsinfo->returnMode = SFRM_Materialize;
 	rsinfo->setResult = tupstore;
 	rsinfo->setDesc = tupdesc;
diff --git a/src/backend/utils/misc/pg_config.c b/src/backend/utils/misc/pg_config.c
index 795c90f001..b80a0e18e5 100644
--- a/src/backend/utils/misc/pg_config.c
+++ b/src/backend/utils/misc/pg_config.c
@@ -66,7 +66,8 @@ pg_config(PG_FUNCTION_ARGS)
 	rsinfo->returnMode = SFRM_Materialize;
 
 	/* initialize our tuplestore */
-	tupstore = MakeFuncResultTuplestore(fcinfo, NULL, true);
+	tupstore = MakeFuncResultTuplestore(fcinfo, NULL, (bool)
+			rsinfo->allowedModes & SFRM_Materialize_Random);
 
 	configdata = get_configdata(my_exec_path, &configdata_len);
 	for (i = 0; i < configdata_len; i++)
-- 
2.32.0

