Rename SetSingleFuncCall() to InitMaterializedSRF()

Per discussion, the existing routine name able to initialize a SRF
function with materialize mode is unpopular, so rename it.  Equally, the
flags of this function are renamed, as of:
- SRF_SINGLE_USE_EXPECTED -> MAT_SRF_USE_EXPECTED_DESC
- SRF_SINGLE_BLESS -> MAT_SRF_BLESS
The previous function and flags introduced in 9e98583 are kept around
for compatibility purposes, so as any extension code already compiled
with v15 continues to work as-is.  The declarations introduced here for
compatibility will be removed from HEAD in a follow-up commit.

The new names have been suggested by Andres Freund and Melanie
Plageman.

Discussion: https://postgr.es/m/20221013194820.ciktb2sbbpw7cljm@awork3.anarazel.de
Backpatch-through: 15
This commit is contained in:
Michael Paquier 2022-10-18 10:22:40 +09:00
parent ef325ee04d
commit f2f7e509e6
35 changed files with 71 additions and 57 deletions

View File

@ -278,7 +278,7 @@ verify_heapam(PG_FUNCTION_ARGS)
ctx.attnum = -1; ctx.attnum = -1;
/* Construct the tuplestore and tuple descriptor */ /* Construct the tuplestore and tuple descriptor */
SetSingleFuncCall(fcinfo, 0); InitMaterializedSRF(fcinfo, 0);
ctx.tupdesc = rsinfo->setDesc; ctx.tupdesc = rsinfo->setDesc;
ctx.tupstore = rsinfo->setResult; ctx.tupstore = rsinfo->setResult;

View File

@ -1934,7 +1934,7 @@ dblink_get_notify(PG_FUNCTION_ARGS)
else else
conn = pconn->conn; conn = pconn->conn;
SetSingleFuncCall(fcinfo, 0); InitMaterializedSRF(fcinfo, 0);
PQconsumeInput(conn); PQconsumeInput(conn);
while ((notify = PQnotifies(conn)) != NULL) while ((notify = PQnotifies(conn)) != NULL)

View File

@ -147,7 +147,7 @@ brin_page_items(PG_FUNCTION_ARGS)
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("must be superuser to use raw page functions"))); errmsg("must be superuser to use raw page functions")));
SetSingleFuncCall(fcinfo, 0); InitMaterializedSRF(fcinfo, 0);
indexRel = index_open(indexRelid, AccessShareLock); indexRel = index_open(indexRelid, AccessShareLock);

View File

@ -129,7 +129,7 @@ gist_page_items_bytea(PG_FUNCTION_ARGS)
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("must be superuser to use raw page functions"))); errmsg("must be superuser to use raw page functions")));
SetSingleFuncCall(fcinfo, 0); InitMaterializedSRF(fcinfo, 0);
page = get_page_from_raw(raw_page); page = get_page_from_raw(raw_page);
@ -213,7 +213,7 @@ gist_page_items(PG_FUNCTION_ARGS)
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("must be superuser to use raw page functions"))); errmsg("must be superuser to use raw page functions")));
SetSingleFuncCall(fcinfo, 0); InitMaterializedSRF(fcinfo, 0);
/* Open the relation */ /* Open the relation */
indexRel = index_open(indexRelid, AccessShareLock); indexRel = index_open(indexRelid, AccessShareLock);

View File

