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:10:39 -0400 |
commit | 5043193b78919a1bd144563aadc2f7f726549913 (patch) | |
tree | 3a518c81df7d452ff9a50a2181d29fd0d76604c3 /contrib/postgres_fdw/postgres_fdw.c | |
parent | 54e07be2dfd314a64dc2ce03a6a7f59cac1c8a13 (diff) | |
download | postgresql-5043193b78919a1bd144563aadc2f7f726549913.tar.gz postgresql-5043193b78919a1bd144563aadc2f7f726549913.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 'contrib/postgres_fdw/postgres_fdw.c')
-rw-r--r-- | contrib/postgres_fdw/postgres_fdw.c | 14 |
1 files changed, 11 insertions, 3 deletions
diff --git a/contrib/postgres_fdw/postgres_fdw.c b/contrib/postgres_fdw/postgres_fdw.c index e4d799cecd5..1902f1f4eae 100644 --- a/contrib/postgres_fdw/postgres_fdw.c +++ b/contrib/postgres_fdw/postgres_fdw.c @@ -748,6 +748,7 @@ postgresGetForeignPlan(PlannerInfo *root, Index scan_relid = baserel->relid; List *fdw_private; List *remote_conds = NIL; + List *remote_exprs = NIL; List *local_exprs = NIL; List *params_list = NIL; List *retrieved_attrs; @@ -769,8 +770,8 @@ postgresGetForeignPlan(PlannerInfo *root, * * This code must match "extract_actual_clauses(scan_clauses, false)" * except for the additional decision about remote versus local execution. - * Note however that we only strip the RestrictInfo nodes from the - * local_exprs list, since appendWhereClause expects a list of + * Note however that we don't strip the RestrictInfo nodes from the + * remote_conds list, since appendWhereClause expects a list of * RestrictInfos. */ foreach(lc, scan_clauses) @@ -784,11 +785,17 @@ postgresGetForeignPlan(PlannerInfo *root, continue; if (list_member_ptr(fpinfo->remote_conds, rinfo)) + { remote_conds = lappend(remote_conds, rinfo); + remote_exprs = lappend(remote_exprs, rinfo->clause); + } else if (list_member_ptr(fpinfo->local_conds, rinfo)) local_exprs = lappend(local_exprs, rinfo->clause); else if (is_foreign_expr(root, baserel, rinfo->clause)) + { remote_conds = lappend(remote_conds, rinfo); + remote_exprs = lappend(remote_exprs, rinfo->clause); + } else local_exprs = lappend(local_exprs, rinfo->clause); } @@ -874,7 +881,8 @@ postgresGetForeignPlan(PlannerInfo *root, scan_relid, params_list, fdw_private, - NIL /* no custom tlist */ ); + NIL, /* no custom tlist */ + remote_exprs); } /* |