Hi,
In add_paths_to_joinrel(), the FDW specific hook GetForeignJoinPaths() is called. This hook if implemented should add ForeignPaths for pushed down joins. create_plan_recurse() calls create_scan_plan() on seeing these paths.
create_scan_plan() generates a list of clauses to be applied on scan from rel->baserestrictinfo and parameterization clauses. This list is passed to create_*scan_plan routine as scanclauses. This code is very specific for single relations scans. Now that we are using create_scan_plan() for creating plan for join relations, it needs some changes so that quals relevant to a join can be passed to create_foreignscan_plan(). A related problem is in create_foreignscan_plan(), which sets ForeignScan::fsSystemCol if a system column is being used in the targetlist or quals. Right now it only checks rel->baserestrictinfo, which is NULL for a joinrel. Thus in case a system column appears in the joinclauses it will not be considered.
Here are possible ways to fix the problem
1. Add joinrestrictinfo field in ForeignPath and use that as scan_clauses in create_foreignscan_plan(). Something like patch attached. FDWs anyway need to examine the join clauses to check whether they are pushable or not. So mostly FDWs have already sorted the clauses (joinclauses and otherclauses as well as pushable and nonpushable) and stored in their private structures. So they probably don't need to look at the scan_clauses passed in. (See WIP patch in [1]).
2. Create a separate ForeignJoinPath node with JoinPath as member (like MergePath). This node then takes entirely different create_*_plan route, ultimately producing a ForeignScan node. This path though clean will have a lot of new and duplicate code.
Any other suggestions welcome.