@ -1555,7 +1555,7 @@ pg_stat_statements_internal(FunctionCallInfo fcinfo,
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
errmsg("pg_stat_statements must be loaded via shared_preload_libraries"))); errmsg("pg_stat_statements must be loaded via shared_preload_libraries")));
SetSingleFuncCall(fcinfo, 0); InitMaterializedSRF(fcinfo, 0);
/* /*
* Check we have the expected number of output arguments. Aside from * Check we have the expected number of output arguments. Aside from

View File

@ -333,7 +333,7 @@ GetWALRecordsInfo(FunctionCallInfo fcinfo, XLogRecPtr start_lsn,
Datum values[PG_GET_WAL_RECORDS_INFO_COLS]; Datum values[PG_GET_WAL_RECORDS_INFO_COLS];
bool nulls[PG_GET_WAL_RECORDS_INFO_COLS]; bool nulls[PG_GET_WAL_RECORDS_INFO_COLS];
SetSingleFuncCall(fcinfo, 0); InitMaterializedSRF(fcinfo, 0);
xlogreader = InitXLogReaderState(start_lsn); xlogreader = InitXLogReaderState(start_lsn);
@ -554,7 +554,7 @@ GetWalStats(FunctionCallInfo fcinfo, XLogRecPtr start_lsn,
Datum values[PG_GET_WAL_STATS_COLS]; Datum values[PG_GET_WAL_STATS_COLS];
bool nulls[PG_GET_WAL_STATS_COLS]; bool nulls[PG_GET_WAL_STATS_COLS];
SetSingleFuncCall(fcinfo, 0); InitMaterializedSRF(fcinfo, 0);
xlogreader = InitXLogReaderState(start_lsn); xlogreader = InitXLogReaderState(start_lsn);

View File

@ -75,7 +75,7 @@ pgrowlocks(PG_FUNCTION_ARGS)
AclResult aclresult; AclResult aclresult;
char **values; char **values;
SetSingleFuncCall(fcinfo, 0); InitMaterializedSRF(fcinfo, 0);
/* Access the table */ /* Access the table */
relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname)); relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname));

View File

@ -1668,7 +1668,7 @@ postgres_fdw_get_connections(PG_FUNCTION_ARGS)
HASH_SEQ_STATUS scan; HASH_SEQ_STATUS scan;
ConnCacheEntry *entry; ConnCacheEntry *entry;
SetSingleFuncCall(fcinfo, 0); InitMaterializedSRF(fcinfo, 0);
/* If cache doesn't exist, we return no records */ /* If cache doesn't exist, we return no records */
if (!ConnectionHash) if (!ConnectionHash)

View File

@ -511,7 +511,7 @@ xpath_table(PG_FUNCTION_ARGS)
PgXmlErrorContext *xmlerrcxt; PgXmlErrorContext *xmlerrcxt;
volatile xmlDocPtr doctree = NULL; volatile xmlDocPtr doctree = NULL;
SetSingleFuncCall(fcinfo, SRF_SINGLE_USE_EXPECTED); InitMaterializedSRF(fcinfo, MAT_SRF_USE_EXPECTED_DESC);
/* must have at least one output column (for the pkey) */ /* must have at least one output column (for the pkey) */
if (rsinfo->setDesc->natts < 1) if (rsinfo->setDesc->natts < 1)

View File

