aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor/execJunk.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/executor/execJunk.c')
-rw-r--r--src/backend/executor/execJunk.c155
1 files changed, 64 insertions, 91 deletions
diff --git a/src/backend/executor/execJunk.c b/src/backend/executor/execJunk.c
index f747976acfa..2dfd90b51fa 100644
--- a/src/backend/executor/execJunk.c
+++ b/src/backend/executor/execJunk.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/executor/execJunk.c,v 1.47 2005/03/14 04:41:12 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/executor/execJunk.c,v 1.48 2005/03/16 21:38:06 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -42,10 +42,10 @@
* We then execute the plan ignoring the "resjunk" attributes.
*
* Finally, when at the top level we get back a tuple, we can call
- * 'ExecGetJunkAttribute' to retrieve the value of the junk attributes we
- * are interested in, and 'ExecRemoveJunk' to remove all the junk attributes
- * from a tuple. This new "clean" tuple is then printed, replaced, deleted
- * or inserted.
+ * ExecGetJunkAttribute to retrieve the value of the junk attributes we
+ * are interested in, and ExecFilterJunk or ExecRemoveJunk to remove all
+ * the junk attributes from a tuple. This new "clean" tuple is then printed,
+ * replaced, deleted or inserted.
*
*-------------------------------------------------------------------------
*/
@@ -76,6 +76,14 @@ ExecInitJunkFilter(List *targetList, bool hasoid, TupleTableSlot *slot)
cleanTupType = ExecCleanTypeFromTL(targetList, hasoid);
/*
+ * Use the given slot, or make a new slot if we weren't given one.
+ */
+ if (slot)
+ ExecSetSlotDescriptor(slot, cleanTupType, false);
+ else
+ slot = MakeSingleTupleTableSlot(cleanTupType);
+
+ /*
* Now calculate the mapping between the original tuple's attributes and
* the "clean" tuple's attributes.
*
@@ -115,9 +123,6 @@ ExecInitJunkFilter(List *targetList, bool hasoid, TupleTableSlot *slot)
junkfilter->jf_cleanMap = cleanMap;
junkfilter->jf_resultSlot = slot;
- if (slot)
- ExecSetSlotDescriptor(slot, cleanTupType, false);
-
return junkfilter;
}
@@ -143,6 +148,14 @@ ExecInitJunkFilterConversion(List *targetList,
int i;
/*
+ * Use the given slot, or make a new slot if we weren't given one.
+ */
+ if (slot)
+ ExecSetSlotDescriptor(slot, cleanTupType, false);
+ else
+ slot = MakeSingleTupleTableSlot(cleanTupType);
+
+ /*
* Calculate the mapping between the original tuple's attributes and
* the "clean" tuple's attributes.
*
@@ -188,9 +201,6 @@ ExecInitJunkFilterConversion(List *targetList,
junkfilter->jf_cleanMap = cleanMap;
junkfilter->jf_resultSlot = slot;
- if (slot)
- ExecSetSlotDescriptor(slot, cleanTupType, false);
-
return junkfilter;
}
@@ -234,115 +244,78 @@ ExecGetJunkAttribute(JunkFilter *junkfilter,
}
/*
- * ExecRemoveJunk
+ * ExecFilterJunk
*
- * Construct and return a tuple with all the junk attributes removed.
- *
- * Note: for historical reasons, this does not store the constructed
- * tuple into the junkfilter's resultSlot. The caller should do that
- * if it wants to.
+ * Construct and return a slot with all the junk attributes removed.
*/
-HeapTuple
-ExecRemoveJunk(JunkFilter *junkfilter, TupleTableSlot *slot)
+TupleTableSlot *
+ExecFilterJunk(JunkFilter *junkfilter, TupleTableSlot *slot)
{
-#define PREALLOC_SIZE 64
- HeapTuple tuple;
- HeapTuple cleanTuple;
+ TupleTableSlot *resultSlot;
AttrNumber *cleanMap;
TupleDesc cleanTupType;
- TupleDesc tupType;
int cleanLength;
- int oldLength;
int i;
Datum *values;
- char *nulls;
+ bool *isnull;
Datum *old_values;
- char *old_nulls;
- Datum values_array[PREALLOC_SIZE];
- Datum old_values_array[PREALLOC_SIZE];
- char nulls_array[PREALLOC_SIZE];
- char old_nulls_array[PREALLOC_SIZE];
+ bool *old_isnull;
/*
- * get info from the slot and the junk filter
+ * Extract all the values of the old tuple.
*/
- tuple = slot->val;
- tupType = slot->ttc_tupleDescriptor;
- oldLength = tupType->natts + 1; /* +1 for NULL */
+ slot_getallattrs(slot);
+ old_values = slot->tts_values;
+ old_isnull = slot->tts_isnull;
+ /*
+ * get info from the junk filter
+ */
cleanTupType = junkfilter->jf_cleanTupType;
cleanLength = cleanTupType->natts;
cleanMap = junkfilter->jf_cleanMap;
+ resultSlot = junkfilter->jf_resultSlot;
/*
- * Create the arrays that will hold the attribute values and the null
- * information for the old tuple and new "clean" tuple.
- *
- * Note: we use memory on the stack to optimize things when we are
- * dealing with a small number of attributes. for large tuples we just
- * use palloc.
+ * Prepare to build a virtual result tuple.
*/
- if (cleanLength > PREALLOC_SIZE)
- {
- values = (Datum *) palloc(cleanLength * sizeof(Datum));
- nulls = (char *) palloc(cleanLength * sizeof(char));
- }
- else
- {
- values = values_array;
- nulls = nulls_array;
- }
- if (oldLength > PREALLOC_SIZE)
- {
- old_values = (Datum *) palloc(oldLength * sizeof(Datum));
- old_nulls = (char *) palloc(oldLength * sizeof(char));
- }
- else
- {
- old_values = old_values_array;
- old_nulls = old_nulls_array;
- }
-
- /*
- * Extract all the values of the old tuple, offsetting the arrays
- * so that old_values[0] is NULL and old_values[1] is the first
- * source attribute; this exactly matches the numbering convention
- * in cleanMap.
- */
- heap_deformtuple(tuple, tupType, old_values + 1, old_nulls + 1);
- old_values[0] = (Datum) 0;
- old_nulls[0] = 'n';
+ ExecClearTuple(resultSlot);
+ values = resultSlot->tts_values;
+ isnull = resultSlot->tts_isnull;
/*
- * Transpose into proper fields of the new tuple.
+ * Transpose data into proper fields of the new tuple.
*/
for (i = 0; i < cleanLength; i++)
{
int j = cleanMap[i];
- values[i] = old_values[j];
- nulls[i] = old_nulls[j];
+ if (j == 0)
+ {
+ values[i] = (Datum) 0;
+ isnull[i] = true;
+ }
+ else
+ {
+ values[i] = old_values[j - 1];
+ isnull[i] = old_isnull[j - 1];
+ }
}
/*
- * Now form the new tuple.
- */
- cleanTuple = heap_formtuple(cleanTupType, values, nulls);
-
- /*
- * We are done. Free any space allocated for 'values' and 'nulls' and
- * return the new tuple.
+ * And return the virtual tuple.
*/
- if (values != values_array)
- {
- pfree(values);
- pfree(nulls);
- }
- if (old_values != old_values_array)
- {
- pfree(old_values);
- pfree(old_nulls);
- }
+ return ExecStoreVirtualTuple(resultSlot);
+}
- return cleanTuple;
+/*
+ * ExecRemoveJunk
+ *
+ * Convenience routine to generate a physical clean tuple,
+ * rather than just a virtual slot.
+ */
+HeapTuple
+ExecRemoveJunk(JunkFilter *junkfilter, TupleTableSlot *slot)
+{
+ return ExecCopySlotTuple(ExecFilterJunk(junkfilter, slot));
}