diff options
author | Robert Haas <rhaas@postgresql.org> | 2015-10-15 13:00:40 -0400 |
---|---|---|
committer | Robert Haas <rhaas@postgresql.org> | 2015-10-15 13:00:40 -0400 |
commit | 5fc4c26db5120bd90348b6ee3101fcddfdf54800 (patch) | |
tree | 36f2df5232f8c58de77536cfd4d0e11889253b49 /src/backend/executor | |
parent | 817588bc2bd684b630da11ca068505dbd985de10 (diff) | |
download | postgresql-5fc4c26db5120bd90348b6ee3101fcddfdf54800.tar.gz postgresql-5fc4c26db5120bd90348b6ee3101fcddfdf54800.zip |
Allow FDWs to push down quals without breaking EvalPlanQual rechecks.
This fixes a long-standing bug which was discovered while investigating
the interaction between the new join pushdown code and the EvalPlanQual
machinery: if a ForeignScan appears on the inner side of a paramaterized
nestloop, an EPQ recheck would re-return the original tuple even if
it no longer satisfied the pushed-down quals due to changed parameter
values.
This fix adds a new member to ForeignScan and ForeignScanState and a
new argument to make_foreignscan, and requires changes to FDWs which
push down quals to populate that new argument with a list of quals they
have chosen to push down. Therefore, I'm only back-patching to 9.5,
even though the bug is not new in 9.5.
Etsuro Fujita, reviewed by me and by Kyotaro Horiguchi.
Diffstat (limited to 'src/backend/executor')
-rw-r--r-- | src/backend/executor/nodeForeignscan.c | 19 |
1 files changed, 17 insertions, 2 deletions
diff --git a/src/backend/executor/nodeForeignscan.c b/src/backend/executor/nodeForeignscan.c index bb28a7372d1..6165e4a6cb4 100644 --- a/src/backend/executor/nodeForeignscan.c +++ b/src/backend/executor/nodeForeignscan.c @@ -25,6 +25,7 @@ #include "executor/executor.h" #include "executor/nodeForeignscan.h" #include "foreign/fdwapi.h" +#include "utils/memutils.h" #include "utils/rel.h" static TupleTableSlot *ForeignNext(ForeignScanState *node); @@ -72,8 +73,19 @@ ForeignNext(ForeignScanState *node) static bool ForeignRecheck(ForeignScanState *node, TupleTableSlot *slot) { - /* There are no access-method-specific conditions to recheck. */ - return true; + ExprContext *econtext; + + /* + * extract necessary information from foreign scan node + */ + econtext = node->ss.ps.ps_ExprContext; + + /* Does the tuple meet the remote qual condition? */ + econtext->ecxt_scantuple = slot; + + ResetExprContext(econtext); + + return ExecQual(node->fdw_recheck_quals, econtext, false); } /* ---------------------------------------------------------------- @@ -135,6 +147,9 @@ ExecInitForeignScan(ForeignScan *node, EState *estate, int eflags) scanstate->ss.ps.qual = (List *) ExecInitExpr((Expr *) node->scan.plan.qual, (PlanState *) scanstate); + scanstate->fdw_recheck_quals = (List *) + ExecInitExpr((Expr *) node->fdw_recheck_quals, + (PlanState *) scanstate); /* * tuple table initialization |