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)