* cdbpath_create_motion_path * Returns a Path that delivers the subpath result to the * given locus, or NULL if it can't be done. * * 'pathkeys' must specify an ordering equal to or weaker than the * subpath's existing ordering. * * If no motion is needed, the caller's subpath is returned unchanged. * Else if require_existing_order is true, NULL is returned if the *
| 190 | * pathkeys otherwise (the usual case). |
| 191 | */ |
| 192 | Path * |
| 193 | cdbpath_create_motion_path(PlannerInfo *root, |
| 194 | Path *subpath, |
| 195 | List *pathkeys, |
| 196 | bool require_existing_order, |
| 197 | CdbPathLocus locus) |
| 198 | { |
| 199 | CdbMotionPath *pathnode; |
| 200 | |
| 201 | Assert(cdbpathlocus_is_valid(locus) && |
| 202 | cdbpathlocus_is_valid(subpath->locus)); |
| 203 | |
| 204 | /* |
| 205 | * ISTM, subpath of ReplicatedWorkers only happened if general join with broadcast. |
| 206 | * And that only happened if we're doing some updating. Such as: |
| 207 | * `explain update rt3 set b = rt2.b from rt2 where rt3.b = rt2.b;` |
| 208 | * where rt3 and rt2 should have different numsegments. |
| 209 | * However, we don't support parallel update yet, so it will never happen. |
| 210 | */ |
| 211 | Assert(!CdbPathLocus_IsReplicatedWorkers(subpath->locus)); |
| 212 | |
| 213 | /* |
| 214 | * Motion is to change path's locus, if target locus is the |
| 215 | * same as the subpath's, there is no need to add motion. |
| 216 | */ |
| 217 | if (cdbpathlocus_equal(subpath->locus, locus)) |
| 218 | return subpath; |
| 219 | |
| 220 | /* Moving subpath output to a single executor process (qDisp or qExec)? */ |
| 221 | if (CdbPathLocus_IsOuterQuery(locus)) |
| 222 | { |
| 223 | /* Outer -> Outer is a no-op */ |
| 224 | if (CdbPathLocus_IsOuterQuery(subpath->locus)) |
| 225 | { |
| 226 | return subpath; |
| 227 | } |
| 228 | |
| 229 | if (CdbPathLocus_IsGeneral(subpath->locus)) |
| 230 | { |
| 231 | /* XXX: this is a bit bogus. We just change the subpath's locus. */ |
| 232 | subpath->locus = locus; |
| 233 | return subpath; |
| 234 | } |
| 235 | |
| 236 | if (CdbPathLocus_IsEntry(subpath->locus) || |
| 237 | CdbPathLocus_IsSingleQE(subpath->locus)) |
| 238 | { |
| 239 | /* |
| 240 | * XXX: this is a bit bogus. We just change the subpath's locus. |
| 241 | * |
| 242 | * This is also bogus, because the outer query might need to run |
| 243 | * in segments. |
| 244 | */ |
| 245 | subpath->locus = locus; |
| 246 | return subpath; |
| 247 | } |
| 248 | } |
| 249 | else if (CdbPathLocus_IsBottleneck(locus)) |
no test coverage detected