mirror of
https://github.com/postgres/postgres.git
synced 2025-04-27 22:56:53 +03:00
Revert the logic for expanding AND/OR conditions in pred_test() to what
it was in 7.4, and add some comments explaining why it has to be this way. I broke it for OR'd index predicates in a fit of code cleanup last summer. Per example from Sergey Koshcheyev.
This commit is contained in:
parent
5c4a91c295
commit
4e89bae704
@ -9,7 +9,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/optimizer/path/indxpath.c,v 1.167 2004/12/31 22:00:04 pgsql Exp $
|
* $PostgreSQL: pgsql/src/backend/optimizer/path/indxpath.c,v 1.168 2005/03/01 00:24:52 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -64,9 +64,9 @@ static bool match_join_clause_to_indexcol(RelOptInfo *rel, IndexOptInfo *index,
|
|||||||
RestrictInfo *rinfo);
|
RestrictInfo *rinfo);
|
||||||
static Oid indexable_operator(Expr *clause, Oid opclass,
|
static Oid indexable_operator(Expr *clause, Oid opclass,
|
||||||
bool indexkey_on_left);
|
bool indexkey_on_left);
|
||||||
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_restrict_list(Expr *predicate, List *restrictinfo_list);
|
||||||
static bool pred_test_recurse_restrict(Expr *predicate, Node *clause);
|
static bool pred_test_recurse_restrict(Expr *predicate, Node *clause);
|
||||||
|
static bool pred_test_recurse_pred(Expr *predicate, Node *clause);
|
||||||
static bool pred_test_simple_clause(Expr *predicate, Node *clause);
|
static bool pred_test_simple_clause(Expr *predicate, Node *clause);
|
||||||
static Relids indexable_outerrelids(RelOptInfo *rel, IndexOptInfo *index);
|
static Relids indexable_outerrelids(RelOptInfo *rel, IndexOptInfo *index);
|
||||||
static Path *make_innerjoin_index_path(Query *root,
|
static Path *make_innerjoin_index_path(Query *root,
|
||||||
@ -749,11 +749,25 @@ check_partial_indexes(Query *root, RelOptInfo *rel)
|
|||||||
* Recursively checks whether the clauses in restrictinfo_list imply
|
* Recursively checks whether the clauses in restrictinfo_list imply
|
||||||
* that the given predicate is true.
|
* that the given predicate is true.
|
||||||
*
|
*
|
||||||
* This routine (together with the routines it calls) first breaks down
|
* This routine (together with the routines it calls) iterates over
|
||||||
* the predicate to its constituent AND/OR elements, then similarly
|
* ANDs in the predicate first, then breaks down the restriction list
|
||||||
* breaks down the restriction clauses to AND/OR elements in an effort
|
* to its constituent AND/OR elements, and iterates over ORs
|
||||||
* to prove that each predicate element is implied. The top-level
|
* in the predicate last. This order is important to make the test
|
||||||
* List structure of each list corresponds to an AND list.
|
* succeed whenever possible. --Nels, Jan '93
|
||||||
|
*
|
||||||
|
* For example, a restriction (a OR b) certainly implies a predicate
|
||||||
|
* (a OR b OR c), but no one element of the predicate is individually
|
||||||
|
* implied by the restriction. By expanding the predicate ORs last
|
||||||
|
* we are able to prove that the whole predicate is implied by each arm
|
||||||
|
* of the restriction. Conversely consider predicate (a AND b) with
|
||||||
|
* restriction (a AND b AND c). This should be implied but we will
|
||||||
|
* fail to prove it if we dissect the restriction first.
|
||||||
|
*
|
||||||
|
* The top-level List structure of each list corresponds to an AND list.
|
||||||
|
* We assume that canonicalize_qual() has been applied and so there
|
||||||
|
* are no explicit ANDs immediately below the top-level List structure.
|
||||||
|
* (If this is not true we might fail to prove an implication that is
|
||||||
|
* valid, but no worse consequences will ensue.)
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
pred_test(List *predicate_list, List *restrictinfo_list)
|
pred_test(List *predicate_list, List *restrictinfo_list)
|
||||||
@ -779,65 +793,23 @@ pred_test(List *predicate_list, List *restrictinfo_list)
|
|||||||
return false; /* no restriction clauses: the test must
|
return false; /* no restriction clauses: the test must
|
||||||
* fail */
|
* fail */
|
||||||
|
|
||||||
|
/* Take care of the AND semantics of the top-level predicate list */
|
||||||
foreach(pred, predicate_list)
|
foreach(pred, predicate_list)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* if any clause is not implied, the whole predicate is not
|
* if any clause is not implied, the whole predicate is not
|
||||||
* implied.
|
* implied.
|
||||||
*/
|
*/
|
||||||
if (!pred_test_recurse_pred(lfirst(pred), restrictinfo_list))
|
if (!pred_test_restrict_list(lfirst(pred), restrictinfo_list))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* pred_test_recurse_pred
|
|
||||||
* Does the "predicate inclusion test" for one conjunct of a predicate
|
|
||||||
* 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
|
* pred_test_restrict_list
|
||||||
* Does the "predicate inclusion test" for one element of a predicate
|
* Does the "predicate inclusion test" for one AND clause of a predicate
|
||||||
* expression. Here we take care of the AND semantics of the top-level
|
* expression. Here we take care of the AND semantics of the top-level
|
||||||
* restrictinfo list.
|
* restrictinfo list.
|
||||||
*/
|
*/
|
||||||
@ -859,10 +831,10 @@ pred_test_restrict_list(Expr *predicate, List *restrictinfo_list)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* pred_test_recurse_restrict
|
* pred_test_recurse_restrict
|
||||||
* Does the "predicate inclusion test" for one element of a predicate
|
* Does the "predicate inclusion test" for one AND clause of a predicate
|
||||||
* expression. Here we recursively deal with the possibility that the
|
* expression. Here we recursively deal with the possibility that the
|
||||||
* restriction-list element is itself an AND or OR structure; also,
|
* restriction-list element is itself an AND or OR structure; also,
|
||||||
* we strip off RestrictInfo nodes to find bare predicate expressions.
|
* we strip off RestrictInfo nodes to find bare qualifier expressions.
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
pred_test_recurse_restrict(Expr *predicate, Node *clause)
|
pred_test_recurse_restrict(Expr *predicate, Node *clause)
|
||||||
@ -903,6 +875,49 @@ pred_test_recurse_restrict(Expr *predicate, Node *clause)
|
|||||||
}
|
}
|
||||||
return false;
|
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. 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
|
else
|
||||||
return pred_test_simple_clause(predicate, clause);
|
return pred_test_simple_clause(predicate, clause);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user