Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit63b1af9

Browse files
committed
Cleanup some aggregate code in the executor
Here we alter the code that calls build_pertrans_for_aggref() so that thefunction no longer needs to special-case whether it's dealing with anaggtransfn or an aggcombinefn. This allows us to reuse thebuild_aggregate_transfn_expr() function and just get rid of thebuild_aggregate_combinefn_expr() completely.All of the special case code that was in build_pertrans_for_aggref() hasbeen moved up to the calling functions.This saves about a dozen lines of code in nodeAgg.c and a few dozen morein parse_agg.cAlso, rename a few variables in nodeAgg.c to try to make it more clearthat we're working with either a aggtransfn or an aggcombinefn. Some ofthe old names would have you believe that we were always working with anaggtransfn.Discussion:https://postgr.es/m/CAApHDvptMQ9FmF0D67zC_w88yVnoNVR2+kkOQGUrCmdxWxLULQ@mail.gmail.com
1 parent7922595 commit63b1af9

File tree

3 files changed

+118
-155
lines changed

3 files changed

+118
-155
lines changed

‎src/backend/executor/nodeAgg.c

Lines changed: 113 additions & 121 deletions
Original file line numberDiff line numberDiff line change
@@ -461,10 +461,11 @@ static void hashagg_tapeinfo_release(HashTapeInfo *tapeinfo, int tapenum);
461461
staticDatumGetAggInitVal(DatumtextInitVal,Oidtranstype);
462462
staticvoidbuild_pertrans_for_aggref(AggStatePerTranspertrans,
463463
AggState*aggstate,EState*estate,
464-
Aggref*aggref,Oidaggtransfn,Oidaggtranstype,
465-
Oidaggserialfn,Oidaggdeserialfn,
466-
DatuminitValue,boolinitValueIsNull,
467-
Oid*inputTypes,intnumArguments);
464+
Aggref*aggref,Oidtransfn_oid,
465+
Oidaggtranstype,Oidaggserialfn,
466+
Oidaggdeserialfn,DatuminitValue,
467+
boolinitValueIsNull,Oid*inputTypes,
468+
intnumArguments);
468469

469470

470471
/*
@@ -3724,8 +3725,8 @@ ExecInitAgg(Agg *node, EState *estate, int eflags)
37243725
Aggref*aggref=lfirst(l);
37253726
AggStatePerAggperagg;
37263727
AggStatePerTranspertrans;
3727-
OidinputTypes[FUNC_MAX_ARGS];
3728-
intnumArguments;
3728+
OidaggTransFnInputTypes[FUNC_MAX_ARGS];
3729+
intnumAggTransFnArgs;
37293730
intnumDirectArgs;
37303731
HeapTupleaggTuple;
37313732
Form_pg_aggregateaggform;
@@ -3859,14 +3860,15 @@ ExecInitAgg(Agg *node, EState *estate, int eflags)
38593860
* could be different from the agg's declared input types, when the
38603861
* agg accepts ANY or a polymorphic type.
38613862
*/
3862-
numArguments=get_aggregate_argtypes(aggref,inputTypes);
3863+
numAggTransFnArgs=get_aggregate_argtypes(aggref,
3864+
aggTransFnInputTypes);
38633865

38643866
/* Count the "direct" arguments, if any */
38653867
numDirectArgs=list_length(aggref->aggdirectargs);
38663868

38673869
/* Detect how many arguments to pass to the finalfn */
38683870
if (aggform->aggfinalextra)
3869-
peragg->numFinalArgs=numArguments+1;
3871+
peragg->numFinalArgs=numAggTransFnArgs+1;
38703872
else
38713873
peragg->numFinalArgs=numDirectArgs+1;
38723874

