* consider_index_join_outer_rels * Generate parameterized paths based on clause relids in the clause list. * * Workhorse for consider_index_join_clauses; see notes therein for rationale. * * 'rel', 'index', 'rclauseset', 'jclauseset', 'eclauseset', and * 'bitindexpaths' as above * 'indexjoinclauses' is a list of IndexClauses for join clauses * 'considered_clauses' is the total number of
| 507 | * '*considered_relids' is a list of all relids sets already considered |
| 508 | */ |
| 509 | static void |
| 510 | consider_index_join_outer_rels(PlannerInfo *root, RelOptInfo *rel, |
| 511 | IndexOptInfo *index, |
| 512 | IndexClauseSet *rclauseset, |
| 513 | IndexClauseSet *jclauseset, |
| 514 | IndexClauseSet *eclauseset, |
| 515 | List **bitindexpaths, |
| 516 | List *indexjoinclauses, |
| 517 | int considered_clauses, |
| 518 | List **considered_relids) |
| 519 | { |
| 520 | ListCell *lc; |
| 521 | |
| 522 | /* Examine relids of each joinclause in the given list */ |
| 523 | foreach(lc, indexjoinclauses) |
| 524 | { |
| 525 | IndexClause *iclause = (IndexClause *) lfirst(lc); |
| 526 | Relids clause_relids = iclause->rinfo->clause_relids; |
| 527 | EquivalenceClass *parent_ec = iclause->rinfo->parent_ec; |
| 528 | int num_considered_relids; |
| 529 | |
| 530 | /* If we already tried its relids set, no need to do so again */ |
| 531 | if (bms_equal_any(clause_relids, *considered_relids)) |
| 532 | continue; |
| 533 | |
| 534 | /* |
| 535 | * Generate the union of this clause's relids set with each |
| 536 | * previously-tried set. This ensures we try this clause along with |
| 537 | * every interesting subset of previous clauses. However, to avoid |
| 538 | * exponential growth of planning time when there are many clauses, |
| 539 | * limit the number of relid sets accepted to 10 * considered_clauses. |
| 540 | * |
| 541 | * Note: get_join_index_paths appends entries to *considered_relids, |
| 542 | * but we do not need to visit such newly-added entries within this |
| 543 | * loop, so we don't use foreach() here. No real harm would be done |
| 544 | * if we did visit them, since the subset check would reject them; but |
| 545 | * it would waste some cycles. |
| 546 | */ |
| 547 | num_considered_relids = list_length(*considered_relids); |
| 548 | for (int pos = 0; pos < num_considered_relids; pos++) |
| 549 | { |
| 550 | Relids oldrelids = (Relids) list_nth(*considered_relids, pos); |
| 551 | |
| 552 | /* |
| 553 | * If either is a subset of the other, no new set is possible. |
| 554 | * This isn't a complete test for redundancy, but it's easy and |
| 555 | * cheap. get_join_index_paths will check more carefully if we |
| 556 | * already generated the same relids set. |
| 557 | */ |
| 558 | if (bms_subset_compare(clause_relids, oldrelids) != BMS_DIFFERENT) |
| 559 | continue; |
| 560 | |
| 561 | /* |
| 562 | * If this clause was derived from an equivalence class, the |
| 563 | * clause list may contain other clauses derived from the same |
| 564 | * eclass. We should not consider that combining this clause with |
| 565 | * one of those clauses generates a usefully different |
| 566 | * parameterization; so skip if any clause derived from the same |
no test coverage detected