9
9
*
10
10
*
11
11
* 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 $
13
13
*
14
14
*-------------------------------------------------------------------------
15
15
*/
@@ -64,10 +64,9 @@ static bool match_join_clause_to_indexcol(RelOptInfo *rel, IndexOptInfo *index,
64
64
RestrictInfo * rinfo );
65
65
static Oid indexable_operator (Expr * clause , Oid opclass ,
66
66
bool 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 );
68
68
static 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 );
71
70
static bool pred_test_simple_clause (Expr * predicate , Node * clause );
72
71
static Relids indexable_outerrelids (RelOptInfo * rel , IndexOptInfo * index );
73
72
static Path * make_innerjoin_index_path (Query * root ,
@@ -750,14 +749,13 @@ check_partial_indexes(Query *root, RelOptInfo *rel)
750
749
* Recursively checks whether the clauses in restrictinfo_list imply
751
750
* that the given predicate is true.
752
751
*
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.
759
757
*/
760
- static bool
758
+ bool
761
759
pred_test (List * predicate_list , List * restrictinfo_list )
762
760
{
763
761
ListCell * pred ;
@@ -785,20 +783,63 @@ pred_test(List *predicate_list, List *restrictinfo_list)
785
783
{
786
784
/*
787
785
* 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.
790
787
*/
791
- if (!pred_test_restrict_list (lfirst (pred ), restrictinfo_list ))
788
+ if (!pred_test_recurse_pred (lfirst (pred ), restrictinfo_list ))
792
789
return false;
793
790
}
794
791
return true;
795
792
}
796
793
797
794
798
795
/*
799
- * pred_test_restrict_list
796
+ * pred_test_recurse_pred
800
797
* 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.
802
843
*/
803
844
static bool
804
845
pred_test_restrict_list (Expr * predicate , List * restrictinfo_list )
@@ -809,23 +850,25 @@ pred_test_restrict_list(Expr *predicate, List *restrictinfo_list)
809
850
{
810
851
RestrictInfo * restrictinfo = (RestrictInfo * ) lfirst (item );
811
852
853
+ Assert (IsA (restrictinfo , RestrictInfo ));
854
+
812
855
/* 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 ))
815
858
return true;
816
859
}
817
860
return false;
818
861
}
819
862
820
863
821
864
/*
822
- * pred_test_recurse_clause
823
- * Does the "predicate inclusion test" for a general restriction-clause
865
+ * pred_test_recurse_restrict
866
+ * Does the "predicate inclusion test" for one element of a predicate
824
867
* 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.
826
869
*/
827
870
static bool
828
- pred_test_recurse_clause (Expr * predicate , Node * clause )
871
+ pred_test_recurse_restrict (Expr * predicate , Node * clause )
829
872
{
830
873
List * items ;
831
874
ListCell * item ;
@@ -837,7 +880,7 @@ pred_test_recurse_clause(Expr *predicate, Node *clause)
837
880
foreach (item , items )
838
881
{
839
882
/* 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 )))
841
884
return false;
842
885
}
843
886
return true;
@@ -851,55 +894,11 @@ pred_test_recurse_clause(Expr *predicate, Node *clause)
851
894
* if any AND item implies the predicate, the whole clause
852
895
* does
853
896
*/
854
- if (pred_test_recurse_clause (predicate , lfirst (item )))
897
+ if (pred_test_recurse_restrict (predicate , lfirst (item )))
855
898
return true;
856
899
}
857
900
return false;
858
901
}
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
- }
903
902
else
904
903
return pred_test_simple_clause (predicate , clause );
905
904
}
0 commit comments