diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2005-02-06 20:15:32 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2005-02-06 20:15:32 +0000 |
commit | 5bb38455e68f78906a703476ae1067b840188a25 (patch) | |
tree | 364bf588537441959a59e01c2d10fe54073772bb | |
parent | 6508888ded311c4c39b28c49d2d160bafc956877 (diff) | |
download | postgresql-5bb38455e68f78906a703476ae1067b840188a25.tar.gz |
Back-port heap_deformtuple() into 7.4 branch; needed for planned fix for
CLUSTER failure after ALTER TABLE SET WITHOUT OIDS.
-rw-r--r-- | src/backend/access/common/heaptuple.c | 124 | ||||
-rw-r--r-- | src/include/access/heapam.h | 4 |
2 files changed, 91 insertions, 37 deletions
diff --git a/src/backend/access/common/heaptuple.c b/src/backend/access/common/heaptuple.c index dad99b0059..cd4e853fa6 100644 --- a/src/backend/access/common/heaptuple.c +++ b/src/backend/access/common/heaptuple.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/common/heaptuple.c,v 1.87 2003/09/25 06:57:56 petere Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/common/heaptuple.c,v 1.87.2.1 2005/02/06 20:15:32 tgl Exp $ * * NOTES * The old interface functions have been converted to macros @@ -512,41 +512,6 @@ heap_copytuple_with_tuple(HeapTuple src, HeapTuple dest) memcpy((char *) dest->t_data, (char *) src->t_data, src->t_len); } -#ifdef NOT_USED -/* ---------------- - * heap_deformtuple - * - * the inverse of heap_formtuple (see below) - * ---------------- - */ -void -heap_deformtuple(HeapTuple tuple, - TupleDesc tdesc, - Datum *values, - char *nulls) -{ - int i; - int natts; - - Assert(HeapTupleIsValid(tuple)); - - natts = tuple->t_natts; - for (i = 0; i < natts; i++) - { - bool isnull; - - values[i] = heap_getattr(tuple, - i + 1, - tdesc, - &isnull); - if (isnull) - nulls[i] = 'n'; - else - nulls[i] = ' '; - } -} -#endif - /* ---------------- * heap_formtuple * @@ -712,6 +677,93 @@ heap_modifytuple(HeapTuple tuple, return newTuple; } +/* ---------------- + * heap_deformtuple + * + * Given a tuple, extract data into values/nulls arrays; this is + * the inverse of heap_formtuple. + * + * Storage for the values/nulls arrays is provided by the caller; + * it should be sized according to tupleDesc->natts not tuple->t_natts. + * + * Note that for pass-by-reference datatypes, the pointer placed + * in the Datum will point into the given tuple. + * + * When all or most of a tuple's fields need to be extracted, + * this routine will be significantly quicker than a loop around + * heap_getattr; the loop will become O(N^2) as soon as any + * noncacheable attribute offsets are involved. + * ---------------- + */ +void +heap_deformtuple(HeapTuple tuple, + TupleDesc tupleDesc, + Datum *values, + char *nulls) +{ + HeapTupleHeader tup = tuple->t_data; + Form_pg_attribute *att = tupleDesc->attrs; + int tdesc_natts = tupleDesc->natts; + int natts; /* number of atts to extract */ + int attnum; + char *tp; /* ptr to tuple data */ + long off; /* offset in tuple data */ + bits8 *bp = tup->t_bits; /* ptr to null bitmask in tuple */ + bool slow = false; /* can we use/set attcacheoff? */ + + natts = tup->t_natts; + + /* + * In inheritance situations, it is possible that the given tuple + * actually has more fields than the caller is expecting. Don't run + * off the end of the caller's arrays. + */ + natts = Min(natts, tdesc_natts); + + tp = (char *) tup + tup->t_hoff; + + off = 0; + + for (attnum = 0; attnum < natts; attnum++) + { + if (!HeapTupleNoNulls(tuple) && att_isnull(attnum, bp)) + { + values[attnum] = (Datum) 0; + nulls[attnum] = 'n'; + slow = true; /* can't use attcacheoff anymore */ + continue; + } + + nulls[attnum] = ' '; + + if (!slow && att[attnum]->attcacheoff >= 0) + off = att[attnum]->attcacheoff; + else + { + off = att_align(off, att[attnum]->attalign); + + if (!slow) + att[attnum]->attcacheoff = off; + } + + values[attnum] = fetchatt(att[attnum], tp + off); + + off = att_addlength(off, att[attnum]->attlen, tp + off); + + if (att[attnum]->attlen <= 0) + slow = true; /* can't use attcacheoff anymore */ + } + + /* + * If tuple doesn't have all the atts indicated by tupleDesc, read the + * rest as null + */ + for (; attnum < tdesc_natts; attnum++) + { + values[attnum] = (Datum) 0; + nulls[attnum] = 'n'; + } +} /* ---------------- * heap_freetuple diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index ed46894d3a..2df812ef00 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: heapam.h,v 1.85 2003/10/01 21:30:52 tgl Exp $ + * $Id: heapam.h,v 1.85.2.1 2005/02/06 20:15:29 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -192,6 +192,8 @@ extern HeapTuple heap_formtuple(TupleDesc tupleDescriptor, Datum *value, char *nulls); extern HeapTuple heap_modifytuple(HeapTuple tuple, Relation relation, Datum *replValue, char *replNull, char *repl); +extern void heap_deformtuple(HeapTuple tuple, TupleDesc tupleDesc, + Datum *values, char *nulls); extern void heap_freetuple(HeapTuple tuple); extern HeapTuple heap_addheader(int natts, bool withoid, Size structlen, void *structure); |