From: Tom Lane Date: Mon, 31 Jul 2017 15:33:46 +0000 (-0400) Subject: Tighten coding for non-composite case in plperl's return_next. X-Git-Tag: REL_10_BETA3~60 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b4cc35fbb709bd6fcae8998f041fd731c9acbf42;p=postgresql Tighten coding for non-composite case in plperl's return_next. Coverity complained about this code's practice of using scalar variables as single-element arrays. While that's really just nitpicking, it probably is more readable to declare them as arrays, so let's do that. A more important point is that the code was just blithely assuming that the result tupledesc has exactly one column; if it doesn't, we'd likely get a crash of some sort in tuplestore_putvalues. Since the tupledesc is manufactured outside of plperl, that seems like an uncomfortably long chain of assumptions. We can nail it down at little cost with a sanity check earlier in the function. --- diff --git a/src/pl/plperl/plperl.c b/src/pl/plperl/plperl.c index b10b4434aa..afebec910d 100644 --- a/src/pl/plperl/plperl.c +++ b/src/pl/plperl/plperl.c @@ -3247,12 +3247,18 @@ plperl_return_next_internal(SV *sv) /* * This is the first call to return_next in the current PL/Perl - * function call, so memoize some lookups + * function call, so identify the output tuple descriptor and create a + * tuplestore to hold the result rows. */ if (prodesc->fn_retistuple) (void) get_call_result_type(fcinfo, NULL, &tupdesc); else + { tupdesc = rsi->expectedDesc; + /* Protect assumption below that we return exactly one column */ + if (tupdesc == NULL || tupdesc->natts != 1) + elog(ERROR, "expected single-column result descriptor for non-composite SETOF result"); + } /* * Make sure the tuple_store and ret_tdesc are sufficiently @@ -3300,20 +3306,20 @@ plperl_return_next_internal(SV *sv) } else { - Datum ret; - bool isNull; + Datum ret[1]; + bool isNull[1]; - ret = plperl_sv_to_datum(sv, - prodesc->result_oid, - -1, - fcinfo, - &prodesc->result_in_func, - prodesc->result_typioparam, - &isNull); + ret[0] = plperl_sv_to_datum(sv, + prodesc->result_oid, + -1, + fcinfo, + &prodesc->result_in_func, + prodesc->result_typioparam, + &isNull[0]); tuplestore_putvalues(current_call_data->tuple_store, current_call_data->ret_tdesc, - &ret, &isNull); + ret, isNull); } MemoryContextSwitchTo(old_cxt);