Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 4e89bae

Browse files
committed
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.
1 parent 5c4a91c commit 4e89bae

File tree

1 file changed

+69
-54
lines changed

1 file changed

+69
-54
lines changed

src/backend/optimizer/path/indxpath.c

Lines changed: 69 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*
1010
*
1111
* IDENTIFICATION
12-
* $PostgreSQL: pgsql/src/backend/optimizer/path/indxpath.c,v 1.167 2004/12/31 22:00:04 pgsql Exp $
12+
* $PostgreSQL: pgsql/src/backend/optimizer/path/indxpath.c,v 1.168 2005/03/01 00:24:52 tgl Exp $
1313
*
1414
*-------------------------------------------------------------------------
1515
*/
@@ -64,9 +64,9 @@ static bool match_join_clause_to_indexcol(RelOptInfo *rel, IndexOptInfo *index,
6464
RestrictInfo *rinfo);
6565
static Oid indexable_operator(Expr *clause, Oid opclass,
6666
bool indexkey_on_left);
67-
static bool pred_test_recurse_pred(Expr *predicate, List *restrictinfo_list);
6867
static bool pred_test_restrict_list(Expr *predicate, List *restrictinfo_list);
6968
static bool pred_test_recurse_restrict(Expr *predicate, Node *clause);
69+
static bool pred_test_recurse_pred(Expr *predicate, Node *clause);
7070
static bool pred_test_simple_clause(Expr *predicate, Node *clause);
7171
static Relids indexable_outerrelids(RelOptInfo *rel, IndexOptInfo *index);
7272
static Path *make_innerjoin_index_path(Query *root,
@@ -749,11 +749,25 @@ check_partial_indexes(Query *root, RelOptInfo *rel)
749749
* Recursively checks whether the clauses in restrictinfo_list imply
750750
* that the given predicate is true.
751751
*
752-
* This routine (together with the routines it calls) first breaks down
753-
* the predicate to its constituent AND/OR elements, then similarly
754-
* breaks down the restriction clauses to AND/OR elements in an effort
755-
* to prove that each predicate element is implied. The top-level
756-
* List structure of each list corresponds to an AND list.
752+
* This routine (together with the routines it calls) iterates over
753+
* ANDs in the predicate first, then breaks down the restriction list
754+
* to its constituent AND/OR elements, and iterates over ORs
755+
* in the predicate last. This order is important to make the test
756+
* succeed whenever possible. --Nels, Jan '93
757+
*
758+
* For example, a restriction (a OR b) certainly implies a predicate
759+
* (a OR b OR c), but no one element of the predicate is individually
760+
* implied by the restriction. By expanding the predicate ORs last
761+
* we are able to prove that the whole predicate is implied by each arm
762+
* of the restriction. Conversely consider predicate (a AND b) with
763+
* restriction (a AND b AND c). This should be implied but we will
764+
* fail to prove it if we dissect the restriction first.
765+
*
766+
* The top-level List structure of each list corresponds to an AND list.
767+
* We assume that canonicalize_qual() has been applied and so there
768+
* are no explicit ANDs immediately below the top-level List structure.
769+
* (If this is not true we might fail to prove an implication that is
770+
* valid, but no worse consequences will ensue.)
757771
*/
758772
bool
759773
pred_test(List *predicate_list, List *restrictinfo_list)
@@ -779,65 +793,23 @@ pred_test(List *predicate_list, List *restrictinfo_list)
779793
return false; /* no restriction clauses: the test must
780794
* fail */
781795

796+
/* Take care of the AND semantics of the top-level predicate list */
782797
foreach(pred, predicate_list)
783798
{
784799
/*
785800
* if any clause is not implied, the whole predicate is not
786801
* implied.
787802
*/
788-
if (!pred_test_recurse_pred(lfirst(pred), restrictinfo_list))
803+
if (!pred_test_restrict_list(lfirst(pred), restrictinfo_list))
789804
return false;
790805
}
791806
return true;
792807
}
793808

