aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor/execTuples.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/executor/execTuples.c')
-rw-r--r--src/backend/executor/execTuples.c61
1 files changed, 43 insertions, 18 deletions
diff --git a/src/backend/executor/execTuples.c b/src/backend/executor/execTuples.c
index 0bb59d26b11..faf910b736f 100644
--- a/src/backend/executor/execTuples.c
+++ b/src/backend/executor/execTuples.c
@@ -15,7 +15,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/executor/execTuples.c,v 1.75 2004/01/07 18:56:26 neilc Exp $
+ * $PostgreSQL: pgsql/src/backend/executor/execTuples.c,v 1.76 2004/04/01 21:28:44 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -109,8 +109,11 @@
#include "funcapi.h"
#include "access/heapam.h"
+#include "catalog/pg_type.h"
#include "executor/executor.h"
#include "utils/lsyscache.h"
+#include "utils/typcache.h"
+
static TupleDesc ExecTypeFromTLInternal(List *targetList,
bool hasoid, bool skipjunk);
@@ -144,16 +147,11 @@ ExecCreateTupleTable(int initialSize) /* initial number of slots in
/*
* Now allocate our new table along with space for the pointers to the
- * tuples.
+ * tuples. Zero out the slots.
*/
newtable = (TupleTable) palloc(sizeof(TupleTableData));
- array = (TupleTableSlot *) palloc(initialSize * sizeof(TupleTableSlot));
-
- /*
- * clean out the slots we just allocated
- */
- MemSet(array, 0, initialSize * sizeof(TupleTableSlot));
+ array = (TupleTableSlot *) palloc0(initialSize * sizeof(TupleTableSlot));
/*
* initialize the new table and return it to the caller.
@@ -514,6 +512,10 @@ TupleTableSlot *
ExecInitNullTupleSlot(EState *estate, TupleDesc tupType)
{
TupleTableSlot *slot = ExecInitExtraTupleSlot(estate);
+ struct tupleDesc nullTupleDesc;
+ HeapTuple nullTuple;
+ Datum values[1];
+ char nulls[1];
/*
* Since heap_getattr() will treat attributes beyond a tuple's t_natts
@@ -521,15 +523,12 @@ ExecInitNullTupleSlot(EState *estate, TupleDesc tupType)
* of zero length. However, the slot descriptor must match the real
* tupType.
*/
- HeapTuple nullTuple;
- Datum values[1];
- char nulls[1];
- static struct tupleDesc NullTupleDesc; /* we assume this inits to
- * zeroes */
+ nullTupleDesc = *tupType;
+ nullTupleDesc.natts = 0;
- ExecSetSlotDescriptor(slot, tupType, false);
+ nullTuple = heap_formtuple(&nullTupleDesc, values, nulls);
- nullTuple = heap_formtuple(&NullTupleDesc, values, nulls);
+ ExecSetSlotDescriptor(slot, tupType, false);
return ExecStoreTuple(nullTuple, slot, InvalidBuffer, true);
}
@@ -590,21 +589,45 @@ ExecTypeFromTLInternal(List *targetList, bool hasoid, bool skipjunk)
resdom->resname,
resdom->restype,
resdom->restypmod,
- 0,
- false);
+ 0);
}
return typeInfo;
}
/*
+ * BlessTupleDesc - make a completed tuple descriptor useful for SRFs
+ *
+ * Rowtype Datums returned by a function must contain valid type information.
+ * This happens "for free" if the tupdesc came from a relcache entry, but
+ * not if we have manufactured a tupdesc for a transient RECORD datatype.
+ * In that case we have to notify typcache.c of the existence of the type.
+ */
+TupleDesc
+BlessTupleDesc(TupleDesc tupdesc)
+{
+ if (tupdesc->tdtypeid == RECORDOID &&
+ tupdesc->tdtypmod < 0)
+ assign_record_type_typmod(tupdesc);
+
+ return tupdesc; /* just for notational convenience */
+}
+
+/*
* TupleDescGetSlot - Initialize a slot based on the supplied tupledesc
+ *
+ * Note: this is obsolete; it is sufficient to call BlessTupleDesc on
+ * the tupdesc. We keep it around just for backwards compatibility with
+ * existing user-written SRFs.
*/
TupleTableSlot *
TupleDescGetSlot(TupleDesc tupdesc)
{
TupleTableSlot *slot;
+ /* The useful work is here */
+ BlessTupleDesc(tupdesc);
+
/* Make a standalone slot */
slot = MakeTupleTableSlot();
@@ -634,6 +657,9 @@ TupleDescGetAttInMetadata(TupleDesc tupdesc)
attinmeta = (AttInMetadata *) palloc(sizeof(AttInMetadata));
+ /* "Bless" the tupledesc so that we can make rowtype datums with it */
+ attinmeta->tupdesc = BlessTupleDesc(tupdesc);
+
/*
* Gather info needed later to call the "in" function for each
* attribute
@@ -653,7 +679,6 @@ TupleDescGetAttInMetadata(TupleDesc tupdesc)
atttypmods[i] = tupdesc->attrs[i]->atttypmod;
}
}
- attinmeta->tupdesc = tupdesc;
attinmeta->attinfuncs = attinfuncinfo;
attinmeta->attelems = attelems;
attinmeta->atttypmods = atttypmods;