1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-26 01:22:12 +03:00

Move per-agg and per-trans duplicate finding to the planner.

This has the advantage that the cost estimates for aggregates can count
the number of calls to transition and final functions correctly.

Bump catalog version, because views can contain Aggrefs.

Reviewed-by: Andres Freund
Discussion: https://www.postgresql.org/message-id/b2e3536b-1dbc-8303-c97e-89cb0b4a9a48%40iki.fi
This commit is contained in:
Heikki Linnakangas
2020-11-24 10:45:00 +02:00
parent e522024bd8
commit 0a2bc5d61e
29 changed files with 955 additions and 747 deletions

View File

@ -55,10 +55,6 @@ typedef struct QualCost
*/
typedef struct AggClauseCosts
{
int numAggs; /* total number of aggregate functions */
int numOrderedAggs; /* number w/ DISTINCT/ORDER BY/WITHIN GROUP */
bool hasNonPartial; /* does any agg not support partial mode? */
bool hasNonSerial; /* is any partial agg non-serializable? */
QualCost transCost; /* total per-input-row execution costs */
QualCost finalCost; /* total per-aggregated-row costs */
Size transitionSpace; /* space for pass-by-ref transition data */
@ -348,6 +344,15 @@ struct PlannerInfo
bool hasAlternativeSubPlans; /* true if we've made any of those */
bool hasRecursion; /* true if planning a recursive WITH item */
/*
* Information about aggregates. Filled by preprocess_aggrefs().
*/
List *agginfos; /* AggInfo structs */
List *aggtransinfos; /* AggTransInfo structs */
int numOrderedAggs; /* number w/ DISTINCT/ORDER BY/WITHIN GROUP */
bool hasNonPartialAggs; /* does any agg not support partial mode? */
bool hasNonSerialAggs; /* is any partial agg non-serializable? */
/* These fields are used only when hasRecursion is true: */
int wt_param_id; /* PARAM_EXEC ID for the work table */
struct Path *non_recursive_path; /* a path for non-recursive term */
@ -2549,4 +2554,71 @@ typedef struct JoinCostWorkspace
double inner_rows_total;
} JoinCostWorkspace;
/*
* AggInfo holds information about an aggregate that needs to be computed.
* Multiple Aggrefs in a query can refer to the same AggInfo by having the
* same 'aggno' value, so that the aggregate is computed only once.
*/
typedef struct AggInfo
{
/*
* Link to an Aggref expr this state value is for.
*
* There can be multiple identical Aggref's sharing the same per-agg. This
* points to the first one of them.
*/
Aggref *representative_aggref;
int transno;
/*
* "shareable" is false if this agg cannot share state values with other
* aggregates because the final function is read-write.
*/
bool shareable;
/* Oid of the final function or InvalidOid */
Oid finalfn_oid;
} AggInfo;
/*
* AggTransInfo holds information about transition state that is used by one
* or more aggregates in the query. Multiple aggregates can share the same
* transition state, if they have the same inputs and the same transition
* function. Aggrefs that share the same transition info have the same
* 'aggtransno' value.
*/
typedef struct AggTransInfo
{
List *args;
Expr *aggfilter;
/* Oid of the state transition function */
Oid transfn_oid;
/* Oid of the serialization function or InvalidOid */
Oid serialfn_oid;
/* Oid of the deserialization function or InvalidOid */
Oid deserialfn_oid;
/* Oid of the combine function or InvalidOid */
Oid combinefn_oid;
/* Oid of state value's datatype */
Oid aggtranstype;
int32 aggtranstypmod;
int transtypeLen;
bool transtypeByVal;
int32 aggtransspace;
/*
* initial value from pg_aggregate entry
*/
Datum initValue;
bool initValueIsNull;
} AggTransInfo;
#endif /* PATHNODES_H */