MCPcopy Create free account
hub / github.com/apache/cloudberry / coerce_function_result_tuple

Function coerce_function_result_tuple

src/pl/plpgsql/src/pl_exec.c:794–897  ·  view source on GitHub ↗

* Helper for plpgsql_exec_function: coerce composite result to the specified * tuple descriptor, and copy it out to upper executor memory. This is split * out mostly for cosmetic reasons --- the logic would be very deeply nested * otherwise. * * estate->retval is updated in-place. */

Source from the content-addressed store, hash-verified

792 * estate->retval is updated in-place.
793 */
794static void
795coerce_function_result_tuple(PLpgSQL_execstate *estate, TupleDesc tupdesc)
796{
797 HeapTuple rettup;
798 TupleDesc retdesc;
799 TupleConversionMap *tupmap;
800
801 /* We assume exec_stmt_return verified that result is composite */
802 Assert(type_is_rowtype(estate->rettype));
803
804 /* We can special-case expanded records for speed */
805 if (VARATT_IS_EXTERNAL_EXPANDED(DatumGetPointer(estate->retval)))
806 {
807 ExpandedRecordHeader *erh = (ExpandedRecordHeader *) DatumGetEOHP(estate->retval);
808
809 Assert(erh->er_magic == ER_MAGIC);
810
811 /* Extract record's TupleDesc */
812 retdesc = expanded_record_get_tupdesc(erh);
813
814 /* check rowtype compatibility */
815 tupmap = convert_tuples_by_position(retdesc,
816 tupdesc,
817 gettext_noop("returned record type does not match expected record type"));
818
819 /* it might need conversion */
820 if (tupmap)
821 {
822 rettup = expanded_record_get_tuple(erh);
823 Assert(rettup);
824 rettup = execute_attr_map_tuple(rettup, tupmap);
825
826 /*
827 * Copy tuple to upper executor memory, as a tuple Datum. Make
828 * sure it is labeled with the caller-supplied tuple type.
829 */
830 estate->retval = PointerGetDatum(SPI_returntuple(rettup, tupdesc));
831 /* no need to free map, we're about to return anyway */
832 }
833 else if (!(tupdesc->tdtypeid == erh->er_decltypeid ||
834 (tupdesc->tdtypeid == RECORDOID &&
835 !ExpandedRecordIsDomain(erh))))
836 {
837 /*
838 * The expanded record has the right physical tupdesc, but the
839 * wrong type ID. (Typically, the expanded record is RECORDOID
840 * but the function is declared to return a named composite type.
841 * As in exec_move_row_from_datum, we don't allow returning a
842 * composite-domain record from a function declared to return
843 * RECORD.) So we must flatten the record to a tuple datum and
844 * overwrite its type fields with the right thing. spi.c doesn't
845 * provide any easy way to deal with this case, so we end up
846 * duplicating the guts of datumCopy() :-(
847 */
848 Size resultsize;
849 HeapTupleHeader tuphdr;
850
851 resultsize = EOH_get_flat_size(&erh->hdr);

Callers 1

plpgsql_exec_functionFunction · 0.85

Calls 12

type_is_rowtypeFunction · 0.85
DatumGetEOHPFunction · 0.85
execute_attr_map_tupleFunction · 0.85
SPI_returntupleFunction · 0.85
EOH_get_flat_sizeFunction · 0.85
SPI_pallocFunction · 0.85
EOH_flatten_intoFunction · 0.85
SPI_datumTransferFunction · 0.85

Tested by

no test coverage detected