99 *
1010 *
1111 * IDENTIFICATION
12- * $PostgreSQL: pgsql/src/backend/optimizer/path/indxpath.c,v 1.164 2004/08/29 05:06:43 momjian Exp $
12+ * $PostgreSQL: pgsql/src/backend/optimizer/path/indxpath.c,v 1.165 2004/10/11 22:56:56 tgl Exp $
1313 *
1414 *-------------------------------------------------------------------------
1515 */
@@ -64,10 +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 ( List * predicate_list ,List * restrictinfo_list );
67+ static bool pred_test_recurse_pred ( Expr * predicate ,List * restrictinfo_list );
6868static bool pred_test_restrict_list (Expr * predicate ,List * restrictinfo_list );
69- static bool pred_test_recurse_clause (Expr * predicate ,Node * clause );
70- static bool pred_test_recurse_pred (Expr * predicate ,Node * clause );
69+ static bool pred_test_recurse_restrict (Expr * predicate ,Node * clause );
7170static bool pred_test_simple_clause (Expr * predicate ,Node * clause );
7271static Relids indexable_outerrelids (RelOptInfo * rel ,IndexOptInfo * index );
7372static Path * make_innerjoin_index_path (Query * root ,
@@ -750,14 +749,13 @@ check_partial_indexes(Query *root, RelOptInfo *rel)
750749 * Recursively checks whether the clauses in restrictinfo_list imply
751750 * that the given predicate is true.
752751 *
753- * This routine (together with the routines it calls) iterates over
754- * ANDs in the predicate first, then reduces the qualification
755- * clauses down to their constituent terms, and iterates over ORs
756- * in the predicate last. This order is important to make the test
757- * succeed whenever possible (assuming the predicate has been converted
758- * to CNF format). --Nels, Jan '93
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.
759757 */
760- static bool
758+ bool
761759pred_test (List * predicate_list ,List * restrictinfo_list )
762760{
763761ListCell * pred ;
@@ -785,20 +783,63 @@ pred_test(List *predicate_list, List *restrictinfo_list)
785783{
786784/*
787785 * if any clause is not implied, the whole predicate is not
788- * implied. Note we assume that any sub-ANDs have been flattened
789- * when the predicate was fed through canonicalize_qual().
786+ * implied.
790787 */
791- if (!pred_test_restrict_list (lfirst (pred ),restrictinfo_list ))
788+ if (!pred_test_recurse_pred (lfirst (pred ),restrictinfo_list ))
792789return false;
793790}
794791return true;
795792}
796793
797794
798795/*
799- *pred_test_restrict_list
796+ *pred_test_recurse_pred
800797 * Does the "predicate inclusion test" for one conjunct of a predicate
801- * expression.
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+
838+ /*
839+ * pred_test_restrict_list
840+ * Does the "predicate inclusion test" for one element of a predicate
841+ * expression. Here we take care of the AND semantics of the top-level
842+ * restrictinfo list.
802843 */
803844static bool
804845pred_test_restrict_list (Expr * predicate ,List * restrictinfo_list )
@@ -809,23 +850,25 @@ pred_test_restrict_list(Expr *predicate, List *restrictinfo_list)
809850{
810851RestrictInfo * restrictinfo = (RestrictInfo * )lfirst (item );
811852
853+ Assert (IsA (restrictinfo ,RestrictInfo ));
854+
812855/* if any clause implies the predicate, return true */
813- if (pred_test_recurse_clause (predicate ,
814- (Node * )restrictinfo -> clause ))
856+ if (pred_test_recurse_restrict (predicate ,
857+ (Node * )restrictinfo -> clause ))
815858return true;
816859}
817860return false;
818861}
819862
820863
821864/*
822- *pred_test_recurse_clause
823- * Does the "predicate inclusion test" fora general restriction-clause
865+ *pred_test_recurse_restrict
866+ * Does the "predicate inclusion test" forone element of a predicate
824867 * expression. Here we recursively deal with the possibility that the
825- * restriction clause is itself an AND or OR structure.
868+ * restriction-list element is itself an AND or OR structure.
826869 */
827870static bool
828- pred_test_recurse_clause (Expr * predicate ,Node * clause )
871+ pred_test_recurse_restrict (Expr * predicate ,Node * clause )
829872{
830873List * items ;
831874ListCell * item ;
@@ -837,7 +880,7 @@ pred_test_recurse_clause(Expr *predicate, Node *clause)
837880foreach (item ,items )
838881{
839882/* if any OR item doesn't imply the predicate, clause doesn't */
840- if (!pred_test_recurse_clause (predicate ,lfirst (item )))
883+ if (!pred_test_recurse_restrict (predicate ,lfirst (item )))
841884return false;
842885}
843886return true;
@@ -851,55 +894,11 @@ pred_test_recurse_clause(Expr *predicate, Node *clause)
851894 * if any AND item implies the predicate, the whole clause
852895 * does
853896 */
854- if (pred_test_recurse_clause (predicate ,lfirst (item )))
897+ if (pred_test_recurse_restrict (predicate ,lfirst (item )))
855898return true;
856899}
857900return false;
858901}
859- else
860- return pred_test_recurse_pred (predicate ,clause );
861- }
862-
863-
864- /*
865- * pred_test_recurse_pred
866- * Does the "predicate inclusion test" for one conjunct of a predicate
867- * expression for a simple restriction clause. Here we recursively deal
868- * with the possibility that the predicate conjunct is itself an AND or
869- * OR structure.
870- */
871- static bool
872- pred_test_recurse_pred (Expr * predicate ,Node * clause )
873- {
874- List * items ;
875- ListCell * item ;
876-
877- Assert (predicate != NULL );
878- if (or_clause ((Node * )predicate ))
879- {
880- items = ((BoolExpr * )predicate )-> args ;
881- foreach (item ,items )
882- {
883- /* if any item is implied, the whole predicate is implied */
884- if (pred_test_recurse_pred (lfirst (item ),clause ))
885- return true;
886- }
887- return false;
888- }
889- else if (and_clause ((Node * )predicate ))
890- {
891- items = ((BoolExpr * )predicate )-> args ;
892- foreach (item ,items )
893- {
894- /*
895- * if any item is not implied, the whole predicate is not
896- * implied
897- */
898- if (!pred_test_recurse_pred (lfirst (item ),clause ))
899- return false;
900- }
901- return true;
902- }
903902else
904903return pred_test_simple_clause (predicate ,clause );
905904}