* create_mergejoin_path * Creates a pathnode corresponding to a mergejoin join between * two relations * * 'joinrel' is the join relation * 'jointype' is the type of join required * 'workspace' is the result from initial_cost_mergejoin * 'extra' contains various information about the join * 'outer_path' is the outer path * 'inner_path' is the inner path * 'restrict_clauses' are the R
| 4105 | * or NIL to use existing ordering |
| 4106 | */ |
| 4107 | Path * |
| 4108 | create_mergejoin_path(PlannerInfo *root, |
| 4109 | RelOptInfo *joinrel, |
| 4110 | JoinType jointype, |
| 4111 | JoinType orig_jointype, /* CDB */ |
| 4112 | JoinCostWorkspace *workspace, |
| 4113 | JoinPathExtraData *extra, |
| 4114 | Path *outer_path, |
| 4115 | Path *inner_path, |
| 4116 | List *restrict_clauses, |
| 4117 | List *pathkeys, |
| 4118 | Relids required_outer, |
| 4119 | List *mergeclauses, |
| 4120 | List *redistribution_clauses, /* CDB */ |
| 4121 | List *outersortkeys, |
| 4122 | List *innersortkeys) |
| 4123 | { |
| 4124 | MergePath *pathnode = makeNode(MergePath); |
| 4125 | CdbPathLocus join_locus; |
| 4126 | List *outermotionkeys; |
| 4127 | List *innermotionkeys; |
| 4128 | bool preserve_outer_ordering; |
| 4129 | bool preserve_inner_ordering; |
| 4130 | int rowidexpr_id; |
| 4131 | |
| 4132 | /* |
| 4133 | * GPDB_92_MERGE_FIXME: Should we keep the pathkeys_contained_in calls? |
| 4134 | */ |
| 4135 | /* |
| 4136 | * Do subpaths have useful ordering? |
| 4137 | */ |
| 4138 | if (outersortkeys == NIL) /* must preserve existing ordering */ |
| 4139 | outermotionkeys = outer_path->pathkeys; |
| 4140 | else if (pathkeys_contained_in(outersortkeys, outer_path->pathkeys)) |
| 4141 | outermotionkeys = outersortkeys;/* lucky coincidence, already ordered */ |
| 4142 | else /* existing order useless; must sort */ |
| 4143 | outermotionkeys = NIL; |
| 4144 | |
| 4145 | if (innersortkeys == NIL) |
| 4146 | innermotionkeys = inner_path->pathkeys; |
| 4147 | else if (pathkeys_contained_in(innersortkeys, inner_path->pathkeys)) |
| 4148 | innermotionkeys = innersortkeys; |
| 4149 | else |
| 4150 | innermotionkeys = NIL; |
| 4151 | |
| 4152 | /* |
| 4153 | * Add motion nodes above subpaths and decide where to join. |
| 4154 | * |
| 4155 | * If we're explicitly sorting one or both sides of the join, don't choose |
| 4156 | * a Motion that would break that ordering again. But as a special case, |
| 4157 | * if there are no merge clauses, then there is no join order that would need |
| 4158 | * preserving. That case can occur with a query like "a FULL JOIN b ON true" |
| 4159 | */ |
| 4160 | if (mergeclauses) |
| 4161 | { |
| 4162 | preserve_outer_ordering = (outersortkeys == NIL); |
| 4163 | preserve_inner_ordering = (innersortkeys == NIL); |
| 4164 | } |
no test coverage detected