@ -145,7 +145,7 @@ pg_get_wal_resource_managers(PG_FUNCTION_ARGS)
Datum values[PG_GET_RESOURCE_MANAGERS_COLS]; Datum values[PG_GET_RESOURCE_MANAGERS_COLS];
bool nulls[PG_GET_RESOURCE_MANAGERS_COLS] = {0}; bool nulls[PG_GET_RESOURCE_MANAGERS_COLS] = {0};
SetSingleFuncCall(fcinfo, 0); InitMaterializedSRF(fcinfo, 0);
for (int rmid = 0; rmid <= RM_MAX_ID; rmid++) for (int rmid = 0; rmid <= RM_MAX_ID; rmid++)
{ {

View File

@ -833,7 +833,7 @@ pg_stat_get_recovery_prefetch(PG_FUNCTION_ARGS)
Datum values[PG_STAT_GET_RECOVERY_PREFETCH_COLS]; Datum values[PG_STAT_GET_RECOVERY_PREFETCH_COLS];
bool nulls[PG_STAT_GET_RECOVERY_PREFETCH_COLS]; bool nulls[PG_STAT_GET_RECOVERY_PREFETCH_COLS];
SetSingleFuncCall(fcinfo, 0); InitMaterializedSRF(fcinfo, 0);
for (int i = 0; i < PG_STAT_GET_RECOVERY_PREFETCH_COLS; ++i) for (int i = 0; i < PG_STAT_GET_RECOVERY_PREFETCH_COLS; ++i)
nulls[i] = false; nulls[i] = false;

View File

@ -1305,7 +1305,7 @@ pg_event_trigger_dropped_objects(PG_FUNCTION_ARGS)
"pg_event_trigger_dropped_objects()"))); "pg_event_trigger_dropped_objects()")));
/* Build tuplestore to hold the result rows */ /* Build tuplestore to hold the result rows */
SetSingleFuncCall(fcinfo, 0); InitMaterializedSRF(fcinfo, 0);
slist_foreach(iter, &(currentEventTriggerState->SQLDropList)) slist_foreach(iter, &(currentEventTriggerState->SQLDropList))
{ {
@ -1835,7 +1835,7 @@ pg_event_trigger_ddl_commands(PG_FUNCTION_ARGS)
"pg_event_trigger_ddl_commands()"))); "pg_event_trigger_ddl_commands()")));
/* Build tuplestore to hold the result rows */ /* Build tuplestore to hold the result rows */
SetSingleFuncCall(fcinfo, 0); InitMaterializedSRF(fcinfo, 0);
foreach(lc, currentEventTriggerState->commandList) foreach(lc, currentEventTriggerState->commandList)
{ {

View File

@ -1941,7 +1941,7 @@ pg_available_extensions(PG_FUNCTION_ARGS)
struct dirent *de; struct dirent *de;
/* Build tuplestore to hold the result rows */ /* Build tuplestore to hold the result rows */
SetSingleFuncCall(fcinfo, 0); InitMaterializedSRF(fcinfo, 0);
location = get_extension_control_directory(); location = get_extension_control_directory();
dir = AllocateDir(location); dir = AllocateDir(location);
@ -2021,7 +2021,7 @@ pg_available_extension_versions(PG_FUNCTION_ARGS)
struct dirent *de; struct dirent *de;
/* Build tuplestore to hold the result rows */ /* Build tuplestore to hold the result rows */
SetSingleFuncCall(fcinfo, 0); InitMaterializedSRF(fcinfo, 0);
location = get_extension_control_directory(); location = get_extension_control_directory();
dir = AllocateDir(location); dir = AllocateDir(location);
@ -2278,7 +2278,7 @@ pg_extension_update_paths(PG_FUNCTION_ARGS)
check_valid_extension_name(NameStr(*extname)); check_valid_extension_name(NameStr(*extname));
/* Build tuplestore to hold the result rows */ /* Build tuplestore to hold the result rows */
SetSingleFuncCall(fcinfo, 0); InitMaterializedSRF(fcinfo, 0);
/* Read the extension's control file */ /* Read the extension's control file */
control = read_extension_control_file(NameStr(*extname)); control = read_extension_control_file(NameStr(*extname));

View File

@ -672,7 +672,7 @@ pg_prepared_statement(PG_FUNCTION_ARGS)
* We put all the tuples into a tuplestore in one scan of the hashtable. * We put all the tuples into a tuplestore in one scan of the hashtable.
* This avoids any issue of the hashtable possibly changing between calls. * This avoids any issue of the hashtable possibly changing between calls.
*/ */
SetSingleFuncCall(fcinfo, 0); InitMaterializedSRF(fcinfo, 0);
/* hash table might be uninitialized */ /* hash table might be uninitialized */
if (prepared_queries) if (prepared_queries)

View File

@ -516,7 +516,7 @@ pg_options_to_table(PG_FUNCTION_ARGS)
rsinfo = (ReturnSetInfo *) fcinfo->resultinfo; rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
/* prepare the result set */ /* prepare the result set */
SetSingleFuncCall(fcinfo, SRF_SINGLE_USE_EXPECTED); InitMaterializedSRF(fcinfo, MAT_SRF_USE_EXPECTED_DESC);
foreach(cell, options) foreach(cell, options)
{ {

View File

@ -930,7 +930,7 @@ pg_stat_get_subscription(PG_FUNCTION_ARGS)
int i; int i;
ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo; ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
SetSingleFuncCall(fcinfo, 0); InitMaterializedSRF(fcinfo, 0);
/* Make sure we get consistent view of the workers. */ /* Make sure we get consistent view of the workers. */
LWLockAcquire(LogicalRepWorkerLock, LW_SHARED); LWLockAcquire(LogicalRepWorkerLock, LW_SHARED);

View File

@ -189,7 +189,7 @@ pg_logical_slot_get_changes_guts(FunctionCallInfo fcinfo, bool confirm, bool bin
} }
} }
SetSingleFuncCall(fcinfo, 0); InitMaterializedSRF(fcinfo, 0);
p->tupstore = rsinfo->setResult; p->tupstore = rsinfo->setResult;
p->tupdesc = rsinfo->setDesc; p->tupdesc = rsinfo->setDesc;

View File

@ -1487,7 +1487,7 @@ pg_show_replication_origin_status(PG_FUNCTION_ARGS)
/* we want to return 0 rows if slot is set to zero */ /* we want to return 0 rows if slot is set to zero */
replorigin_check_prerequisites(false, true); replorigin_check_prerequisites(false, true);
SetSingleFuncCall(fcinfo, 0); InitMaterializedSRF(fcinfo, 0);
/* prevent slots from being concurrently dropped */ /* prevent slots from being concurrently dropped */
LWLockAcquire(ReplicationOriginLock, LW_SHARED); LWLockAcquire(ReplicationOriginLock, LW_SHARED);

View File

@ -242,7 +242,7 @@ pg_get_replication_slots(PG_FUNCTION_ARGS)
* name, which shouldn't contain anything particularly sensitive. * name, which shouldn't contain anything particularly sensitive.
*/ */
SetSingleFuncCall(fcinfo, 0); InitMaterializedSRF(fcinfo, 0);
currlsn = GetXLogWriteRecPtr(); currlsn = GetXLogWriteRecPtr();

View File

@ -3476,7 +3476,7 @@ pg_stat_get_wal_senders(PG_FUNCTION_ARGS)
int num_standbys; int num_standbys;
int i; int i;
SetSingleFuncCall(fcinfo, 0); InitMaterializedSRF(fcinfo, 0);
/* /*
* Get the currently active synchronous standbys. This could be out of * Get the currently active synchronous standbys. This could be out of

View File

@ -543,7 +543,7 @@ pg_get_shmem_allocations(PG_FUNCTION_ARGS)
Datum values[PG_GET_SHMEM_SIZES_COLS]; Datum values[PG_GET_SHMEM_SIZES_COLS];
bool nulls[PG_GET_SHMEM_SIZES_COLS]; bool nulls[PG_GET_SHMEM_SIZES_COLS];
SetSingleFuncCall(fcinfo, 0); InitMaterializedSRF(fcinfo, 0);
LWLockAcquire(ShmemIndexLock, LW_SHARED); LWLockAcquire(ShmemIndexLock, LW_SHARED);

View File

@ -5059,7 +5059,7 @@ pg_timezone_names(PG_FUNCTION_ARGS)
Interval *resInterval; Interval *resInterval;
struct pg_itm_in itm_in; struct pg_itm_in itm_in;
SetSingleFuncCall(fcinfo, 0); InitMaterializedSRF(fcinfo, 0);
/* initialize timezone scanning code */ /* initialize timezone scanning code */
tzenum = pg_tzenumerate_start(); tzenum = pg_tzenumerate_start();

View File

@ -491,7 +491,7 @@ pg_ls_dir(PG_FUNCTION_ARGS)
include_dot_dirs = PG_GETARG_BOOL(2); include_dot_dirs = PG_GETARG_BOOL(2);
} }
SetSingleFuncCall(fcinfo, SRF_SINGLE_USE_EXPECTED); InitMaterializedSRF(fcinfo, MAT_SRF_USE_EXPECTED_DESC);
dirdesc = AllocateDir(location); dirdesc = AllocateDir(location);
if (!dirdesc) if (!dirdesc)
@ -549,7 +549,7 @@ pg_ls_dir_files(FunctionCallInfo fcinfo, const char *dir, bool missing_ok)
DIR *dirdesc; DIR *dirdesc;
struct dirent *de; struct dirent *de;
SetSingleFuncCall(fcinfo, 0); InitMaterializedSRF(fcinfo, 0);
/* /*
* Now walk the directory. Note that we must do this within a single SRF * Now walk the directory. Note that we must do this within a single SRF

View File

@ -421,7 +421,7 @@ pg_hba_file_rules(PG_FUNCTION_ARGS)
* also more efficient than having to look up our current position in the * also more efficient than having to look up our current position in the
* parsed list every time. * parsed list every time.
*/ */
SetSingleFuncCall(fcinfo, 0); InitMaterializedSRF(fcinfo, 0);
/* Fill the tuplestore */ /* Fill the tuplestore */
rsi = (ReturnSetInfo *) fcinfo->resultinfo; rsi = (ReturnSetInfo *) fcinfo->resultinfo;
@ -554,7 +554,7 @@ pg_ident_file_mappings(PG_FUNCTION_ARGS)
* also more efficient than having to look up our current position in the * also more efficient than having to look up our current position in the
* parsed list every time. * parsed list every time.
*/ */
SetSingleFuncCall(fcinfo, 0); InitMaterializedSRF(fcinfo, 0);
/* Fill the tuplestore */ /* Fill the tuplestore */
rsi = (ReturnSetInfo *) fcinfo->resultinfo; rsi = (ReturnSetInfo *) fcinfo->resultinfo;

