From 35b92aea89b13edd2036190068fb4f67c9cbb44f Mon Sep 17 00:00:00 2001 From: cailei19 Date: Thu, 16 Mar 2023 23:22:48 -0700 Subject: [PATCH] agg expr step reduce --- src/common/backend/catalog/builtin_funcs.ini | 16 +- src/gausskernel/optimizer/util/clauses.cpp | 47 +- src/gausskernel/runtime/executor/execExpr.cpp | 128 ++-- .../runtime/executor/execExprInterp.cpp | 545 ++++++++++-------- src/gausskernel/runtime/executor/nodeAgg.cpp | 320 ++++++---- .../runtime/vecexecutor/vecnode/vecagg.cpp | 9 +- .../vecexecutor/vecnode/vecwindowagg.cpp | 59 +- src/include/executor/node/nodeAgg.h | 1 + src/include/nodes/execExpr.h | 53 +- 9 files changed, 661 insertions(+), 517 deletions(-) diff --git a/src/common/backend/catalog/builtin_funcs.ini b/src/common/backend/catalog/builtin_funcs.ini index a9fcebd01..24c70d2cf 100755 --- a/src/common/backend/catalog/builtin_funcs.ini +++ b/src/common/backend/catalog/builtin_funcs.ini @@ -5707,7 +5707,7 @@ ), AddFuncGroup( "int8_avg_accum_numeric", 1, - AddBuiltinFunc(_0(5439), _1("int8_avg_accum_numeric"), _2(2), _3(false), _4(false), _5(int8_avg_accum), _6(2281), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 2281, 20), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("int8_avg_accum"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33(NULL), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(5439), _1("int8_avg_accum_numeric"), _2(2), _3(false), _4(false), _5(int8_avg_accum_numeric), _6(2281), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 2281, 20), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("int8_avg_accum_numeric"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33(NULL), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "int8_avg_collect", 1, @@ -7265,7 +7265,7 @@ ), AddFuncGroup( "numeric_accum_numeric", 1, - AddBuiltinFunc(_0(5440), _1("numeric_accum_numeric"), _2(2), _3(false), _4(false), _5(numeric_accum), _6(2281), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 2281, 1700), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("numeric_accum"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("aggregate transition function"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(5440), _1("numeric_accum_numeric"), _2(2), _3(false), _4(false), _5(numeric_accum_numeric), _6(2281), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 2281, 1700), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("numeric_accum_numeric"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("aggregate transition function"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "numeric_add", 1, @@ -7277,7 +7277,7 @@ ), AddFuncGroup( "numeric_avg_numeric", 1, - AddBuiltinFunc(_0(5441), _1("numeric_avg_numeric"), _2(1), _3(false), _4(false), _5(numeric_avg), _6(1700), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("numeric_avg"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("aggregate final function"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(5441), _1("numeric_avg_numeric"), _2(1), _3(false), _4(false), _5(numeric_avg_numeric), _6(1700), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("numeric_avg_numeric"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("aggregate final function"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "numeric_avg_accum", 1, @@ -7285,7 +7285,7 @@ ), AddFuncGroup( "numeric_avg_accum_numeric", 1, - AddBuiltinFunc(_0(5442), _1("numeric_avg_accum_numeric"), _2(2), _3(false), _4(false), _5(numeric_avg_accum), _6(1231), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 2281, 1700), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("numeric_avg_accum"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("aggregate transition function"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(5442), _1("numeric_avg_accum_numeric"), _2(2), _3(false), _4(false), _5(numeric_avg_accum_numeric), _6(1231), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 2281, 1700), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("numeric_avg_accum_numeric"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("aggregate transition function"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "numeric_avg_collect", 1, @@ -7421,7 +7421,7 @@ ), AddFuncGroup( "numeric_stddev_pop_numeric", 1, - AddBuiltinFunc(_0(5443), _1("numeric_stddev_pop_numeric"), _2(1), _3(false), _4(false), _5(numeric_stddev_pop), _6(1700), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("numeric_stddev_pop"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("aggregate final function"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(5443), _1("numeric_stddev_pop_numeric"), _2(1), _3(false), _4(false), _5(numeric_stddev_pop_numeric), _6(1700), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("numeric_stddev_pop_numeric"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("aggregate final function"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "numeric_stddev_samp", 1, @@ -7429,7 +7429,7 @@ ), AddFuncGroup( "numeric_stddev_samp_numeric", 1, - AddBuiltinFunc(_0(5444), _1("numeric_stddev_samp_numeric"), _2(1), _3(false), _4(false), _5(numeric_stddev_samp), _6(1700), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("numeric_stddev_samp"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("aggregate final function"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(5444), _1("numeric_stddev_samp_numeric"), _2(1), _3(false), _4(false), _5(numeric_stddev_samp_numeric), _6(1700), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("numeric_stddev_samp_numeric"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("aggregate final function"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "numeric_sub", 1, @@ -7461,7 +7461,7 @@ ), AddFuncGroup( "numeric_var_pop_numeric", 1, - AddBuiltinFunc(_0(5445), _1("numeric_var_pop_numeric"), _2(1), _3(false), _4(false), _5(numeric_var_pop), _6(1700), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("numeric_var_pop"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("aggregate final function"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(5445), _1("numeric_var_pop_numeric"), _2(1), _3(false), _4(false), _5(numeric_var_pop_numeric), _6(1700), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("numeric_var_pop_numeric"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("aggregate final function"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "numeric_var_samp", 1, @@ -7469,7 +7469,7 @@ ), AddFuncGroup( "numeric_var_samp_numeric", 1, - AddBuiltinFunc(_0(5446), _1("numeric_var_samp_numeric"), _2(1), _3(false), _4(false), _5(numeric_var_samp), _6(1700), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("numeric_var_samp"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("aggregate final function"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(5446), _1("numeric_var_samp_numeric"), _2(1), _3(false), _4(false), _5(numeric_var_samp_numeric), _6(1700), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("numeric_var_samp_numeric"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("aggregate final function"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "numeric_varchar", 1, diff --git a/src/gausskernel/optimizer/util/clauses.cpp b/src/gausskernel/optimizer/util/clauses.cpp index 140806240..f67ce201f 100644 --- a/src/gausskernel/optimizer/util/clauses.cpp +++ b/src/gausskernel/optimizer/util/clauses.cpp @@ -696,27 +696,32 @@ static void count_agg_clauses_walker_isa(Node* node, count_agg_clauses_context* * but the difference of pg_aggregate bwtween pg and og * we have to do some hard code here(og's pg_aggregate doesn't have the column aggtransspace) */ - switch (aggtransfn) { - case 5439: /* int8_avg_accum_numeric */ - costs->transitionSpace +=48; - costs->aggWidth += 48; - break; - case 5440: /* numeric_accum_numeric */ - case 5442: /* numeric_avg_accum_numeric */ - costs->transitionSpace += 128; - costs->aggWidth += 128; - break; - default: - /* - * INTERNAL transition type is a special case: although INTERNAL - * is pass-by-value, it's almost certainly being used as a pointer - * to some large data structure. We assume usage of - * ALLOCSET_DEFAULT_INITSIZE, which is a good guess if the data is - * being kept in a private memory context, as is done by - * array_agg() for instance. - */ - costs->transitionSpace += ALLOCSET_DEFAULT_INITSIZE; - costs->aggWidth += ALLOCSET_DEFAULT_INITSIZE; + if (u_sess->attr.attr_common.enable_expr_fusion && u_sess->attr.attr_sql.query_dop_tmp == 1) { + switch (aggtransfn) { + case 5439: /* int8_avg_accum_numeric */ + costs->transitionSpace +=48; + costs->aggWidth += 48; + break; + case 5440: /* numeric_accum_numeric */ + case 5442: /* numeric_avg_accum_numeric */ + costs->transitionSpace += 128; + costs->aggWidth += 128; + break; + default: + /* + * INTERNAL transition type is a special case: although INTERNAL + * is pass-by-value, it's almost certainly being used as a pointer + * to some large data structure. We assume usage of + * ALLOCSET_DEFAULT_INITSIZE, which is a good guess if the data is + * being kept in a private memory context, as is done by + * array_agg() for instance. + */ + costs->transitionSpace += ALLOCSET_DEFAULT_INITSIZE; + costs->aggWidth += ALLOCSET_DEFAULT_INITSIZE; + } + } else { + costs->transitionSpace += ALLOCSET_DEFAULT_INITSIZE; + costs->aggWidth += ALLOCSET_DEFAULT_INITSIZE; } #else /* diff --git a/src/gausskernel/runtime/executor/execExpr.cpp b/src/gausskernel/runtime/executor/execExpr.cpp index 3102548ed..ad0aca78a 100644 --- a/src/gausskernel/runtime/executor/execExpr.cpp +++ b/src/gausskernel/runtime/executor/execExpr.cpp @@ -2993,89 +2993,75 @@ ExprState *ExecBuildAggTrans(AggState *aggstate, AggStatePerPhase phase, bool do return state; } -/* - * Build transition/combine function invocation for a single transition - * value. This is separated from ExecBuildAggTrans() because there are - * multiple callsites (hash and sort in some grouping set cases). - */ -static void ExecBuildAggTransCall(ExprState *state, AggState *aggstate, ExprEvalStep *scratch, FunctionCallInfo fcinfo, - AggStatePerTrans pertrans, int transno, int setno, int setoff, bool ishash, - bool iscollect) +static ExprEvalOp ExecBuildAggTransOpcodeInit(AggStatePerTrans pertrans, FunctionCallInfo fcinfo) +{ + /* trans by val */ + if (pertrans->transtypeByVal) { + if (fcinfo->flinfo->fn_strict && pertrans->initValueIsNull) { + return EEOP_AGG_PLAIN_TRANS_INIT_STRICT_BYVAL; + } else if (fcinfo->flinfo->fn_strict) { + return EEOP_AGG_PLAIN_TRANS_STRICT_BYVAL; + } else { + return EEOP_AGG_PLAIN_TRANS_BYVAL; + } + } + + /* trans by ref */ + if (fcinfo->flinfo->fn_strict && pertrans->initValueIsNull) { + return EEOP_AGG_PLAIN_TRANS_INIT_STRICT_BYREF; + } else if (fcinfo->flinfo->fn_strict) { + return EEOP_AGG_PLAIN_TRANS_STRICT_BYREF; + } else { + return EEOP_AGG_PLAIN_TRANS_BYREF; + } +} + +static ExprEvalOp ExecBuildAggCollectOpcodeInit(AggStatePerTrans pertrans, FunctionCallInfo fcinfo) +{ + /* collect by val */ + if (pertrans->transtypeByVal) { + if (fcinfo->flinfo->fn_strict && pertrans->initCollectValueIsNull) { + return EEOP_AGG_COLLECT_PLAIN_TRANS_INIT_STRICT_BYVAL; + } else if (fcinfo->flinfo->fn_strict) { + return EEOP_AGG_COLLECT_PLAIN_TRANS_STRICT_BYVAL; + } else { + return EEOP_AGG_COLLECT_PLAIN_TRANS_BYVAL; + } + } + + /* collect by ref */ + if (fcinfo->flinfo->fn_strict && pertrans->initCollectValueIsNull) { + return EEOP_AGG_COLLECT_PLAIN_TRANS_INIT_STRICT_BYREF; + } else if (fcinfo->flinfo->fn_strict) { + return EEOP_AGG_COLLECT_PLAIN_TRANS_STRICT_BYREF; + } else { + return EEOP_AGG_COLLECT_PLAIN_TRANS_BYREF; + } +} + +static void ExecBuildAggTransCall(ExprState *state, AggState *aggstate, ExprEvalStep *scratch, FunctionCallInfo fcinfo, + AggStatePerTrans pertrans, int transno, int setno, int setoff, bool ishash, bool iscollect) { - int adjust_init_jumpnull = -1; - int adjust_strict_jumpnull = -1; MemoryContext aggcontext; aggcontext = aggstate->aggcontexts[setno]; - /* - * If the initial value for the transition state doesn't exist in the - * pg_aggregate table then we will let the first non-NULL value returned - * from the outer procNode become the initial value. (This is useful for - * aggregates like max() and min().) The noTransValue flag signals that we - * still need to do this. - */ - if (pertrans->numSortCols == 0 && fcinfo->flinfo->fn_strict && pertrans->initValueIsNull) { - scratch->opcode = iscollect ? EEOP_AGG_COLLECT_INIT_TRANS : EEOP_AGG_INIT_TRANS; - scratch->d.agg_init_trans.aggstate = aggstate; - scratch->d.agg_init_trans.pertrans = pertrans; - scratch->d.agg_init_trans.setno = setno; - scratch->d.agg_init_trans.setoff = setoff; - scratch->d.agg_init_trans.transno = transno; - scratch->d.agg_init_trans.aggcontext = aggcontext; - scratch->d.agg_init_trans.jumpnull = -1; /* adjust later */ - ExprEvalPushStep(state, scratch); - - /* see comment about jumping out below */ - adjust_init_jumpnull = state->steps_len - 1; - } - - if (pertrans->numSortCols == 0 && fcinfo->flinfo->fn_strict) { - scratch->opcode = iscollect ? EEOP_AGG_COLLECT_STRICT_TRANS_CHECK : EEOP_AGG_STRICT_TRANS_CHECK; - scratch->d.agg_strict_trans_check.aggstate = aggstate; - scratch->d.agg_strict_trans_check.setno = setno; - scratch->d.agg_strict_trans_check.setoff = setoff; - scratch->d.agg_strict_trans_check.transno = transno; - scratch->d.agg_strict_trans_check.jumpnull = -1; /* adjust later */ - ExprEvalPushStep(state, scratch); - - /* - * Note, we don't push into adjust_bailout here - those jump to the - * end of all transition value computations. Here a single transition - * value is NULL, so just skip processing the individual value. - */ - adjust_strict_jumpnull = state->steps_len - 1; - } - - /* invoke appropriate transition implementation */ - if (pertrans->numSortCols == 0 && pertrans->transtypeByVal) - scratch->opcode = iscollect ? EEOP_AGG_COLLECT_PLAIN_TRANS_BYVAL : EEOP_AGG_PLAIN_TRANS_BYVAL; - else if (pertrans->numSortCols == 0) - scratch->opcode = iscollect ? EEOP_AGG_COLLECT_PLAIN_TRANS : EEOP_AGG_PLAIN_TRANS; - else if (pertrans->numInputs == 1) + if (pertrans->numSortCols == 0) { + if (iscollect) { + scratch->opcode = ExecBuildAggCollectOpcodeInit(pertrans, fcinfo); + } else { + scratch->opcode = ExecBuildAggTransOpcodeInit(pertrans, fcinfo); + } + } else if (pertrans->numInputs == 1) { scratch->opcode = EEOP_AGG_ORDERED_TRANS_DATUM; - else + } else { scratch->opcode = EEOP_AGG_ORDERED_TRANS_TUPLE; + } - scratch->d.agg_trans.aggstate = aggstate; scratch->d.agg_trans.pertrans = pertrans; scratch->d.agg_trans.setno = setno; scratch->d.agg_trans.setoff = setoff; scratch->d.agg_trans.transno = transno; scratch->d.agg_trans.aggcontext = aggcontext; ExprEvalPushStep(state, scratch); - - /* adjust jumps so they jump till after transition invocation */ - if (adjust_init_jumpnull != -1) { - ExprEvalStep *as = &state->steps[adjust_init_jumpnull]; - - Assert(as->d.agg_init_trans.jumpnull == -1); - as->d.agg_init_trans.jumpnull = state->steps_len; - } - if (adjust_strict_jumpnull != -1) { - ExprEvalStep *as = &state->steps[adjust_strict_jumpnull]; - - Assert(as->d.agg_strict_trans_check.jumpnull == -1); - as->d.agg_strict_trans_check.jumpnull = state->steps_len; - } } \ No newline at end of file diff --git a/src/gausskernel/runtime/executor/execExprInterp.cpp b/src/gausskernel/runtime/executor/execExprInterp.cpp index 602f9abba..3276f7913 100644 --- a/src/gausskernel/runtime/executor/execExprInterp.cpp +++ b/src/gausskernel/runtime/executor/execExprInterp.cpp @@ -64,7 +64,6 @@ #include "utils/memutils.h" #include "miscadmin.h" #include "nodes/nodeFuncs.h" -#include "nodes/execExpr.h" #include "parser/parsetree.h" #include "pgstat.h" #include "utils/builtins.h" @@ -168,6 +167,15 @@ extern bool func_has_refcursor_args(Oid Funcid, FunctionCallInfoData* fcinfo); extern void check_huge_clob_paramter(FunctionCallInfoData* fcinfo, bool is_have_huge_clob); extern Datum fetch_lob_value_from_tuple(varatt_lob_pointer* lob_pointer, Oid update_oid, bool* is_null); +static FORCE_INLINE void ExecAggPlainTransByVal(AggState *aggstate, AggStatePerTrans pertrans, + AggStatePerGroup pergroup, MemoryContext aggcontext, int setno); +static FORCE_INLINE void ExecAggCollectPlainTransByVal(AggState *aggstate, AggStatePerTrans pertrans, + AggStatePerGroup pergroup, MemoryContext aggcontext, int setno); +static FORCE_INLINE void ExecAggPlainTransByRef(AggState *aggstate, AggStatePerTrans pertrans, + AggStatePerGroup pergroup, MemoryContext aggcontext, int setno); +static FORCE_INLINE void ExecAggCollectPlainTransByRef(AggState *aggstate, AggStatePerTrans pertrans, + AggStatePerGroup pergroup, MemoryContext aggcontext, int setno); + /* * Prepare ExprState for interpreted execution. */ @@ -595,14 +603,18 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull, ExprDoneCo &&CASE_EEOP_AGG_STRICT_DESERIALIZE, &&CASE_EEOP_AGG_DESERIALIZE, &&CASE_EEOP_AGG_STRICT_INPUT_CHECK, - &&CASE_EEOP_AGG_INIT_TRANS, - &&CASE_EEOP_AGG_COLLECT_INIT_TRANS, - &&CASE_EEOP_AGG_STRICT_TRANS_CHECK, - &&CASE_EEOP_AGG_COLLECT_STRICT_TRANS_CHECK, + &&CASE_EEOP_AGG_PLAIN_TRANS_INIT_STRICT_BYVAL, + &&CASE_EEOP_AGG_COLLECT_PLAIN_TRANS_INIT_STRICT_BYVAL, + &&CASE_EEOP_AGG_PLAIN_TRANS_STRICT_BYVAL, + &&CASE_EEOP_AGG_COLLECT_PLAIN_TRANS_STRICT_BYVAL, &&CASE_EEOP_AGG_PLAIN_TRANS_BYVAL, &&CASE_EEOP_AGG_COLLECT_PLAIN_TRANS_BYVAL, - &&CASE_EEOP_AGG_PLAIN_TRANS, - &&CASE_EEOP_AGG_COLLECT_PLAIN_TRANS, + &&CASE_EEOP_AGG_PLAIN_TRANS_INIT_STRICT_BYREF, + &&CASE_EEOP_AGG_COLLECT_PLAIN_TRANS_INIT_STRICT_BYREF, + &&CASE_EEOP_AGG_PLAIN_TRANS_STRICT_BYREF, + &&CASE_EEOP_AGG_COLLECT_PLAIN_TRANS_STRICT_BYREF, + &&CASE_EEOP_AGG_PLAIN_TRANS_BYREF, + &&CASE_EEOP_AGG_COLLECT_PLAIN_TRANS_BYREF, &&CASE_EEOP_AGG_ORDERED_TRANS_DATUM, &&CASE_EEOP_AGG_ORDERED_TRANS_TUPLE, &&CASE_EEOP_LAST @@ -1626,304 +1638,248 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull, ExprDoneCo EEO_NEXT(); } - /* - * Initialize an aggregate's first value if necessary. - */ - EEO_CASE(EEOP_AGG_INIT_TRANS) + EEO_CASE(EEOP_AGG_PLAIN_TRANS_INIT_STRICT_BYVAL) { - AggState *aggstate; - AggStatePerGroup pergroup; + AggState *aggstate = castNode(AggState, state->parent); + AggStatePerTrans pertrans = op->d.agg_trans.pertrans; + AggStatePerGroup pergroup = &aggstate->all_pergroups + [op->d.agg_trans.setoff * aggstate->numtrans + op->d.agg_trans.transno]; - aggstate = op->d.agg_init_trans.aggstate; - pergroup = - &aggstate - ->all_pergroups[op->d.agg_init_trans.setoff * aggstate->numtrans + op->d.agg_init_trans.transno]; + Assert(pertrans->transtypeByVal); - /* If transValue has not yet been initialized, do so now. */ if (pergroup->noTransValue) { - AggStatePerTrans pertrans = op->d.agg_init_trans.pertrans; - - aggstate->curaggcontext = op->d.agg_init_trans.aggcontext; - aggstate->current_set = op->d.agg_init_trans.setno; - - ExecAggInitGroup(aggstate, pertrans, pergroup, op->d.agg_init_trans.aggcontext); - + /* If transValue has not yet been initialized, do so now. */ + ExecAggInitGroup(aggstate, pertrans, pergroup, op->d.agg_trans.aggcontext); /* copied trans value from input, done this round */ - EEO_JUMP(op->d.agg_init_trans.jumpnull); + } else if (likely(!pergroup->transValueIsNull)) { + /* invoke transition function, unless prevented by strictness */ + ExecAggPlainTransByVal(aggstate, pertrans, pergroup, + op->d.agg_trans.aggcontext, + op->d.agg_trans.setno); } EEO_NEXT(); } - /* - * Initialize an aggregate's collect first value if necessary. - */ - EEO_CASE(EEOP_AGG_COLLECT_INIT_TRANS) + + EEO_CASE(EEOP_AGG_COLLECT_PLAIN_TRANS_INIT_STRICT_BYVAL) { - AggState *aggstate; - AggStatePerGroup pergroup; + AggState *aggstate = castNode(AggState, state->parent); + AggStatePerTrans pertrans = op->d.agg_trans.pertrans; + AggStatePerGroup pergroup = &aggstate->all_pergroups + [op->d.agg_trans.setoff * aggstate->numtrans + + op->d.agg_trans.transno]; - aggstate = op->d.agg_init_trans.aggstate; - pergroup = - &aggstate - ->all_pergroups[op->d.agg_init_trans.setoff * aggstate->numtrans + op->d.agg_init_trans.transno]; + Assert(pertrans->transtypeByVal); - /* If transValue has not yet been initialized, do so now. */ if (pergroup->noCollectValue) { - AggStatePerTrans pertrans = op->d.agg_init_trans.pertrans; - - aggstate->curaggcontext = op->d.agg_init_trans.aggcontext; - aggstate->current_set = op->d.agg_init_trans.setno; - - ExecAggInitCollectGroup(aggstate, pertrans, pergroup, op->d.agg_init_trans.aggcontext); - + /* If transValue has not yet been initialized, do so now. */ + ExecAggInitCollectGroup(aggstate, pertrans, pergroup, + op->d.agg_trans.aggcontext); /* copied trans value from input, done this round */ - EEO_JUMP(op->d.agg_init_trans.jumpnull); + } else if (likely(!pergroup->collectValueIsNull)) { + /* invoke transition function, unless prevented by strictness */ + ExecAggCollectPlainTransByVal(aggstate, pertrans, pergroup, + op->d.agg_trans.aggcontext, + op->d.agg_trans.setno); } EEO_NEXT(); } - /* check that a strict aggregate's input isn't NULL */ - EEO_CASE(EEOP_AGG_STRICT_TRANS_CHECK) + /* see comments above EEOP_AGG_PLAIN_TRANS_INIT_STRICT_BYVAL */ + EEO_CASE(EEOP_AGG_PLAIN_TRANS_STRICT_BYVAL) { - AggState *aggstate; - AggStatePerGroup pergroup; + AggState *aggstate = castNode(AggState, state->parent); + AggStatePerTrans pertrans = op->d.agg_trans.pertrans; + AggStatePerGroup pergroup = &aggstate->all_pergroups + [op->d.agg_trans.setoff * aggstate->numtrans + + op->d.agg_trans.transno]; - aggstate = op->d.agg_strict_trans_check.aggstate; - pergroup = &aggstate->all_pergroups[op->d.agg_strict_trans_check.setoff * aggstate->numtrans + - op->d.agg_strict_trans_check.transno]; + Assert(pertrans->transtypeByVal); - if (unlikely(pergroup->transValueIsNull)) - EEO_JUMP(op->d.agg_strict_trans_check.jumpnull); - - EEO_NEXT(); - } - /* check that a strict aggregate's collect input isn't NULL */ - EEO_CASE(EEOP_AGG_COLLECT_STRICT_TRANS_CHECK) - { - AggState *aggstate; - AggStatePerGroup pergroup; - - aggstate = op->d.agg_strict_trans_check.aggstate; - pergroup = &aggstate->all_pergroups[op->d.agg_strict_trans_check.setoff * aggstate->numtrans + - op->d.agg_strict_trans_check.transno]; - - if (unlikely(pergroup->collectValueIsNull)) - EEO_JUMP(op->d.agg_strict_trans_check.jumpnull); + if (likely(!pergroup->transValueIsNull)) { + ExecAggPlainTransByVal(aggstate, pertrans, pergroup, + op->d.agg_trans.aggcontext, + op->d.agg_trans.setno); + } EEO_NEXT(); } - /* - * Evaluate aggregate transition / combine function that has a - * by-value transition type. That's a seperate case from the - * by-reference implementation because it's a bit simpler. - */ + /* see comments above EEOP_AGG_PLAIN_TRANS_INIT_STRICT_BYVAL */ + EEO_CASE(EEOP_AGG_COLLECT_PLAIN_TRANS_STRICT_BYVAL) + { + AggState *aggstate = castNode(AggState, state->parent); + AggStatePerTrans pertrans = op->d.agg_trans.pertrans; + AggStatePerGroup pergroup = &aggstate->all_pergroups + [op->d.agg_trans.setoff * aggstate->numtrans + + op->d.agg_trans.transno]; + + + Assert(pertrans->transtypeByVal); + + if (likely(!pergroup->collectValueIsNull)) { + ExecAggCollectPlainTransByVal(aggstate, pertrans, pergroup, + op->d.agg_trans.aggcontext, + op->d.agg_trans.setno); + } + + EEO_NEXT(); + } + + /* see comments above EEOP_AGG_PLAIN_TRANS_INIT_STRICT_BYVAL */ EEO_CASE(EEOP_AGG_PLAIN_TRANS_BYVAL) { - AggState *aggstate; - AggStatePerTrans pertrans; - AggStatePerGroup pergroup; - FunctionCallInfo fcinfo; - MemoryContext oldContext; - Datum newVal; + AggState *aggstate = castNode(AggState, state->parent); + AggStatePerTrans pertrans = op->d.agg_trans.pertrans; + AggStatePerGroup pergroup = &aggstate->all_pergroups + [op->d.agg_trans.setoff * aggstate->numtrans + + op->d.agg_trans.transno]; - aggstate = op->d.agg_trans.aggstate; - pertrans = op->d.agg_trans.pertrans; - - pergroup = &aggstate->all_pergroups[op->d.agg_trans.setoff * aggstate->numtrans + op->d.agg_trans.transno]; Assert(pertrans->transtypeByVal); - fcinfo = &pertrans->transfn_fcinfo; - - /* cf. select_current_set() */ - aggstate->curaggcontext = op->d.agg_trans.aggcontext; - aggstate->current_set = op->d.agg_trans.setno; - - /* set up aggstate->curpertrans for AggGetAggref() */ - aggstate->curpertrans = pertrans; - - /* invoke transition function in per-tuple context */ - oldContext = MemoryContextSwitchTo(aggstate->tmpcontext->ecxt_per_tuple_memory); - - fcinfo->arg[0] = pergroup->transValue; - fcinfo->argnull[0] = pergroup->transValueIsNull; - fcinfo->isnull = false; /* just in case transfn doesn't set it */ - - newVal = FunctionCallInvoke(fcinfo); - - pergroup->transValue = newVal; - pergroup->transValueIsNull = fcinfo->isnull; - - MemoryContextSwitchTo(oldContext); + ExecAggPlainTransByVal(aggstate, pertrans, pergroup, + op->d.agg_trans.aggcontext, + op->d.agg_trans.setno); EEO_NEXT(); } - /* - * Evaluate aggregate collect function that has a - * by-value transition type. That's a seperate case from the - * by-reference implementation because it's a bit simpler. - */ + + /* see comments above EEOP_AGG_PLAIN_TRANS_INIT_STRICT_BYVAL */ EEO_CASE(EEOP_AGG_COLLECT_PLAIN_TRANS_BYVAL) { - AggState *aggstate; - AggStatePerTrans pertrans; - AggStatePerGroup pergroup; - FunctionCallInfo fcinfo; - MemoryContext oldContext; - Datum newVal; + AggState *aggstate = castNode(AggState, state->parent); + AggStatePerTrans pertrans = op->d.agg_trans.pertrans; + AggStatePerGroup pergroup = &aggstate->all_pergroups + [op->d.agg_trans.setoff * aggstate->numtrans + + op->d.agg_trans.transno]; - aggstate = op->d.agg_trans.aggstate; - pertrans = op->d.agg_trans.pertrans; - - pergroup = &aggstate->all_pergroups[op->d.agg_trans.setoff * aggstate->numtrans + op->d.agg_trans.transno]; Assert(pertrans->transtypeByVal); - fcinfo = &pertrans->collectfn_fcinfo; - - /* cf. select_current_set() */ - aggstate->curaggcontext = op->d.agg_trans.aggcontext; - aggstate->current_set = op->d.agg_trans.setno; - - /* set up aggstate->curpertrans for AggGetAggref() */ - aggstate->curpertrans = pertrans; - - /* invoke transition function in per-tuple context */ - oldContext = MemoryContextSwitchTo(aggstate->tmpcontext->ecxt_per_tuple_memory); - - fcinfo->arg[0] = pergroup->collectValue; - fcinfo->argnull[0] = pergroup->collectValueIsNull; - fcinfo->isnull = false; /* just in case transfn doesn't set it */ - - newVal = FunctionCallInvoke(fcinfo); - - pergroup->collectValue = newVal; - pergroup->collectValueIsNull = fcinfo->isnull; - - MemoryContextSwitchTo(oldContext); + ExecAggCollectPlainTransByVal(aggstate, pertrans, pergroup, + op->d.agg_trans.aggcontext, + op->d.agg_trans.setno); EEO_NEXT(); } - /* - * Evaluate aggregate transition / combine function that has a - * by-reference transition type. - * - * Could optimize a bit further by splitting off by-reference - * fixed-length types, but currently that doesn't seem worth it. - */ - EEO_CASE(EEOP_AGG_PLAIN_TRANS) + /* see comments above EEOP_AGG_PLAIN_TRANS_INIT_STRICT_BYVAL */ + EEO_CASE(EEOP_AGG_PLAIN_TRANS_INIT_STRICT_BYREF) { - AggState *aggstate; - AggStatePerTrans pertrans; - AggStatePerGroup pergroup; - FunctionCallInfo fcinfo; - MemoryContext oldContext; - Datum newVal; + AggState *aggstate = castNode(AggState, state->parent); + AggStatePerTrans pertrans = op->d.agg_trans.pertrans; + AggStatePerGroup pergroup = &aggstate->all_pergroups + [op->d.agg_trans.setoff * aggstate->numtrans + + op->d.agg_trans.transno]; - aggstate = op->d.agg_trans.aggstate; - pertrans = op->d.agg_trans.pertrans; - - pergroup = &aggstate->all_pergroups[op->d.agg_trans.setoff * aggstate->numtrans + op->d.agg_trans.transno]; Assert(!pertrans->transtypeByVal); - fcinfo = &pertrans->transfn_fcinfo; - - /* cf. select_current_set() */ - aggstate->curaggcontext = op->d.agg_trans.aggcontext; - aggstate->current_set = op->d.agg_trans.setno; - - /* set up aggstate->curpertrans for AggGetAggref() */ - aggstate->curpertrans = pertrans; - - /* invoke transition function in per-tuple context */ - oldContext = MemoryContextSwitchTo(aggstate->tmpcontext->ecxt_per_tuple_memory); - - fcinfo->arg[0] = pergroup->transValue; - fcinfo->argnull[0] = pergroup->transValueIsNull; - fcinfo->isnull = false; /* just in case transfn doesn't set it */ - - newVal = FunctionCallInvoke(fcinfo); - - /* - * For pass-by-ref datatype, must copy the new value into - * aggcontext and free the prior transValue. But if transfn - * returned a pointer to its first input, we don't need to do - * anything. Also, if transfn returned a pointer to a R/W - * expanded object that is already a child of the aggcontext, - * assume we can adopt that value without copying it. - */ - if (DatumGetPointer(newVal) != DatumGetPointer(pergroup->transValue)) - newVal = ExecAggTransReparent(aggstate, pertrans, newVal, fcinfo->isnull, pergroup->transValue, - pergroup->transValueIsNull); - - pergroup->transValue = newVal; - pergroup->transValueIsNull = fcinfo->isnull; - - MemoryContextSwitchTo(oldContext); + if (pergroup->noTransValue) { + ExecAggInitGroup(aggstate, pertrans, pergroup, op->d.agg_trans.aggcontext); + } else if (likely(!pergroup->transValueIsNull)) { + ExecAggPlainTransByRef(aggstate, pertrans, pergroup, + op->d.agg_trans.aggcontext, + op->d.agg_trans.setno); + } EEO_NEXT(); } - /* - * Evaluate aggregate collect function that has a - * by-reference transition type. - * - * Could optimize a bit further by splitting off by-reference - * fixed-length types, but currently that doesn't seem worth it. - */ - EEO_CASE(EEOP_AGG_COLLECT_PLAIN_TRANS) + + /* see comments above EEOP_AGG_PLAIN_TRANS_INIT_STRICT_BYVAL */ + EEO_CASE(EEOP_AGG_COLLECT_PLAIN_TRANS_INIT_STRICT_BYREF) { - AggState *aggstate; - AggStatePerTrans pertrans; - AggStatePerGroup pergroup; - FunctionCallInfo fcinfo; - MemoryContext oldContext; - Datum newVal; + AggState *aggstate = castNode(AggState, state->parent); + AggStatePerTrans pertrans = op->d.agg_trans.pertrans; + AggStatePerGroup pergroup = &aggstate->all_pergroups + [op->d.agg_trans.setoff * aggstate->numtrans + + op->d.agg_trans.transno]; - aggstate = op->d.agg_trans.aggstate; - pertrans = op->d.agg_trans.pertrans; - - pergroup = &aggstate->all_pergroups[op->d.agg_trans.setoff * aggstate->numtrans + op->d.agg_trans.transno]; Assert(!pertrans->transtypeByVal); - fcinfo = &pertrans->collectfn_fcinfo; + if (pergroup->noCollectValue) { + ExecAggInitCollectGroup(aggstate, pertrans, pergroup, op->d.agg_trans.aggcontext); + } else if (likely(!pergroup->collectValueIsNull)) { + ExecAggCollectPlainTransByRef(aggstate, pertrans, pergroup, + op->d.agg_trans.aggcontext, + op->d.agg_trans.setno); + } - /* cf. select_current_set() */ - aggstate->curaggcontext = op->d.agg_trans.aggcontext; - aggstate->current_set = op->d.agg_trans.setno; + EEO_NEXT(); + } + - /* set up aggstate->curpertrans for AggGetAggref() */ - aggstate->curpertrans = pertrans; + /* see comments above EEOP_AGG_PLAIN_TRANS_INIT_STRICT_BYVAL */ + EEO_CASE(EEOP_AGG_PLAIN_TRANS_STRICT_BYREF) + { + AggState *aggstate = castNode(AggState, state->parent); + AggStatePerTrans pertrans = op->d.agg_trans.pertrans; + AggStatePerGroup pergroup = &aggstate->all_pergroups + [op->d.agg_trans.setoff * aggstate->numtrans + + op->d.agg_trans.transno]; - /* invoke transition function in per-tuple context */ - oldContext = MemoryContextSwitchTo(aggstate->tmpcontext->ecxt_per_tuple_memory); + Assert(!pertrans->transtypeByVal); - fcinfo->arg[0] = pergroup->collectValue; - fcinfo->argnull[0] = pergroup->collectValueIsNull; - fcinfo->isnull = false; /* just in case transfn doesn't set it */ + if (likely(!pergroup->transValueIsNull)) + ExecAggPlainTransByRef(aggstate, pertrans, pergroup, + op->d.agg_trans.aggcontext, + op->d.agg_trans.setno); + EEO_NEXT(); + } - newVal = FunctionCallInvoke(fcinfo); + /* see comments above EEOP_AGG_PLAIN_TRANS_INIT_STRICT_BYVAL */ + EEO_CASE(EEOP_AGG_COLLECT_PLAIN_TRANS_STRICT_BYREF) + { + AggState *aggstate = castNode(AggState, state->parent); + AggStatePerTrans pertrans = op->d.agg_trans.pertrans; + AggStatePerGroup pergroup = &aggstate->all_pergroups + [op->d.agg_trans.setoff * aggstate->numtrans + + op->d.agg_trans.transno]; - /* - * For pass-by-ref datatype, must copy the new value into - * aggcontext and free the prior transValue. But if transfn - * returned a pointer to its first input, we don't need to do - * anything. Also, if transfn returned a pointer to a R/W - * expanded object that is already a child of the aggcontext, - * assume we can adopt that value without copying it. - */ - if (DatumGetPointer(newVal) != DatumGetPointer(pergroup->transValue)) - newVal = ExecAggTransReparent(aggstate, pertrans, newVal, fcinfo->isnull, pergroup->collectValue, - pergroup->collectValueIsNull); + Assert(!pertrans->transtypeByVal); - pergroup->collectValue = newVal; - pergroup->collectValueIsNull = fcinfo->isnull; + if (likely(!pergroup->collectValueIsNull)) + ExecAggCollectPlainTransByRef(aggstate, pertrans, pergroup, + op->d.agg_trans.aggcontext, + op->d.agg_trans.setno); + EEO_NEXT(); + } - MemoryContextSwitchTo(oldContext); + /* see comments above EEOP_AGG_PLAIN_TRANS_INIT_STRICT_BYVAL */ + EEO_CASE(EEOP_AGG_PLAIN_TRANS_BYREF) + { + AggState *aggstate = castNode(AggState, state->parent); + AggStatePerTrans pertrans = op->d.agg_trans.pertrans; + AggStatePerGroup pergroup = &aggstate->all_pergroups + [op->d.agg_trans.setoff * aggstate->numtrans + + op->d.agg_trans.transno]; + + Assert(!pertrans->transtypeByVal); + + ExecAggPlainTransByRef(aggstate, pertrans, pergroup, + op->d.agg_trans.aggcontext, + op->d.agg_trans.setno); + + EEO_NEXT(); + } + + /* see comments above EEOP_AGG_PLAIN_TRANS_INIT_STRICT_BYVAL */ + EEO_CASE(EEOP_AGG_COLLECT_PLAIN_TRANS_BYREF) + { + AggState *aggstate = castNode(AggState, state->parent); + AggStatePerTrans pertrans = op->d.agg_trans.pertrans; + AggStatePerGroup pergroup = &aggstate->all_pergroups + [op->d.agg_trans.setoff * aggstate->numtrans + + op->d.agg_trans.transno]; + + Assert(!pertrans->transtypeByVal); + + ExecAggCollectPlainTransByRef(aggstate, pertrans, pergroup, + op->d.agg_trans.aggcontext, + op->d.agg_trans.setno); EEO_NEXT(); } @@ -4344,4 +4300,115 @@ void ExecEvalAggOrderedTransTuple(ExprState *state, ExprEvalStep *op, ExprContex pertrans->sortslot->tts_nvalid = pertrans->numInputs; ExecStoreVirtualTuple(pertrans->sortslot); tuplesort_puttupleslot(pertrans->sortstates[setno], pertrans->sortslot); +} + +static FORCE_INLINE void ExecAggPlainTransByVal(AggState *aggstate, AggStatePerTrans pertrans, + AggStatePerGroup pergroup, MemoryContext aggcontext, int setno) +{ + FunctionCallInfo fcinfo = &pertrans->transfn_fcinfo; + MemoryContext oldContext; + Datum newVal; + + aggstate->curaggcontext = aggcontext; + aggstate->current_set = setno; + aggstate->curpertrans = pertrans; + + oldContext = MemoryContextSwitchTo(aggstate->tmpcontext->ecxt_per_tuple_memory); + + fcinfo->arg[0] = pergroup->transValue; + fcinfo->argnull[0] = pergroup->transValueIsNull; + fcinfo->isnull = false; + + newVal = FunctionCallInvoke(fcinfo); + + pergroup->transValue = newVal; + pergroup->transValueIsNull = fcinfo->isnull; + + MemoryContextSwitchTo(oldContext); +} + +static FORCE_INLINE void ExecAggCollectPlainTransByVal(AggState *aggstate, AggStatePerTrans pertrans, + AggStatePerGroup pergroup, MemoryContext aggcontext, int setno) +{ + FunctionCallInfo fcinfo = &pertrans->collectfn_fcinfo; + MemoryContext oldContext; + Datum newVal; + + aggstate->curaggcontext = aggcontext; + aggstate->current_set = setno; + + aggstate->curpertrans = pertrans; + + oldContext = MemoryContextSwitchTo(aggstate->tmpcontext->ecxt_per_tuple_memory); + + fcinfo->arg[0] = pergroup->collectValue; + fcinfo->argnull[0] = pergroup->collectValueIsNull; + fcinfo->isnull = false; + + newVal = FunctionCallInvoke(fcinfo); + + pergroup->collectValue = newVal; + pergroup->collectValueIsNull = fcinfo->isnull; + + MemoryContextSwitchTo(oldContext); +} + +static FORCE_INLINE void ExecAggPlainTransByRef(AggState *aggstate, AggStatePerTrans pertrans, + AggStatePerGroup pergroup, MemoryContext aggcontext, int setno) +{ + FunctionCallInfo fcinfo = &pertrans->transfn_fcinfo; + MemoryContext oldContext; + Datum newVal; + + aggstate->curaggcontext = aggcontext; + aggstate->current_set = setno; + aggstate->curpertrans = pertrans; + + oldContext = MemoryContextSwitchTo(aggstate->tmpcontext->ecxt_per_tuple_memory); + + fcinfo->arg[0] = pergroup->transValue; + fcinfo->argnull[0] = pergroup->transValueIsNull; + fcinfo->isnull = false; + + newVal = FunctionCallInvoke(fcinfo); + + if (DatumGetPointer(newVal) != DatumGetPointer(pergroup->transValue)) { + newVal = ExecAggTransReparent(aggstate, pertrans, newVal, fcinfo->isnull, pergroup->transValue, + pergroup->transValueIsNull); + } + + pergroup->transValue = newVal; + pergroup->transValueIsNull = fcinfo->isnull; + + MemoryContextSwitchTo(oldContext); +} + +static FORCE_INLINE void ExecAggCollectPlainTransByRef(AggState *aggstate, AggStatePerTrans pertrans, + AggStatePerGroup pergroup, MemoryContext aggcontext, int setno) +{ + FunctionCallInfo fcinfo = &pertrans->collectfn_fcinfo; + MemoryContext oldContext; + Datum newVal; + + aggstate->curaggcontext = aggcontext; + aggstate->current_set = setno; + aggstate->curpertrans = pertrans; + + oldContext = MemoryContextSwitchTo(aggstate->tmpcontext->ecxt_per_tuple_memory); + + fcinfo->arg[0] = pergroup->collectValue; + fcinfo->argnull[0] = pergroup->collectValueIsNull; + fcinfo->isnull = false; + + newVal = FunctionCallInvoke(fcinfo); + + if (DatumGetPointer(newVal) != DatumGetPointer(pergroup->collectValue)) { + newVal = ExecAggTransReparent(aggstate, pertrans, newVal, fcinfo->isnull, pergroup->collectValue, + pergroup->collectValueIsNull); + } + + pergroup->collectValue = newVal; + pergroup->collectValueIsNull = fcinfo->isnull; + + MemoryContextSwitchTo(oldContext); } \ No newline at end of file diff --git a/src/gausskernel/runtime/executor/nodeAgg.cpp b/src/gausskernel/runtime/executor/nodeAgg.cpp index 242dc6f01..ed4dc8aa7 100644 --- a/src/gausskernel/runtime/executor/nodeAgg.cpp +++ b/src/gausskernel/runtime/executor/nodeAgg.cpp @@ -192,11 +192,13 @@ static void finalize_aggregates_flattened(AggState *aggstate, AggStatePerAggForF AggStatePerGroup pergroup, int currentSet); static void build_pertrans_for_aggref(AggStatePerTrans pertrans, AggState *aggsate, EState *estate, Aggref *aggref, Oid aggtransfn, Oid aggtranstype, Datum initValue, bool initValueIsNull, - Oid *inputTypes, int numArguments); + Oid *inputTypes, int numArguments, bool isInitNumericSum); static int find_compatible_peragg(Aggref *newagg, AggState *aggstate, int lastaggno, List **same_input_transnos); -static int find_compatible_pertrans(AggState *aggstate, Aggref *newagg, Oid aggtransfn, Oid aggtranstype, - Datum initValue, bool initValueIsNull, List *possible_matches); +static int find_compatible_pertrans(AggState *aggstate, Oid aggfnOid, Oid *aggtransfnOid, Oid *aggtranstype, + Datum initValue, bool *initValueIsNull, List *possible_matches); static void exec_lookups_agg_flattened(AggState *aggstate, Agg *node, EState *estate); +static void exec_agg_finalfn_init(AggState *aggstate, Agg *node, AggStatePerAggForFlattenedExpr peragg, AggStatePerTrans pertrans, + Oid *input_types, int num_arguments); /* * Switch to phase "newphase", which must either be 0 (to reset) or @@ -3075,10 +3077,8 @@ static void advance_transition_function_flattened(AggState *aggstate, AggStatePe AggStatePerGroup pergroupstate) { FunctionCallInfo fcinfo = &pertrans->transfn_fcinfo; - int numTransInputs = pertrans->numTransInputs; MemoryContext oldContext; Datum newVal; - int i; if (pertrans->transfn.fn_strict) { int numTransInputs = pertrans->numTransInputs; @@ -3368,7 +3368,7 @@ static void finalize_aggregates_flattened(AggState *aggstate, AggStatePerAggForF static void build_pertrans_for_aggref(AggStatePerTrans pertrans, AggState *aggstate, EState *estate, Aggref *aggref, Oid aggtransfn, Oid aggtranstype, Datum initValue, bool initValueIsNull, - Oid *inputTypes, int numArguments) + Oid *inputTypes, int numArguments, bool isInitNumericSum) { int numGroupingSets = Max(aggstate->maxsets, 1); Expr *transfnexpr; @@ -3385,8 +3385,6 @@ static void build_pertrans_for_aggref(AggStatePerTrans pertrans, AggState *aggst pertrans->transfn_oid = aggtransfn; pertrans->initValue = initValue; pertrans->initValueIsNull = initValueIsNull; - - numDirectArgs = list_length(aggref->aggdirectargs); pertrans->numInputs = numInputs = list_length(aggref->args); pertrans->aggtranstype = aggtranstype; @@ -3396,6 +3394,13 @@ static void build_pertrans_for_aggref(AggStatePerTrans pertrans, AggState *aggst pertrans->numTransInputs = numArguments; } + /* init tranfn (except INT8SUMFUNCOID、NUMERICSUMFUNCOID) */ + if ((aggref->aggfnoid == INT8SUMFUNCOID || aggref->aggfnoid == NUMERICSUMFUNCOID) && + !isInitNumericSum) { + return; + } + + numDirectArgs = list_length(aggref->aggdirectargs); build_aggregate_transfn_expr(inputTypes, numArguments, numDirectArgs, aggref->aggvariadic, aggtranstype, aggref->inputcollid, aggtransfn, &transfnexpr); fmgr_info(aggtransfn, &pertrans->transfn); @@ -3521,29 +3526,60 @@ static int find_compatible_peragg(Aggref *newagg, AggState *aggstate, int lastag return -1; } -static int find_compatible_pertrans(AggState *aggstate, Aggref *newagg, Oid aggtransfn, Oid aggtranstype, - Datum initValue, bool initValueIsNull, List *transnos) +static int find_compatible_pertrans(AggState *aggstate, Oid aggfnOid, Oid *aggtransfnOid, Oid *aggtranstype, + Datum initValue, bool *initValueIsNull, List *possible_matches) { ListCell *lc; + int result = -1; + Oid newtransfnOid = *aggtransfnOid; + Oid newaggtranstype = *aggtranstype; + bool newinitValueIsNull = *initValueIsNull; - foreach (lc, transnos) { +#ifndef ENABLE_MULTIPLE_NODES + numeric_transfn_info_change(aggfnOid, &newtransfnOid, &newaggtranstype); + newinitValueIsNull = numeric_agg_trans_initvalisnull(newtransfnOid, newinitValueIsNull); +#endif + + foreach (lc, possible_matches) { int transno = lfirst_int(lc); AggStatePerTrans pertrans = &aggstate->pertrans[transno]; + Oid newtransfnOidtemp = pertrans->transfn_oid; + Oid newaggtranstypetemp = pertrans->aggtranstype; + bool newinitValueIsNulltemp = pertrans->initValueIsNull; - if (aggtransfn != pertrans->transfn_oid || aggtranstype != pertrans->aggtranstype) { +#ifndef ENABLE_MULTIPLE_NODES + Oid aggfnOidtemp = pertrans->aggref->aggfnoid; + if (aggfnOidtemp == INT8SUMFUNCOID || aggfnOidtemp == NUMERICSUMFUNCOID) { + numeric_transfn_info_change(aggfnOidtemp, &newtransfnOidtemp, &newaggtranstypetemp); + newinitValueIsNulltemp = numeric_agg_trans_initvalisnull(newtransfnOidtemp, newinitValueIsNulltemp); + } +#endif + + if (newtransfnOid != newtransfnOidtemp || newaggtranstype != newaggtranstypetemp) { continue; } - if (initValueIsNull && pertrans->initValueIsNull) { - return transno; + if (newinitValueIsNull && newinitValueIsNulltemp) { + result = transno; + break; } - if (!initValueIsNull && !pertrans->initValueIsNull && + if (!newinitValueIsNull && !newinitValueIsNulltemp && datumIsEqual(initValue, pertrans->initValue, pertrans->transtypeByVal, pertrans->transtypeLen)) { - return transno; + result = transno; + break; } } - return -1; + +#ifndef ENABLE_MULTIPLE_NODES + if (aggfnOid != INT8SUMFUNCOID && aggfnOid != NUMERICSUMFUNCOID) { + *aggtransfnOid = newtransfnOid; + *aggtranstype = newaggtranstype; + *initValueIsNull = newinitValueIsNull; + } +#endif + + return result; } static void exec_lookups_agg(AggState *aggstate, Agg *node, EState *estate) @@ -3944,6 +3980,99 @@ static void exec_lookups_agg(AggState *aggstate, Agg *node, EState *estate) return; } +static void exec_agg_finalfn_init(AggState *aggstate, Agg *node, AggStatePerAggForFlattenedExpr peragg, AggStatePerTrans pertrans, + Oid *input_types, int num_arguments) +{ + AclResult aclresult; + Oid finalfn_oid = peragg->finalfn_oid; + Oid collectfn_oid = peragg->collectfn_oid; + Oid transfn_oid = pertrans->transfn_oid; + Aggref *aggref = pertrans->aggref; + Oid aggtranstype = pertrans->aggtranstype; + Expr *finalfnexpr = NULL; + + peragg->is_avg = false; + if (finalfn_oid == 1830) { + peragg->is_avg = true; + } +#ifdef ENABLE_MULTIPLE_NODES + /* + * For PGXC final and collection functions are used to combine results at Coordinator, + * disable those for Datanode + */ + if (IS_PGXC_DATANODE) { + if (!u_sess->exec_cxt.under_stream_runtime) { + peragg->finalfn_oid = finalfn_oid = InvalidOid; + collectfn_oid = InvalidOid; + } else { + if (need_adjust_agg_inner_func_type(peraggstate->aggref)) { + if (!node->is_final && !node->single_node) + peragg->finalfn_oid = finalfn_oid = InvalidOid; + if (aggref->aggstage == 0 && !node->is_final && !node->single_node) + collectfn_oid = InvalidOid; + } + } + } +#else + if (IS_STREAM_PLAN || StreamThreadAmI()) { + if (need_adjust_agg_inner_func_type(peragg->aggref)) { + if (!node->is_final && !node->single_node) { + peragg->finalfn_oid = finalfn_oid = InvalidOid; + } + if (aggref->aggstage == 0 && !node->is_final && !node->single_node) { + collectfn_oid = InvalidOid; + } + } + } +#endif /* ENABLE_MULTIPLE_NODES */ + /* Check that aggregate owner has permission to call component fns */ + { + HeapTuple procTuple; + Oid aggOwner; + + procTuple = SearchSysCache1(PROCOID, ObjectIdGetDatum(aggref->aggfnoid)); + if (!HeapTupleIsValid(procTuple)) + ereport(ERROR, (errcode(ERRCODE_CACHE_LOOKUP_FAILED), errmodule(MOD_EXECUTOR), + errmsg("cache lookup failed for aggregate function %u", aggref->aggfnoid))); + aggOwner = ((Form_pg_proc)GETSTRUCT(procTuple))->proowner; + ReleaseSysCache(procTuple); + + aclresult = pg_proc_aclcheck(transfn_oid, aggOwner, ACL_EXECUTE); + if (aclresult != ACLCHECK_OK) + aclcheck_error(aclresult, ACL_KIND_PROC, get_func_name(transfn_oid)); + if (OidIsValid(finalfn_oid)) { + aclresult = pg_proc_aclcheck(finalfn_oid, aggOwner, ACL_EXECUTE); + if (aclresult != ACLCHECK_OK) + aclcheck_error(aclresult, ACL_KIND_PROC, get_func_name(finalfn_oid)); + } + + if (OidIsValid(collectfn_oid)) { + aclresult = pg_proc_aclcheck(collectfn_oid, aggOwner, ACL_EXECUTE); + if (aclresult != ACLCHECK_OK) + aclcheck_error(aclresult, ACL_KIND_PROC, get_func_name(collectfn_oid)); + } + } + + if (AGGKIND_IS_ORDERED_SET(aggref->aggkind)) { + peragg->numFinalArgs = num_arguments + 1; + } else { + peragg->numFinalArgs = 1; + } + + /* Initialize any direct-argument expressions */ + peragg->aggdirectargs = ExecInitExprList(aggref->aggdirectargs, (PlanState *)aggstate); + /* + * build expression trees using actual argument & result types for the + * finalfn, if it exists + */ + if (OidIsValid(finalfn_oid)) { + build_aggregate_finalfn_expr(input_types, peragg->numFinalArgs, aggtranstype, aggref->aggtype, + aggref->inputcollid, finalfn_oid, &finalfnexpr); + fmgr_info(finalfn_oid, &peragg->finalfn); + fmgr_info_set_expr((Node *)finalfnexpr, &peragg->finalfn); + } +} + static void exec_lookups_agg_flattened(AggState *aggstate, Agg *node, EState *estate) { int aggno = -1; @@ -4006,10 +4135,9 @@ static void exec_lookups_agg_flattened(AggState *aggstate, Agg *node, EState *es HeapTuple aggTuple; Form_pg_aggregate aggform; AclResult aclresult; - Oid transfn_oid, finalfn_oid; + Oid transfn_oid; Oid collectfn_oid; Expr *collectfnexpr = NULL; - Expr *finalfnexpr = NULL; Oid aggtranstype; Datum textInitVal; @@ -4051,103 +4179,9 @@ static void exec_lookups_agg_flattened(AggState *aggstate, Agg *node, EState *es aclcheck_error(aclresult, ACL_KIND_PROC, get_func_name(aggref->aggfnoid)); transfn_oid = aggform->aggtransfn; - peragg->finalfn_oid = finalfn_oid = aggform->aggfinalfn; - - collectfn_oid = aggform->aggcollectfn; - - peragg->is_avg = false; - if (finalfn_oid == 1830) { - peragg->is_avg = true; - } -#ifdef ENABLE_MULTIPLE_NODES - /* - * For PGXC final and collection functions are used to combine results at Coordinator, - * disable those for Datanode - */ - if (IS_PGXC_DATANODE) { - if (!u_sess->exec_cxt.under_stream_runtime) { - peragg->finalfn_oid = finalfn_oid = InvalidOid; - collectfn_oid = InvalidOid; - } else { - if (need_adjust_agg_inner_func_type(peraggstate->aggref)) { - if (!node->is_final && !node->single_node) - peragg->finalfn_oid = finalfn_oid = InvalidOid; - if (aggref->aggstage == 0 && !node->is_final && !node->single_node) - collectfn_oid = InvalidOid; - } - } - } -#else - if (IS_STREAM_PLAN || StreamThreadAmI()) { - if (need_adjust_agg_inner_func_type(peragg->aggref)) { - if (!node->is_final && !node->single_node) { - peragg->finalfn_oid = finalfn_oid = InvalidOid; - } - if (aggref->aggstage == 0 && !node->is_final && !node->single_node) { - collectfn_oid = InvalidOid; - } - } - } -#endif /* ENABLE_MULTIPLE_NODES */ - /* Check that aggregate owner has permission to call component fns */ - { - HeapTuple procTuple; - Oid aggOwner; - - procTuple = SearchSysCache1(PROCOID, ObjectIdGetDatum(aggref->aggfnoid)); - if (!HeapTupleIsValid(procTuple)) - ereport(ERROR, (errcode(ERRCODE_CACHE_LOOKUP_FAILED), errmodule(MOD_EXECUTOR), - errmsg("cache lookup failed for aggregate function %u", aggref->aggfnoid))); - aggOwner = ((Form_pg_proc)GETSTRUCT(procTuple))->proowner; - ReleaseSysCache(procTuple); - - aclresult = pg_proc_aclcheck(transfn_oid, aggOwner, ACL_EXECUTE); - if (aclresult != ACLCHECK_OK) - aclcheck_error(aclresult, ACL_KIND_PROC, get_func_name(transfn_oid)); - if (OidIsValid(finalfn_oid)) { - aclresult = pg_proc_aclcheck(finalfn_oid, aggOwner, ACL_EXECUTE); - if (aclresult != ACLCHECK_OK) - aclcheck_error(aclresult, ACL_KIND_PROC, get_func_name(finalfn_oid)); - } - - if (OidIsValid(collectfn_oid)) { - aclresult = pg_proc_aclcheck(collectfn_oid, aggOwner, ACL_EXECUTE); - if (aclresult != ACLCHECK_OK) - aclcheck_error(aclresult, ACL_KIND_PROC, get_func_name(collectfn_oid)); - } - } - - /* - * Get the the number of actual arguments and identify the actual - * datatypes of the aggregate inputs (saved in inputTypes). When - * agg accepts ANY or a polymorphic type, the actual datatype - * could be different from the agg's declared input types. - */ - numArguments = get_aggregate_argtypes(aggref, inputTypes, FUNC_MAX_ARGS); - - /* - * When agg accepts ANY or a polymorphic type, resolve actual - * type of transition state - */ - aggtranstype = resolve_aggregate_transtype(aggref->aggfnoid, aggform->aggtranstype, inputTypes, numArguments); - /* Detect how many arguments to pass to the finalfn */ - if (AGGKIND_IS_ORDERED_SET(aggref->aggkind)) - peragg->numFinalArgs = numArguments + 1; - else - peragg->numFinalArgs = 1; - - /* Initialize any direct-argument expressions */ - peragg->aggdirectargs = ExecInitExprList(aggref->aggdirectargs, (PlanState *)aggstate); - /* - * build expression trees using actual argument & result types for the - * finalfn, if it exists - */ - if (OidIsValid(finalfn_oid)) { - build_aggregate_finalfn_expr(inputTypes, peragg->numFinalArgs, aggtranstype, aggref->aggtype, - aggref->inputcollid, finalfn_oid, &finalfnexpr); - fmgr_info(finalfn_oid, &peragg->finalfn); - fmgr_info_set_expr((Node *)finalfnexpr, &peragg->finalfn); - } + aggtranstype = aggform->aggtranstype; + peragg->finalfn_oid = aggform->aggfinalfn; + peragg->collectfn_oid = collectfn_oid = aggform->aggcollectfn; /* get info about the result type's datatype */ get_typlenbyval(aggref->aggtype, &peragg->resulttypeLen, &peragg->resulttypeByVal); @@ -4206,9 +4240,23 @@ static void exec_lookups_agg_flattened(AggState *aggstate, Agg *node, EState *es if (OidIsValid(collectfn_oid) && (aggref->aggstage > 0 || aggstate->is_final)) { existing_transno = -1; } else { - existing_transno = find_compatible_pertrans(aggstate, aggref, transfn_oid, aggtranstype, initValue, - initValueIsNull, same_input_transnos); + existing_transno = find_compatible_pertrans(aggstate, aggref->aggfnoid, &transfn_oid, &aggtranstype, initValue, + &initValueIsNull, same_input_transnos); } + + /* + * Get the the number of actual arguments and identify the actual + * datatypes of the aggregate inputs (saved in inputTypes). When + * agg accepts ANY or a polymorphic type, the actual datatype + * could be different from the agg's declared input types. + */ + numArguments = get_aggregate_argtypes(aggref, inputTypes, FUNC_MAX_ARGS); + + /* + * When agg accepts ANY or a polymorphic type, resolve actual + * type of transition state + */ + aggtranstype = resolve_aggregate_transtype(aggref->aggfnoid, aggtranstype, inputTypes, numArguments); if (existing_transno != -1) { /* * Existing compatible trans found, so just point the 'peragg' to @@ -4219,7 +4267,7 @@ static void exec_lookups_agg_flattened(AggState *aggstate, Agg *node, EState *es } else { pertrans = &pertransstates[++transno]; build_pertrans_for_aggref(pertrans, aggstate, estate, aggref, transfn_oid, aggtranstype, initValue, - initValueIsNull, inputTypes, numArguments); + initValueIsNull, inputTypes, numArguments, false); if (OidIsValid(collectfn_oid)) { fmgr_info(collectfn_oid, &pertrans->collectfn); pertrans->collectfn.fn_expr = (Node *)collectfnexpr; @@ -4231,6 +4279,14 @@ static void exec_lookups_agg_flattened(AggState *aggstate, Agg *node, EState *es } peragg->transno = transno; } + + /* init final (except INT8SUMFUNCOID、NUMERICSUMFUNCOID) */ + if (aggref->aggfnoid != INT8SUMFUNCOID && aggref->aggfnoid != NUMERICSUMFUNCOID) { +#ifndef ENABLE_MULTIPLE_NODES + numeric_finalfn_info_change(aggref->aggfnoid, &peragg->finalfn_oid); +#endif + exec_agg_finalfn_init(aggstate, node, peragg, pertrans, inputTypes, numArguments); + } ReleaseSysCache(aggTuple); } @@ -4251,6 +4307,32 @@ static void exec_lookups_agg_flattened(AggState *aggstate, Agg *node, EState *es if (numaggrefs != list_length(aggstate->aggs)) ereport(ERROR, (errcode(ERRCODE_GROUPING_ERROR), errmsg("aggregate function calls cannot be nested"))); + /* INT8SUMFUNCOID and NUMERICSUMFUNCOID init */ + for (int i = 0; i < aggstate->numaggs; i++) { + Oid inputTypes[FUNC_MAX_ARGS]; + int numArguments; + AggStatePerAggForFlattenedExpr peragg = &aggstate->peragg_flattened[i]; + AggStatePerTrans pertrans = &aggstate->pertrans[peragg->transno]; + Oid aggfnoid = peragg->aggref->aggfnoid; + + if (aggfnoid == INT8SUMFUNCOID || aggfnoid == NUMERICSUMFUNCOID) { +#ifndef ENABLE_MULTIPLE_NODES + if (aggstate->numtrans < aggstate->numaggs) { + numeric_transfn_info_change(aggfnoid, &pertrans->transfn_oid, &pertrans->aggtranstype); + pertrans->initValueIsNull = numeric_agg_trans_initvalisnull(pertrans->transfn_oid, + pertrans->initValueIsNull); + numeric_finalfn_info_change(aggfnoid, &peragg->finalfn_oid); + } +#endif + numArguments = get_aggregate_argtypes(peragg->aggref, inputTypes, FUNC_MAX_ARGS); + pertrans->aggtranstype = + resolve_aggregate_transtype(aggfnoid, pertrans->aggtranstype, inputTypes, numArguments); + + build_pertrans_for_aggref(pertrans, aggstate, estate, peragg->aggref, pertrans->transfn_oid, + pertrans->aggtranstype, pertrans->initValue, pertrans->initValueIsNull, inputTypes, numArguments, true); + exec_agg_finalfn_init(aggstate, node, peragg, pertrans, inputTypes, numArguments); + } + } /* * Build expressions doing all the transition work at once. We build a * different one for each phase, as the number of transition function diff --git a/src/gausskernel/runtime/vecexecutor/vecnode/vecagg.cpp b/src/gausskernel/runtime/vecexecutor/vecnode/vecagg.cpp index d2aa8ba1c..0caaac1da 100644 --- a/src/gausskernel/runtime/vecexecutor/vecnode/vecagg.cpp +++ b/src/gausskernel/runtime/vecexecutor/vecnode/vecagg.cpp @@ -442,7 +442,9 @@ VecAggState* ExecInitVecAggregation(VecAgg* node, EState* estate, int eflags) transfn_oid = aggform->aggtransfn; finalfn_oid = aggform->aggfinalfn; #ifndef ENABLE_MULTIPLE_NODES - numeric_aggfn_info_change(aggref->aggfnoid, &transfn_oid, &aggtranstype, &transfn_oid); + if (estate->es_is_flt_frame) { + numeric_aggfn_info_change(aggref->aggfnoid, &transfn_oid, &aggtranstype, &transfn_oid); + } #endif peraggstate->transfn_oid = transfn_oid; peraggstate->finalfn_oid = finalfn_oid; @@ -522,7 +524,10 @@ VecAggState* ExecInitVecAggregation(VecAgg* node, EState* estate, int eflags) */ text_init_val = SysCacheGetAttr(AGGFNOID, agg_tuple, Anum_pg_aggregate_agginitval, &peraggstate->initValueIsNull); #ifndef ENABLE_MULTIPLE_NODES - peraggstate->initValueIsNull = numeric_agg_trans_initvalisnull(peraggstate->transfn_oid, peraggstate->initValueIsNull); + if (estate->es_is_flt_frame) { + peraggstate->initValueIsNull = numeric_agg_trans_initvalisnull(peraggstate->transfn_oid, + peraggstate->initValueIsNull); + } #endif if (peraggstate->initValueIsNull) peraggstate->initValue = (Datum)0; diff --git a/src/gausskernel/runtime/vecexecutor/vecnode/vecwindowagg.cpp b/src/gausskernel/runtime/vecexecutor/vecnode/vecwindowagg.cpp index 0e1001e96..0b0cd05d7 100644 --- a/src/gausskernel/runtime/vecexecutor/vecnode/vecwindowagg.cpp +++ b/src/gausskernel/runtime/vecexecutor/vecnode/vecwindowagg.cpp @@ -550,21 +550,23 @@ VecWinAggRuntime::VecWinAggRuntime(VecWindowAggState* runtime) : BaseAggRunner() if (m_sortKey > 0) { m_cellvar_encoded[i] = CheckAggEncoded(peraggstate->transfn.fn_rettype); #ifndef ENABLE_MULTIPLE_NODES - /* - * fix some case that row agg function has both transfn and finnal - * but vec agg function only have transfn - */ - if (OidIsValid(peraggstate->finalfn.fn_oid) && - runtime->windowAggInfo[i].vec_final_function.flinfo == NULL) { - m_cellvar_encoded[i] = CheckAggEncoded(peraggstate->finalfn.fn_rettype); - } - /* - * in some case, vec agg function has its own rettyp - * XXX: hard code here - */ - if (perfuncstate->flinfo.fn_oid == 2100 || perfuncstate->flinfo.fn_oid == 2103 - || perfuncstate->flinfo.fn_oid == 2717 || perfuncstate->flinfo.fn_oid == 2159) { - m_cellvar_encoded[i] = true; + if (m_winruntime->ss.ps.state->es_is_flt_frame) { + /* + * fix some case that row agg function has both transfn and finnal + * but vec agg function only have transfn + */ + if (OidIsValid(peraggstate->finalfn.fn_oid) && + runtime->windowAggInfo[i].vec_final_function.flinfo == NULL) { + m_cellvar_encoded[i] = CheckAggEncoded(peraggstate->finalfn.fn_rettype); + } + /* + * in some case, vec agg function has its own rettyp + * XXX: hard code here + */ + if (perfuncstate->flinfo.fn_oid == 2100 || perfuncstate->flinfo.fn_oid == 2103 + || perfuncstate->flinfo.fn_oid == 2717 || perfuncstate->flinfo.fn_oid == 2159) { + m_cellvar_encoded[i] = true; + } } #endif } @@ -665,7 +667,11 @@ void VecWinAggRuntime::DispatchWindowFunction(WindowStatePerFunc perfuncstate, i #ifdef ENABLE_MULTIPLE_NODES InitFunctionCallInfoData(m_windowFunc[i], &perfuncstate->flinfo, 2, perfuncstate->winCollation, NULL, NULL); #else - InitFunctionCallInfoData(m_windowFunc[i], &perfuncstate->flinfo, 2, perfuncstate->winCollation, (Node *)m_winruntime, NULL); + if (m_winruntime->ss.ps.state->es_is_flt_frame) { + InitFunctionCallInfoData(m_windowFunc[i], &perfuncstate->flinfo, 2, perfuncstate->winCollation, (Node *)m_winruntime, NULL); + } else { + InitFunctionCallInfoData(m_windowFunc[i], &perfuncstate->flinfo, 2, perfuncstate->winCollation, NULL, NULL); + } #endif if (m_aggNum == 0 || m_sortKey == 0) @@ -707,8 +713,13 @@ void VecWinAggRuntime::DispatchAggFunction( InitFunctionCallInfoData( aggInfo->vec_agg_function, &peraggState->transfn, 2, perfuncstate->winCollation, NULL, NULL); #else - InitFunctionCallInfoData( - aggInfo->vec_agg_function, &peraggState->transfn, 2, perfuncstate->winCollation, (Node*)m_winruntime, NULL); + if (m_winruntime->ss.ps.state->es_is_flt_frame) { + InitFunctionCallInfoData(aggInfo->vec_agg_function, &peraggState->transfn, 2, perfuncstate->winCollation, + (Node*)m_winruntime, NULL); + } else { + InitFunctionCallInfoData( + aggInfo->vec_agg_function, &peraggState->transfn, 2, perfuncstate->winCollation, NULL, NULL); + } #endif aggInfo->vec_agg_cache = &entry->vec_agg_cache[0]; @@ -716,14 +727,18 @@ void VecWinAggRuntime::DispatchAggFunction( aggInfo->vec_agg_function.flinfo->vec_fn_addr = aggInfo->vec_agg_cache[0]; -#ifdef ENABLE_MULTIPLE_NODES if (OidIsValid(peraggState->finalfn_oid)) { +#ifdef ENABLE_MULTIPLE_NODES InitFunctionCallInfoData( aggInfo->vec_final_function, &peraggState->finalfn, 2, perfuncstate->winCollation, NULL, NULL); #else - if (OidIsValid(peraggState->finalfn_oid) && aggInfo->vec_agg_final[0]) { - InitFunctionCallInfoData( - aggInfo->vec_final_function, &peraggState->finalfn, 2, perfuncstate->winCollation, (Node*)m_winruntime, NULL); + if (m_winruntime->ss.ps.state->es_is_flt_frame && aggInfo->vec_agg_final[0]) { + InitFunctionCallInfoData(aggInfo->vec_final_function, &peraggState->finalfn, 2, + perfuncstate->winCollation, (Node*)m_winruntime, NULL); + } else { + InitFunctionCallInfoData( + aggInfo->vec_final_function, &peraggState->finalfn, 2, perfuncstate->winCollation, NULL, NULL); + } #endif aggInfo->vec_final_function.flinfo->fn_addr = aggInfo->vec_agg_final[0]; } diff --git a/src/include/executor/node/nodeAgg.h b/src/include/executor/node/nodeAgg.h index eb1bad51d..6052d7fdb 100644 --- a/src/include/executor/node/nodeAgg.h +++ b/src/include/executor/node/nodeAgg.h @@ -387,6 +387,7 @@ typedef struct AggStatePerAggForFlattenedExprData { bool resulttypeByVal; #ifdef PGXC bool is_avg; + Oid collectfn_oid; #endif /* PGXC */ } AggStatePerAggForFlattenedExprData; diff --git a/src/include/nodes/execExpr.h b/src/include/nodes/execExpr.h index 0dfcf6c44..1b198d517 100644 --- a/src/include/nodes/execExpr.h +++ b/src/include/nodes/execExpr.h @@ -228,20 +228,24 @@ typedef enum ExprEvalOp EEOP_PREFIX_BTYEA, EEOP_PREFIX_TEXT, - /* aggregation related nodes */ - EEOP_AGG_STRICT_DESERIALIZE, - EEOP_AGG_DESERIALIZE, - EEOP_AGG_STRICT_INPUT_CHECK, - EEOP_AGG_INIT_TRANS, - EEOP_AGG_COLLECT_INIT_TRANS, - EEOP_AGG_STRICT_TRANS_CHECK, - EEOP_AGG_COLLECT_STRICT_TRANS_CHECK, - EEOP_AGG_PLAIN_TRANS_BYVAL, - EEOP_AGG_COLLECT_PLAIN_TRANS_BYVAL, - EEOP_AGG_PLAIN_TRANS, - EEOP_AGG_COLLECT_PLAIN_TRANS, - EEOP_AGG_ORDERED_TRANS_DATUM, - EEOP_AGG_ORDERED_TRANS_TUPLE, + /* aggregation related nodes */ + EEOP_AGG_STRICT_DESERIALIZE, + EEOP_AGG_DESERIALIZE, + EEOP_AGG_STRICT_INPUT_CHECK, + EEOP_AGG_PLAIN_TRANS_INIT_STRICT_BYVAL, + EEOP_AGG_COLLECT_PLAIN_TRANS_INIT_STRICT_BYVAL, + EEOP_AGG_PLAIN_TRANS_STRICT_BYVAL, + EEOP_AGG_COLLECT_PLAIN_TRANS_STRICT_BYVAL, + EEOP_AGG_PLAIN_TRANS_BYVAL, + EEOP_AGG_COLLECT_PLAIN_TRANS_BYVAL, + EEOP_AGG_PLAIN_TRANS_INIT_STRICT_BYREF, + EEOP_AGG_COLLECT_PLAIN_TRANS_INIT_STRICT_BYREF, + EEOP_AGG_PLAIN_TRANS_STRICT_BYREF, + EEOP_AGG_COLLECT_PLAIN_TRANS_STRICT_BYREF, + EEOP_AGG_PLAIN_TRANS_BYREF, + EEOP_AGG_COLLECT_PLAIN_TRANS_BYREF, + EEOP_AGG_ORDERED_TRANS_DATUM, + EEOP_AGG_ORDERED_TRANS_TUPLE, /* non-existent operation, used e.g. to check array lengths */ EEOP_LAST @@ -646,27 +650,6 @@ typedef struct ExprEvalStep /* for EEOP_AGG_INIT_TRANS */ struct { - AggState *aggstate; - AggStatePerTrans pertrans; - MemoryContext aggcontext; - int setno; - int transno; - int setoff; - int jumpnull; - } agg_init_trans; - - /* for EEOP_AGG_STRICT_TRANS_CHECK */ - struct { - AggState *aggstate; - int setno; - int transno; - int setoff; - int jumpnull; - } agg_strict_trans_check; - - /* for EEOP_AGG_{PLAIN,ORDERED}_TRANS* */ - struct { - AggState *aggstate; AggStatePerTrans pertrans; MemoryContext aggcontext; int setno;