diff --git a/src/gausskernel/runtime/executor/nodeAgg.cpp b/src/gausskernel/runtime/executor/nodeAgg.cpp index cc540f10f..5feabb98b 100644 --- a/src/gausskernel/runtime/executor/nodeAgg.cpp +++ b/src/gausskernel/runtime/executor/nodeAgg.cpp @@ -266,6 +266,37 @@ void initialize_phase(AggState* aggstate, int newphase) aggstate->phase = &aggstate->phases[newphase]; } +Datum get_bit_and_initval(Oid aggtranstype, int typmod) +{ + Oid typinput; + Oid typioparam; + char* strInitVal = NULL; + Datum initVal; + errno_t rc; + getTypeInputInfo(aggtranstype, &typinput, &typioparam); + int initValLen = typmod - (int)VARHDRSZ; + int charsPerByte = 2; + size_t strLen = (initValLen + 1) * charsPerByte + 1; // +2 for "\x" and +1 for '\0' + strInitVal = (char*)palloc(strLen * sizeof(char)); + strInitVal[0] = '\\'; + strInitVal[1] = 'x'; + strInitVal[strLen - 1] = '\0'; + rc = memset_s(strInitVal + charsPerByte, initValLen * charsPerByte, 'F', initValLen * charsPerByte); + securec_check(rc, "\0", "\0"); + initVal = OidInputFunctionCall(typinput, strInitVal, typioparam, -1); + pfree_ext(strInitVal); + return initVal; +} + +bool is_binary_type_in_dolphin(Oid typeOid) +{ + if (u_sess->attr.attr_sql.dolphin) { + return false; + } + return (typeOid == get_typeoid(PG_CATALOG_NAMESPACE, "binary")) || + (typeOid == get_typeoid(PG_CATALOG_NAMESPACE, "varbinary")); +} + /* * Fetch a tuple from either the outer plan (for phase 0) or from the sorter * populated by the previous phase. Copy it to the sorter for the next phase @@ -463,8 +494,19 @@ static void advance_transition_function( int i; for (i = 1; i <= numTransInputs; i++) { - if (fcinfo->argnull[i]) + Oid aggtranstype = peraggstate->aggref->aggtrantype; + ListCell* arg = list_head(peraggstate->aggref->args); + TargetEntry *tle = (TargetEntry *)lfirst(arg); + if (fcinfo->argnull[i] && strcmp(get_func_name(peraggstate->aggref->aggfnoid), "bit_and") == 0 && + is_binary_type_in_dolphin(aggtranstype) && + pergroupstate->transValueIsNull && IsA(tle->expr, Var)) { + Var* var = (Var*)tle->expr; + pergroupstate->transValue = get_bit_and_initval(aggtranstype, var->vartypmod); + pergroupstate->transValueIsNull = false; return; + } else if (fcinfo->argnull[i]) { + return; + } } if (pergroupstate->noTransValue) { /* diff --git a/src/gausskernel/runtime/executor/nodeWindowAgg.cpp b/src/gausskernel/runtime/executor/nodeWindowAgg.cpp index f6a0f2dee..ed806bc38 100644 --- a/src/gausskernel/runtime/executor/nodeWindowAgg.cpp +++ b/src/gausskernel/runtime/executor/nodeWindowAgg.cpp @@ -51,6 +51,7 @@ #include "utils/memutils.h" #include "utils/syscache.h" #include "windowapi.h" +#include "executor/node/nodeAgg.h" static TupleTableSlot* ExecWindowAgg(PlanState* state); static void initialize_windowaggregate( @@ -137,7 +138,18 @@ static void advance_windowaggregate( * just keep the prior transValue. */ for (i = 1; i <= num_arguments; i++) { - if (fcinfo->argnull[i]) { + Oid aggtranstype = perfuncstate->wfunc->wintype; + ListCell* arg = list_head(perfuncstate->wfunc->args); + TargetEntry *tle = (TargetEntry *)lfirst(arg); + if (fcinfo->argnull[i] && strcmp(get_func_name(perfuncstate->wfunc->winfnoid), "bit_and") == 0 && + is_binary_type_in_dolphin(aggtranstype) && + peraggstate->transValueIsNull && IsA(tle, Var)) { + Var* var = (Var*)tle; + peraggstate->transValue = get_bit_and_initval(aggtranstype, var->vartypmod); + peraggstate->transValueIsNull = false; + MemoryContextSwitchTo(old_context); + return; + } else if (fcinfo->argnull[i]) { MemoryContextSwitchTo(old_context); return; } diff --git a/src/include/executor/node/nodeAgg.h b/src/include/executor/node/nodeAgg.h index b38e927bd..eaecc8f2c 100644 --- a/src/include/executor/node/nodeAgg.h +++ b/src/include/executor/node/nodeAgg.h @@ -488,5 +488,7 @@ extern void agg_spill_to_disk(AggWriteFileControl* TempFileControl, TupleHashTab int64 numGroups, bool isAgg, int planId, int dop, Instrumentation* intrument = NULL); extern void ExecEarlyFreeAggregation(AggState* node); extern void ExecReSetAgg(AggState* node); +extern bool is_binary_type_in_dolphin(Oid typeOid); +extern Datum get_bit_and_initval(Oid aggtranstype, int initValLen); #endif /* NODEAGG_H */