diff options
author | Tom Lane | 2017-07-31 15:33:46 +0000 |
---|---|---|
committer | Tom Lane | 2017-07-31 15:33:46 +0000 |
commit | b4cc35fbb709bd6fcae8998f041fd731c9acbf42 (patch) | |
tree | 6156231828882029edda3172da6f02d83a3e440e | |
parent | d2a51e3efcbab5b288bbadba1a7dfa123a50ba5b (diff) |
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.
-rw-r--r-- | src/pl/plperl/plperl.c | 28 |
1 files changed, 17 insertions, 11 deletions
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); |