mirror of
https://github.com/postgres/postgres.git
synced 2025-07-02 09:02:37 +03:00
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.
This commit is contained in:
@ -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
|
||||
|
Reference in New Issue
Block a user