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

Commit2742c45

Browse files
committed
expression eval: Reduce number of steps for agg transition invocations.
Do so by combining the various steps that are part of aggregatetransition function invocation into one larger step. As some of thecurrent steps are only necessary for some aggregates, have one variantof the aggregate transition step for each possible combination.To avoid further manual copies of code in the different transitionstep implementations, move most of the code into helper functionsmarked as "always inline".The benefit of this change is an increase in performance whenaggregating lots of rows. This comes in part due to the reduced numberof indirect jumps due to the reduced number of steps, and in part byreducing redundant setup code across steps. This mainly benefitsinterpreted execution, but the code generated by JIT is also improveda bit.As a nice side-effect it also ends up making the code a bit simpler.A small additional optimization is removing the need to setaggstate->curaggcontext before calling ExecAggInitGroup, choosing toinstead passign curaggcontext as an argument. It was, in contrast toother aggregate related functions, only needed to fetch a memorycontext to copy the transition value into.Author: Andres FreundDiscussion:https://postgr.es/m/20191023163849.sosqbfs5yenocez3@alap3.anarazel.dehttps://postgr.es/m/5c371df7cee903e8cd4c685f90c6c72086d3a2dc.camel@j-davis.com
1 parent7d672b7 commit2742c45

File tree

5 files changed

+332
-348
lines changed

5 files changed

+332
-348
lines changed

‎src/backend/executor/execExpr.c

