From c12693d8f3bbbffcb79f6af476cc647402e1145e Mon Sep 17 00:00:00 2001 From: Andres Freund Date: Mon, 29 Jan 2018 12:16:53 -0800 Subject: [PATCH] Introduce ExecQualAndReset() helper. It's a common task to evaluate a qual and reset the corresponding expression context. Currently that requires storing the result of the qual eval, resetting the context, and then reacting on the result. As that's awkward several places only reset the context next time through a node. That's not great, so introduce a helper that evaluates and resets. It's a bit ugly that it currently uses MemoryContextReset() instead of ResetExprContext(), but that seems easier than reordering all of executor.h. Author: Andres Freund Discussion: https://postgr.es/m/20180109222544.f7loxrunqh3xjl5f@alap3.anarazel.de --- src/backend/executor/nodeBitmapHeapscan.c | 9 ++------- src/backend/executor/nodeHash.c | 10 ++-------- src/backend/executor/nodeIndexonlyscan.c | 3 +-- src/backend/executor/nodeIndexscan.c | 11 +++-------- src/include/executor/executor.h | 17 +++++++++++++++++ 5 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/backend/executor/nodeBitmapHeapscan.c b/src/backend/executor/nodeBitmapHeapscan.c index 7ba1db7d7e..fa65d4efbe 100644 --- a/src/backend/executor/nodeBitmapHeapscan.c +++ b/src/backend/executor/nodeBitmapHeapscan.c @@ -352,9 +352,7 @@ BitmapHeapNext(BitmapHeapScanState *node) if (tbmres->recheck) { econtext->ecxt_scantuple = slot; - ResetExprContext(econtext); - - if (!ExecQual(node->bitmapqualorig, econtext)) + if (!ExecQualAndReset(node->bitmapqualorig, econtext)) { /* Fails recheck, so drop it and loop back for another */ InstrCountFiltered2(node, 1); @@ -717,10 +715,7 @@ BitmapHeapRecheck(BitmapHeapScanState *node, TupleTableSlot *slot) /* Does the tuple meet the original qual conditions? */ econtext->ecxt_scantuple = slot; - - ResetExprContext(econtext); - - return ExecQual(node->bitmapqualorig, econtext); + return ExecQualAndReset(node->bitmapqualorig, econtext); } /* ---------------------------------------------------------------- diff --git a/src/backend/executor/nodeHash.c b/src/backend/executor/nodeHash.c index a9149ef81c..c26b8ea44e 100644 --- a/src/backend/executor/nodeHash.c +++ b/src/backend/executor/nodeHash.c @@ -1942,10 +1942,7 @@ ExecScanHashBucket(HashJoinState *hjstate, false); /* do not pfree */ econtext->ecxt_innertuple = inntuple; - /* reset temp memory each time to avoid leaks from qual expr */ - ResetExprContext(econtext); - - if (ExecQual(hjclauses, econtext)) + if (ExecQualAndReset(hjclauses, econtext)) { hjstate->hj_CurTuple = hashTuple; return true; @@ -2002,10 +1999,7 @@ ExecParallelScanHashBucket(HashJoinState *hjstate, false); /* do not pfree */ econtext->ecxt_innertuple = inntuple; - /* reset temp memory each time to avoid leaks from qual expr */ - ResetExprContext(econtext); - - if (ExecQual(hjclauses, econtext)) + if (ExecQualAndReset(hjclauses, econtext)) { hjstate->hj_CurTuple = hashTuple; return true; diff --git a/src/backend/executor/nodeIndexonlyscan.c b/src/backend/executor/nodeIndexonlyscan.c index f61b3abf32..8ffcc52bea 100644 --- a/src/backend/executor/nodeIndexonlyscan.c +++ b/src/backend/executor/nodeIndexonlyscan.c @@ -214,8 +214,7 @@ IndexOnlyNext(IndexOnlyScanState *node) if (scandesc->xs_recheck) { econtext->ecxt_scantuple = slot; - ResetExprContext(econtext); - if (!ExecQual(node->indexqual, econtext)) + if (!ExecQualAndReset(node->indexqual, econtext)) { /* Fails recheck, so drop it and loop back for another */ InstrCountFiltered2(node, 1); diff --git a/src/backend/executor/nodeIndexscan.c b/src/backend/executor/nodeIndexscan.c index eed69a0c66..b8b961add4 100644 --- a/src/backend/executor/nodeIndexscan.c +++ b/src/backend/executor/nodeIndexscan.c @@ -152,8 +152,7 @@ IndexNext(IndexScanState *node) if (scandesc->xs_recheck) { econtext->ecxt_scantuple = slot; - ResetExprContext(econtext); - if (!ExecQual(node->indexqualorig, econtext)) + if (!ExecQualAndReset(node->indexqualorig, econtext)) { /* Fails recheck, so drop it and loop back for another */ InstrCountFiltered2(node, 1); @@ -300,8 +299,7 @@ next_indextuple: if (scandesc->xs_recheck) { econtext->ecxt_scantuple = slot; - ResetExprContext(econtext); - if (!ExecQual(node->indexqualorig, econtext)) + if (!ExecQualAndReset(node->indexqualorig, econtext)) { /* Fails recheck, so drop it and loop back for another */ InstrCountFiltered2(node, 1); @@ -420,10 +418,7 @@ IndexRecheck(IndexScanState *node, TupleTableSlot *slot) /* Does the tuple meet the indexqual condition? */ econtext->ecxt_scantuple = slot; - - ResetExprContext(econtext); - - return ExecQual(node->indexqualorig, econtext); + return ExecQualAndReset(node->indexqualorig, econtext); } diff --git a/src/include/executor/executor.h b/src/include/executor/executor.h index 6545a80222..1d824eff36 100644 --- a/src/include/executor/executor.h +++ b/src/include/executor/executor.h @@ -17,6 +17,7 @@ #include "catalog/partition.h" #include "executor/execdesc.h" #include "nodes/parsenodes.h" +#include "utils/memutils.h" /* @@ -381,6 +382,22 @@ ExecQual(ExprState *state, ExprContext *econtext) } #endif +/* + * ExecQualAndReset() - evaluate qual with ExecQual() and reset expression + * context. + */ +#ifndef FRONTEND +static inline bool +ExecQualAndReset(ExprState *state, ExprContext *econtext) +{ + bool ret = ExecQual(state, econtext); + + /* inline ResetExprContext, to avoid ordering issue in this file */ + MemoryContextReset(econtext->ecxt_per_tuple_memory); + return ret; +} +#endif + extern bool ExecCheck(ExprState *state, ExprContext *context); /*