diff options
Diffstat (limited to 'src/backend/optimizer/path/indxpath.c')
-rw-r--r-- | src/backend/optimizer/path/indxpath.c | 135 |
1 files changed, 67 insertions, 68 deletions
diff --git a/src/backend/optimizer/path/indxpath.c b/src/backend/optimizer/path/indxpath.c index 08aee2010ef..2a0c3d1c5d6 100644 --- a/src/backend/optimizer/path/indxpath.c +++ b/src/backend/optimizer/path/indxpath.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/optimizer/path/indxpath.c,v 1.164 2004/08/29 05:06:43 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/optimizer/path/indxpath.c,v 1.165 2004/10/11 22:56:56 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -64,10 +64,9 @@ static bool match_join_clause_to_indexcol(RelOptInfo *rel, IndexOptInfo *index, RestrictInfo *rinfo); static Oid indexable_operator(Expr *clause, Oid opclass, bool indexkey_on_left); -static bool pred_test(List *predicate_list, List *restrictinfo_list); +static bool pred_test_recurse_pred(Expr *predicate, List *restrictinfo_list); static bool pred_test_restrict_list(Expr *predicate, List *restrictinfo_list); -static bool pred_test_recurse_clause(Expr *predicate, Node *clause); -static bool pred_test_recurse_pred(Expr *predicate, Node *clause); +static bool pred_test_recurse_restrict(Expr *predicate, Node *clause); static bool pred_test_simple_clause(Expr *predicate, Node *clause); static Relids indexable_outerrelids(RelOptInfo *rel, IndexOptInfo *index); static Path *make_innerjoin_index_path(Query *root, @@ -750,14 +749,13 @@ check_partial_indexes(Query *root, RelOptInfo *rel) * Recursively checks whether the clauses in restrictinfo_list imply * that the given predicate is true. * - * This routine (together with the routines it calls) iterates over - * ANDs in the predicate first, then reduces the qualification - * clauses down to their constituent terms, and iterates over ORs - * in the predicate last. This order is important to make the test - * succeed whenever possible (assuming the predicate has been converted - * to CNF format). --Nels, Jan '93 + * This routine (together with the routines it calls) first breaks down + * the predicate to its constituent AND/OR elements, then similarly + * breaks down the restriction clauses to AND/OR elements in an effort + * to prove that each predicate element is implied. The top-level + * List structure of each list corresponds to an AND list. */ -static bool +bool pred_test(List *predicate_list, List *restrictinfo_list) { ListCell *pred; @@ -785,10 +783,9 @@ pred_test(List *predicate_list, List *restrictinfo_list) { /* * if any clause is not implied, the whole predicate is not - * implied. Note we assume that any sub-ANDs have been flattened - * when the predicate was fed through canonicalize_qual(). + * implied. */ - if (!pred_test_restrict_list(lfirst(pred), restrictinfo_list)) + if (!pred_test_recurse_pred(lfirst(pred), restrictinfo_list)) return false; } return true; @@ -796,9 +793,53 @@ pred_test(List *predicate_list, List *restrictinfo_list) /* - * pred_test_restrict_list + * pred_test_recurse_pred * Does the "predicate inclusion test" for one conjunct of a predicate - * expression. + * expression. Here we recursively deal with the possibility that the + * predicate conjunct is itself an AND or OR structure. + */ +static bool +pred_test_recurse_pred(Expr *predicate, List *restrictinfo_list) +{ + List *items; + ListCell *item; + + Assert(predicate != NULL); + if (or_clause((Node *) predicate)) + { + items = ((BoolExpr *) predicate)->args; + foreach(item, items) + { + /* if any item is implied, the whole predicate is implied */ + if (pred_test_recurse_pred(lfirst(item), restrictinfo_list)) + return true; + } + return false; + } + else if (and_clause((Node *) predicate)) + { + items = ((BoolExpr *) predicate)->args; + foreach(item, items) + { + /* + * if any item is not implied, the whole predicate is not + * implied + */ + if (!pred_test_recurse_pred(lfirst(item), restrictinfo_list)) + return false; + } + return true; + } + else + return pred_test_restrict_list(predicate, restrictinfo_list); +} + + +/* + * pred_test_restrict_list + * Does the "predicate inclusion test" for one element of a predicate + * expression. Here we take care of the AND semantics of the top-level + * restrictinfo list. */ static bool pred_test_restrict_list(Expr *predicate, List *restrictinfo_list) @@ -809,9 +850,11 @@ pred_test_restrict_list(Expr *predicate, List *restrictinfo_list) { RestrictInfo *restrictinfo = (RestrictInfo *) lfirst(item); + Assert(IsA(restrictinfo, RestrictInfo)); + /* if any clause implies the predicate, return true */ - if (pred_test_recurse_clause(predicate, - (Node *) restrictinfo->clause)) + if (pred_test_recurse_restrict(predicate, + (Node *) restrictinfo->clause)) return true; } return false; @@ -819,13 +862,13 @@ pred_test_restrict_list(Expr *predicate, List *restrictinfo_list) /* - * pred_test_recurse_clause - * Does the "predicate inclusion test" for a general restriction-clause + * pred_test_recurse_restrict + * Does the "predicate inclusion test" for one element of a predicate * expression. Here we recursively deal with the possibility that the - * restriction clause is itself an AND or OR structure. + * restriction-list element is itself an AND or OR structure. */ static bool -pred_test_recurse_clause(Expr *predicate, Node *clause) +pred_test_recurse_restrict(Expr *predicate, Node *clause) { List *items; ListCell *item; @@ -837,7 +880,7 @@ pred_test_recurse_clause(Expr *predicate, Node *clause) foreach(item, items) { /* if any OR item doesn't imply the predicate, clause doesn't */ - if (!pred_test_recurse_clause(predicate, lfirst(item))) + if (!pred_test_recurse_restrict(predicate, lfirst(item))) return false; } return true; @@ -851,56 +894,12 @@ pred_test_recurse_clause(Expr *predicate, Node *clause) * if any AND item implies the predicate, the whole clause * does */ - if (pred_test_recurse_clause(predicate, lfirst(item))) + if (pred_test_recurse_restrict(predicate, lfirst(item))) return true; } return false; } else - return pred_test_recurse_pred(predicate, clause); -} - - -/* - * pred_test_recurse_pred - * Does the "predicate inclusion test" for one conjunct of a predicate - * expression for a simple restriction clause. Here we recursively deal - * with the possibility that the predicate conjunct is itself an AND or - * OR structure. - */ -static bool -pred_test_recurse_pred(Expr *predicate, Node *clause) -{ - List *items; - ListCell *item; - - Assert(predicate != NULL); - if (or_clause((Node *) predicate)) - { - items = ((BoolExpr *) predicate)->args; - foreach(item, items) - { - /* if any item is implied, the whole predicate is implied */ - if (pred_test_recurse_pred(lfirst(item), clause)) - return true; - } - return false; - } - else if (and_clause((Node *) predicate)) - { - items = ((BoolExpr *) predicate)->args; - foreach(item, items) - { - /* - * if any item is not implied, the whole predicate is not - * implied - */ - if (!pred_test_recurse_pred(lfirst(item), clause)) - return false; - } - return true; - } - else return pred_test_simple_clause(predicate, clause); } |