* cdbpathlocus_from_subquery * * Returns a locus describing the distribution of a subquery. * The subquery plan should have been generated already. * * 'subqplan' is the subquery plan. * 'subqrelid' is the subquery RTE index in the current query level, for * building Var nodes that reference the subquery's result columns. */
| 432 | * building Var nodes that reference the subquery's result columns. |
| 433 | */ |
| 434 | CdbPathLocus |
| 435 | cdbpathlocus_from_subquery(struct PlannerInfo *root, |
| 436 | RelOptInfo *rel, |
| 437 | Path *subpath) |
| 438 | { |
| 439 | CdbPathLocus locus; |
| 440 | |
| 441 | if (CdbPathLocus_IsHashed(subpath->locus) || |
| 442 | CdbPathLocus_IsHashedOJ(subpath->locus)) |
| 443 | { |
| 444 | bool failed = false; |
| 445 | List *distkeys = NIL; |
| 446 | int numsegments = subpath->locus.numsegments; |
| 447 | ListCell *dk_cell; |
| 448 | List *usable_subtlist = NIL; |
| 449 | List *new_vars = NIL; |
| 450 | ListCell *lc; |
| 451 | ListCell *lc2 = NULL; |
| 452 | RelOptInfo *parentrel = NULL; |
| 453 | |
| 454 | /* |
| 455 | * If the subquery we're pulling up is a child of an append rel, |
| 456 | * the pathkey should refer to the parent rel's Vars, not the child. |
| 457 | * Normally, the planner puts the parent and child expressions in an |
| 458 | * equivalence class for any potentially useful expressions, but that's |
| 459 | * done earlier in the planning already. |
| 460 | */ |
| 461 | if (rel->reloptkind == RELOPT_OTHER_MEMBER_REL) |
| 462 | { |
| 463 | if (root->append_rel_array == NULL || root->append_rel_array[rel->relid] == NULL) |
| 464 | elog(ERROR, "child rel %u not found in append_rel_array", rel->relid); |
| 465 | |
| 466 | /* Direct looking for AppendRelInfos by relid in the append_rel_array */ |
| 467 | AppendRelInfo *appendrel = root->append_rel_array[rel->relid]; |
| 468 | Index parent_relid = appendrel->parent_relid; |
| 469 | parentrel = root->simple_rel_array[parent_relid]; |
| 470 | Assert(list_length(parentrel->reltarget->exprs) == list_length(rel->reltarget->exprs)); |
| 471 | } |
| 472 | |
| 473 | if (parentrel) |
| 474 | lc2 = list_head(parentrel->reltarget->exprs); |
| 475 | foreach (lc, rel->reltarget->exprs) |
| 476 | { |
| 477 | Expr *expr = (Expr *) lfirst(lc); |
| 478 | Var *var; |
| 479 | Expr *subexpr; |
| 480 | Expr *parentexpr = NULL; |
| 481 | |
| 482 | if (parentrel) |
| 483 | { |
| 484 | parentexpr = lfirst(lc2); |
| 485 | lc2 = lnext(parentrel->reltarget->exprs, lc2); |
| 486 | } |
| 487 | |
| 488 | if (!IsA(expr, Var)) |
| 489 | continue; |
| 490 | var = (Var *) expr; |
| 491 |
no test coverage detected