0

As far as I understand, SPI_getbinval returns a pointer into the passed row. That is, the following would be unsafe:

dat = SPI_getbinval(SPI_tuptable->vals[0], SPI_tuptable->tupdesc, 1, &isnull);
SPI_finished();
if (isnull)
    PG_RETURN_NULL();
// Unsafe since SPI_finished() deallocates SPI_tuptable
return dat;

The SPI interface provides the utility SPI_copytuple. Is the following safe? Is there any problem with using SPI_tuptable->tupdesc? Moreover, is there a more efficient way to do this directly with the returned Datum instead of copying the entire HeapTuple?

// We copy the whole tuple into the outer context.  Better way to copy an individual Datum?
dat = SPI_getbinval(SPI_copytuple(SPI_tuptable->vals[0]), SPI_tuptable->tupdesc, 1, &isnull);
SPI_finished();
if (isnull)
  PG_RETURN_NULL();
return dat;
2
  • What is the data type of the Datum? Nov 15, 2021 at 4:03
  • Ideally, I'd like to just return Datum in the most generic way as there are many functions that require this. Nov 15, 2021 at 20:56

1 Answer 1

0

You should figure out the data type, then call datumCopy with the appropriate arguments:

/*-------------------------------------------------------------------------
 * datumCopy
 *
 * Make a copy of a non-NULL datum.
 *
 * If the datatype is pass-by-reference, memory is obtained with palloc().
 *
 * If the value is a reference to an expanded object, we flatten into memory
 * obtained with palloc().  We need to copy because one of the main uses of
 * this function is to copy a datum out of a transient memory context that's
 * about to be destroyed, and the expanded object is probably in a child
 * context that will also go away.  Moreover, many callers assume that the
 * result is a single pfree-able chunk.
 *-------------------------------------------------------------------------
 */

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.