summaryrefslogtreecommitdiff
path: root/src/backend/executor/nodeAgg.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/executor/nodeAgg.c')
-rw-r--r--src/backend/executor/nodeAgg.c48
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
}
/*