aboutsummaryrefslogtreecommitdiff
path: root/src/backend/access/common/heaptuple.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/access/common/heaptuple.c')
-rw-r--r--src/backend/access/common/heaptuple.c74
1 files changed, 53 insertions, 21 deletions
diff --git a/src/backend/access/common/heaptuple.c b/src/backend/access/common/heaptuple.c
index f1b20ff2732..4355c0df4c7 100644
--- a/src/backend/access/common/heaptuple.c
+++ b/src/backend/access/common/heaptuple.c
@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/access/common/heaptuple.c,v 1.89 2004/01/16 20:51:30 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/access/common/heaptuple.c,v 1.90 2004/04/01 21:28:43 tgl Exp $
*
* NOTES
* The old interface functions have been converted to macros
@@ -31,6 +31,8 @@
/* ----------------
* ComputeDataSize
+ *
+ * Determine size of the data area of a tuple to be constructed
* ----------------
*/
Size
@@ -417,7 +419,7 @@ nocachegetattr(HeapTuple tuple,
* ----------------
*/
Datum
-heap_getsysattr(HeapTuple tup, int attnum, bool *isnull)
+heap_getsysattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
{
Datum result;
@@ -451,6 +453,31 @@ heap_getsysattr(HeapTuple tup, int attnum, bool *isnull)
case TableOidAttributeNumber:
result = ObjectIdGetDatum(tup->t_tableOid);
break;
+
+ /*
+ * If the attribute number is 0, then we are supposed to return
+ * the entire tuple as a row-type Datum. (Using zero for this
+ * purpose is unclean since it risks confusion with "invalid attr"
+ * result codes, but it's not worth changing now.)
+ *
+ * We have to make a copy of the tuple so we can safely insert the
+ * Datum overhead fields, which are not set in on-disk tuples.
+ */
+ case InvalidAttrNumber:
+ {
+ HeapTupleHeader dtup;
+
+ dtup = (HeapTupleHeader) palloc(tup->t_len);
+ memcpy((char *) dtup, (char *) tup->t_data, tup->t_len);
+
+ HeapTupleHeaderSetDatumLength(dtup, tup->t_len);
+ HeapTupleHeaderSetTypeId(dtup, tupleDesc->tdtypeid);
+ HeapTupleHeaderSetTypMod(dtup, tupleDesc->tdtypmod);
+
+ result = PointerGetDatum(dtup);
+ }
+ break;
+
default:
elog(ERROR, "invalid attnum: %d", attnum);
result = 0; /* keep compiler quiet */
@@ -547,19 +574,10 @@ heap_deformtuple(HeapTuple tuple,
/* ----------------
* heap_formtuple
*
- * constructs a tuple from the given *value and *null arrays
- *
- * old comments
- * Handles alignment by aligning 2 byte attributes on short boundries
- * and 3 or 4 byte attributes on long word boundries on a vax; and
- * aligning non-byte attributes on short boundries on a sun. Does
- * not properly align fixed length arrays of 1 or 2 byte types (yet).
+ * constructs a tuple from the given *value and *nulls arrays
*
* Null attributes are indicated by a 'n' in the appropriate byte
- * of the *null. Non-null attributes are indicated by a ' ' (space).
- *
- * Fix me. (Figure that must keep context if debug--allow give oid.)
- * Assumes in order.
+ * of *nulls. Non-null attributes are indicated by a ' ' (space).
* ----------------
*/
HeapTuple
@@ -581,6 +599,9 @@ heap_formtuple(TupleDesc tupleDescriptor,
errmsg("number of columns (%d) exceeds limit (%d)",
numberOfAttributes, MaxTupleAttributeNumber)));
+ /*
+ * Determine total space needed
+ */
for (i = 0; i < numberOfAttributes; i++)
{
if (nulls[i] != ' ')
@@ -602,15 +623,26 @@ heap_formtuple(TupleDesc tupleDescriptor,
len += ComputeDataSize(tupleDescriptor, value, nulls);
- tuple = (HeapTuple) palloc(HEAPTUPLESIZE + len);
+ /*
+ * Allocate and zero the space needed. Note that the tuple body and
+ * HeapTupleData management structure are allocated in one chunk.
+ */
+ tuple = (HeapTuple) palloc0(HEAPTUPLESIZE + len);
tuple->t_datamcxt = CurrentMemoryContext;
- td = tuple->t_data = (HeapTupleHeader) ((char *) tuple + HEAPTUPLESIZE);
-
- MemSet((char *) td, 0, len);
+ tuple->t_data = td = (HeapTupleHeader) ((char *) tuple + HEAPTUPLESIZE);
+ /*
+ * And fill in the information. Note we fill the Datum fields even
+ * though this tuple may never become a Datum.
+ */
tuple->t_len = len;
ItemPointerSetInvalid(&(tuple->t_self));
tuple->t_tableOid = InvalidOid;
+
+ HeapTupleHeaderSetDatumLength(td, len);
+ HeapTupleHeaderSetTypeId(td, tupleDescriptor->tdtypeid);
+ HeapTupleHeaderSetTypMod(td, tupleDescriptor->tdtypmod);
+
td->t_natts = numberOfAttributes;
td->t_hoff = hoff;
@@ -759,15 +791,15 @@ heap_addheader(int natts, /* max domain index */
hoff = MAXALIGN(hoff);
len = hoff + structlen;
- tuple = (HeapTuple) palloc(HEAPTUPLESIZE + len);
+ tuple = (HeapTuple) palloc0(HEAPTUPLESIZE + len);
+ tuple->t_datamcxt = CurrentMemoryContext;
+ tuple->t_data = td = (HeapTupleHeader) ((char *) tuple + HEAPTUPLESIZE);
tuple->t_len = len;
ItemPointerSetInvalid(&(tuple->t_self));
tuple->t_tableOid = InvalidOid;
- tuple->t_datamcxt = CurrentMemoryContext;
- tuple->t_data = td = (HeapTupleHeader) ((char *) tuple + HEAPTUPLESIZE);
- MemSet((char *) td, 0, hoff);
+ /* we don't bother to fill the Datum fields */
td->t_natts = natts;
td->t_hoff = hoff;