mirror of
https://github.com/postgres/postgres.git
synced 2025-07-07 00:36:50 +03:00
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.
This commit is contained in:
@ -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)
|
|||||||
}
|
}
|
||||||
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);
|
||||||
|
Reference in New Issue
Block a user