Commit b4cc35fb authored by Tom Lane's avatar Tom Lane

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.
parent d2a51e3e
...@@ -3247,12 +3247,18 @@ plperl_return_next_internal(SV *sv) ...@@ -3247,12 +3247,18 @@ plperl_return_next_internal(SV *sv)
/* /*
* This is the first call to return_next in the current PL/Perl * 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) if (prodesc->fn_retistuple)
(void) get_call_result_type(fcinfo, NULL, &tupdesc); (void) get_call_result_type(fcinfo, NULL, &tupdesc);
else else
{
tupdesc = rsi->expectedDesc; 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 * Make sure the tuple_store and ret_tdesc are sufficiently
...@@ -3300,20 +3306,20 @@ plperl_return_next_internal(SV *sv) ...@@ -3300,20 +3306,20 @@ plperl_return_next_internal(SV *sv)
} }
else else
{ {
Datum ret; Datum ret[1];
bool isNull; bool isNull[1];
ret = plperl_sv_to_datum(sv, ret[0] = plperl_sv_to_datum(sv,
prodesc->result_oid, prodesc->result_oid,
-1, -1,
fcinfo, fcinfo,
&prodesc->result_in_func, &prodesc->result_in_func,
prodesc->result_typioparam, prodesc->result_typioparam,
&isNull); &isNull[0]);
tuplestore_putvalues(current_call_data->tuple_store, tuplestore_putvalues(current_call_data->tuple_store,
current_call_data->ret_tdesc, current_call_data->ret_tdesc,
&ret, &isNull); ret, isNull);
} }
MemoryContextSwitchTo(old_cxt); MemoryContextSwitchTo(old_cxt);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment