diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2000-12-27 23:59:14 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2000-12-27 23:59:14 +0000 |
commit | 8609d4abf248f0eede4ed9505226da3f7e3e7c84 (patch) | |
tree | 39e5a813099835056d76dd385478069d01a8dcbf /src/backend/access/common/heaptuple.c | |
parent | 97799fc4757fd2699e0238254875994253659582 (diff) | |
download | postgresql-8609d4abf248f0eede4ed9505226da3f7e3e7c84.tar.gz postgresql-8609d4abf248f0eede4ed9505226da3f7e3e7c84.zip |
Fix portability problems recently exposed by regression tests on Alphas.
1. Distinguish cases where a Datum representing a tuple datatype is an OID
from cases where it is a pointer to TupleTableSlot, and make sure we use
the right typlen in each case.
2. Make fetchatt() and related code support 8-byte by-value datatypes on
machines where Datum is 8 bytes. Centralize knowledge of the available
by-value datatype sizes in two macros in tupmacs.h, so that this will be
easier if we ever have to do it again.
Diffstat (limited to 'src/backend/access/common/heaptuple.c')
-rw-r--r-- | src/backend/access/common/heaptuple.c | 234 |
1 files changed, 97 insertions, 137 deletions
diff --git a/src/backend/access/common/heaptuple.c b/src/backend/access/common/heaptuple.c index e76fa5a5652..6405320f85d 100644 --- a/src/backend/access/common/heaptuple.c +++ b/src/backend/access/common/heaptuple.c @@ -2,14 +2,14 @@ * * heaptuple.c * This file contains heap tuple accessor and mutator routines, as well - * as a few various tuple utilities. + * as various tuple utilities. * * Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1994, Regents of the University of California * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/common/heaptuple.c,v 1.67 2000/11/30 18:38:45 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/common/heaptuple.c,v 1.68 2000/12/27 23:59:10 tgl Exp $ * * NOTES * The old interface functions have been converted to macros @@ -23,16 +23,6 @@ #include "access/heapam.h" #include "catalog/pg_type.h" -/* Used by heap_getattr() macro, for speed */ -long heap_sysoffset[] = { -/* Only the first one is pass-by-ref, and is handled specially in the macro */ - offsetof(HeapTupleHeaderData, t_ctid), - offsetof(HeapTupleHeaderData, t_oid), - offsetof(HeapTupleHeaderData, t_xmin), - offsetof(HeapTupleHeaderData, t_cmin), - offsetof(HeapTupleHeaderData, t_xmax), - offsetof(HeapTupleHeaderData, t_cmax) -}; /* ---------------------------------------------------------------- * misc support routines @@ -48,12 +38,12 @@ ComputeDataSize(TupleDesc tupleDesc, Datum *value, char *nulls) { - uint32 data_length; + uint32 data_length = 0; int i; int numberOfAttributes = tupleDesc->natts; Form_pg_attribute *att = tupleDesc->attrs; - for (data_length = 0, i = 0; i < numberOfAttributes; i++) + for (i = 0; i < numberOfAttributes; i++) { if (nulls[i] != ' ') continue; @@ -114,38 +104,33 @@ DataFill(char *data, *bitP |= bitmask; } + /* XXX we are aligning the pointer itself, not the offset */ data = (char *) att_align((long) data, att[i]->attlen, att[i]->attalign); - switch (att[i]->attlen) + + if (att[i]->attbyval) { - case -1: - *infomask |= HEAP_HASVARLENA; - if (VARATT_IS_EXTERNAL(value[i])) - *infomask |= HEAP_HASEXTERNAL; - if (VARATT_IS_COMPRESSED(value[i])) - *infomask |= HEAP_HASCOMPRESSED; - data_length = VARATT_SIZE(DatumGetPointer(value[i])); - memmove(data, DatumGetPointer(value[i]), data_length); - break; - case sizeof(char): - *data = att[i]->attbyval ? - DatumGetChar(value[i]) : *((char *) value[i]); - break; - case sizeof(int16): - *(short *) data = (att[i]->attbyval ? - DatumGetInt16(value[i]) : - *((short *) value[i])); - break; - case sizeof(int32): - *(int32 *) data = (att[i]->attbyval ? - DatumGetInt32(value[i]) : - *((int32 *) value[i])); - break; - default: - Assert(att[i]->attlen >= 0); - memmove(data, DatumGetPointer(value[i]), - (size_t) (att[i]->attlen)); - break; + /* pass-by-value */ + store_att_byval(data, value[i], att[i]->attlen); + } + else if (att[i]->attlen == -1) + { + /* varlena */ + *infomask |= HEAP_HASVARLENA; + if (VARATT_IS_EXTERNAL(value[i])) + *infomask |= HEAP_HASEXTERNAL; + if (VARATT_IS_COMPRESSED(value[i])) + *infomask |= HEAP_HASCOMPRESSED; + data_length = VARATT_SIZE(DatumGetPointer(value[i])); + memcpy(data, DatumGetPointer(value[i]), data_length); + } + else + { + /* fixed-length pass-by-reference */ + Assert(att[i]->attlen >= 0); + memcpy(data, DatumGetPointer(value[i]), + (size_t) (att[i]->attlen)); } + data = (char *) att_addlength((long) data, att[i]->attlen, value[i]); } } @@ -192,89 +177,6 @@ heap_attisnull(HeapTuple tup, int attnum) return 0; } -/* ---------------------------------------------------------------- - * system attribute heap tuple support - * ---------------------------------------------------------------- - */ - -/* ---------------- - * heap_sysattrlen - * - * This routine returns the length of a system attribute. - * ---------------- - */ -int -heap_sysattrlen(AttrNumber attno) -{ - HeapTupleHeader f = NULL; - - switch (attno) - { - case TableOidAttributeNumber: - return sizeof f->t_oid; - case SelfItemPointerAttributeNumber: - return sizeof f->t_ctid; - case ObjectIdAttributeNumber: - return sizeof f->t_oid; - case MinTransactionIdAttributeNumber: - return sizeof f->t_xmin; - case MinCommandIdAttributeNumber: - return sizeof f->t_cmin; - case MaxTransactionIdAttributeNumber: - return sizeof f->t_xmax; - case MaxCommandIdAttributeNumber: - return sizeof f->t_cmax; - - default: - elog(ERROR, "sysattrlen: System attribute number %d unknown.", attno); - return 0; - } -} - -/* ---------------- - * heap_sysattrbyval - * - * This routine returns the "by-value" property of a system attribute. - * ---------------- - */ -bool -heap_sysattrbyval(AttrNumber attno) -{ - bool byval; - - switch (attno) - { - case TableOidAttributeNumber: - byval = true; - break; - case SelfItemPointerAttributeNumber: - byval = false; - break; - case ObjectIdAttributeNumber: - byval = true; - break; - case MinTransactionIdAttributeNumber: - byval = true; - break; - case MinCommandIdAttributeNumber: - byval = true; - break; - case MaxTransactionIdAttributeNumber: - byval = true; - break; - case MaxCommandIdAttributeNumber: - byval = true; - break; - default: - byval = true; - elog(ERROR, "sysattrbyval: System attribute number %d unknown.", - attno); - break; - } - - return byval; -} - /* ---------------- * nocachegetattr * @@ -332,8 +234,7 @@ nocachegetattr(HeapTuple tuple, /* This is handled in the macro */ if (att[attnum]->attcacheoff != -1) { - return (Datum) - fetchatt(&(att[attnum]), + return fetchatt(att[attnum], (char *) tup + tup->t_hoff + att[attnum]->attcacheoff); } #endif @@ -397,8 +298,8 @@ nocachegetattr(HeapTuple tuple, { if (att[attnum]->attcacheoff != -1) { - return (Datum) fetchatt(&(att[attnum]), - tp + att[attnum]->attcacheoff); + return fetchatt(att[attnum], + tp + att[attnum]->attcacheoff); } else if (!HeapTupleAllFixed(tuple)) { @@ -460,7 +361,7 @@ nocachegetattr(HeapTuple tuple, off = att_addlength(off, att[j]->attlen, tp + off); } - return (Datum) fetchatt(&(att[attnum]), tp + att[attnum]->attcacheoff); + return fetchatt(att[attnum], tp + att[attnum]->attcacheoff); } else { @@ -508,11 +409,67 @@ nocachegetattr(HeapTuple tuple, off = att_align(off, att[attnum]->attlen, att[attnum]->attalign); - return (Datum) fetchatt(&(att[attnum]), tp + off); + return fetchatt(att[attnum], tp + off); } } /* ---------------- + * heap_getsysattr + * + * Fetch the value of a system attribute for a tuple. + * + * This is a support routine for the heap_getattr macro. The macro + * has already determined that the attnum refers to a system attribute. + * ---------------- + */ +Datum +heap_getsysattr(HeapTuple tup, int attnum, bool *isnull) +{ + Datum result; + + Assert(tup); + + /* Currently, no sys attribute ever reads as NULL. */ + if (isnull) + *isnull = false; + + switch (attnum) + { + case SelfItemPointerAttributeNumber: + /* pass-by-reference datatype */ + result = PointerGetDatum(&(tup->t_self)); + break; + case ObjectIdAttributeNumber: + result = ObjectIdGetDatum(tup->t_data->t_oid); + break; + case MinTransactionIdAttributeNumber: + /* XXX should have a TransactionIdGetDatum macro */ + result = (Datum) (tup->t_data->t_xmin); + break; + case MinCommandIdAttributeNumber: + /* XXX should have a CommandIdGetDatum macro */ + result = (Datum) (tup->t_data->t_cmin); + break; + case MaxTransactionIdAttributeNumber: + /* XXX should have a TransactionIdGetDatum macro */ + result = (Datum) (tup->t_data->t_xmax); + break; + case MaxCommandIdAttributeNumber: + /* XXX should have a CommandIdGetDatum macro */ + result = (Datum) (tup->t_data->t_cmax); + break; + case TableOidAttributeNumber: + result = ObjectIdGetDatum(tup->t_tableOid); + break; + default: + elog(ERROR, "heap_getsysattr: invalid attnum %d", attnum); + result = 0; /* keep compiler quiet */ + break; + } + return result; +} + +/* ---------------- * heap_copytuple * * returns a copy of an entire tuple @@ -630,18 +587,21 @@ heap_formtuple(TupleDesc tupleDescriptor, int i; int numberOfAttributes = tupleDescriptor->natts; + if (numberOfAttributes > MaxHeapAttributeNumber) + elog(ERROR, "heap_formtuple: numberOfAttributes of %d > %d", + numberOfAttributes, MaxHeapAttributeNumber); + len = offsetof(HeapTupleHeaderData, t_bits); - for (i = 0; i < numberOfAttributes && !hasnull; i++) + for (i = 0; i < numberOfAttributes; i++) { if (nulls[i] != ' ') + { hasnull = true; + break; + } } - if (numberOfAttributes > MaxHeapAttributeNumber) - elog(ERROR, "heap_formtuple: numberOfAttributes of %d > %d", - numberOfAttributes, MaxHeapAttributeNumber); - if (hasnull) { bitmaplen = BITMAPLEN(numberOfAttributes); |