Fix oversight in indexscan plan creation. I recently added code to use
authorTom Lane
Thu, 6 Oct 2005 16:01:55 +0000 (16:01 +0000)
committerTom Lane
Thu, 6 Oct 2005 16:01:55 +0000 (16:01 +0000)
predicate_implied_by() to detect redundant filter conditions, but forgot
that predicate_implied_by() assumes its first argument contains only
immutable functions.  Add a check to guarantee that.  Also, test to see
if filter conditions can be discarded because they are redundant with
the predicate of a partial index.

src/backend/optimizer/plan/createplan.c
src/backend/optimizer/util/predtest.c

index 5ddc5d654de9256a938249364a07abbb2eab1384..8d1d7a2ecad9b8b057a3de246e80c7147b200492 100644 (file)
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/optimizer/plan/createplan.c,v 1.198 2005/09/24 22:54:37 tgl Exp $
+ *   $PostgreSQL: pgsql/src/backend/optimizer/plan/createplan.c,v 1.199 2005/10/06 16:01:54 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -819,7 +819,9 @@ create_indexscan_plan(PlannerInfo *root,
     * (particularly with OR'd index conditions) we may have scan_clauses
     * that are not equal to, but are logically implied by, the index quals;
     * so we also try a predicate_implied_by() check to see if we can discard
-    * quals that way.
+    * quals that way.  (predicate_implied_by assumes its first input contains
+    * only immutable functions, so we have to check that.)  We can also
+    * discard quals that are implied by a partial index's predicate.
     *
     * While at it, we strip off the RestrictInfos to produce a list of
     * plain expressions.
@@ -832,9 +834,15 @@ create_indexscan_plan(PlannerInfo *root,
        Assert(IsA(rinfo, RestrictInfo));
        if (list_member_ptr(nonlossy_indexquals, rinfo))
            continue;
-       if (predicate_implied_by(list_make1(rinfo->clause),
-                                nonlossy_indexquals))
-           continue;
+       if (!contain_mutable_functions((Node *) rinfo->clause))
+       {
+           List    *clausel = list_make1(rinfo->clause);
+
+           if (predicate_implied_by(clausel, nonlossy_indexquals))
+               continue;
+           if (predicate_implied_by(clausel, best_path->indexinfo->indpred))
+               continue;
+       }
        qpqual = lappend(qpqual, rinfo->clause);
    }
 
@@ -916,6 +924,14 @@ create_bitmap_scan_plan(PlannerInfo *root,
     * OR'd index conditions) we may have scan_clauses that are not equal to,
     * but are logically implied by, the index quals; so we also try a
     * predicate_implied_by() check to see if we can discard quals that way.
+    * (predicate_implied_by assumes its first input contains only immutable
+    * functions, so we have to check that.)  We can also discard quals that
+    * are implied by a partial index's predicate.
+    *
+    * XXX For the moment, we only consider partial index predicates in the
+    * simple single-index-scan case.  Is it worth trying to be smart about
+    * more complex cases?  Perhaps create_bitmap_subplan should be made to
+    * include predicate info in what it constructs.
     */
    qpqual = NIL;
    foreach(l, scan_clauses)
@@ -924,9 +940,20 @@ create_bitmap_scan_plan(PlannerInfo *root,
 
        if (list_member(indexquals, clause))
            continue;
-       if (predicate_implied_by(list_make1(clause),
-                                indexquals))
-           continue;
+       if (!contain_mutable_functions(clause))
+       {
+           List    *clausel = list_make1(clause);
+
+           if (predicate_implied_by(clausel, indexquals))
+               continue;
+           if (IsA(best_path->bitmapqual, IndexPath))
+           {
+               IndexPath *ipath = (IndexPath *) best_path->bitmapqual;
+
+               if (predicate_implied_by(clausel, ipath->indexinfo->indpred))
+                   continue;
+           }
+       }
        qpqual = lappend(qpqual, clause);
    }
 
index 9628f9186eb96d65a3b43fa0b283d1065af52eaf..2a0896fa63e0e527466b66eaa61c847741d2e9e0 100644 (file)
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/optimizer/util/predtest.c,v 1.2 2005/07/23 21:05:47 tgl Exp $
+ *   $PostgreSQL: pgsql/src/backend/optimizer/util/predtest.c,v 1.3 2005/10/06 16:01:55 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -47,7 +47,7 @@ static bool btree_predicate_proof(Expr *predicate, Node *clause,
  * valid, but no worse consequences will ensue.
  *
  * We assume the predicate has already been checked to contain only
- * immutable functions and operators.  (In current use this is true
+ * immutable functions and operators.  (In most current uses this is true
  * because the predicate is part of an index predicate that has passed
  * CheckPredicate().)  We dare not make deductions based on non-immutable
  * functions, because they might change answers between the time we make