diff options
Diffstat (limited to 'src/backend/executor/execJunk.c')
-rw-r--r-- | src/backend/executor/execJunk.c | 155 |
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)); } |