View File

@ -1923,7 +1923,7 @@ each_worker_jsonb(FunctionCallInfo fcinfo, const char *funcname, bool as_text)
funcname))); funcname)));
rsi = (ReturnSetInfo *) fcinfo->resultinfo; rsi = (ReturnSetInfo *) fcinfo->resultinfo;
SetSingleFuncCall(fcinfo, SRF_SINGLE_BLESS); InitMaterializedSRF(fcinfo, MAT_SRF_BLESS);
tmp_cxt = AllocSetContextCreate(CurrentMemoryContext, tmp_cxt = AllocSetContextCreate(CurrentMemoryContext,
"jsonb_each temporary cxt", "jsonb_each temporary cxt",
@ -2003,7 +2003,7 @@ each_worker(FunctionCallInfo fcinfo, bool as_text)
rsi = (ReturnSetInfo *) fcinfo->resultinfo; rsi = (ReturnSetInfo *) fcinfo->resultinfo;
SetSingleFuncCall(fcinfo, SRF_SINGLE_BLESS); InitMaterializedSRF(fcinfo, MAT_SRF_BLESS);
state->tuple_store = rsi->setResult; state->tuple_store = rsi->setResult;
state->ret_tdesc = rsi->setDesc; state->ret_tdesc = rsi->setDesc;
@ -2166,8 +2166,7 @@ elements_worker_jsonb(FunctionCallInfo fcinfo, const char *funcname,
rsi = (ReturnSetInfo *) fcinfo->resultinfo; rsi = (ReturnSetInfo *) fcinfo->resultinfo;
SetSingleFuncCall(fcinfo, InitMaterializedSRF(fcinfo, MAT_SRF_USE_EXPECTED_DESC | MAT_SRF_BLESS);
SRF_SINGLE_USE_EXPECTED | SRF_SINGLE_BLESS);
tmp_cxt = AllocSetContextCreate(CurrentMemoryContext, tmp_cxt = AllocSetContextCreate(CurrentMemoryContext,
"jsonb_array_elements temporary cxt", "jsonb_array_elements temporary cxt",
@ -2245,7 +2244,7 @@ elements_worker(FunctionCallInfo fcinfo, const char *funcname, bool as_text)
state = palloc0(sizeof(ElementsState)); state = palloc0(sizeof(ElementsState));
sem = palloc0(sizeof(JsonSemAction)); sem = palloc0(sizeof(JsonSemAction));
SetSingleFuncCall(fcinfo, SRF_SINGLE_USE_EXPECTED | SRF_SINGLE_BLESS); InitMaterializedSRF(fcinfo, MAT_SRF_USE_EXPECTED_DESC | MAT_SRF_BLESS);
rsi = (ReturnSetInfo *) fcinfo->resultinfo; rsi = (ReturnSetInfo *) fcinfo->resultinfo;
state->tuple_store = rsi->setResult; state->tuple_store = rsi->setResult;
state->ret_tdesc = rsi->setDesc; state->ret_tdesc = rsi->setDesc;

View File

@ -121,7 +121,7 @@ pg_get_backend_memory_contexts(PG_FUNCTION_ARGS)
{ {
ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo; ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
SetSingleFuncCall(fcinfo, 0); InitMaterializedSRF(fcinfo, 0);
PutMemoryContextsStatsTupleStore(rsinfo->setResult, rsinfo->setDesc, PutMemoryContextsStatsTupleStore(rsinfo->setResult, rsinfo->setDesc,
TopMemoryContext, NULL, 0); TopMemoryContext, NULL, 0);

View File

@ -208,7 +208,7 @@ pg_tablespace_databases(PG_FUNCTION_ARGS)
DIR *dirdesc; DIR *dirdesc;
struct dirent *de; struct dirent *de;
SetSingleFuncCall(fcinfo, SRF_SINGLE_USE_EXPECTED); InitMaterializedSRF(fcinfo, MAT_SRF_USE_EXPECTED_DESC);
if (tablespaceOid == GLOBALTABLESPACE_OID) if (tablespaceOid == GLOBALTABLESPACE_OID)
{ {

View File

@ -481,7 +481,7 @@ pg_stat_get_progress_info(PG_FUNCTION_ARGS)
(errcode(ERRCODE_INVALID_PARAMETER_VALUE), (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("invalid command name: \"%s\"", cmd))); errmsg("invalid command name: \"%s\"", cmd)));
SetSingleFuncCall(fcinfo, 0); InitMaterializedSRF(fcinfo, 0);
/* 1-based index */ /* 1-based index */
for (curr_backend = 1; curr_backend <= num_backends; curr_backend++) for (curr_backend = 1; curr_backend <= num_backends; curr_backend++)
@ -545,7 +545,7 @@ pg_stat_get_activity(PG_FUNCTION_ARGS)
int pid = PG_ARGISNULL(0) ? -1 : PG_GETARG_INT32(0); int pid = PG_ARGISNULL(0) ? -1 : PG_GETARG_INT32(0);
ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo; ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
SetSingleFuncCall(fcinfo, 0); InitMaterializedSRF(fcinfo, 0);
/* 1-based index */ /* 1-based index */
for (curr_backend = 1; curr_backend <= num_backends; curr_backend++) for (curr_backend = 1; curr_backend <= num_backends; curr_backend++)
@ -1818,7 +1818,7 @@ pg_stat_get_slru(PG_FUNCTION_ARGS)
int i; int i;
PgStat_SLRUStats *stats; PgStat_SLRUStats *stats;
SetSingleFuncCall(fcinfo, 0); InitMaterializedSRF(fcinfo, 0);
/* request SLRU stats from the cumulative stats system */ /* request SLRU stats from the cumulative stats system */
stats = pgstat_fetch_slru(); stats = pgstat_fetch_slru();

View File

@ -4809,7 +4809,7 @@ text_to_table(PG_FUNCTION_ARGS)
SplitTextOutputData tstate; SplitTextOutputData tstate;
tstate.astate = NULL; tstate.astate = NULL;
SetSingleFuncCall(fcinfo, SRF_SINGLE_USE_EXPECTED); InitMaterializedSRF(fcinfo, MAT_SRF_USE_EXPECTED_DESC);
tstate.tupstore = rsi->setResult; tstate.tupstore = rsi->setResult;
tstate.tupdesc = rsi->setDesc; tstate.tupdesc = rsi->setDesc;

View File

@ -305,7 +305,7 @@ If available, the expected tuple descriptor is passed in ReturnSetInfo;
in other contexts the expectedDesc field will be NULL. The function need in other contexts the expectedDesc field will be NULL. The function need
not pay attention to expectedDesc, but it may be useful in special cases. not pay attention to expectedDesc, but it may be useful in special cases.
SetSingleFuncCall() is a helper function able to setup the function's InitMaterializedSRF() is a helper function able to setup the function's
ReturnSetInfo for a single call, filling in the Tuplestore and the ReturnSetInfo for a single call, filling in the Tuplestore and the
TupleDesc with the proper configuration for Materialize mode. TupleDesc with the proper configuration for Materialize mode.

View File

@ -57,7 +57,16 @@ static TypeFuncClass get_type_func_class(Oid typid, Oid *base_typeid);
/* /*
* SetSingleFuncCall * Compatibility function for v15.
*/
void
SetSingleFuncCall(FunctionCallInfo fcinfo, bits32 flags)
{
InitMaterializedSRF(fcinfo, flags);
}
/*
* InitMaterializedSRF
* *
* Helper function to build the state of a set-returning function used * Helper function to build the state of a set-returning function used
* in the context of a single call with materialize mode. This code * in the context of a single call with materialize mode. This code
@ -65,15 +74,15 @@ static TypeFuncClass get_type_func_class(Oid typid, Oid *base_typeid);
* the TupleDesc used with the function and stores them into the * the TupleDesc used with the function and stores them into the
* function's ReturnSetInfo. * function's ReturnSetInfo.
* *
* "flags" can be set to SRF_SINGLE_USE_EXPECTED, to use the tuple * "flags" can be set to MAT_SRF_USE_EXPECTED_DESC, to use the tuple
* descriptor coming from expectedDesc, which is the tuple descriptor * descriptor coming from expectedDesc, which is the tuple descriptor
* expected by the caller. SRF_SINGLE_BLESS can be set to complete the * expected by the caller. MAT_SRF_BLESS can be set to complete the
* information associated to the tuple descriptor, which is necessary * information associated to the tuple descriptor, which is necessary
* in some cases where the tuple descriptor comes from a transient * in some cases where the tuple descriptor comes from a transient
* RECORD datatype. * RECORD datatype.
*/ */
void void
SetSingleFuncCall(FunctionCallInfo fcinfo, bits32 flags) InitMaterializedSRF(FunctionCallInfo fcinfo, bits32 flags)
{ {
bool random_access; bool random_access;
ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo; ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
@ -88,7 +97,7 @@ SetSingleFuncCall(FunctionCallInfo fcinfo, bits32 flags)
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED), (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("set-valued function called in context that cannot accept a set"))); errmsg("set-valued function called in context that cannot accept a set")));
if (!(rsinfo->allowedModes & SFRM_Materialize) || if (!(rsinfo->allowedModes & SFRM_Materialize) ||
((flags & SRF_SINGLE_USE_EXPECTED) != 0 && rsinfo->expectedDesc == NULL)) ((flags & MAT_SRF_USE_EXPECTED_DESC) != 0 && rsinfo->expectedDesc == NULL))
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED), (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("materialize mode required, but it is not allowed in this context"))); errmsg("materialize mode required, but it is not allowed in this context")));
@ -101,7 +110,7 @@ SetSingleFuncCall(FunctionCallInfo fcinfo, bits32 flags)
old_context = MemoryContextSwitchTo(per_query_ctx); old_context = MemoryContextSwitchTo(per_query_ctx);
/* build a tuple descriptor for our result type */ /* build a tuple descriptor for our result type */
if ((flags & SRF_SINGLE_USE_EXPECTED) != 0) if ((flags & MAT_SRF_USE_EXPECTED_DESC) != 0)
stored_tupdesc = CreateTupleDescCopy(rsinfo->expectedDesc); stored_tupdesc = CreateTupleDescCopy(rsinfo->expectedDesc);
else else
{ {
@ -110,7 +119,7 @@ SetSingleFuncCall(FunctionCallInfo fcinfo, bits32 flags)
} }
/* If requested, bless the tuple descriptor */ /* If requested, bless the tuple descriptor */
if ((flags & SRF_SINGLE_BLESS) != 0) if ((flags & MAT_SRF_BLESS) != 0)
BlessTupleDesc(stored_tupdesc); BlessTupleDesc(stored_tupdesc);
random_access = (rsinfo->allowedModes & SFRM_Materialize_Random) != 0; random_access = (rsinfo->allowedModes & SFRM_Materialize_Random) != 0;

View File

@ -10476,7 +10476,7 @@ show_all_file_settings(PG_FUNCTION_ARGS)
conf = ProcessConfigFileInternal(PGC_SIGHUP, false, DEBUG3); conf = ProcessConfigFileInternal(PGC_SIGHUP, false, DEBUG3);
/* Build a tuplestore to return our results in */ /* Build a tuplestore to return our results in */
SetSingleFuncCall(fcinfo, 0); InitMaterializedSRF(fcinfo, 0);
/* Process the results and create a tuplestore */ /* Process the results and create a tuplestore */
for (seqno = 1; conf != NULL; conf = conf->next, seqno++) for (seqno = 1; conf != NULL; conf = conf->next, seqno++)

View File

@ -30,7 +30,7 @@ pg_config(PG_FUNCTION_ARGS)
int i = 0; int i = 0;
/* initialize our tuplestore */ /* initialize our tuplestore */
SetSingleFuncCall(fcinfo, 0); InitMaterializedSRF(fcinfo, 0);
configdata = get_configdata(my_exec_path, &configdata_len); configdata = get_configdata(my_exec_path, &configdata_len);
for (i = 0; i < configdata_len; i++) for (i = 0; i < configdata_len; i++)

View File

@ -1139,7 +1139,7 @@ pg_cursor(PG_FUNCTION_ARGS)
* We put all the tuples into a tuplestore in one scan of the hashtable. * We put all the tuples into a tuplestore in one scan of the hashtable.
* This avoids any issue of the hashtable possibly changing between calls. * This avoids any issue of the hashtable possibly changing between calls.
*/ */
SetSingleFuncCall(fcinfo, 0); InitMaterializedSRF(fcinfo, 0);
hash_seq_init(&hash_seq, PortalHashTable); hash_seq_init(&hash_seq, PortalHashTable);
while ((hentry = hash_seq_search(&hash_seq)) != NULL) while ((hentry = hash_seq_search(&hash_seq)) != NULL)

View File

@ -278,7 +278,7 @@ extern Datum HeapTupleHeaderGetDatum(HeapTupleHeader tuple);
* memory allocated in multi_call_memory_ctx, but holding file descriptors or * memory allocated in multi_call_memory_ctx, but holding file descriptors or
* other non-memory resources open across calls is a bug. SRFs that need * other non-memory resources open across calls is a bug. SRFs that need
* such resources should not use these macros, but instead populate a * such resources should not use these macros, but instead populate a
* tuplestore during a single call, as set up by SetSingleFuncCall() (see * tuplestore during a single call, as set up by InitMaterializedSRF() (see
* fmgr/README). Alternatively, set up a callback to release resources * fmgr/README). Alternatively, set up a callback to release resources
* at query shutdown, using RegisterExprContextCallback(). * at query shutdown, using RegisterExprContextCallback().
* *
@ -287,9 +287,15 @@ extern Datum HeapTupleHeaderGetDatum(HeapTupleHeader tuple);
/* from funcapi.c */ /* from funcapi.c */
/* flag bits for SetSingleFuncCall() */ /* flag bits for InitMaterializedSRF() */
#define SRF_SINGLE_USE_EXPECTED 0x01 /* use expectedDesc as tupdesc */ #define MAT_SRF_USE_EXPECTED_DESC 0x01 /* use expectedDesc as tupdesc. */
#define SRF_SINGLE_BLESS 0x02 /* validate tuple for SRF */ #define MAT_SRF_BLESS 0x02 /* "Bless" a tuple descriptor with
* BlessTupleDesc(). */
extern void InitMaterializedSRF(FunctionCallInfo fcinfo, bits32 flags);
/* Compatibility declarations, for v15 */
#define SRF_SINGLE_USE_EXPECTED MAT_SRF_USE_EXPECTED_DESC
#define SRF_SINGLE_BLESS MAT_SRF_BLESS
extern void SetSingleFuncCall(FunctionCallInfo fcinfo, bits32 flags); extern void SetSingleFuncCall(FunctionCallInfo fcinfo, bits32 flags);
extern FuncCallContext *init_MultiFuncCall(PG_FUNCTION_ARGS); extern FuncCallContext *init_MultiFuncCall(PG_FUNCTION_ARGS);