]> granicus.if.org Git - postgresql/commitdiff
Fix oversight in indexscan plan creation. I recently added code to use
authorTom Lane <tgl@sss.pgh.pa.us>
Thu, 6 Oct 2005 16:01:55 +0000 (16:01 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
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