Skip to content

Commit e77216f

Browse files
committed
Simplify more checks related to set-returning functions
This makes more consistent the SRF-related checks in the area of PL/pgSQL, PL/Perl, PL/Tcl, pageinspect and some of the JSON worker functions, making it easier to grep for the same error patterns through the code, reducing a bit the translation work. It is worth noting that each_worker_jsonb()/each_worker() in jsonfuncs.c and pageinspect's brin_page_items() were doing a check on expectedDesc that is not required as they fetch their tuple descriptor directly from get_call_result_type(). This looks like a set of copy-paste errors that have spread over the years. This commit is a continuation of the changes begun in 07daca5, for any remaining code paths on sight. Like fcc2817, this makes the code more consistent, easing the integration of a larger patch that will refactor the way tuplestores are created and checked in a good portion of the set-returning functions present in core. I have worked my way through the changes of this patch by myself, and Ranier has proposed the same changes in a different thread in parallel, though there were some inconsistencies related in expectedDesc in what was proposed by him. Author: Michael Paquier, Ranier Vilela Discussion: https://postgr.es/m/CAAKRu_azyd1Z3W_r7Ou4sorTjRCs+PxeHw1CWJeXKofkE6TuZg@mail.gmail.com Discussion: https://postgr.es/m/CAEudQApm=AFuJjEHLBjBcJbxcw4pBMwg2sHwXyCXYcbBOj3hpg@mail.gmail.com
1 parent fcc2817 commit e77216f

File tree

5 files changed

+63
-39
lines changed

5 files changed

+63
-39
lines changed

contrib/pageinspect/brinfuncs.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,8 +148,7 @@ brin_page_items(PG_FUNCTION_ARGS)
148148
ereport(ERROR,
149149
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
150150
errmsg("set-valued function called in context that cannot accept a set")));
151-
if (!(rsinfo->allowedModes & SFRM_Materialize) ||
152-
rsinfo->expectedDesc == NULL)
151+
if (!(rsinfo->allowedModes & SFRM_Materialize))
153152
ereport(ERROR,
154153
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
155154
errmsg("materialize mode required, but it is not allowed in this context")));

src/backend/utils/adt/jsonfuncs.c

Lines changed: 35 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1927,21 +1927,19 @@ each_worker_jsonb(FunctionCallInfo fcinfo, const char *funcname, bool as_text)
19271927

19281928
rsi = (ReturnSetInfo *) fcinfo->resultinfo;
19291929

1930-
if (!rsi || !IsA(rsi, ReturnSetInfo) ||
1931-
(rsi->allowedModes & SFRM_Materialize) == 0 ||
1932-
rsi->expectedDesc == NULL)
1930+
if (!rsi || !IsA(rsi, ReturnSetInfo))
1931+
ereport(ERROR,
1932+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1933+
errmsg("set-valued function called in context that cannot accept a set")));
1934+
if (!(rsi->allowedModes & SFRM_Materialize))
19331935
ereport(ERROR,
19341936
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1935-
errmsg("set-valued function called in context that "
1936-
"cannot accept a set")));
1937+
errmsg("materialize mode required, but it is not allowed in this context")));
19371938

19381939
rsi->returnMode = SFRM_Materialize;
19391940

19401941
if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
1941-
ereport(ERROR,
1942-
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1943-
errmsg("function returning record called in context "
1944-
"that cannot accept type record")));
1942+
elog(ERROR, "return type must be a row type");
19451943

19461944
old_cxt = MemoryContextSwitchTo(rsi->econtext->ecxt_per_query_memory);
19471945

@@ -2039,13 +2037,15 @@ each_worker(FunctionCallInfo fcinfo, bool as_text)
20392037

20402038
rsi = (ReturnSetInfo *) fcinfo->resultinfo;
20412039

2042-
if (!rsi || !IsA(rsi, ReturnSetInfo) ||
2043-
(rsi->allowedModes & SFRM_Materialize) == 0 ||
2044-
rsi->expectedDesc == NULL)
2040+
if (!rsi || !IsA(rsi, ReturnSetInfo))
2041+
ereport(ERROR,
2042+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2043+
errmsg("set-valued function called in context that cannot accept a set")));
2044+
2045+
if (!(rsi->allowedModes & SFRM_Materialize))
20452046
ereport(ERROR,
20462047
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2047-
errmsg("set-valued function called in context that "
2048-
"cannot accept a set")));
2048+
errmsg("materialize mode required, but it is not allowed in this context")));
20492049

20502050
rsi->returnMode = SFRM_Materialize;
20512051

@@ -2227,13 +2227,16 @@ elements_worker_jsonb(FunctionCallInfo fcinfo, const char *funcname,
22272227

22282228
rsi = (ReturnSetInfo *) fcinfo->resultinfo;
22292229

2230-
if (!rsi || !IsA(rsi, ReturnSetInfo) ||
2231-
(rsi->allowedModes & SFRM_Materialize) == 0 ||
2230+
if (!rsi || !IsA(rsi, ReturnSetInfo))
2231+
ereport(ERROR,
2232+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2233+
errmsg("set-valued function called in context that cannot accept a set")));
2234+
2235+
if (!(rsi->allowedModes & SFRM_Materialize) ||
22322236
rsi->expectedDesc == NULL)
22332237
ereport(ERROR,
22342238
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2235-
errmsg("set-valued function called in context that "
2236-
"cannot accept a set")));
2239+
errmsg("materialize mode required, but it is not allowed in this context")));
22372240

22382241
rsi->returnMode = SFRM_Materialize;
22392242

@@ -2336,13 +2339,16 @@ elements_worker(FunctionCallInfo fcinfo, const char *funcname, bool as_text)
23362339

23372340
rsi = (ReturnSetInfo *) fcinfo->resultinfo;
23382341

