diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2001-07-16 05:07:00 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2001-07-16 05:07:00 +0000 |
commit | f31dc0ada731d89313dbca7ef5da91d674fc640c (patch) | |
tree | a9c8343c489be6f99c5a9dff58838f72cf7d5dc4 /src/backend/utils/adt/selfuncs.c | |
parent | 237e5dfa581503b2ab877c73eecde517d284563c (diff) | |
download | postgresql-f31dc0ada731d89313dbca7ef5da91d674fc640c.tar.gz postgresql-f31dc0ada731d89313dbca7ef5da91d674fc640c.zip |
Partial indexes work again, courtesy of Martijn van Oosterhout.
Note: I didn't force an initdb, figuring that one today was enough.
However, there is a new function in pg_proc.h, and pg_dump won't be
able to dump partial indexes until you add that function.
Diffstat (limited to 'src/backend/utils/adt/selfuncs.c')
-rw-r--r-- | src/backend/utils/adt/selfuncs.c | 60 |
1 files changed, 50 insertions, 10 deletions
diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c index 3ab3881c257..e0cfeefaee4 100644 --- a/src/backend/utils/adt/selfuncs.c +++ b/src/backend/utils/adt/selfuncs.c @@ -15,7 +15,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/adt/selfuncs.c,v 1.94 2001/06/25 21:11:44 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/adt/selfuncs.c,v 1.95 2001/07/16 05:06:59 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -86,6 +86,7 @@ #include "optimizer/cost.h" #include "optimizer/pathnode.h" #include "optimizer/plancat.h" +#include "optimizer/prep.h" #include "parser/parse_func.h" #include "parser/parse_oper.h" #include "parser/parsetree.h" @@ -2950,24 +2951,63 @@ genericcostestimate(Query *root, RelOptInfo *rel, { double numIndexTuples; double numIndexPages; + List *selectivityQuals = indexQuals; - /* Estimate the fraction of main-table tuples that will be visited */ - *indexSelectivity = clauselist_selectivity(root, indexQuals, - lfirsti(rel->relids)); + /* + * If the index is partial, AND the index predicate with the explicitly + * given indexquals to produce a more accurate idea of the index + * restriction. This may produce redundant clauses, which we hope that + * cnfify and clauselist_selectivity will deal with intelligently. + * + * Note that index->indpred and indexQuals are both in implicit-AND + * form to start with, which we have to make explicit to hand to + * canonicalize_qual, and then we get back implicit-AND form again. + */ + if (index->indpred != NIL) + { + Expr *andedQuals; - /* Estimate the number of index tuples that will be visited */ - numIndexTuples = *indexSelectivity * index->tuples; + andedQuals = make_ands_explicit(nconc(listCopy(index->indpred), + indexQuals)); + selectivityQuals = canonicalize_qual(andedQuals, true); + } - /* Estimate the number of index pages that will be retrieved */ - numIndexPages = *indexSelectivity * index->pages; + /* Estimate the fraction of main-table tuples that will be visited */ + *indexSelectivity = clauselist_selectivity(root, selectivityQuals, + lfirsti(rel->relids)); /* - * Always estimate at least one tuple and page are touched, even when + * Estimate the number of tuples that will be visited. We do it in + * this rather peculiar-looking way in order to get the right answer + * for partial indexes. We can bound the number of tuples by the + * index size, in any case. + */ + numIndexTuples = *indexSelectivity * rel->tuples; + + if (numIndexTuples > index->tuples) + numIndexTuples = index->tuples; + + /* + * Always estimate at least one tuple is touched, even when * indexSelectivity estimate is tiny. */ if (numIndexTuples < 1.0) numIndexTuples = 1.0; - if (numIndexPages < 1.0) + + /* + * Estimate the number of index pages that will be retrieved. + * + * For all currently-supported index types, the first page of the index + * is a metadata page, and we should figure on fetching that plus a + * pro-rated fraction of the remaining pages. + */ + if (index->pages > 1 && index->tuples > 0) + { + numIndexPages = (numIndexTuples / index->tuples) * (index->pages - 1); + numIndexPages += 1; /* count the metapage too */ + numIndexPages = ceil(numIndexPages); + } + else numIndexPages = 1.0; /* |