summaryrefslogtreecommitdiff
path: root/src/backend/optimizer
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/optimizer')
-rw-r--r--src/backend/optimizer/path/allpaths.c16
-rw-r--r--src/backend/optimizer/path/indxpath.c13
-rw-r--r--src/backend/optimizer/path/orindxpath.c4
-rw-r--r--src/backend/optimizer/util/plancat.c13
4 files changed, 30 insertions, 16 deletions
diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c
index b94b8a58112..4e0d9ca4e57 100644
--- a/src/backend/optimizer/path/allpaths.c
+++ b/src/backend/optimizer/path/allpaths.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/optimizer/path/allpaths.c,v 1.179 2009/01/01 17:23:43 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/optimizer/path/allpaths.c,v 1.180 2009/02/15 20:16:21 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -225,19 +225,25 @@ set_plain_rel_pathlist(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte)
return;
}
+ /*
+ * Test any partial indexes of rel for applicability. We must do this
+ * first since partial unique indexes can affect size estimates.
+ */
+ check_partial_indexes(root, rel);
+
/* Mark rel with estimated output rows, width, etc */
set_baserel_size_estimates(root, rel);
- /* Test any partial indexes of rel for applicability */
- check_partial_indexes(root, rel);
-
/*
* Check to see if we can extract any restriction conditions from join
* quals that are OR-of-AND structures. If so, add them to the rel's
- * restriction list, and recompute the size estimates.
+ * restriction list, and redo the above steps.
*/
if (create_or_index_quals(root, rel))
+ {
+ check_partial_indexes(root, rel);
set_baserel_size_estimates(root, rel);
+ }
/*
* Generate paths and add them to the rel's pathlist.
diff --git a/src/backend/optimizer/path/indxpath.c b/src/backend/optimizer/path/indxpath.c
index b3482b4b5bc..6f27a191828 100644
--- a/src/backend/optimizer/path/indxpath.c
+++ b/src/backend/optimizer/path/indxpath.c
@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/optimizer/path/indxpath.c,v 1.235 2009/01/01 17:23:43 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/optimizer/path/indxpath.c,v 1.236 2009/02/15 20:16:21 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1367,8 +1367,12 @@ match_rowcompare_to_indexcol(IndexOptInfo *index,
/*
* check_partial_indexes
- * Check each partial index of the relation, and mark it predOK or not
- * depending on whether the predicate is satisfied for this query.
+ * Check each partial index of the relation, and mark it predOK if
+ * the index's predicate is satisfied for this query.
+ *
+ * Note: it is possible for this to get re-run after adding more restrictions
+ * to the rel; so we might be able to prove more indexes OK. We assume that
+ * adding more restrictions can't make an index not OK.
*/
void
check_partial_indexes(PlannerInfo *root, RelOptInfo *rel)
@@ -1383,6 +1387,9 @@ check_partial_indexes(PlannerInfo *root, RelOptInfo *rel)
if (index->indpred == NIL)
continue; /* ignore non-partial indexes */
+ if (index->predOK)
+ continue; /* don't repeat work if already proven OK */
+
index->predOK = predicate_implied_by(index->indpred,
restrictinfo_list);
}
diff --git a/src/backend/optimizer/path/orindxpath.c b/src/backend/optimizer/path/orindxpath.c
index 638078e169d..2f8a67394e2 100644
--- a/src/backend/optimizer/path/orindxpath.c
+++ b/src/backend/optimizer/path/orindxpath.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/optimizer/path/orindxpath.c,v 1.87 2009/02/06 23:43:23 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/optimizer/path/orindxpath.c,v 1.88 2009/02/15 20:16:21 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -181,6 +181,6 @@ create_or_index_quals(PlannerInfo *root, RelOptInfo *rel)
/* It isn't an outer join clause, so no need to adjust outer_selec */
}
- /* Tell caller to recompute rel's rows estimate */
+ /* Tell caller to recompute partial index status and rowcount estimate */
return true;
}
diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c
index f4f8ac8a763..e880e668cba 100644
--- a/src/backend/optimizer/util/plancat.c
+++ b/src/backend/optimizer/util/plancat.c
@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/optimizer/util/plancat.c,v 1.154 2009/01/07 22:40:49 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/optimizer/util/plancat.c,v 1.155 2009/02/15 20:16:21 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -939,15 +939,16 @@ has_unique_index(RelOptInfo *rel, AttrNumber attno)
/*
* Note: ignore partial indexes, since they don't allow us to conclude
- * that all attr values are distinct. We don't take any interest in
- * expressional indexes either. Also, a multicolumn unique index
- * doesn't allow us to conclude that just the specified attr is
- * unique.
+ * that all attr values are distinct, *unless* they are marked predOK
+ * which means we know the index's predicate is satisfied by the query.
+ * We don't take any interest in expressional indexes either. Also, a
+ * multicolumn unique index doesn't allow us to conclude that just the
+ * specified attr is unique.
*/
if (index->unique &&
index->ncolumns == 1 &&
index->indexkeys[0] == attno &&
- index->indpred == NIL)
+ (index->indpred == NIL || index->predOK))
return true;
}
return false;