summaryrefslogtreecommitdiff
path: root/src/include
diff options
context:
space:
mode:
Diffstat (limited to 'src/include')
-rw-r--r--src/include/access/heapam.h10
-rw-r--r--src/include/access/htup.h71
-rw-r--r--src/include/executor/tuptable.h25
-rw-r--r--src/include/utils/tuplestore.h24
4 files changed, 112 insertions, 18 deletions
diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h
index e016a527403..7301be4ae34 100644
--- a/src/include/access/heapam.h
+++ b/src/include/access/heapam.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/access/heapam.h,v 1.111 2006/05/10 23:18:39 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/access/heapam.h,v 1.112 2006/06/27 02:51:39 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -217,7 +217,13 @@ extern void heap_deform_tuple(HeapTuple tuple, TupleDesc tupleDesc,
Datum *values, bool *isnull);
extern void heap_deformtuple(HeapTuple tuple, TupleDesc tupleDesc,
Datum *values, char *nulls);
-extern void heap_freetuple(HeapTuple tuple);
+extern void heap_freetuple(HeapTuple htup);
+extern MinimalTuple heap_form_minimal_tuple(TupleDesc tupleDescriptor,
+ Datum *values, bool *isnull);
+extern void heap_free_minimal_tuple(MinimalTuple mtup);
+extern MinimalTuple heap_copy_minimal_tuple(MinimalTuple mtup);
+extern HeapTuple heap_tuple_from_minimal_tuple(MinimalTuple mtup);
+extern MinimalTuple minimal_tuple_from_heap_tuple(HeapTuple htup);
extern HeapTuple heap_addheader(int natts, bool withoid,
Size structlen, void *structure);
diff --git a/src/include/access/htup.h b/src/include/access/htup.h
index 57db9f84934..170ad657fb7 100644
--- a/src/include/access/htup.h
+++ b/src/include/access/htup.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/access/htup.h,v 1.82 2006/05/10 23:18:39 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/access/htup.h,v 1.83 2006/06/27 02:51:39 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -31,7 +31,7 @@
*/
#define MaxTupleAttributeNumber 1664 /* 8 * 208 */
-/*----------
+/*
* MaxHeapAttributeNumber limits the number of (user) columns in a table.
* This should be somewhat less than MaxTupleAttributeNumber. It must be
* at least one less, else we will fail to do UPDATEs on a maximal-width
@@ -42,11 +42,10 @@
* In any case, depending on column data types you will likely be running
* into the disk-block-based limit on overall tuple size if you have more
* than a thousand or so columns. TOAST won't help.
- *----------
*/
#define MaxHeapAttributeNumber 1600 /* 8 * 200 */
-/*----------
+/*
* Heap tuple header. To avoid wasting space, the fields should be
* layed out in such a way to avoid structure padding.
*
@@ -101,7 +100,6 @@
* t_infomask), then it is stored just before the user data, which begins at
* the offset shown by t_hoff. Note that t_hoff must be a multiple of
* MAXALIGN.
- *----------
*/
typedef struct HeapTupleFields
@@ -141,6 +139,8 @@ typedef struct HeapTupleHeaderData
ItemPointerData t_ctid; /* current TID of this or newer tuple */
+ /* Fields below here must match MinimalTupleData! */
+
int16 t_natts; /* number of attributes */
uint16 t_infomask; /* various flag bits, see below */
@@ -355,6 +355,62 @@ do { \
/*
+ * MinimalTuple is an alternate representation that is used for transient
+ * tuples inside the executor, in places where transaction status information
+ * is not required, the tuple rowtype is known, and shaving off a few bytes
+ * is worthwhile because we need to store many tuples. The representation
+ * is chosen so that tuple access routines can work with either full or
+ * minimal tuples via a HeapTupleData pointer structure. The access routines
+ * see no difference, except that they must not access the transaction status
+ * or t_ctid fields because those aren't there.
+ *
+ * For the most part, MinimalTuples should be accessed via TupleTableSlot
+ * routines. These routines will prevent access to the "system columns"
+ * and thereby prevent accidental use of the nonexistent fields.
+ *
+ * MinimalTupleData contains a length word, some padding, and fields matching
+ * HeapTupleHeaderData beginning with t_natts. The padding is chosen so that
+ * offsetof(t_natts) is the same modulo MAXIMUM_ALIGNOF in both structs.
+ * This makes data alignment rules equivalent in both cases.
+ *
+ * When a minimal tuple is accessed via a HeapTupleData pointer, t_data is
+ * set to point MINIMAL_TUPLE_OFFSET bytes before the actual start of the
+ * minimal tuple --- that is, where a full tuple matching the minimal tuple's
+ * data would start. This trick is what makes the structs seem equivalent.
+ *
+ * Note that t_hoff is computed the same as in a full tuple, hence it includes
+ * the MINIMAL_TUPLE_OFFSET distance. t_len does not include that, however.
+ */
+#define MINIMAL_TUPLE_OFFSET \
+ ((offsetof(HeapTupleHeaderData, t_natts) - sizeof(uint32)) / MAXIMUM_ALIGNOF * MAXIMUM_ALIGNOF)
+#define MINIMAL_TUPLE_PADDING \
+ ((offsetof(HeapTupleHeaderData, t_natts) - sizeof(uint32)) % MAXIMUM_ALIGNOF)
+
+typedef struct MinimalTupleData
+{
+ uint32 t_len; /* actual length of minimal tuple */
+
+ char mt_padding[MINIMAL_TUPLE_PADDING];
+
+ /* Fields below here must match HeapTupleHeaderData! */
+
+ int16 t_natts; /* number of attributes */
+
+ uint16 t_infomask; /* various flag bits, see below */
+
+ uint8 t_hoff; /* sizeof header incl. bitmap, padding */
+
+ /* ^ - 27 bytes - ^ */
+
+ bits8 t_bits[1]; /* bitmap of NULLs -- VARIABLE LENGTH */
+
+ /* MORE DATA FOLLOWS AT END OF STRUCT */
+} MinimalTupleData;
+
+typedef MinimalTupleData *MinimalTuple;
+
+
+/*
* HeapTupleData is an in-memory data structure that points to a tuple.
*
* There are several ways in which this data structure is used:
@@ -376,6 +432,11 @@ do { \
* it's difficult to tell apart from case #1. It should be used only in
* limited contexts where the code knows that case #1 will never apply.)
*
+ * * Separately allocated minimal tuple: t_data points MINIMAL_TUPLE_OFFSET
+ * bytes before the start of a MinimalTuple. As with the previous case,
+ * this can't be told apart from case #1 by inspection; code setting up
+ * or destroying this representation has to know what it's doing.
+ *
* t_len should always be valid, except in the pointer-to-nothing case.
* t_self and t_tableOid should be valid if the HeapTupleData points to
* a disk buffer, or if it represents a copy of a tuple on disk. They
diff --git a/src/include/executor/tuptable.h b/src/include/executor/tuptable.h
index b506651fbbd..85318351340 100644
--- a/src/include/executor/tuptable.h
+++ b/src/include/executor/tuptable.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/executor/tuptable.h,v 1.31 2006/06/16 18:42:23 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/executor/tuptable.h,v 1.32 2006/06/27 02:51:40 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -23,7 +23,8 @@
* independent TupleTableSlots. There are several cases we need to handle:
* 1. physical tuple in a disk buffer page
* 2. physical tuple constructed in palloc'ed memory
- * 3. "virtual" tuple consisting of Datum/isnull arrays
+ * 3. "minimal" physical tuple constructed in palloc'ed memory
+ * 4. "virtual" tuple consisting of Datum/isnull arrays
*
* The first two cases are similar in that they both deal with "materialized"
* tuples, but resource management is different. For a tuple in a disk page
@@ -31,6 +32,11 @@
* to the tuple is dropped; while for a palloc'd tuple we usually want the
* tuple pfree'd when the TupleTableSlot's reference is dropped.
*
+ * A "minimal" tuple is handled similarly to a palloc'd regular tuple.
+ * At present, minimal tuples never are stored in buffers, so there is no
+ * parallel to case 1. Note that a minimal tuple has no "system columns".
+ * (Actually, it could have an OID, but we have no need to access the OID.)
+ *
* A "virtual" tuple is an optimization used to minimize physical data
* copying in a nest of plan nodes. Any pass-by-reference Datums in the
* tuple point to storage that is not directly associated with the
@@ -83,6 +89,15 @@
* tts_values/tts_isnull are allocated when a descriptor is assigned to the
* slot; they are of length equal to the descriptor's natts.
*
+ * tts_mintuple must always be NULL if the slot does not hold a "minimal"
+ * tuple. When it does, tts_mintuple points to the actual MinimalTupleData
+ * object (the thing to be pfree'd if tts_shouldFree is true). In this case
+ * tts_tuple points at tts_minhdr and the fields of that are set correctly
+ * for access to the minimal tuple; in particular, tts_minhdr.t_data points
+ * MINIMAL_TUPLE_OFFSET bytes before tts_mintuple. (tts_mintuple is therefore
+ * redundant, but for code simplicity we store it explicitly anyway.) This
+ * case otherwise behaves identically to the regular-physical-tuple case.
+ *
* tts_slow/tts_off are saved state for slot_deform_tuple, and should not
* be touched by any other code.
*----------
@@ -100,6 +115,8 @@ typedef struct TupleTableSlot
int tts_nvalid; /* # of valid values in tts_values */
Datum *tts_values; /* current per-attribute values */
bool *tts_isnull; /* current per-attribute isnull flags */
+ MinimalTuple tts_mintuple; /* set if it's a minimal tuple, else NULL */
+ HeapTupleData tts_minhdr; /* workspace if it's a minimal tuple */
long tts_off; /* saved state for slot_deform_tuple */
} TupleTableSlot;
@@ -133,10 +150,14 @@ extern TupleTableSlot *ExecStoreTuple(HeapTuple tuple,
TupleTableSlot *slot,
Buffer buffer,
bool shouldFree);
+extern TupleTableSlot *ExecStoreMinimalTuple(MinimalTuple mtup,
+ TupleTableSlot *slot,
+ bool shouldFree);
extern TupleTableSlot *ExecClearTuple(TupleTableSlot *slot);
extern TupleTableSlot *ExecStoreVirtualTuple(TupleTableSlot *slot);
extern TupleTableSlot *ExecStoreAllNullTuple(TupleTableSlot *slot);
extern HeapTuple ExecCopySlotTuple(TupleTableSlot *slot);
+extern MinimalTuple ExecCopySlotMinimalTuple(TupleTableSlot *slot);
extern HeapTuple ExecFetchSlotTuple(TupleTableSlot *slot);
extern HeapTuple ExecMaterializeSlot(TupleTableSlot *slot);
extern TupleTableSlot *ExecCopySlot(TupleTableSlot *dstslot,
diff --git a/src/include/utils/tuplestore.h b/src/include/utils/tuplestore.h
index a671bf438ff..62279344144 100644
--- a/src/include/utils/tuplestore.h
+++ b/src/include/utils/tuplestore.h
@@ -14,17 +14,23 @@
* A temporary file is used to handle the data if it exceeds the
* space limit specified by the caller.
*
+ * Beginning in Postgres 8.2, what is stored is just MinimalTuples;
+ * callers cannot expect valid system columns in regurgitated tuples.
+ * Also, we have changed the API to return tuples in TupleTableSlots,
+ * so that there is a check to prevent attempted access to system columns.
+ *
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/utils/tuplestore.h,v 1.17 2006/03/05 15:59:08 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/utils/tuplestore.h,v 1.18 2006/06/27 02:51:40 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef TUPLESTORE_H
#define TUPLESTORE_H
-#include "access/htup.h"
+#include "executor/tuptable.h"
+
/* Tuplestorestate is an opaque type whose details are not known outside
* tuplestore.c.
@@ -32,7 +38,7 @@
typedef struct Tuplestorestate Tuplestorestate;
/*
- * Currently we only need to store HeapTuples, but it would be easy
+ * Currently we only need to store MinimalTuples, but it would be easy
* to support the same behavior for IndexTuples and/or bare Datums.
*/
@@ -40,17 +46,17 @@ extern Tuplestorestate *tuplestore_begin_heap(bool randomAccess,
bool interXact,
int maxKBytes);
-extern void tuplestore_puttuple(Tuplestorestate *state, void *tuple);
+extern void tuplestore_puttupleslot(Tuplestorestate *state,
+ TupleTableSlot *slot);
+extern void tuplestore_puttuple(Tuplestorestate *state, HeapTuple tuple);
/* tuplestore_donestoring() used to be required, but is no longer used */
#define tuplestore_donestoring(state) ((void) 0)
/* backwards scan is only allowed if randomAccess was specified 'true' */
-extern void *tuplestore_gettuple(Tuplestorestate *state, bool forward,
- bool *should_free);
-
-#define tuplestore_getheaptuple(state, forward, should_free) \
- ((HeapTuple) tuplestore_gettuple(state, forward, should_free))
+extern bool tuplestore_gettupleslot(Tuplestorestate *state, bool forward,
+ TupleTableSlot *slot);
+extern bool tuplestore_advance(Tuplestorestate *state, bool forward);
extern void tuplestore_end(Tuplestorestate *state);