diff options
author | Michael Paquier <michael@paquier.xyz> | 2022-03-08 10:12:22 +0900 |
---|---|---|
committer | Michael Paquier <michael@paquier.xyz> | 2022-03-08 10:12:22 +0900 |
commit | 5b81703787bfc1e6072c8e37125eba0c5598b807 (patch) | |
tree | 64fa53f8604641fc8ba17da54cf2b127b5016dac /contrib/pageinspect/gistfuncs.c | |
parent | d5ed9da41d96988d905b49bebb273a9b2d6e2915 (diff) | |
download | postgresql-5b81703787bfc1e6072c8e37125eba0c5598b807.tar.gz postgresql-5b81703787bfc1e6072c8e37125eba0c5598b807.zip |
Simplify SRFs using materialize mode in contrib/ modules
9e98583 introduced a helper to centralize building their needed state
(tuplestore, tuple descriptors, etc.), checking for any errors. This
commit updates all places of contrib/ that can be switched to use
SetSingleFuncCall() as a drop-in replacement, resulting in the removal
of a lot of boilerplate code in all the modules updated by this commit.
Per analysis, some places remain as they are:
- pg_logdir_ls() in adminpack/ uses historically TYPEFUNC_RECORD as
return type, and I suspect that changing it may cause issues at run-time
with some of its past versions, down to 1.0.
- dblink/ uses a wrapper function doing exactly the work of
SetSingleFuncCall(). Here the switch should be possible, but rather
invasive so it does not seem the extra backpatch maintenance cost.
- tablefunc/, similarly, uses multiple helper functions with portions of
SetSingleFuncCall() spread across the code paths of this module.
Author: Melanie Plageman
Discussion: https://postgr.es/m/CAAKRu_bvDPJoL9mH6eYwvBpPtTGQwbDzfJbCM-OjkSZDu5yTPg@mail.gmail.com
Diffstat (limited to 'contrib/pageinspect/gistfuncs.c')
-rw-r--r-- | contrib/pageinspect/gistfuncs.c | 60 |
1 files changed, 4 insertions, 56 deletions
diff --git a/contrib/pageinspect/gistfuncs.c b/contrib/pageinspect/gistfuncs.c index 96e3cab1cc3..10d6dd44d4e 100644 --- a/contrib/pageinspect/gistfuncs.c +++ b/contrib/pageinspect/gistfuncs.c @@ -97,10 +97,6 @@ gist_page_items_bytea(PG_FUNCTION_ARGS) { bytea *raw_page = PG_GETARG_BYTEA_P(0); ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo; - bool randomAccess; - TupleDesc tupdesc; - Tuplestorestate *tupstore; - MemoryContext oldcontext; Page page; OffsetNumber offset; OffsetNumber maxoff = InvalidOffsetNumber; @@ -110,29 +106,7 @@ gist_page_items_bytea(PG_FUNCTION_ARGS) (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("must be superuser to use raw page functions"))); - /* check to see if caller supports us returning a tuplestore */ - if (rsinfo == NULL || !IsA(rsinfo, ReturnSetInfo)) - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("set-valued function called in context that cannot accept a set"))); - if (!(rsinfo->allowedModes & SFRM_Materialize)) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("materialize mode required, but it is not allowed in this context"))); - - /* The tupdesc and tuplestore must be created in ecxt_per_query_memory */ - oldcontext = MemoryContextSwitchTo(rsinfo->econtext->ecxt_per_query_memory); - - if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) - elog(ERROR, "return type must be a row type"); - - randomAccess = (rsinfo->allowedModes & SFRM_Materialize_Random) != 0; - tupstore = tuplestore_begin_heap(randomAccess, false, work_mem); - rsinfo->returnMode = SFRM_Materialize; - rsinfo->setResult = tupstore; - rsinfo->setDesc = tupdesc; - - MemoryContextSwitchTo(oldcontext); + SetSingleFuncCall(fcinfo, 0); page = get_page_from_raw(raw_page); @@ -173,7 +147,7 @@ gist_page_items_bytea(PG_FUNCTION_ARGS) values[3] = BoolGetDatum(ItemIdIsDead(id)); values[4] = PointerGetDatum(tuple_bytea); - tuplestore_putvalues(tupstore, tupdesc, values, nulls); + tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, values, nulls); } return (Datum) 0; @@ -185,11 +159,7 @@ gist_page_items(PG_FUNCTION_ARGS) bytea *raw_page = PG_GETARG_BYTEA_P(0); Oid indexRelid = PG_GETARG_OID(1); ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo; - bool randomAccess; Relation indexRel; - TupleDesc tupdesc; - Tuplestorestate *tupstore; - MemoryContext oldcontext; Page page; OffsetNumber offset; OffsetNumber maxoff = InvalidOffsetNumber; @@ -199,29 +169,7 @@ gist_page_items(PG_FUNCTION_ARGS) (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("must be superuser to use raw page functions"))); - /* check to see if caller supports us returning a tuplestore */ - if (rsinfo == NULL || !IsA(rsinfo, ReturnSetInfo)) - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("set-valued function called in context that cannot accept a set"))); - if (!(rsinfo->allowedModes & SFRM_Materialize)) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("materialize mode required, but it is not allowed in this context"))); - - /* The tupdesc and tuplestore must be created in ecxt_per_query_memory */ - oldcontext = MemoryContextSwitchTo(rsinfo->econtext->ecxt_per_query_memory); - - if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) - elog(ERROR, "return type must be a row type"); - - randomAccess = (rsinfo->allowedModes & SFRM_Materialize_Random) != 0; - tupstore = tuplestore_begin_heap(randomAccess, false, work_mem); - rsinfo->returnMode = SFRM_Materialize; - rsinfo->setResult = tupstore; - rsinfo->setDesc = tupdesc; - - MemoryContextSwitchTo(oldcontext); + SetSingleFuncCall(fcinfo, 0); /* Open the relation */ indexRel = index_open(indexRelid, AccessShareLock); @@ -272,7 +220,7 @@ gist_page_items(PG_FUNCTION_ARGS) nulls[4] = true; } - tuplestore_putvalues(tupstore, tupdesc, values, nulls); + tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, values, nulls); } relation_close(indexRel, AccessShareLock); |