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

Function exec_move_row_from_datum

src/pl/plpgsql/src/pl_exec.c:7350–7575  ·  view source on GitHub ↗

* exec_move_row_from_datum Move a composite Datum into a record or row * * This is equivalent to deconstruct_composite_datum() followed by * exec_move_row(), but we can optimize things if the Datum is an * expanded-record reference. * * Note: it's caller's responsibility to be sure value is of composite type. */

Source from the content-addressed store, hash-verified

7348 * Note: it's caller's responsibility to be sure value is of composite type.
7349 */
7350static void
7351exec_move_row_from_datum(PLpgSQL_execstate *estate,
7352 PLpgSQL_variable *target,
7353 Datum value)
7354{
7355 /* Check to see if source is an expanded record */
7356 if (VARATT_IS_EXTERNAL_EXPANDED(DatumGetPointer(value)))
7357 {
7358 ExpandedRecordHeader *erh = (ExpandedRecordHeader *) DatumGetEOHP(value);
7359 ExpandedRecordHeader *newerh = NULL;
7360
7361 Assert(erh->er_magic == ER_MAGIC);
7362
7363 /* These cases apply if the target is record not row... */
7364 if (target->dtype == PLPGSQL_DTYPE_REC)
7365 {
7366 PLpgSQL_rec *rec = (PLpgSQL_rec *) target;
7367
7368 /*
7369 * If it's the same record already stored in the variable, do
7370 * nothing. This would happen only in silly cases like "r := r",
7371 * but we need some check to avoid possibly freeing the variable's
7372 * live value below. Note that this applies even if what we have
7373 * is a R/O pointer.
7374 */
7375 if (erh == rec->erh)
7376 return;
7377
7378 /*
7379 * Make sure rec->rectypeid is up-to-date before using it.
7380 */
7381 revalidate_rectypeid(rec);
7382
7383 /*
7384 * If we have a R/W pointer, we're allowed to just commandeer
7385 * ownership of the expanded record. If it's of the right type to
7386 * put into the record variable, do that. (Note we don't accept
7387 * an expanded record of a composite-domain type as a RECORD
7388 * value. We'll treat it as the base composite type instead;
7389 * compare logic in make_expanded_record_for_rec.)
7390 */
7391 if (VARATT_IS_EXTERNAL_EXPANDED_RW(DatumGetPointer(value)) &&
7392 (rec->rectypeid == erh->er_decltypeid ||
7393 (rec->rectypeid == RECORDOID &&
7394 !ExpandedRecordIsDomain(erh))))
7395 {
7396 assign_record_var(estate, rec, erh);
7397 return;
7398 }
7399
7400 /*
7401 * If we already have an expanded record object in the target
7402 * variable, and the source record contains a valid tuple
7403 * representation with the right rowtype, then we can skip making
7404 * a new expanded record and just assign the tuple with
7405 * expanded_record_set_tuple. (We can't do the equivalent if we
7406 * have to do field-by-field assignment, since that wouldn't be
7407 * atomic if there's an error.) We consider that there's a

Callers 2

plpgsql_exec_functionFunction · 0.85
exec_assign_valueFunction · 0.85

Calls 12

DatumGetEOHPFunction · 0.85
revalidate_rectypeidFunction · 0.85
assign_record_varFunction · 0.85
exec_move_rowFunction · 0.85
MemoryContextSwitchToFunction · 0.85
lookup_rowtype_tupdescFunction · 0.85

Tested by

no test coverage detected