mirror of
https://github.com/postgres/postgres.git
synced 2025-11-22 12:22:45 +03:00
Support multi-stage aggregation.
Aggregate nodes now have two new modes: a "partial" mode where they output the unfinalized transition state, and a "finalize" mode where they accept unfinalized transition states rather than individual values as input. These new modes are not used anywhere yet, but they will be necessary for parallel aggregation. The infrastructure also figures to be useful for cases where we want to aggregate local data and remote data via the FDW interface, and want to bring back partial aggregates from the remote side that can then be combined with locally generated partial aggregates to produce the final value. It may also be useful even when neither FDWs nor parallelism are in play, as explained in the comments in nodeAgg.c. David Rowley and Simon Riggs, reviewed by KaiGai Kohei, Heikki Linnakangas, Haribabu Kommi, and me.
This commit is contained in:
@@ -57,6 +57,7 @@ AggregateCreate(const char *aggName,
|
||||
Oid variadicArgType,
|
||||
List *aggtransfnName,
|
||||
List *aggfinalfnName,
|
||||
List *aggcombinefnName,
|
||||
List *aggmtransfnName,
|
||||
List *aggminvtransfnName,
|
||||
List *aggmfinalfnName,
|
||||
@@ -77,6 +78,7 @@ AggregateCreate(const char *aggName,
|
||||
Form_pg_proc proc;
|
||||
Oid transfn;
|
||||
Oid finalfn = InvalidOid; /* can be omitted */
|
||||
Oid combinefn = InvalidOid; /* can be omitted */
|
||||
Oid mtransfn = InvalidOid; /* can be omitted */
|
||||
Oid minvtransfn = InvalidOid; /* can be omitted */
|
||||
Oid mfinalfn = InvalidOid; /* can be omitted */
|
||||
@@ -396,6 +398,30 @@ AggregateCreate(const char *aggName,
|
||||
}
|
||||
Assert(OidIsValid(finaltype));
|
||||
|
||||
/* handle the combinefn, if supplied */
|
||||
if (aggcombinefnName)
|
||||
{
|
||||
Oid combineType;
|
||||
|
||||
/*
|
||||
* Combine function must have 2 argument, each of which is the
|
||||
* trans type
|
||||
*/
|
||||
fnArgs[0] = aggTransType;
|
||||
fnArgs[1] = aggTransType;
|
||||
|
||||
combinefn = lookup_agg_function(aggcombinefnName, 2, fnArgs,
|
||||
variadicArgType, &combineType);
|
||||
|
||||
/* Ensure the return type matches the aggregates trans type */
|
||||
if (combineType != aggTransType)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_DATATYPE_MISMATCH),
|
||||
errmsg("return type of combine function %s is not %s",
|
||||
NameListToString(aggcombinefnName),
|
||||
format_type_be(aggTransType))));
|
||||
}
|
||||
|
||||
/*
|
||||
* If finaltype (i.e. aggregate return type) is polymorphic, inputs must
|
||||
* be polymorphic also, else parser will fail to deduce result type.
|
||||
@@ -567,6 +593,7 @@ AggregateCreate(const char *aggName,
|
||||
values[Anum_pg_aggregate_aggnumdirectargs - 1] = Int16GetDatum(numDirectArgs);
|
||||
values[Anum_pg_aggregate_aggtransfn - 1] = ObjectIdGetDatum(transfn);
|
||||
values[Anum_pg_aggregate_aggfinalfn - 1] = ObjectIdGetDatum(finalfn);
|
||||
values[Anum_pg_aggregate_aggcombinefn - 1] = ObjectIdGetDatum(combinefn);
|
||||
values[Anum_pg_aggregate_aggmtransfn - 1] = ObjectIdGetDatum(mtransfn);
|
||||
values[Anum_pg_aggregate_aggminvtransfn - 1] = ObjectIdGetDatum(minvtransfn);
|
||||
values[Anum_pg_aggregate_aggmfinalfn - 1] = ObjectIdGetDatum(mfinalfn);
|
||||
@@ -618,6 +645,15 @@ AggregateCreate(const char *aggName,
|
||||
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
|
||||
}
|
||||
|
||||
/* Depends on combine function, if any */
|
||||
if (OidIsValid(combinefn))
|
||||
{
|
||||
referenced.classId = ProcedureRelationId;
|
||||
referenced.objectId = combinefn;
|
||||
referenced.objectSubId = 0;
|
||||
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
|
||||
}
|
||||
|
||||
/* Depends on forward transition function, if any */
|
||||
if (OidIsValid(mtransfn))
|
||||
{
|
||||
@@ -659,7 +695,7 @@ AggregateCreate(const char *aggName,
|
||||
|
||||
/*
|
||||
* lookup_agg_function
|
||||
* common code for finding transfn, invtransfn and finalfn
|
||||
* common code for finding transfn, invtransfn, finalfn, and combinefn
|
||||
*
|
||||
* Returns OID of function, and stores its return type into *rettype
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user