794809

795-
/*
796-
* pred_test_recurse_pred
797-
* Does the "predicate inclusion test" for one conjunct of a predicate
798-
* expression. Here we recursively deal with the possibility that the
799-
* predicate conjunct is itself an AND or OR structure.
800-
*/
801-
static bool
802-
pred_test_recurse_pred(Expr *predicate, List *restrictinfo_list)
803-
{
804-
List *items;
805-
ListCell *item;
806-
807-
Assert(predicate != NULL);
808-
if (or_clause((Node *) predicate))
809-
{
810-
items = ((BoolExpr *) predicate)->args;
811-
foreach(item, items)
812-
{
813-
/* if any item is implied, the whole predicate is implied */
814-
if (pred_test_recurse_pred(lfirst(item), restrictinfo_list))
815-
return true;
816-
}
817-
return false;
818-
}
819-
else if (and_clause((Node *) predicate))
820-
{
821-
items = ((BoolExpr *) predicate)->args;
822-
foreach(item, items)
823-
{
824-
/*
825-
* if any item is not implied, the whole predicate is not
826-
* implied
827-
*/
828-
if (!pred_test_recurse_pred(lfirst(item), restrictinfo_list))
829-
return false;
830-
}
831-
return true;
832-
}
833-
else
834-
return pred_test_restrict_list(predicate, restrictinfo_list);
835-
}
836-
837-
838810
/*
839811
* pred_test_restrict_list
840-
* Does the "predicate inclusion test" for one element of a predicate
812+
* Does the "predicate inclusion test" for one AND clause of a predicate
841813
* expression. Here we take care of the AND semantics of the top-level
842814
* restrictinfo list.
843815
*/
@@ -859,10 +831,10 @@ pred_test_restrict_list(Expr *predicate, List *restrictinfo_list)
859831

860832
/*
861833
* pred_test_recurse_restrict
862-
* Does the "predicate inclusion test" for one element of a predicate
834+
* Does the "predicate inclusion test" for one AND clause of a predicate
863835
* expression. Here we recursively deal with the possibility that the
864836
* restriction-list element is itself an AND or OR structure; also,
865-
* we strip off RestrictInfo nodes to find bare predicate expressions.
837+
* we strip off RestrictInfo nodes to find bare qualifier expressions.
866838
*/
867839
static bool
868840
pred_test_recurse_restrict(Expr *predicate, Node *clause)
@@ -903,6 +875,49 @@ pred_test_recurse_restrict(Expr *predicate, Node *clause)
903875
}
904876
return false;
905877
}
878+
else
879+
return pred_test_recurse_pred(predicate, clause);
880+
}
881+
882+
883+
/*
884+
* pred_test_recurse_pred
885+
* Does the "predicate inclusion test" for one conjunct of a predicate
886+
* expression. Here we recursively deal with the possibility that the
887+
* predicate conjunct is itself an AND or OR structure.
888+
*/
889+
static bool
890+
pred_test_recurse_pred(Expr *predicate, Node *clause)
891+
{
892+
List *items;
893+
ListCell *item;
894+
895+
Assert(predicate != NULL);
896+
if (or_clause((Node *) predicate))
897+
{
898+
items = ((BoolExpr *) predicate)->args;
899+
foreach(item, items)
900+
{
901+
/* if any item is implied, the whole predicate is implied */
902+
if (pred_test_recurse_pred(lfirst(item), clause))
903+
return true;
904+
}
905+
return false;
906+
}
907+
else if (and_clause((Node *) predicate))
908+
{
909+
items = ((BoolExpr *) predicate)->args;
910+
foreach(item, items)
911+
{
912+
/*
913+
* if any item is not implied, the whole predicate is not
914+
* implied
915+
*/
916+
if (!pred_test_recurse_pred(lfirst(item), clause))
917+
return false;
918+
}
919+
return true;
920+
}
906921
else
907922
return pred_test_simple_clause(predicate, clause);
908923
}

0 commit comments

Comments
 (0)