aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/selfuncs.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils/adt/selfuncs.c')
-rw-r--r--src/backend/utils/adt/selfuncs.c390
1 files changed, 60 insertions, 330 deletions
diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c
index 7ec3e4dc1b8..f1c458b761c 100644
--- a/src/backend/utils/adt/selfuncs.c
+++ b/src/backend/utils/adt/selfuncs.c
@@ -1,16 +1,20 @@
/*-------------------------------------------------------------------------
*
* selfuncs.c
- * Selectivity functions for system catalogs and builtin types
+ * Selectivity functions and index cost estimation functions for
+ * standard operators and index access methods.
*
- * These routines are registered in the operator catalog in the
- * "oprrest" and "oprjoin" attributes.
+ * Selectivity routines are registered in the pg_operator catalog
+ * in the "oprrest" and "oprjoin" attributes.
+ *
+ * Index cost functions are registered in the pg_am catalog
+ * in the "amcostestimate" attribute.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/selfuncs.c,v 1.48 2000/01/15 22:43:24 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/selfuncs.c,v 1.49 2000/01/22 23:50:20 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -23,6 +27,7 @@
#include "catalog/pg_proc.h"
#include "catalog/pg_statistic.h"
#include "catalog/pg_type.h"
+#include "optimizer/cost.h"
#include "parser/parse_func.h"
#include "parser/parse_oper.h"
#include "utils/builtins.h"
@@ -700,349 +705,74 @@ getattstatistics(Oid relid, AttrNumber attnum, Oid opid, Oid typid,
return true;
}
-float64
-btreesel(Oid operatorObjectId,
- Oid indrelid,
- AttrNumber attributeNumber,
- char *constValue,
- int32 constFlag,
- int32 nIndexKeys,
- Oid indexrelid)
-{
- float64 result;
-
- if (FunctionalSelectivity(nIndexKeys, attributeNumber))
- {
-
- /*
- * Need to call the functions selectivity function here. For now
- * simply assume it's 1/3 since functions don't currently have
- * selectivity functions
- */
- result = (float64) palloc(sizeof(float64data));
- *result = 1.0 / 3.0;
- }
- else
- {
- RegProcedure oprrest = get_oprrest(operatorObjectId);
-
- /*
- * Operators used for indexes should have selectivity estimators.
- * (An alternative is to default to 0.5, as the optimizer does in
- * dealing with operators occurring in WHERE clauses, but if you
- * are going to the trouble of making index support you probably
- * don't want to miss the benefits of a good selectivity estimate.)
- */
- if (!oprrest)
- {
-#if 1
- /*
- * XXX temporary fix for 6.5: rtree operators are missing their
- * selectivity estimators, so return a default estimate instead.
- * Ugh.
- */
- result = (float64) palloc(sizeof(float64data));
- *result = 0.5;
-#else
- elog(ERROR,
- "Operator %u must have a restriction selectivity estimator to be used in an index",
- operatorObjectId);
-#endif
- }
- else
- result = (float64) fmgr(oprrest,
- (char *) operatorObjectId,
- (char *) indrelid,
- (char *) (int) attributeNumber,
- (char *) constValue,
- (char *) constFlag,
- NULL);
- }
-
- if (!PointerIsValid(result))
- elog(ERROR, "Btree Selectivity: bad pointer");
- if (*result < 0.0 || *result > 1.0)
- elog(ERROR, "Btree Selectivity: bad value %f", *result);
-
- return result;
-}
-
-float64
-btreenpage(Oid operatorObjectId,
- Oid indrelid,
- AttrNumber attributeNumber,
- char *constValue,
- int32 constFlag,
- int32 nIndexKeys,
- Oid indexrelid)
-{
- float64 temp,
- result;
- float64data tempData;
- HeapTuple atp;
- int npage;
-
- if (FunctionalSelectivity(nIndexKeys, attributeNumber))
- {
-
- /*
- * Need to call the functions selectivity function here. For now
- * simply assume it's 1/3 since functions don't currently have
- * selectivity functions
- */
- tempData = 1.0 / 3.0;
- temp = &tempData;
- }
- else
- {
- RegProcedure oprrest = get_oprrest(operatorObjectId);
-
- /*
- * Operators used for indexes should have selectivity estimators.
- * (An alternative is to default to 0.5, as the optimizer does in
- * dealing with operators occurring in WHERE clauses, but if you
- * are going to the trouble of making index support you probably
- * don't want to miss the benefits of a good selectivity estimate.)
- */
- if (!oprrest)
- {
-#if 1
- /*
- * XXX temporary fix for 6.5: rtree operators are missing their
- * selectivity estimators, so return a default estimate instead.
- * Ugh.
- */
- tempData = 0.5;
- temp = &tempData;
-#else
- elog(ERROR,
- "Operator %u must have a restriction selectivity estimator to be used in an index",
- operatorObjectId);
-#endif
- }
- else
- temp = (float64) fmgr(oprrest,
- (char *) operatorObjectId,
- (char *) indrelid,
- (char *) (int) attributeNumber,
- (char *) constValue,
- (char *) constFlag,
- NULL);
- }
-
- atp = SearchSysCacheTuple(RELOID,
- ObjectIdGetDatum(indexrelid),
- 0, 0, 0);
- if (!HeapTupleIsValid(atp))
- {
- elog(ERROR, "btreenpage: no index tuple %u", indexrelid);
- return 0;
- }
-
- npage = ((Form_pg_class) GETSTRUCT(atp))->relpages;
- result = (float64) palloc(sizeof(float64data));
- *result = *temp * npage;
- return result;
-}
-
-float64
-hashsel(Oid operatorObjectId,
- Oid indrelid,
- AttrNumber attributeNumber,
- char *constValue,
- int32 constFlag,
- int32 nIndexKeys,
- Oid indexrelid)
-{
-
- float64 result;
- float64data resultData;
- HeapTuple atp;
- int ntuples;
-
- if (FunctionalSelectivity(nIndexKeys, attributeNumber))
- {
-
- /*
- * Need to call the functions selectivity function here. For now
- * simply use 1/Number of Tuples since functions don't currently
- * have selectivity functions
- */
-
- atp = SearchSysCacheTuple(RELOID,
- ObjectIdGetDatum(indexrelid),
- 0, 0, 0);
- if (!HeapTupleIsValid(atp))
- {
- elog(ERROR, "hashsel: no index tuple %u", indexrelid);
- return 0;
- }
- ntuples = ((Form_pg_class) GETSTRUCT(atp))->reltuples;
- if (ntuples > 0)
- resultData = 1.0 / (float64data) ntuples;
- else
- resultData = (float64data) (1.0 / 100.0);
- result = &resultData;
-
- }
- else
- {
- RegProcedure oprrest = get_oprrest(operatorObjectId);
-
- /*
- * Operators used for indexes should have selectivity estimators.
- * (An alternative is to default to 0.5, as the optimizer does in
- * dealing with operators occurring in WHERE clauses, but if you
- * are going to the trouble of making index support you probably
- * don't want to miss the benefits of a good selectivity estimate.)
- */
- if (!oprrest)
- elog(ERROR,
- "Operator %u must have a restriction selectivity estimator to be used in a hash index",
- operatorObjectId);
-
- result = (float64) fmgr(oprrest,
- (char *) operatorObjectId,
- (char *) indrelid,
- (char *) (int) attributeNumber,
- (char *) constValue,
- (char *) constFlag,
- NULL);
- }
-
- if (!PointerIsValid(result))
- elog(ERROR, "Hash Table Selectivity: bad pointer");
- if (*result < 0.0 || *result > 1.0)
- elog(ERROR, "Hash Table Selectivity: bad value %f", *result);
-
- return result;
-
-
-}
+/*-------------------------------------------------------------------------
+ *
+ * Index cost estimation functions
+ *
+ * genericcostestimate is a general-purpose estimator for use when we
+ * don't have any better idea about how to estimate. Index-type-specific
+ * knowledge can be incorporated in the type-specific routines.
+ *
+ *-------------------------------------------------------------------------
+ */
-float64
-hashnpage(Oid operatorObjectId,
- Oid indrelid,
- AttrNumber attributeNumber,
- char *constValue,
- int32 constFlag,
- int32 nIndexKeys,
- Oid indexrelid)
+static void
+genericcostestimate(Query *root, RelOptInfo *rel,
+ IndexOptInfo *index, List *indexQuals,
+ Cost *indexAccessCost, Selectivity *indexSelectivity)
{
- float64 temp,
- result;
- float64data tempData;
- HeapTuple atp;
- int npage;
- int ntuples;
-
- atp = SearchSysCacheTuple(RELOID,
- ObjectIdGetDatum(indexrelid),
- 0, 0, 0);
- if (!HeapTupleIsValid(atp))
- {
- elog(ERROR, "hashsel: no index tuple %u", indexrelid);
- return 0;
- }
+ double numIndexTuples;
+ double numIndexPages;
+ /* Estimate the fraction of main-table tuples that will be visited */
+ *indexSelectivity = clauselist_selec(root, indexQuals);
- if (FunctionalSelectivity(nIndexKeys, attributeNumber))
- {
-
- /*
- * Need to call the functions selectivity function here. For now,
- * use 1/Number of Tuples since functions don't currently have
- * selectivity functions
- */
-
- ntuples = ((Form_pg_class) GETSTRUCT(atp))->reltuples;
- if (ntuples > 0)
- tempData = 1.0 / (float64data) ntuples;
- else
- tempData = (float64data) (1.0 / 100.0);
- temp = &tempData;
-
- }
- else
- {
- RegProcedure oprrest = get_oprrest(operatorObjectId);
+ /* Estimate the number of index tuples that will be visited */
+ numIndexTuples = *indexSelectivity * index->tuples;
- /*
- * Operators used for indexes should have selectivity estimators.
- * (An alternative is to default to 0.5, as the optimizer does in
- * dealing with operators occurring in WHERE clauses, but if you
- * are going to the trouble of making index support you probably
- * don't want to miss the benefits of a good selectivity estimate.)
- */
- if (!oprrest)
- elog(ERROR,
- "Operator %u must have a restriction selectivity estimator to be used in a hash index",
- operatorObjectId);
-
- temp = (float64) fmgr(oprrest,
- (char *) operatorObjectId,
- (char *) indrelid,
- (char *) (int) attributeNumber,
- (char *) constValue,
- (char *) constFlag,
- NULL);
- }
+ /* Estimate the number of index pages that will be retrieved */
+ numIndexPages = *indexSelectivity * index->pages;
- npage = ((Form_pg_class) GETSTRUCT(atp))->relpages;
- result = (float64) palloc(sizeof(float64data));
- *result = *temp * npage;
- return result;
+ /* Compute the index access cost */
+ *indexAccessCost = numIndexPages + cpu_index_page_weight * numIndexTuples;
}
+/*
+ * For first cut, just use generic function for all index types.
+ */
-float64
-rtsel(Oid operatorObjectId,
- Oid indrelid,
- AttrNumber attributeNumber,
- char *constValue,
- int32 constFlag,
- int32 nIndexKeys,
- Oid indexrelid)
+void
+btcostestimate(Query *root, RelOptInfo *rel,
+ IndexOptInfo *index, List *indexQuals,
+ Cost *indexAccessCost, Selectivity *indexSelectivity)
{
- return (btreesel(operatorObjectId, indrelid, attributeNumber,
- constValue, constFlag, nIndexKeys, indexrelid));
+ genericcostestimate(root, rel, index, indexQuals,
+ indexAccessCost, indexSelectivity);
}
-float64
-rtnpage(Oid operatorObjectId,
- Oid indrelid,
- AttrNumber attributeNumber,
- char *constValue,
- int32 constFlag,
- int32 nIndexKeys,
- Oid indexrelid)
+void
+rtcostestimate(Query *root, RelOptInfo *rel,
+ IndexOptInfo *index, List *indexQuals,
+ Cost *indexAccessCost, Selectivity *indexSelectivity)
{
- return (btreenpage(operatorObjectId, indrelid, attributeNumber,
- constValue, constFlag, nIndexKeys, indexrelid));
+ genericcostestimate(root, rel, index, indexQuals,
+ indexAccessCost, indexSelectivity);
}
-float64
-gistsel(Oid operatorObjectId,
- Oid indrelid,
- AttrNumber attributeNumber,
- char *constValue,
- int32 constFlag,
- int32 nIndexKeys,
- Oid indexrelid)
+void
+hashcostestimate(Query *root, RelOptInfo *rel,
+ IndexOptInfo *index, List *indexQuals,
+ Cost *indexAccessCost, Selectivity *indexSelectivity)
{
- return (btreesel(operatorObjectId, indrelid, attributeNumber,
- constValue, constFlag, nIndexKeys, indexrelid));
+ genericcostestimate(root, rel, index, indexQuals,
+ indexAccessCost, indexSelectivity);
}
-float64
-gistnpage(Oid operatorObjectId,
- Oid indrelid,
- AttrNumber attributeNumber,
- char *constValue,
- int32 constFlag,
- int32 nIndexKeys,
- Oid indexrelid)
+void
+gistcostestimate(Query *root, RelOptInfo *rel,
+ IndexOptInfo *index, List *indexQuals,
+ Cost *indexAccessCost, Selectivity *indexSelectivity)
{
- return (btreenpage(operatorObjectId, indrelid, attributeNumber,
- constValue, constFlag, nIndexKeys, indexrelid));
+ genericcostestimate(root, rel, index, indexQuals,
+ indexAccessCost, indexSelectivity);
}