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,
6464RestrictInfo * rinfo );
6565static Oid indexable_operator (Expr * clause ,Oid opclass ,
6666bool indexkey_on_left );
67- static bool pred_test_recurse_pred (Expr * predicate ,List * restrictinfo_list );
6867static bool pred_test_restrict_list (Expr * predicate ,List * restrictinfo_list );
6968static bool pred_test_recurse_restrict (Expr * predicate ,Node * clause );
69+ static bool pred_test_recurse_pred (Expr * predicate ,Node * clause );
7070static bool pred_test_simple_clause (Expr * predicate ,Node * clause );
7171static Relids indexable_outerrelids (RelOptInfo * rel ,IndexOptInfo * index );
7272static 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 */
758772bool
759773pred_test (List * predicate_list ,List * restrictinfo_list )
@@ -779,65 +793,23 @@ pred_test(List *predicate_list, List *restrictinfo_list)
779793return false;/* no restriction clauses: the test must
780794 * fail */
781795
796+ /* Take care of the AND semantics of the top-level predicate list */
782797foreach (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 ))
789804return false;
790805}
791806return 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 oneelement of a predicate
812+ * Does the "predicate inclusion test" for oneAND 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 oneelement of a predicate
834+ * Does the "predicate inclusion test" for oneAND 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 barepredicate expressions.
837+ * we strip off RestrictInfo nodes to find barequalifier expressions.
866838 */
867839static bool
868840pred_test_recurse_restrict (Expr * predicate ,Node * clause )
@@ -903,6 +875,49 @@ pred_test_recurse_restrict(Expr *predicate, Node *clause)
903875}
904876return 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+ }
906921else
907922return pred_test_simple_clause (predicate ,clause );
908923}