* postgresGetForeignJoinPaths * Add possible ForeignPath to joinrel, if join is safe to push down. */
| 6032 | * Add possible ForeignPath to joinrel, if join is safe to push down. |
| 6033 | */ |
| 6034 | static void |
| 6035 | postgresGetForeignJoinPaths(PlannerInfo *root, |
| 6036 | RelOptInfo *joinrel, |
| 6037 | RelOptInfo *outerrel, |
| 6038 | RelOptInfo *innerrel, |
| 6039 | JoinType jointype, |
| 6040 | JoinPathExtraData *extra) |
| 6041 | { |
| 6042 | PgFdwRelationInfo *fpinfo; |
| 6043 | ForeignPath *joinpath; |
| 6044 | double rows; |
| 6045 | int width; |
| 6046 | Cost startup_cost; |
| 6047 | Cost total_cost; |
| 6048 | Path *epq_path; /* Path to create plan to be executed when |
| 6049 | * EvalPlanQual gets triggered. */ |
| 6050 | |
| 6051 | /* |
| 6052 | * Skip if this join combination has been considered already. |
| 6053 | */ |
| 6054 | if (joinrel->fdw_private) |
| 6055 | return; |
| 6056 | |
| 6057 | /* |
| 6058 | * This code does not work for joins with lateral references, since those |
| 6059 | * must have parameterized paths, which we don't generate yet. |
| 6060 | */ |
| 6061 | if (!bms_is_empty(joinrel->lateral_relids)) |
| 6062 | return; |
| 6063 | |
| 6064 | /* |
| 6065 | * Create unfinished PgFdwRelationInfo entry which is used to indicate |
| 6066 | * that the join relation is already considered, so that we won't waste |
| 6067 | * time in judging safety of join pushdown and adding the same paths again |
| 6068 | * if found safe. Once we know that this join can be pushed down, we fill |
| 6069 | * the entry. |
| 6070 | */ |
| 6071 | fpinfo = (PgFdwRelationInfo *) palloc0(sizeof(PgFdwRelationInfo)); |
| 6072 | fpinfo->pushdown_safe = false; |
| 6073 | joinrel->fdw_private = fpinfo; |
| 6074 | /* attrs_used is only for base relations. */ |
| 6075 | fpinfo->attrs_used = NULL; |
| 6076 | |
| 6077 | /* |
| 6078 | * If there is a possibility that EvalPlanQual will be executed, we need |
| 6079 | * to be able to reconstruct the row using scans of the base relations. |
| 6080 | * GetExistingLocalJoinPath will find a suitable path for this purpose in |
| 6081 | * the path list of the joinrel, if one exists. We must be careful to |
| 6082 | * call it before adding any ForeignPath, since the ForeignPath might |
| 6083 | * dominate the only suitable local path available. We also do it before |
| 6084 | * calling foreign_join_ok(), since that function updates fpinfo and marks |
| 6085 | * it as pushable if the join is found to be pushable. |
| 6086 | */ |
| 6087 | if (root->parse->commandType == CMD_DELETE || |
| 6088 | root->parse->commandType == CMD_UPDATE || |
| 6089 | root->rowMarks) |
| 6090 | { |
| 6091 | epq_path = GetExistingLocalJoinPath(joinrel); |
nothing calls this directly
no test coverage detected