2339-
if (!rsi || !IsA(rsi, ReturnSetInfo) ||
2340-
(rsi->allowedModes & SFRM_Materialize) == 0 ||
2342+
if (!rsi || !IsA(rsi, ReturnSetInfo))
2343+
ereport(ERROR,
2344+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2345+
errmsg("set-valued function called in context that cannot accept a set")));
2346+
2347+
if (!(rsi->allowedModes & SFRM_Materialize) ||
23412348
rsi->expectedDesc == NULL)
23422349
ereport(ERROR,
23432350
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2344-
errmsg("set-valued function called in context that "
2345-
"cannot accept a set")));
2351+
errmsg("materialize mode required, but it is not allowed in this context")));
23462352

23472353
rsi->returnMode = SFRM_Materialize;
23482354

@@ -3798,12 +3804,15 @@ populate_recordset_worker(FunctionCallInfo fcinfo, const char *funcname,
37983804

37993805
rsi = (ReturnSetInfo *) fcinfo->resultinfo;
38003806

3801-
if (!rsi || !IsA(rsi, ReturnSetInfo) ||
3802-
(rsi->allowedModes & SFRM_Materialize) == 0)
3807+
if (!rsi || !IsA(rsi, ReturnSetInfo))
3808+
ereport(ERROR,
3809+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3810+
errmsg("set-valued function called in context that cannot accept a set")));
3811+
3812+
if (!(rsi->allowedModes & SFRM_Materialize))
38033813
ereport(ERROR,
38043814
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3805-
errmsg("set-valued function called in context that "
3806-
"cannot accept a set")));
3815+
errmsg("materialize mode required, but it is not allowed in this context")));
38073816

38083817
rsi->returnMode = SFRM_Materialize;
38093818

src/pl/plperl/plperl.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2414,12 +2414,15 @@ plperl_func_handler(PG_FUNCTION_ARGS)
24142414
if (prodesc->fn_retisset)
24152415
{
24162416
/* Check context before allowing the call to go through */
2417-
if (!rsi || !IsA(rsi, ReturnSetInfo) ||
2418-
(rsi->allowedModes & SFRM_Materialize) == 0)
2417+
if (!rsi || !IsA(rsi, ReturnSetInfo))
24192418
ereport(ERROR,
24202419
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2421-
errmsg("set-valued function called in context that "
2422-
"cannot accept a set")));
2420+
errmsg("set-valued function called in context that cannot accept a set")));
2421+
2422+
if (!(rsi->allowedModes & SFRM_Materialize))
2423+
ereport(ERROR,
2424+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2425+
errmsg("materialize mode required, but it is not allowed in this context")));
24232426
}
24242427

24252428
activate_interpreter(prodesc->interp);

src/pl/plpgsql/src/pl_exec.c

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -629,11 +629,16 @@ plpgsql_exec_function(PLpgSQL_function *func, FunctionCallInfo fcinfo,
629629
ReturnSetInfo *rsi = estate.rsi;
630630

631631
/* Check caller can handle a set result */
632-
if (!rsi || !IsA(rsi, ReturnSetInfo) ||
633-
(rsi->allowedModes & SFRM_Materialize) == 0)
632+
if (!rsi || !IsA(rsi, ReturnSetInfo))
634633
ereport(ERROR,
635634
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
636635
errmsg("set-valued function called in context that cannot accept a set")));
636+
637+
if (!(rsi->allowedModes & SFRM_Materialize))
638+
ereport(ERROR,
639+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
640+
errmsg("materialize mode required, but it is not allowed in this context")));
641+
637642
rsi->returnMode = SFRM_Materialize;
638643

639644
/* If we produced any tuples, send back the result */
@@ -3645,13 +3650,17 @@ exec_init_tuple_store(PLpgSQL_execstate *estate)
36453650
/*
36463651
* Check caller can handle a set result in the way we want
36473652
*/
3648-
if (!rsi || !IsA(rsi, ReturnSetInfo) ||
3649-
(rsi->allowedModes & SFRM_Materialize) == 0 ||
3650-
rsi->expectedDesc == NULL)
3653+
if (!rsi || !IsA(rsi, ReturnSetInfo))
36513654
ereport(ERROR,
36523655
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
36533656
errmsg("set-valued function called in context that cannot accept a set")));
36543657

3658+
if (!(rsi->allowedModes & SFRM_Materialize) ||
3659+
rsi->expectedDesc == NULL)
3660+
ereport(ERROR,
3661+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3662+
errmsg("materialize mode required, but it is not allowed in this context")));
3663+
36553664
/*
36563665
* Switch to the right memory context and resource owner for storing the
36573666
* tuplestore for return set. If we're within a subtransaction opened for

src/pl/tcl/pltcl.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -829,12 +829,16 @@ pltcl_func_handler(PG_FUNCTION_ARGS, pltcl_call_state *call_state,
829829
{
830830
ReturnSetInfo *rsi = (ReturnSetInfo *) fcinfo->resultinfo;
831831

832-
if (!rsi || !IsA(rsi, ReturnSetInfo) ||
833-
(rsi->allowedModes & SFRM_Materialize) == 0)
832+
if (!rsi || !IsA(rsi, ReturnSetInfo))
834833
ereport(ERROR,
835834
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
836835
errmsg("set-valued function called in context that cannot accept a set")));
837836

837+
if (!(rsi->allowedModes & SFRM_Materialize))
838+
ereport(ERROR,
839+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
840+
errmsg("materialize mode required, but it is not allowed in this context")));
841+
838842
call_state->rsi = rsi;
839843
call_state->tuple_store_cxt = rsi->econtext->ecxt_per_query_memory;
840844
call_state->tuple_store_owner = CurrentResourceOwner;

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy