mirror of
https://github.com/postgres/postgres.git
synced 2025-07-27 12:41:57 +03:00
Simplify planner's final setup of Aggrefs for partial aggregation.
Commit e06a38965's original coding for constructing the execution-time expression tree for a combining aggregate was rather messy, involving duplicating quite a lot of code in setrefs.c so that it could inject a nonstandard matching rule for Aggrefs. Get rid of that in favor of explicitly constructing a combining Aggref with a partial Aggref as input, then allowing setref's normal matching logic to match the partial Aggref to the output of the lower plan node and hence replace it with a Var. In passing, rename and redocument make_partialgroup_input_target to have some connection to what it actually does.
This commit is contained in:
@ -14,12 +14,9 @@
|
||||
*/
|
||||
#include "postgres.h"
|
||||
|
||||
#include "access/htup_details.h"
|
||||
#include "catalog/pg_type.h"
|
||||
#include "nodes/makefuncs.h"
|
||||
#include "nodes/nodeFuncs.h"
|
||||
#include "optimizer/tlist.h"
|
||||
#include "utils/syscache.h"
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
@ -762,51 +759,3 @@ apply_pathtarget_labeling_to_tlist(List *tlist, PathTarget *target)
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* apply_partialaggref_adjustment
|
||||
* Convert PathTarget to be suitable for a partial aggregate node. We simply
|
||||
* adjust any Aggref nodes found in the target and set the aggoutputtype
|
||||
* appropriately. This allows exprType() to return the
|
||||
* actual type that will be produced.
|
||||
*
|
||||
* Note: We expect 'target' to be a flat target list and not have Aggrefs buried
|
||||
* within other expressions.
|
||||
*/
|
||||
void
|
||||
apply_partialaggref_adjustment(PathTarget *target)
|
||||
{
|
||||
ListCell *lc;
|
||||
|
||||
foreach(lc, target->exprs)
|
||||
{
|
||||
Aggref *aggref = (Aggref *) lfirst(lc);
|
||||
|
||||
if (IsA(aggref, Aggref))
|
||||
{
|
||||
Aggref *newaggref;
|
||||
|
||||
newaggref = (Aggref *) copyObject(aggref);
|
||||
|
||||
/*
|
||||
* Normally, a partial aggregate returns the aggregate's
|
||||
* transition type, but if that's INTERNAL, it returns BYTEA
|
||||
* instead. (XXX this assumes we're doing parallel aggregate with
|
||||
* serialization; later we might need an argument to tell this
|
||||
* function whether we're doing parallel or just local partial
|
||||
* aggregation.)
|
||||
*/
|
||||
Assert(OidIsValid(newaggref->aggtranstype));
|
||||
|
||||
if (newaggref->aggtranstype == INTERNALOID)
|
||||
newaggref->aggoutputtype = BYTEAOID;
|
||||
else
|
||||
newaggref->aggoutputtype = newaggref->aggtranstype;
|
||||
|
||||
/* flag it as partial */
|
||||
newaggref->aggpartial = true;
|
||||
|
||||
lfirst(lc) = newaggref;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user