Lines changed: 48 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -3229,8 +3229,6 @@ ExecBuildAggTransCall(ExprState *state, AggState *aggstate,
32293229
FunctionCallInfofcinfo,AggStatePerTranspertrans,
32303230
inttransno,intsetno,intsetoff,boolishash)
32313231
{
3232-
intadjust_init_jumpnull=-1;
3233-
intadjust_strict_jumpnull=-1;
32343232
ExprContext*aggcontext;
32353233

32363234
if (ishash)
@@ -3239,52 +3237,61 @@ ExecBuildAggTransCall(ExprState *state, AggState *aggstate,
32393237
aggcontext=aggstate->aggcontexts[setno];
32403238

32413239
/*
3240+
* Determine appropriate transition implementation.
3241+
*
3242+
* For non-ordered aggregates:
3243+
*
32423244
* If the initial value for the transition state doesn't exist in the
32433245
* pg_aggregate table then we will let the first non-NULL value returned
32443246
* from the outer procNode become the initial value. (This is useful for
32453247
* aggregates like max() and min().) The noTransValue flag signals that we
3246-
* still need to do this.
3248+
* need to do so. If true, generate a
3249+
* EEOP_AGG_INIT_STRICT_PLAIN_TRANS{,_BYVAL} step. This step also needs to
3250+
* do the work described next:
3251+
*
3252+
* If the function is strict, but does have an initial value, choose
3253+
* EEOP_AGG_STRICT_PLAIN_TRANS{,_BYVAL}, which skips the transition
3254+
* function if the transition value has become NULL (because a previous
3255+
* transition function returned NULL). This step also needs to do the work
3256+
* described next:
3257+
*
3258+
* Otherwise we call EEOP_AGG_PLAIN_TRANS{,_BYVAL}, which does not have to
3259+
* perform either of the above checks.
3260+
*
3261+
* Having steps with overlapping responsibilities is not nice, but
3262+
* aggregations are very performance sensitive, making this worthwhile.
3263+
*
3264+
* For ordered aggregates:
3265+
*
3266+
* Only need to choose between the faster path for a single orderred
3267+
* column, and the one between multiple columns. Checking strictness etc
3268+
* is done when finalizing the aggregate. See
3269+
* process_ordered_aggregate_{single, multi} and
3270+
* advance_transition_function.
32473271
*/
3248-
if (pertrans->numSortCols==0&&
3249-
fcinfo->flinfo->fn_strict&&
3250-
pertrans->initValueIsNull)
3251-
{
3252-
scratch->opcode=EEOP_AGG_INIT_TRANS;
3253-
scratch->d.agg_init_trans.pertrans=pertrans;
3254-
scratch->d.agg_init_trans.setno=setno;
3255-
scratch->d.agg_init_trans.setoff=setoff;
3256-
scratch->d.agg_init_trans.transno=transno;
3257-
scratch->d.agg_init_trans.aggcontext=aggcontext;
3258-
scratch->d.agg_init_trans.jumpnull=-1;/* adjust later */
3259-
ExprEvalPushStep(state,scratch);
3260-
3261-
/* see comment about jumping out below */
3262-
adjust_init_jumpnull=state->steps_len-1;
3263-
}
3264-
3265-
if (pertrans->numSortCols==0&&
3266-
fcinfo->flinfo->fn_strict)
3272+
if (pertrans->numSortCols==0)
32673273
{
3268-
scratch->opcode=EEOP_AGG_STRICT_TRANS_CHECK;
3269-
scratch->d.agg_strict_trans_check.setno=setno;
3270-
scratch->d.agg_strict_trans_check.setoff=setoff;
3271-
scratch->d.agg_strict_trans_check.transno=transno;
3272-
scratch->d.agg_strict_trans_check.jumpnull=-1;/* adjust later */
3273-
ExprEvalPushStep(state,scratch);
3274-
3275-
/*
3276-
* Note, we don't push into adjust_bailout here - those jump to the
3277-
* end of all transition value computations. Here a single transition
3278-
* value is NULL, so just skip processing the individual value.
3279-
*/
3280-
adjust_strict_jumpnull=state->steps_len-1;
3274+
if (pertrans->transtypeByVal)
3275+
{
3276+
if (fcinfo->flinfo->fn_strict&&
3277+
pertrans->initValueIsNull)
3278+
scratch->opcode=EEOP_AGG_PLAIN_TRANS_INIT_STRICT_BYVAL;
3279+
elseif (fcinfo->flinfo->fn_strict)
3280+
scratch->opcode=EEOP_AGG_PLAIN_TRANS_STRICT_BYVAL;
3281+
else
3282+
scratch->opcode=EEOP_AGG_PLAIN_TRANS_BYVAL;
3283+
}
3284+
else
3285+
{
3286+
if (fcinfo->flinfo->fn_strict&&
3287+
pertrans->initValueIsNull)
3288+
scratch->opcode=EEOP_AGG_PLAIN_TRANS_INIT_STRICT_BYREF;
3289+
elseif (fcinfo->flinfo->fn_strict)
3290+
scratch->opcode=EEOP_AGG_PLAIN_TRANS_STRICT_BYREF;
3291+
else
3292+
scratch->opcode=EEOP_AGG_PLAIN_TRANS_BYREF;
3293+
}
32813294
}
3282-
3283-
/* invoke appropriate transition implementation */
3284-
if (pertrans->numSortCols==0&&pertrans->transtypeByVal)
3285-
scratch->opcode=EEOP_AGG_PLAIN_TRANS_BYVAL;
3286-
elseif (pertrans->numSortCols==0)
3287-
scratch->opcode=EEOP_AGG_PLAIN_TRANS;
32883295
elseif (pertrans->numInputs==1)
32893296
scratch->opcode=EEOP_AGG_ORDERED_TRANS_DATUM;
32903297
else
@@ -3296,22 +3303,6 @@ ExecBuildAggTransCall(ExprState *state, AggState *aggstate,
32963303
scratch->d.agg_trans.transno=transno;
32973304
scratch->d.agg_trans.aggcontext=aggcontext;
32983305
ExprEvalPushStep(state,scratch);
3299-
3300-
/* adjust jumps so they jump till after transition invocation */
3301-
if (adjust_init_jumpnull!=-1)
3302-
{
3303-
ExprEvalStep*as=&state->steps[adjust_init_jumpnull];
3304-
3305-
Assert(as->d.agg_init_trans.jumpnull==-1);
3306-
as->d.agg_init_trans.jumpnull=state->steps_len;
3307-
}
3308-
if (adjust_strict_jumpnull!=-1)
3309-
{
3310-
ExprEvalStep*as=&state->steps[adjust_strict_jumpnull];
3311-
3312-
Assert(as->d.agg_strict_trans_check.jumpnull==-1);
3313-
as->d.agg_strict_trans_check.jumpnull=state->steps_len;
3314-
}
33153306
}
33163307

33173308
/*

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp