Put back code in nodeAgg to generate a dummy all-nulls input tuple

before calling execProject, when the outerPlan has returned zero tuples.
I took this out under the mistaken impression that the input tuple
couldn't be referenced by execProject if we weren't in GROUP BY mode.
But it can, if we're in an UPDATE or DELETE...
This commit is contained in:
Tom Lane 1999-10-30 01:18:16 +00:00
parent 60f3e6b3a5
commit b021e9a130
1 changed files with 35 additions and 16 deletions

View File

@ -11,7 +11,7 @@
* SQL aggregates. (Do not expect POSTQUEL semantics.) -- ay 2/95 * SQL aggregates. (Do not expect POSTQUEL semantics.) -- ay 2/95
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/nodeAgg.c,v 1.57 1999/10/08 03:49:55 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/executor/nodeAgg.c,v 1.58 1999/10/30 01:18:16 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -408,24 +408,43 @@ ExecAgg(Agg *node)
return NULL; return NULL;
} }
else else
{
aggstate->agg_done = true; aggstate->agg_done = true;
/* /*
* We used to create a dummy all-nulls input tuple here if * If inputtuple==NULL (ie, the outerPlan didn't return anything),
* inputTuple == NULL (ie, the outerPlan didn't return anything). * create a dummy all-nulls input tuple for use by execProject.
* However, now that we don't return a bogus tuple in Group mode, * 99.44% of the time this is a waste of cycles, because
* we can only get here with inputTuple == NULL in non-Group mode. * ordinarily the projected output tuple's targetlist cannot
* So, if the parser has done its job right, the projected output * contain any direct (non-aggregated) references to input
* tuple's targetList must not contain any direct references to * columns, so the dummy tuple will not be referenced. However
* input columns, and so it's a waste of time to create an * there are special cases where this isn't so --- in particular
* all-nulls input tuple. We just let the tuple slot get set * an UPDATE involving an aggregate will have a targetlist
* to NULL instead. The values returned for the aggregates will * reference to ctid. We need to return a null for ctid in that
* be the initial values of the transition functions. * situation, not coredump.
*
* The values returned for the aggregates will be the initial
* values of the transition functions.
*/ */
if (inputTuple == NULL)
{
TupleDesc tupType;
Datum *tupValue;
char *null_array;
AttrNumber attnum;
tupType = aggstate->csstate.css_ScanTupleSlot->ttc_tupleDescriptor;
tupValue = projInfo->pi_tupValue;
null_array = (char *) palloc(sizeof(char) * tupType->natts);
for (attnum = 0; attnum < tupType->natts; attnum++)
null_array[attnum] = 'n';
inputTuple = heap_formtuple(tupType, tupValue, null_array);
pfree(null_array);
}
}
/* /*
* Store the representative input tuple (or NULL, if none) * Store the representative input tuple in the tuple table slot
* in the tuple table slot reserved for it. * reserved for it.
*/ */
ExecStoreTuple(inputTuple, ExecStoreTuple(inputTuple,
aggstate->csstate.css_ScanTupleSlot, aggstate->csstate.css_ScanTupleSlot,