diff options
Diffstat (limited to 'src/backend/executor/nodeAgg.c')
| -rw-r--r-- | src/backend/executor/nodeAgg.c | 48 |
1 files changed, 47 insertions, 1 deletions
diff --git a/src/backend/executor/nodeAgg.c b/src/backend/executor/nodeAgg.c index a47a9ad549..9d0f4ea103 100644 --- a/src/backend/executor/nodeAgg.c +++ b/src/backend/executor/nodeAgg.c @@ -31,6 +31,11 @@ #include "utils/syscache.h" #include "optimizer/clauses.h" +#ifdef FREE_TUPLE_MEMORY +#include <utils/portal.h> +#include <utils/trace.h> +#endif + /* * AggFuncInfo - * keeps the transition functions information around @@ -113,7 +118,9 @@ ExecAgg(Agg *node) isNull1 = FALSE, isNull2 = FALSE; bool qual_result; - +#ifdef FREE_TUPLE_MEMORY + bool free_tuple_memory = pg_options[OPT_FREE_TUPLE_MEMORY]; +#endif /* --------------------- * get state info from node @@ -241,6 +248,10 @@ ExecAgg(Agg *node) for (;;) { TupleTableSlot *outerslot; +#ifdef FREE_TUPLE_MEMORY + Oid valueType; + bool isByValue = 0; +#endif isNull = isNull1 = isNull2 = 0; outerslot = ExecProcNode(outerPlan, (Plan *) node); @@ -293,6 +304,31 @@ ExecAgg(Agg *node) newVal = ExecEvalExpr(aggref->target, econtext, &isNull, &isDone); } +#ifdef FREE_TUPLE_MEMORY + if (free_tuple_memory) { + switch (nodeTag(aggref->target)) { + case T_Const: + isByValue = ((Const*) (aggref->target))->constbyval; + break; + case T_Var: + valueType = ((Var*) (aggref->target))->vartype; + isByValue = typeByVal(typeidType(valueType)); + break; + case T_Array: + isByValue = ((Array*)(aggref->target))->arrayelembyval; + break; + case T_ArrayRef: + isByValue =((ArrayRef*)(aggref->target))->refelembyval; + break; + case T_Expr: + valueType = ((Expr*) (aggref->target))->typeOid; + isByValue = typeByVal(typeidType(valueType)); + break; + default: + break; + } + } +#endif if (isNull && !aggref->usenulls) continue; /* ignore this tuple for this agg */ @@ -353,6 +389,16 @@ ExecAgg(Agg *node) (FmgrValues *) args, &isNull2); Assert(!isNull2); } + +#ifdef FREE_TUPLE_MEMORY + /* try to pfree newVal if not isByValue - dz */ + if (free_tuple_memory && !isByValue && + PortalHeapMemoryIsValid(CurrentMemoryContext, + (Pointer) newVal)) + { + pfree(newVal); + } +#endif } /* |
