scan_relid,
                             NIL,    /* no expressions to evaluate */
                             best_path->fdw_private,
 -                           NIL /* no custom tlist */ );
 +                           NIL,    /* no custom tlist */
 +                           NIL /* no remote quals */ );
  }
  
  /*
             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;
       *
      * 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)
              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);
     }
                              scan_relid,
                             params_list,
                             fdw_private,
 -                           NIL /* no custom tlist */ );
 +                           NIL,    /* no custom tlist */
 +                           remote_exprs);
  }
  
  /*
               evaluation of the <structfield>fdw_exprs</> expression tree.
      </para>
  
 +    <para>
 +     Any clauses removed from the plan node's qual list must instead be added
 +     to <literal>fdw_recheck_quals</> in order to ensure correct behavior
 +     at the <literal>READ COMMITTED</> isolation level.  When a concurrent
 +     update occurs for some other table involved in the query, the executor
 +     may need to verify that all of the original quals are still satisfied for
 +     the tuple, possibly against a different set of parameter values.
 +    </para>
 +
      <para>
       Another <structname>ForeignScan</> field that can be filled by FDWs
       is <structfield>fdw_scan_tlist</>, which describes the tuples returned by
          #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);
   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);
  }
  
  /* ----------------------------------------------------------------
      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
             COPY_NODE_FIELD(fdw_exprs);
     COPY_NODE_FIELD(fdw_private);
     COPY_NODE_FIELD(fdw_scan_tlist);
 +   COPY_NODE_FIELD(fdw_recheck_quals);
     COPY_BITMAPSET_FIELD(fs_relids);
     COPY_SCALAR_FIELD(fsSystemCol);
  
             WRITE_NODE_FIELD(fdw_exprs);
     WRITE_NODE_FIELD(fdw_private);
     WRITE_NODE_FIELD(fdw_scan_tlist);
 +   WRITE_NODE_FIELD(fdw_recheck_quals);
     WRITE_BITMAPSET_FIELD(fs_relids);
     WRITE_BOOL_FIELD(fsSystemCol);
  }
             READ_NODE_FIELD(fdw_exprs);
     READ_NODE_FIELD(fdw_private);
     READ_NODE_FIELD(fdw_scan_tlist);
 +   READ_NODE_FIELD(fdw_recheck_quals);
     READ_BITMAPSET_FIELD(fs_relids);
     READ_BOOL_FIELD(fsSystemCol);
  
                     replace_nestloop_params(root, (Node *) scan_plan->scan.plan.qual);
         scan_plan->fdw_exprs = (List *)
             replace_nestloop_params(root, (Node *) scan_plan->fdw_exprs);
 +       scan_plan->fdw_recheck_quals = (List *)
 +           replace_nestloop_params(root,
 +                                   (Node *) scan_plan->fdw_recheck_quals);
     }
  
     /*
                   Index scanrelid,
                  List *fdw_exprs,
                  List *fdw_private,
 -                List *fdw_scan_tlist)
 +                List *fdw_scan_tlist,
 +                List *fdw_recheck_quals)
  {
     ForeignScan *node = makeNode(ForeignScan);
     Plan       *plan = &node->scan.plan;
      node->fdw_exprs = fdw_exprs;
     node->fdw_private = fdw_private;
     node->fdw_scan_tlist = fdw_scan_tlist;
 +   node->fdw_recheck_quals = fdw_recheck_quals;
     /* fs_relids will be filled in by create_foreignscan_plan */
     node->fs_relids = NULL;
     /* fsSystemCol will be filled in by create_foreignscan_plan */
             }
     else
     {
 -       /* Adjust tlist, qual, fdw_exprs in the standard way */
 +       /* Adjust tlist, qual, fdw_exprs, etc. in the standard way */
         fscan->scan.plan.targetlist =
             fix_scan_list(root, fscan->scan.plan.targetlist, rtoffset);
         fscan->scan.plan.qual =
             fix_scan_list(root, fscan->scan.plan.qual, rtoffset);
         fscan->fdw_exprs =
             fix_scan_list(root, fscan->fdw_exprs, rtoffset);
 +       fscan->fdw_recheck_quals =
 +           fix_scan_list(root, fscan->fdw_recheck_quals, rtoffset);
     }
  
     /* Adjust fs_relids if needed */
                     break;
  
         case T_ForeignScan:
 -           finalize_primnode((Node *) ((ForeignScan *) plan)->fdw_exprs,
 -                             &context);
 -           /* We assume fdw_scan_tlist cannot contain Params */
 -           context.paramids = bms_add_members(context.paramids, scan_params);
 +           {
 +               ForeignScan *fscan = (ForeignScan *) plan;
 +
 +               finalize_primnode((Node *) fscan->fdw_exprs,
 +                                 &context);
 +               finalize_primnode((Node *) fscan->fdw_recheck_quals,
 +                                 &context);
 +
 +               /* We assume fdw_scan_tlist cannot contain Params */
 +               context.paramids = bms_add_members(context.paramids,
 +                                                  scan_params);
 +           }
             break;
  
         case T_CustomScan:
          typedef struct ForeignScanState
  {
     ScanState   ss;             /* its first field is NodeTag */
 +   List       *fdw_recheck_quals;  /* original quals not in ss.ps.qual */
     /* use struct pointer to avoid including fdwapi.h here */
     struct FdwRoutine *fdwroutine;
     void       *fdw_state;      /* foreign-data wrapper can keep state here */
           * fdw_scan_tlist is never actually executed; it just holds expression trees
   * describing what is in the scan tuple's columns.
   *
 + * fdw_recheck_quals should contain any quals which the core system passed to
 + * the FDW but which were not added to scan.plan.quals; that is, it should
 + * contain the quals being checked remotely.  This is needed for correct
 + * behavior during EvalPlanQual rechecks.
 + *
   * When the plan node represents a foreign join, scan.scanrelid is zero and
   * fs_relids must be consulted to identify the join relation.  (fs_relids
   * is valid for simple scans as well, but will always match scan.scanrelid.)
      List       *fdw_exprs;      /* expressions that FDW may evaluate */
     List       *fdw_private;    /* private data for FDW */
     List       *fdw_scan_tlist; /* optional tlist describing scan tuple */
 +   List       *fdw_recheck_quals;  /* original quals not in scan.plan.quals */
     Bitmapset  *fs_relids;      /* RTIs generated by this scan */
     bool        fsSystemCol;    /* true if any "system column" is needed */
  } ForeignScan;
                           Index scanrelid, Plan *subplan);
  extern ForeignScan *make_foreignscan(List *qptlist, List *qpqual,
                  Index scanrelid, List *fdw_exprs, List *fdw_private,
 -                List *fdw_scan_tlist);
 +                List *fdw_scan_tlist, List *fdw_recheck_quals);
  extern Append *make_append(List *appendplans, List *tlist);
  extern RecursiveUnion *make_recursive_union(List *tlist,
                      Plan *lefttree, Plan *righttree, int wtParam,