void
check_partial_indexes(PlannerInfo *root, RelOptInfo *rel)
{
- List *restrictinfo_list = rel->baserestrictinfo;
- ListCell *ilist;
+ List *clauselist;
+ bool have_partial;
+ Relids otherrels;
+ ListCell *lc;
- foreach(ilist, rel->indexlist)
+ /*
+ * Frequently, there will be no partial indexes, so first check to make
+ * sure there's something useful to do here.
+ */
+ have_partial = false;
+ foreach(lc, rel->indexlist)
{
- IndexOptInfo *index = (IndexOptInfo *) lfirst(ilist);
+ IndexOptInfo *index = (IndexOptInfo *) lfirst(lc);
+
+ if (index->indpred == NIL)
+ continue; /* ignore non-partial indexes */
+
+ if (index->predOK)
+ continue; /* don't repeat work if already proven OK */
+
+ have_partial = true;
+ break;
+ }
+ if (!have_partial)
+ return;
+
+ /*
+ * Construct a list of clauses that we can assume true for the purpose
+ * of proving the index(es) usable. Restriction clauses for the rel are
+ * always usable, and so are any join clauses that are "movable to" this
+ * rel. Also, we can consider any EC-derivable join clauses (which must
+ * be "movable to" this rel, by definition).
+ */
+ clauselist = list_copy(rel->baserestrictinfo);
+
+ /* Scan the rel's join clauses */
+ foreach(lc, rel->joininfo)
+ {
+ RestrictInfo *rinfo = (RestrictInfo *) lfirst(lc);
+
+ /* Check if clause can be moved to this rel */
+ if (!join_clause_is_movable_to(rinfo, rel->relid))
+ continue;
+
+ clauselist = lappend(clauselist, rinfo);
+ }
+
+ /*
+ * Add on any equivalence-derivable join clauses. Computing the correct
+ * relid sets for generate_join_implied_equalities is slightly tricky
+ * because the rel could be a child rel rather than a true baserel, and
+ * in that case we must remove its parent's relid from all_baserels.
+ */
+ if (rel->reloptkind == RELOPT_OTHER_MEMBER_REL)
+ {
+ /* Lookup parent->child translation data */
+ AppendRelInfo *appinfo = find_childrel_appendrelinfo(root, rel);
+
+ otherrels = bms_difference(root->all_baserels,
+ bms_make_singleton(appinfo->parent_relid));
+ }
+ else
+ otherrels = bms_difference(root->all_baserels, rel->relids);
+
+ if (!bms_is_empty(otherrels))
+ clauselist =
+ list_concat(clauselist,
+ generate_join_implied_equalities(root,
+ bms_union(rel->relids,
+ otherrels),
+ otherrels,
+ rel));
+
+ /* Now try to prove each index predicate true */
+ foreach(lc, rel->indexlist)
+ {
+ IndexOptInfo *index = (IndexOptInfo *) lfirst(lc);
if (index->indpred == NIL)
continue; /* ignore non-partial indexes */
if (index->predOK)
continue; /* don't repeat work if already proven OK */
- index->predOK = predicate_implied_by(index->indpred,
- restrictinfo_list);
+ index->predOK = predicate_implied_by(index->indpred, clauselist);
}
}