@@ -3880,7 +3882,7 @@ ExecInitAgg(Agg *node, EState *estate, int eflags)
38803882
*/
38813883
if (OidIsValid(finalfn_oid))
38823884
{
3883-
build_aggregate_finalfn_expr(inputTypes,
3885+
build_aggregate_finalfn_expr(aggTransFnInputTypes,
38843886
peragg->numFinalArgs,
38853887
aggtranstype,
38863888
aggref->aggtype,
@@ -3911,7 +3913,7 @@ ExecInitAgg(Agg *node, EState *estate, int eflags)
39113913
/*
39123914
* If this aggregation is performing state combines, then instead
39133915
* of using the transition function, we'll use the combine
3914-
* function
3916+
* function.
39153917
*/
39163918
if (DO_AGGSPLIT_COMBINE(aggstate->aggsplit))
39173919
{
@@ -3924,8 +3926,7 @@ ExecInitAgg(Agg *node, EState *estate, int eflags)
39243926
else
39253927
transfn_oid=aggform->aggtransfn;
39263928

3927-
aclresult=pg_proc_aclcheck(transfn_oid,aggOwner,
3928-
ACL_EXECUTE);
3929+
aclresult=pg_proc_aclcheck(transfn_oid,aggOwner,ACL_EXECUTE);
39293930
if (aclresult!=ACLCHECK_OK)
39303931
aclcheck_error(aclresult,OBJECT_FUNCTION,
39313932
get_func_name(transfn_oid));
@@ -3943,11 +3944,72 @@ ExecInitAgg(Agg *node, EState *estate, int eflags)
39433944
else
39443945
initValue=GetAggInitVal(textInitVal,aggtranstype);
39453946

3946-
build_pertrans_for_aggref(pertrans,aggstate,estate,
3947-
aggref,transfn_oid,aggtranstype,
3948-
serialfn_oid,deserialfn_oid,
3949-
initValue,initValueIsNull,
3950-
inputTypes,numArguments);
3947+
if (DO_AGGSPLIT_COMBINE(aggstate->aggsplit))
3948+
{
3949+
OidcombineFnInputTypes[]= {aggtranstype,
3950+
aggtranstype};
3951+
3952+
/*
3953+
* When combining there's only one input, the to-be-combined
3954+
* transition value. The transition value is not counted
3955+
* here.
3956+
*/
3957+
pertrans->numTransInputs=1;
3958+
3959+
/* aggcombinefn always has two arguments of aggtranstype */
3960+
build_pertrans_for_aggref(pertrans,aggstate,estate,
3961+
aggref,transfn_oid,aggtranstype,
3962+
serialfn_oid,deserialfn_oid,
3963+
initValue,initValueIsNull,
3964+
combineFnInputTypes,2);
3965+
3966+
/*
3967+
* Ensure that a combine function to combine INTERNAL states
3968+
* is not strict. This should have been checked during CREATE
3969+
* AGGREGATE, but the strict property could have been changed
3970+
* since then.
3971+
*/
3972+
if (pertrans->transfn.fn_strict&&aggtranstype==INTERNALOID)
3973+
ereport(ERROR,
3974+
(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
3975+
errmsg("combine function with transition type %s must not be declared STRICT",
3976+
format_type_be(aggtranstype))));
3977+
}
3978+
else
3979+
{
3980+
/* Detect how many arguments to pass to the transfn */
3981+
if (AGGKIND_IS_ORDERED_SET(aggref->aggkind))
3982+
pertrans->numTransInputs=list_length(aggref->args);
3983+
else
3984+
pertrans->numTransInputs=numAggTransFnArgs;
3985+
3986+
build_pertrans_for_aggref(pertrans,aggstate,estate,
3987+
aggref,transfn_oid,aggtranstype,
3988+
serialfn_oid,deserialfn_oid,
3989+
initValue,initValueIsNull,
3990+
aggTransFnInputTypes,
3991+
numAggTransFnArgs);
3992+
3993+
/*
3994+
* If the transfn is strict and the initval is NULL, make sure
3995+
* input type and transtype are the same (or at least
3996+
* binary-compatible), so that it's OK to use the first
3997+
* aggregated input value as the initial transValue. This
3998+
* should have been checked at agg definition time, but we
3999+
* must check again in case the transfn's strictness property
4000+
* has been changed.
4001+
*/
4002+
if (pertrans->transfn.fn_strict&&pertrans->initValueIsNull)
4003+
{
4004+
if (numAggTransFnArgs <=numDirectArgs||
4005+
!IsBinaryCoercible(aggTransFnInputTypes[numDirectArgs],
4006+
aggtranstype))
4007+
ereport(ERROR,
4008+
(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
4009+
errmsg("aggregate %u needs to have compatible input type and transition type",
4010+
aggref->aggfnoid)));
4011+
}
4012+
}
39514013
}
39524014
else
39534015
pertrans->aggshared= true;
@@ -4039,20 +4101,24 @@ ExecInitAgg(Agg *node, EState *estate, int eflags)
40394101
* Build the state needed to calculate a state value for an aggregate.
40404102
*
40414103
* This initializes all the fields in 'pertrans'. 'aggref' is the aggregate
4042-
* to initialize the state for. 'aggtransfn', 'aggtranstype', and the rest
4104+
* to initialize the state for. 'transfn_oid', 'aggtranstype', and the rest
40434105
* of the arguments could be calculated from 'aggref', but the caller has
40444106
* calculated them already, so might as well pass them.
4107+
*
4108+
* 'transfn_oid' may be either the Oid of the aggtransfn or the aggcombinefn.
40454109
*/
40464110
staticvoid
40474111
build_pertrans_for_aggref(AggStatePerTranspertrans,
40484112
AggState*aggstate,EState*estate,
40494113
Aggref*aggref,
4050-
Oidaggtransfn,Oidaggtranstype,
4114+
Oidtransfn_oid,Oidaggtranstype,
40514115
Oidaggserialfn,Oidaggdeserialfn,
40524116
DatuminitValue,boolinitValueIsNull,
40534117
Oid*inputTypes,intnumArguments)
40544118
{
40554119
intnumGroupingSets=Max(aggstate->maxsets,1);
4120+
Expr*transfnexpr;
4121+
intnumTransArgs;
40564122
Expr*serialfnexpr=NULL;
40574123
Expr*deserialfnexpr=NULL;
40584124
ListCell*lc;
@@ -4067,7 +4133,7 @@ build_pertrans_for_aggref(AggStatePerTrans pertrans,
40674133
pertrans->aggref=aggref;
40684134
pertrans->aggshared= false;
40694135
pertrans->aggCollation=aggref->inputcollid;
4070-
pertrans->transfn_oid=aggtransfn;
4136+
pertrans->transfn_oid=transfn_oid;
40714137
pertrans->serialfn_oid=aggserialfn;
40724138
pertrans->deserialfn_oid=aggdeserialfn;
40734139
pertrans->initValue=initValue;
@@ -4081,111 +4147,34 @@ build_pertrans_for_aggref(AggStatePerTrans pertrans,
40814147

40824148
pertrans->aggtranstype=aggtranstype;
40834149

4150+
/* account for the current transition state */
4151+
numTransArgs=pertrans->numTransInputs+1;
4152+
40844153
/*
4085-
* When combining states, we have no use at all for the aggregate
4086-
* function's transfn. Instead we use the combinefn. In this case, the
4087-
* transfn and transfn_oid fields of pertrans refer to the combine
4088-
* function rather than the transition function.
4154+
* Set up infrastructure for calling the transfn. Note that invtrans is
4155+
* not needed here.
40894156
*/
4090-
if (DO_AGGSPLIT_COMBINE(aggstate->aggsplit))
4091-
{
4092-
Expr*combinefnexpr;
4093-
size_tnumTransArgs;
4094-
4095-
/*
4096-
* When combining there's only one input, the to-be-combined added
4097-
* transition value from below (this node's transition value is
4098-
* counted separately).
4099-
*/
4100-
pertrans->numTransInputs=1;
4101-
4102-
/* account for the current transition state */
4103-
numTransArgs=pertrans->numTransInputs+1;
4104-
4105-
build_aggregate_combinefn_expr(aggtranstype,
4106-
aggref->inputcollid,
4107-
aggtransfn,
4108-
&combinefnexpr);
4109-
fmgr_info(aggtransfn,&pertrans->transfn);
4110-
fmgr_info_set_expr((Node*)combinefnexpr,&pertrans->transfn);
4111-
4112-
pertrans->transfn_fcinfo=
4113-
(FunctionCallInfo)palloc(SizeForFunctionCallInfo(2));
4114-
InitFunctionCallInfoData(*pertrans->transfn_fcinfo,
4115-
&pertrans->transfn,
4116-
numTransArgs,
4117-
pertrans->aggCollation,
4118-
(void*)aggstate,NULL);
4119-
4120-
/*
4121-
* Ensure that a combine function to combine INTERNAL states is not
4122-
* strict. This should have been checked during CREATE AGGREGATE, but
4123-
* the strict property could have been changed since then.
4124-
*/
4125-
if (pertrans->transfn.fn_strict&&aggtranstype==INTERNALOID)
4126-
ereport(ERROR,
4127-
(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
4128-
errmsg("combine function with transition type %s must not be declared STRICT",
4129-
format_type_be(aggtranstype))));
4130-
}
4131-
else
4132-
{
4133-
Expr*transfnexpr;
4134-
size_tnumTransArgs;
4135-
4136-
/* Detect how many arguments to pass to the transfn */
4137-
if (AGGKIND_IS_ORDERED_SET(aggref->aggkind))
4138-
pertrans->numTransInputs=numInputs;
4139-
else
4140-
pertrans->numTransInputs=numArguments;
4157+
build_aggregate_transfn_expr(inputTypes,
4158+
numArguments,
4159+
numDirectArgs,
4160+
aggref->aggvariadic,
4161+
aggtranstype,
4162+
aggref->inputcollid,
4163+
transfn_oid,
4164+
InvalidOid,
4165+
&transfnexpr,
4166+
NULL);
41414167

4142-
/* account for the current transition state */
4143-
numTransArgs=pertrans->numTransInputs+1;
4168+
fmgr_info(transfn_oid,&pertrans->transfn);
4169+
fmgr_info_set_expr((Node*)transfnexpr,&pertrans->transfn);
41444170

4145-
/*
4146-
* Set up infrastructure for calling the transfn. Note that
4147-
* invtransfn is not needed here.
4148-
*/
4149-
build_aggregate_transfn_expr(inputTypes,
4150-
numArguments,
4151-
numDirectArgs,
4152-
aggref->aggvariadic,
4153-
aggtranstype,
4154-
aggref->inputcollid,
4155-
aggtransfn,
4156-
InvalidOid,
4157-
&transfnexpr,
4158-
NULL);
4159-
fmgr_info(aggtransfn,&pertrans->transfn);
4160-
fmgr_info_set_expr((Node*)transfnexpr,&pertrans->transfn);
4161-
4162-
pertrans->transfn_fcinfo=
4163-
(FunctionCallInfo)palloc(SizeForFunctionCallInfo(numTransArgs));
4164-
InitFunctionCallInfoData(*pertrans->transfn_fcinfo,
4165-
&pertrans->transfn,
4166-
numTransArgs,
4167-
pertrans->aggCollation,
4168-
(void*)aggstate,NULL);
4169-
4170-
/*
4171-
* If the transfn is strict and the initval is NULL, make sure input
4172-
* type and transtype are the same (or at least binary-compatible), so
4173-
* that it's OK to use the first aggregated input value as the initial
4174-
* transValue. This should have been checked at agg definition time,
4175-
* but we must check again in case the transfn's strictness property
4176-
* has been changed.
4177-
*/
4178-
if (pertrans->transfn.fn_strict&&pertrans->initValueIsNull)
4179-
{
4180-
if (numArguments <=numDirectArgs||
4181-
!IsBinaryCoercible(inputTypes[numDirectArgs],
4182-
aggtranstype))
4183-
ereport(ERROR,
4184-
(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
4185-
errmsg("aggregate %u needs to have compatible input type and transition type",
4186-
aggref->aggfnoid)));
4187-
}
4188-
}
4171+
pertrans->transfn_fcinfo=
4172+
(FunctionCallInfo)palloc(SizeForFunctionCallInfo(numTransArgs));
4173+
InitFunctionCallInfoData(*pertrans->transfn_fcinfo,
4174+
&pertrans->transfn,
4175+
numTransArgs,
4176+
pertrans->aggCollation,
4177+
(void*)aggstate,NULL);
41894178

41904179
/* get info about the state value's datatype */
41914180
get_typlenbyval(aggtranstype,
@@ -4276,6 +4265,9 @@ build_pertrans_for_aggref(AggStatePerTrans pertrans,
42764265
*/
42774266
Assert(aggstate->aggstrategy!=AGG_HASHED&&aggstate->aggstrategy!=AGG_MIXED);
42784267

4268+
/* ORDER BY aggregates are not supported with partial aggregation */
4269+
Assert(!DO_AGGSPLIT_COMBINE(aggstate->aggsplit));
4270+
42794271
/* If we have only one input, we need its len/byval info. */
42804272
if (numInputs==1)
42814273
{

‎src/backend/parser/parse_agg.c

Lines changed: 5 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1959,6 +1959,11 @@ resolve_aggregate_transtype(Oid aggfuncid,
19591959
* latter may be InvalidOid, however if invtransfn_oid is set then
19601960
* transfn_oid must also be set.
19611961
*
1962+
* transfn_oid may also be passed as the aggcombinefn when the *transfnexpr is
1963+
* to be used for a combine aggregate phase. We expect invtransfn_oid to be
1964+
* InvalidOid in this case since there is no such thing as an inverse
1965+
* combinefn.
1966+
*
19621967
* Pointers to the constructed trees are returned into *transfnexpr,
19631968
* *invtransfnexpr. If there is no invtransfn, the respective pointer is set
19641969
* to NULL. Since use of the invtransfn is optional, NULL may be passed for
@@ -2021,35 +2026,6 @@ build_aggregate_transfn_expr(Oid *agg_input_types,
20212026
}
20222027
}
20232028

2024-
/*
2025-
* Like build_aggregate_transfn_expr, but creates an expression tree for the
2026-
* combine function of an aggregate, rather than the transition function.
2027-
*/
2028-
void
2029-
build_aggregate_combinefn_expr(Oidagg_state_type,
2030-
Oidagg_input_collation,
2031-
Oidcombinefn_oid,
2032-
Expr**combinefnexpr)
2033-
{
2034-
Node*argp;
2035-
List*args;
2036-
FuncExpr*fexpr;
2037-
2038-
/* combinefn takes two arguments of the aggregate state type */
2039-
argp=make_agg_arg(agg_state_type,agg_input_collation);
2040-
2041-
args=list_make2(argp,argp);
2042-
2043-
fexpr=makeFuncExpr(combinefn_oid,
2044-
agg_state_type,
2045-
args,
2046-
InvalidOid,
2047-
agg_input_collation,
2048-
COERCE_EXPLICIT_CALL);
2049-
/* combinefn is currently never treated as variadic */
2050-
*combinefnexpr= (Expr*)fexpr;
2051-
}
2052-
20532029
/*
20542030
* Like build_aggregate_transfn_expr, but creates an expression tree for the
20552031
* serialization function of an aggregate.

‎src/include/parser/parse_agg.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,6 @@ extern void build_aggregate_transfn_expr(Oid *agg_input_types,
4646
Expr**transfnexpr,
4747
Expr**invtransfnexpr);
4848

49-
externvoidbuild_aggregate_combinefn_expr(Oidagg_state_type,
50-
Oidagg_input_collation,
51-
Oidcombinefn_oid,
52-
Expr**combinefnexpr);
53-
5449
externvoidbuild_aggregate_serialfn_expr(Oidserialfn_oid,
5550
Expr**serialfnexpr);
5651

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp