aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor
diff options
context:
space:
mode:
authorRobert Haas <rhaas@postgresql.org>2015-10-15 13:00:40 -0400
committerRobert Haas <rhaas@postgresql.org>2015-10-15 13:00:40 -0400
commit5fc4c26db5120bd90348b6ee3101fcddfdf54800 (patch)
tree36f2df5232f8c58de77536cfd4d0e11889253b49 /src/backend/executor
parent817588bc2bd684b630da11ca068505dbd985de10 (diff)
downloadpostgresql-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.c19
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