diff options
Diffstat (limited to 'src/backend/access/common/heaptuple.c')
-rw-r--r-- | src/backend/access/common/heaptuple.c | 80 |
1 files changed, 43 insertions, 37 deletions
diff --git a/src/backend/access/common/heaptuple.c b/src/backend/access/common/heaptuple.c index ac5749c713..38f770f92b 100644 --- a/src/backend/access/common/heaptuple.c +++ b/src/backend/access/common/heaptuple.c @@ -658,6 +658,41 @@ heap_copytuple_with_tuple(HeapTuple src, HeapTuple dest) memcpy((char *) dest->t_data, (char *) src->t_data, src->t_len); } +/* ---------------- + * heap_copy_tuple_as_datum + * + * copy a tuple as a composite-type Datum + * ---------------- + */ +Datum +heap_copy_tuple_as_datum(HeapTuple tuple, TupleDesc tupleDesc) +{ + HeapTupleHeader td; + + /* + * If the tuple contains any external TOAST pointers, we have to inline + * those fields to meet the conventions for composite-type Datums. + */ + if (HeapTupleHasExternal(tuple)) + return toast_flatten_tuple_to_datum(tuple->t_data, + tuple->t_len, + tupleDesc); + + /* + * Fast path for easy case: just make a palloc'd copy and insert the + * correct composite-Datum header fields (since those may not be set if + * the given tuple came from disk, rather than from heap_form_tuple). + */ + td = (HeapTupleHeader) palloc(tuple->t_len); + memcpy((char *) td, (char *) tuple->t_data, tuple->t_len); + + HeapTupleHeaderSetDatumLength(td, tuple->t_len); + HeapTupleHeaderSetTypeId(td, tupleDesc->tdtypeid); + HeapTupleHeaderSetTypMod(td, tupleDesc->tdtypmod); + + return PointerGetDatum(td); +} + /* * heap_form_tuple * construct a tuple from the given values[] and isnull[] arrays, @@ -676,7 +711,6 @@ heap_form_tuple(TupleDesc tupleDescriptor, data_len; int hoff; bool hasnull = false; - Form_pg_attribute *att = tupleDescriptor->attrs; int numberOfAttributes = tupleDescriptor->natts; int i; @@ -687,28 +721,14 @@ heap_form_tuple(TupleDesc tupleDescriptor, numberOfAttributes, MaxTupleAttributeNumber))); /* - * Check for nulls and embedded tuples; expand any toasted attributes in - * embedded tuples. This preserves the invariant that toasting can only - * go one level deep. - * - * We can skip calling toast_flatten_tuple_attribute() if the attribute - * couldn't possibly be of composite type. All composite datums are - * varlena and have alignment 'd'; furthermore they aren't arrays. Also, - * if an attribute is already toasted, it must have been sent to disk - * already and so cannot contain toasted attributes. + * Check for nulls */ for (i = 0; i < numberOfAttributes; i++) { if (isnull[i]) - hasnull = true; - else if (att[i]->attlen == -1 && - att[i]->attalign == 'd' && - att[i]->attndims == 0 && - !VARATT_IS_EXTENDED(DatumGetPointer(values[i]))) { - values[i] = toast_flatten_tuple_attribute(values[i], - att[i]->atttypid, - att[i]->atttypmod); + hasnull = true; + break; } } @@ -738,7 +758,8 @@ heap_form_tuple(TupleDesc tupleDescriptor, /* * And fill in the information. Note we fill the Datum fields even though - * this tuple may never become a Datum. + * this tuple may never become a Datum. This lets HeapTupleHeaderGetDatum + * identify the tuple type if needed. */ tuple->t_len = len; ItemPointerSetInvalid(&(tuple->t_self)); @@ -1428,7 +1449,6 @@ heap_form_minimal_tuple(TupleDesc tupleDescriptor, data_len; int hoff; bool hasnull = false; - Form_pg_attribute *att = tupleDescriptor->attrs; int numberOfAttributes = tupleDescriptor->natts; int i; @@ -1439,28 +1459,14 @@ heap_form_minimal_tuple(TupleDesc tupleDescriptor, numberOfAttributes, MaxTupleAttributeNumber))); /* - * Check for nulls and embedded tuples; expand any toasted attributes in - * embedded tuples. This preserves the invariant that toasting can only - * go one level deep. - * - * We can skip calling toast_flatten_tuple_attribute() if the attribute - * couldn't possibly be of composite type. All composite datums are - * varlena and have alignment 'd'; furthermore they aren't arrays. Also, - * if an attribute is already toasted, it must have been sent to disk - * already and so cannot contain toasted attributes. + * Check for nulls */ for (i = 0; i < numberOfAttributes; i++) { if (isnull[i]) - hasnull = true; - else if (att[i]->attlen == -1 && - att[i]->attalign == 'd' && - att[i]->attndims == 0 && - !VARATT_IS_EXTENDED(values[i])) { - values[i] = toast_flatten_tuple_attribute(values[i], - att[i]->atttypid, - att[i]->atttypmod); + hasnull = true; + break; } } |