Commit 71ed7eb4 authored by Tom Lane's avatar Tom Lane

Revise handling of index-type-specific indexscan cost estimation, per

pghackers discussion of 5-Jan-2000.  The amopselect and amopnpages
estimators are gone, and in their place is a per-AM amcostestimate
procedure (linked to from pg_am, not pg_amop).
parent 78845177
.\" This is -*-nroff-*-
.\" XXX standard disclaimer belongs here....
.\" $Header: /cvsroot/pgsql/doc/src/sgml/catalogs.sgml,v 2.2 2000/01/11 01:40:04 tgl Exp $
.\" $Header: /cvsroot/pgsql/doc/src/sgml/catalogs.sgml,v 2.3 2000/01/22 23:50:08 tgl Exp $
.TH "SYSTEM CATALOGS" INTRO 03/13/94 PostgreSQL PostgreSQL
.SH "Section 7 - System Catalogs"
.de LS
......@@ -138,6 +138,8 @@ pg_am
regproc ambuild /* "build new index" function */
regproc amcreate /* - deprecated */
regproc amdestroy /* - deprecated */
regproc amcostestimate /* estimate cost of an indexscan */
.fi
.nf M
pg_amop
......@@ -148,10 +150,6 @@ pg_amop
oid amopopr /* the operator */
int2 amopstrategy /* traversal/search strategy number
to which this operator applies */
regproc amopselect /* function to calculate the operator
selectivity */
regproc amopnpages /* function to calculate the number of
pages that will be examined */
.fi
.nf M
pg_amproc
......
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/xindex.sgml,v 1.5 1999/07/22 15:11:05 thomas Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/xindex.sgml,v 1.6 2000/01/22 23:50:08 tgl Exp $
Postgres documentation
-->
......@@ -403,20 +403,9 @@ CREATE OPERATOR = (
<entry>the <filename>oid</filename>s of the operators for the opclass
(which we'll get in just a minute)</entry>
</row>
<row>
<entry>amopselect, amopnpages</entry>
<entry>cost functions</entry>
</row>
</tbody>
</tgroup>
</table>
The cost functions are used by the query optimizer to decide whether or
not to use a given index in a scan. Fortunately, these already exist.
The two functions we'll use are <filename>btreesel</filename>, which
estimates the selectivity of the <acronym>B-tree</acronym>, and
<filename>btreenpage</filename>, which estimates the number of pages a
search will touch in the tree.
</para>
<para>
......@@ -460,10 +449,8 @@ CREATE OPERATOR = (
equal, in <filename>pg_amop</filename>. We add the instances we need:
<programlisting>
INSERT INTO pg_amop (amopid, amopclaid, amopopr, amopstrategy,
amopselect, amopnpages)
SELECT am.oid, opcl.oid, c.opoid, 1,
'btreesel'::regproc, 'btreenpage'::regproc
INSERT INTO pg_amop (amopid, amopclaid, amopopr, amopstrategy)
SELECT am.oid, opcl.oid, c.opoid, 1
FROM pg_am am, pg_opclass opcl, complex_abs_ops_tmp c
WHERE amname = 'btree' AND
opcname = 'complex_abs_ops' AND
......@@ -519,13 +506,11 @@ CREATE OPERATOR = (
<para>
Now we need to add a hashing strategy to allow the type to be indexed.
We do this by using another type in pg_am but we reuse the sames ops.
We do this by using another type in pg_am but we reuse the same ops.
<programlisting>
INSERT INTO pg_amop (amopid, amopclaid, amopopr, amopstrategy,
amopselect, amopnpages)
SELECT am.oid, opcl.oid, c.opoid, 1,
'hashsel'::regproc, 'hashnpage'::regproc
INSERT INTO pg_amop (amopid, amopclaid, amopopr, amopstrategy)
SELECT am.oid, opcl.oid, c.opoid, 1
FROM pg_am am, pg_opclass opcl, complex_abs_ops_tmp c
WHERE amname = 'hash' AND
opcname = 'complex_abs_ops' AND
......
......@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/index/indexam.c,v 1.38 1999/12/30 05:04:50 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/access/index/indexam.c,v 1.39 2000/01/22 23:50:09 tgl Exp $
*
* INTERFACE ROUTINES
* index_open - open an index relation by relationId
......@@ -69,21 +69,6 @@
#include "access/heapam.h"
#include "utils/relcache.h"
/* ----------------
* undefine macros we aren't going to use that would otherwise
* get in our way.. delete is defined in c.h and the am's are
* defined in heapam.h
* ----------------
*/
#undef delete
#undef aminsert
#undef amdelete
#undef ambeginscan
#undef amrescan
#undef amendscan
#undef ammarkpos
#undef amrestrpos
#undef amgettuple
/* ----------------------------------------------------------------
* macros used in index_ routines
......@@ -358,6 +343,27 @@ index_getnext(IndexScanDesc scan,
return result;
}
/* ----------------
* index_cost_estimator
*
* Fetch the amcostestimate procedure OID for an index.
*
* We could combine fetching and calling the procedure,
* as index_insert does for example; but that would require
* importing a bunch of planner/optimizer stuff into this file.
* ----------------
*/
RegProcedure
index_cost_estimator(Relation relation)
{
RegProcedure procedure;
RELATION_CHECKS;
GET_REL_PROCEDURE(cost_estimator, amcostestimate);
return procedure;
}
/* ----------------
* index_getprocid
*
......
......@@ -2,7 +2,7 @@
* Routines for handling of 'SET var TO',
* 'SHOW var' and 'RESET var' statements.
*
* $Id: variable.c,v 1.27 2000/01/15 02:59:29 petere Exp $
* $Id: variable.c,v 1.28 2000/01/22 23:50:10 tgl Exp $
*
*/
......@@ -14,7 +14,8 @@
#include "catalog/pg_shadow.h"
#include "commands/variable.h"
#include "miscadmin.h"
#include "optimizer/internal.h"
#include "optimizer/cost.h"
#include "optimizer/paths.h"
#include "utils/builtins.h"
#include "utils/tqual.h"
#include "utils/trace.h"
......@@ -45,10 +46,6 @@ static bool show_XactIsoLevel(void);
static bool reset_XactIsoLevel(void);
static bool parse_XactIsoLevel(const char *);
extern Cost _cpu_page_weight_;
extern Cost _cpu_index_page_weight_;
extern bool _use_geqo_;
extern int32 _use_geqo_rels_;
extern bool _use_keyset_query_optimizer;
/*
......@@ -183,23 +180,23 @@ parse_geqo(const char *value)
if (strcasecmp(tok, "on") == 0)
{
int32 geqo_rels = GEQO_RELS;
int new_geqo_rels = GEQO_RELS;
if (val != NULL)
{
geqo_rels = pg_atoi(val, sizeof(int32), '\0');
if (geqo_rels <= 1)
new_geqo_rels = pg_atoi(val, sizeof(int), '\0');
if (new_geqo_rels <= 1)
elog(ERROR, "Bad value for # of relations (%s)", val);
pfree(val);
}
_use_geqo_ = true;
_use_geqo_rels_ = geqo_rels;
enable_geqo = true;
geqo_rels = new_geqo_rels;
}
else if (strcasecmp(tok, "off") == 0)
{
if ((val != NULL) && (*val != '\0'))
elog(ERROR, "%s does not allow a parameter", tok);
_use_geqo_ = false;
enable_geqo = false;
}
else
elog(ERROR, "Bad value for GEQO (%s)", value);
......@@ -212,8 +209,8 @@ static bool
show_geqo()
{
if (_use_geqo_)
elog(NOTICE, "GEQO is ON beginning with %d relations", _use_geqo_rels_);
if (enable_geqo)
elog(NOTICE, "GEQO is ON beginning with %d relations", geqo_rels);
else
elog(NOTICE, "GEQO is OFF");
return TRUE;
......@@ -224,11 +221,11 @@ reset_geqo(void)
{
#ifdef GEQO
_use_geqo_ = true;
enable_geqo = true;
#else
_use_geqo_ = false;
enable_geqo = false;
#endif
_use_geqo_rels_ = GEQO_RELS;
geqo_rels = GEQO_RELS;
return TRUE;
}
......@@ -240,7 +237,7 @@ reset_geqo(void)
static bool
parse_cost_heap(const char *value)
{
float32 res;
float64 res;
if (value == NULL)
{
......@@ -248,8 +245,8 @@ parse_cost_heap(const char *value)
return TRUE;
}
res = float4in((char *) value);
_cpu_page_weight_ = *res;
res = float8in((char *) value);
cpu_page_weight = *res;
return TRUE;
}
......@@ -258,14 +255,14 @@ static bool
show_cost_heap()
{
elog(NOTICE, "COST_HEAP is %f", _cpu_page_weight_);
elog(NOTICE, "COST_HEAP is %f", cpu_page_weight);
return TRUE;
}
static bool
reset_cost_heap()
{
_cpu_page_weight_ = _CPU_PAGE_WEIGHT_;
cpu_page_weight = CPU_PAGE_WEIGHT;
return TRUE;
}
......@@ -277,7 +274,7 @@ reset_cost_heap()
static bool
parse_cost_index(const char *value)
{
float32 res;
float64 res;
if (value == NULL)
{
......@@ -285,8 +282,8 @@ parse_cost_index(const char *value)
return TRUE;
}
res = float4in((char *) value);
_cpu_index_page_weight_ = *res;
res = float8in((char *) value);
cpu_index_page_weight = *res;
return TRUE;
}
......@@ -295,14 +292,14 @@ static bool
show_cost_index()
{
elog(NOTICE, "COST_INDEX is %f", _cpu_index_page_weight_);
elog(NOTICE, "COST_INDEX is %f", cpu_index_page_weight);
return TRUE;
}
static bool
reset_cost_index()
{
_cpu_index_page_weight_ = _CPU_INDEX_PAGE_WEIGHT_;
cpu_index_page_weight = CPU_INDEX_PAGE_WEIGHT;
return TRUE;
}
......
......@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.100 2000/01/17 00:14:46 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.101 2000/01/22 23:50:11 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -1031,6 +1031,7 @@ _copyIndexOptInfo(IndexOptInfo *from)
}
newnode->relam = from->relam;
newnode->amcostestimate = from->amcostestimate;
newnode->indproc = from->indproc;
Node_Copy(from, newnode, indpred);
......
......@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.78 2000/01/14 00:53:21 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.79 2000/01/22 23:50:12 tgl Exp $
*
* NOTES
* Most of the read functions for plan nodes are tested. (In fact, they
......@@ -1330,34 +1330,6 @@ _readRelOptInfo()
return local_node;
}
/* ----------------
* _readIndexOptInfo
* ----------------
*/
static IndexOptInfo *
_readIndexOptInfo()
{
IndexOptInfo *local_node;
char *token;
int length;
local_node = makeNode(IndexOptInfo);
token = lsptok(NULL, &length); /* get :indexoid */
token = lsptok(NULL, &length); /* now read it */
local_node->indexoid = (Oid) atoi(token);
token = lsptok(NULL, &length); /* get :pages */
token = lsptok(NULL, &length); /* now read it */
local_node->pages = atol(token);
token = lsptok(NULL, &length); /* get :tuples */
token = lsptok(NULL, &length); /* now read it */
local_node->tuples = atof(token);
return local_node;
}
/* ----------------
* _readTargetEntry
* ----------------
......@@ -1900,8 +1872,6 @@ parsePlanString(void)
return_value = _readEState();
else if (length == 10 && strncmp(token, "RELOPTINFO", length) == 0)
return_value = _readRelOptInfo();
else if (length == 12 && strncmp(token, "INDEXOPTINFO", length) == 0)
return_value = _readIndexOptInfo();
else if (length == 11 && strncmp(token, "TARGETENTRY", length) == 0)
return_value = _readTargetEntry();
else if (length == 3 && strncmp(token, "RTE", length) == 0)
......
......@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/_deadcode/Attic/xfunc.c,v 1.11 1999/11/22 17:56:10 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/_deadcode/Attic/xfunc.c,v 1.12 2000/01/22 23:50:13 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -1100,27 +1100,27 @@ xfunc_expense_per_tuple(JoinPath joinnode, int whichchild)
if (IsA(joinnode, HashPath))
{
if (whichchild == INNER)
return (1 + _CPU_PAGE_WEIGHT_) * outers_per_page / NBuffers;
return (1 + cpu_page_weight) * outers_per_page / NBuffers;
else
return (((1 + _CPU_PAGE_WEIGHT_) * outers_per_page / NBuffers)
+ _CPU_PAGE_WEIGHT_
return (((1 + cpu_page_weight) * outers_per_page / NBuffers)
+ cpu_page_weight
/ xfunc_card_product(get_relids(innerrel)));
}
else if (IsA(joinnode, MergePath))
{
/* assumes sort exists, and costs one (I/O + CPU) per tuple */
if (whichchild == INNER)
return ((2 * _CPU_PAGE_WEIGHT_ + 1)
return ((2 * cpu_page_weight + 1)
/ xfunc_card_product(get_relids(outerrel)));
else
return ((2 * _CPU_PAGE_WEIGHT_ + 1)
return ((2 * cpu_page_weight + 1)
/ xfunc_card_product(get_relids(innerrel)));
}
else
/* nestloop */
{
Assert(IsA(joinnode, JoinPath));
return _CPU_PAGE_WEIGHT_;
return cpu_page_weight;
}
}
......
......@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/allpaths.c,v 1.55 2000/01/09 00:26:29 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/allpaths.c,v 1.56 2000/01/22 23:50:14 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -21,13 +21,12 @@
#include "optimizer/paths.h"
#ifdef GEQO
bool _use_geqo_ = true;
bool enable_geqo = true;
#else
bool _use_geqo_ = false;
bool enable_geqo = false;
#endif
int32 _use_geqo_rels_ = GEQO_RELS;
int geqo_rels = GEQO_RELS;
static void set_base_rel_pathlist(Query *root, List *rels);
......@@ -165,11 +164,11 @@ make_one_rel_by_joins(Query *root, List *rels, int levels_needed)
* genetic query optimizer entry point *
* <utesch@aut.tu-freiberg.de> *
*******************************************/
if ((_use_geqo_) && length(root->base_rel_list) >= _use_geqo_rels_)
if (enable_geqo && length(root->base_rel_list) >= geqo_rels)
return geqo(root);
/*******************************************
* rest will be deprecated in case of GEQO *
* rest will be skipped in case of GEQO *
*******************************************/
while (--levels_needed)
......
This diff is collapsed.
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/indxpath.c,v 1.76 2000/01/09 00:26:31 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/indxpath.c,v 1.77 2000/01/22 23:50:14 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -1393,19 +1393,6 @@ index_innerjoin(Query *root, RelOptInfo *rel, IndexOptInfo *index,
List *clausegroup = lfirst(i);
IndexPath *pathnode = makeNode(IndexPath);
List *indexquals;
long npages;
Selectivity selec;
indexquals = get_actual_clauses(clausegroup);
/* expand special operators to indexquals the executor can handle */
indexquals = expand_indexqual_conditions(indexquals);
index_selectivity(root,
rel,
index,
indexquals,
&npages,
&selec);
/* XXX this code ought to be merged with create_index_path? */
......@@ -1413,6 +1400,10 @@ index_innerjoin(Query *root, RelOptInfo *rel, IndexOptInfo *index,
pathnode->path.parent = rel;
pathnode->path.pathkeys = build_index_pathkeys(root, rel, index);
indexquals = get_actual_clauses(clausegroup);
/* expand special operators to indexquals the executor can handle */
indexquals = expand_indexqual_conditions(indexquals);
/* Note that we are making a pathnode for a single-scan indexscan;
* therefore, both indexid and indexqual should be single-element
* lists.
......@@ -1423,8 +1414,7 @@ index_innerjoin(Query *root, RelOptInfo *rel, IndexOptInfo *index,
/* joinrelids saves the rels needed on the outer side of the join */
pathnode->joinrelids = lfirst(outerrelids_list);
pathnode->path.path_cost = cost_index(rel, index,
npages, selec,
pathnode->path.path_cost = cost_index(root, rel, index, indexquals,
true);
path_list = lappend(path_list, pathnode);
......
......@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/joinpath.c,v 1.47 2000/01/09 00:26:33 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/joinpath.c,v 1.48 2000/01/22 23:50:15 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -102,7 +102,7 @@ update_rels_pathlist_for_joins(Query *root, List *joinrels)
/*
* Find potential mergejoin clauses.
*/
if (_enable_mergejoin_)
if (enable_mergejoin)
mergeclause_list = select_mergejoin_clauses(joinrel->restrictinfo);
/*
......@@ -141,7 +141,7 @@ update_rels_pathlist_for_joins(Query *root, List *joinrels)
* 4. Consider paths where both outer and inner relations must be
* hashed before being joined.
*/
if (_enable_hashjoin_)
if (enable_hashjoin)
pathlist = add_pathlist(joinrel, pathlist,
hash_inner_and_outer(root, joinrel,
outerrel,
......
......@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/orindxpath.c,v 1.33 2000/01/09 00:26:33 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/orindxpath.c,v 1.34 2000/01/22 23:50:15 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -215,21 +215,11 @@ best_or_subclause_index(Query *root,
foreach(ilist, indices)
{
IndexOptInfo *index = (IndexOptInfo *) lfirst(ilist);
long npages;
Selectivity selec;
Cost subcost;
Assert(IsA(index, IndexOptInfo));
index_selectivity(root,
rel,
index,
indexqual,
&npages,
&selec);
subcost = cost_index(rel, index,
npages, selec,
subcost = cost_index(root, rel, index, indexqual,
false);
if (first_run || subcost < *retCost)
......
......@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/initsplan.c,v 1.41 2000/01/09 00:26:36 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/initsplan.c,v 1.42 2000/01/22 23:50:16 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -257,9 +257,9 @@ add_join_info_to_rels(Query *root, RestrictInfo *restrictinfo,
static void
set_restrictinfo_joininfo(RestrictInfo *restrictinfo)
{
if (_enable_mergejoin_)
if (enable_mergejoin)
check_mergejoinable(restrictinfo);
if (_enable_hashjoin_)
if (enable_hashjoin)
check_hashjoinable(restrictinfo);
}
......
......@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/pathnode.c,v 1.56 2000/01/09 00:26:37 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/pathnode.c,v 1.57 2000/01/22 23:50:17 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -214,64 +214,26 @@ create_index_path(Query *root,
List *restriction_clauses)
{
IndexPath *pathnode = makeNode(IndexPath);
List *indexquals;
pathnode->path.pathtype = T_IndexScan;
pathnode->path.parent = rel;
pathnode->path.pathkeys = build_index_pathkeys(root, rel, index);
/*
* Note that we are making a pathnode for a single-scan indexscan;
* therefore, both indexid and indexqual should be single-element
* lists. We initialize indexqual to contain one empty sublist,
* representing a single index traversal with no index restriction
* conditions. If we do have restriction conditions to use, they
* will get inserted below.
*/
pathnode->indexid = lconsi(index->indexoid, NIL);
pathnode->indexqual = lcons(NIL, NIL);
pathnode->joinrelids = NIL; /* no join clauses here */
if (restriction_clauses == NIL)
{
/*
* We have no restriction clauses, so compute scan cost using
* selectivity of 1.0.
*/
pathnode->path.path_cost = cost_index(rel, index,
index->pages,
(Selectivity) 1.0,
false);
}
else
{
/*
* Compute scan cost for the case when 'index' is used with
* restriction clause(s). Also, place indexqual in path node.
*/
List *indexquals;
long npages;
Selectivity selec;
indexquals = get_actual_clauses(restriction_clauses);
/* expand special operators to indexquals the executor can handle */
indexquals = expand_indexqual_conditions(indexquals);
/* Insert qual list into 1st sublist of pathnode->indexqual;
* we already made the cons cell above, no point in wasting it...
/*
* We are making a pathnode for a single-scan indexscan; therefore,
* both indexid and indexqual should be single-element lists.
*/
lfirst(pathnode->indexqual) = indexquals;
index_selectivity(root,
rel,
index,
indexquals,
&npages,
&selec);
pathnode->indexid = lconsi(index->indexoid, NIL);
pathnode->indexqual = lcons(indexquals, NIL);
pathnode->joinrelids = NIL; /* no join clauses here */
pathnode->path.path_cost = cost_index(rel, index,
npages, selec,
pathnode->path.path_cost = cost_index(root, rel, index, indexquals,
false);
}
return pathnode;
}
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/plancat.c,v 1.44 2000/01/15 02:59:31 petere Exp $
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/plancat.c,v 1.45 2000/01/22 23:50:17 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -136,6 +136,7 @@ find_secondary_indexes(Query *root, Index relid)
info->relam = relam;
info->pages = indexRelation->rd_rel->relpages;
info->tuples = indexRelation->rd_rel->reltuples;
info->amcostestimate = index_cost_estimator(indexRelation);
index_close(indexRelation);
/*
......@@ -168,216 +169,6 @@ find_secondary_indexes(Query *root, Index relid)
return indexes;
}
/*
* index_selectivity
* Estimate the selectivity of an index scan with the given index quals.
*
* NOTE: an indexscan plan node can actually represent several passes,
* but here we consider the cost of just one pass.
*
* 'root' is the query root
* 'rel' is the relation being scanned
* 'index' is the index to be used
* 'indexquals' is the list of qual condition exprs (implicit AND semantics)
* '*idxPages' receives an estimate of the number of index pages touched
* '*idxSelec' receives an estimate of selectivity of the scan, ie fraction
* of the relation's tuples that will be retrieved
*/
void
index_selectivity(Query *root,
RelOptInfo *rel,
IndexOptInfo *index,
List *indexquals,
long *idxPages,
Selectivity *idxSelec)
{
int relid;
Oid baserelid,
indexrelid;
HeapTuple indRel,
indexTuple;
Form_pg_class indexrelation;
Oid relam;
Form_pg_index pgindex;
int nIndexKeys;
float64data npages,
select,
fattr_select;
bool nphack = false;
List *q;
Assert(length(rel->relids) == 1); /* must be a base rel */
relid = lfirsti(rel->relids);
baserelid = getrelid(relid, root->rtable);
indexrelid = index->indexoid;
indRel = SearchSysCacheTuple(RELOID,
ObjectIdGetDatum(indexrelid),
0, 0, 0);
if (!HeapTupleIsValid(indRel))
elog(ERROR, "index_selectivity: index %u not found in pg_class",
indexrelid);
indexrelation = (Form_pg_class) GETSTRUCT(indRel);
relam = indexrelation->relam;
indexTuple = SearchSysCacheTuple(INDEXRELID,
ObjectIdGetDatum(indexrelid),
0, 0, 0);
if (!HeapTupleIsValid(indexTuple))
elog(ERROR, "index_selectivity: index %u not found in pg_index",
indexrelid);
pgindex = (Form_pg_index) GETSTRUCT(indexTuple);
nIndexKeys = 1;
while (pgindex->indclass[nIndexKeys] != InvalidOid)
nIndexKeys++;
/*
* Hack for non-functional btree npages estimation: npages =
* index_pages * selectivity_of_1st_attr_clause(s) - vadim 04/24/97
*/
if (relam == BTREE_AM_OID && pgindex->indproc == InvalidOid)
nphack = true;
npages = 0.0;
select = 1.0;
fattr_select = 1.0;
foreach(q, indexquals)
{
Node *expr = (Node *) lfirst(q);
Oid opno;
int dummyrelid;
AttrNumber attno;
Datum value;
int flag;
Oid indclass;
HeapTuple amopTuple;
Form_pg_amop amop;
float64 amopnpages,
amopselect;
/*
* Extract info from clause.
*/
if (is_opclause(expr))
opno = ((Oper *) ((Expr *) expr)->oper)->opno;
else
opno = InvalidOid;
get_relattval(expr, relid, &dummyrelid, &attno, &value, &flag);
/*
* Find the AM class for this key.
*/
if (pgindex->indproc != InvalidOid)
{
/*
* Functional index: AM class is the first one defined since
* functional indices have exactly one key.
*/
indclass = pgindex->indclass[0];
}
else
{
int i;
indclass = InvalidOid;
for (i = 0; pgindex->indkey[i]; i++)
{
if (attno == pgindex->indkey[i])
{
indclass = pgindex->indclass[i];
break;
}
}
}
if (!OidIsValid(indclass))
{
/*
* Presumably this means that we are using a functional index
* clause and so had no variable to match to the index key ...
* if not we are in trouble.
*/
elog(NOTICE, "index_selectivity: no key %d in index %u",
attno, indexrelid);
continue;
}
amopTuple = SearchSysCacheTuple(AMOPOPID,
ObjectIdGetDatum(indclass),
ObjectIdGetDatum(opno),
ObjectIdGetDatum(relam),
0);
if (!HeapTupleIsValid(amopTuple))
{
/*
* We might get here because indxpath.c selected a binary-
* compatible index. Try again with the compatible operator.
*/
if (opno != InvalidOid)
{
opno = indexable_operator((Expr *) expr, indclass, relam,
((flag & SEL_RIGHT) != 0));
amopTuple = SearchSysCacheTuple(AMOPOPID,
ObjectIdGetDatum(indclass),
ObjectIdGetDatum(opno),
ObjectIdGetDatum(relam),
0);
}
if (!HeapTupleIsValid(amopTuple))
elog(ERROR, "index_selectivity: no amop %u %u %u",
indclass, opno, relam);
}
amop = (Form_pg_amop) GETSTRUCT(amopTuple);
if (!nphack)
{
amopnpages = (float64) fmgr(amop->amopnpages,
(char *) opno,
(char *) baserelid,
(char *) (int) attno,
(char *) value,
(char *) flag,
(char *) nIndexKeys,
(char *) indexrelid);
if (PointerIsValid(amopnpages))
npages += *amopnpages;
}
amopselect = (float64) fmgr(amop->amopselect,
(char *) opno,
(char *) baserelid,
(char *) (int) attno,
(char *) value,
(char *) flag,
(char *) nIndexKeys,
(char *) indexrelid);
if (PointerIsValid(amopselect))
{
select *= *amopselect;
if (nphack && attno == pgindex->indkey[0])
fattr_select *= *amopselect;
}
}
/*
* Estimation of npages below is hack of course, but it's better than
* it was before. - vadim 04/09/97
*/
if (nphack)
{
npages = fattr_select * indexrelation->relpages;
*idxPages = (long) ceil((double) npages);
}
else
{
if (nIndexKeys > 1)
npages = npages / (1.0 + nIndexKeys);
*idxPages = (long) ceil((double) (npages / nIndexKeys));
}
*idxSelec = select;
}
/*
* restriction_selectivity
*
......
......@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.139 2000/01/09 12:17:33 ishii Exp $
* $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.140 2000/01/22 23:50:18 tgl Exp $
*
* NOTES
* this is the "main" module of the postgres backend and
......@@ -1055,19 +1055,22 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
switch (optarg[0])
{
case 's': /* seqscan */
_enable_seqscan_ = false;
enable_seqscan = false;
break;
case 'i': /* indexscan */
_enable_indexscan_ = false;
enable_indexscan = false;
break;
case 't': /* tidscan */
enable_tidscan = false;
break;
case 'n': /* nestloop */
_enable_nestloop_ = false;
enable_nestloop = false;
break;
case 'm': /* mergejoin */
_enable_mergejoin_ = false;
enable_mergejoin = false;
break;
case 'h': /* hashjoin */
_enable_hashjoin_ = false;
enable_hashjoin = false;
break;
default:
errs++;
......@@ -1512,7 +1515,7 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
if (!IsUnderPostmaster)
{
puts("\nPOSTGRES backend interactive interface ");
puts("$Revision: 1.139 $ $Date: 2000/01/09 12:17:33 $\n");
puts("$Revision: 1.140 $ $Date: 2000/01/22 23:50:18 $\n");
}
/*
......
This diff is collapsed.
......@@ -6,7 +6,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
* $Id: genam.h,v 1.21 1999/12/30 05:05:13 tgl Exp $
* $Id: genam.h,v 1.22 2000/01/22 23:50:22 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -38,6 +38,7 @@ extern void index_markpos(IndexScanDesc scan);
extern void index_restrpos(IndexScanDesc scan);
extern RetrieveIndexResult index_getnext(IndexScanDesc scan,
ScanDirection direction);
extern RegProcedure index_cost_estimator(Relation relation);
extern RegProcedure index_getprocid(Relation irel, AttrNumber attnum,
uint16 procnum);
extern Datum GetIndexValue(HeapTuple tuple, TupleDesc hTupDesc,
......
......@@ -36,7 +36,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
* $Id: catversion.h,v 1.8 2000/01/18 05:08:29 ishii Exp $
* $Id: catversion.h,v 1.9 2000/01/22 23:50:23 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -52,6 +52,6 @@
*/
/* yyyymmddN */
#define CATALOG_VERSION_NO 200001171
#define CATALOG_VERSION_NO 200001221
#endif
......@@ -7,7 +7,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
* $Id: pg_am.h,v 1.11 1999/02/13 23:21:04 momjian Exp $
* $Id: pg_am.h,v 1.12 2000/01/22 23:50:23 tgl Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
......@@ -57,6 +57,7 @@ CATALOG(pg_am)
regproc ambuild;
regproc amcreate;
regproc amdestroy;
regproc amcostestimate;
} FormData_pg_am;
/* ----------------
......@@ -70,7 +71,7 @@ typedef FormData_pg_am *Form_pg_am;
* compiler constants for pg_am
* ----------------
*/
#define Natts_pg_am 22
#define Natts_pg_am 23
#define Anum_pg_am_amname 1
#define Anum_pg_am_amowner 2
#define Anum_pg_am_amkind 3
......@@ -93,21 +94,22 @@ typedef FormData_pg_am *Form_pg_am;
#define Anum_pg_am_ambuild 20
#define Anum_pg_am_amcreate 21
#define Anum_pg_am_amdestroy 22
#define Anum_pg_am_amcostestimate 23
/* ----------------
* initial contents of pg_am
* ----------------
*/
DATA(insert OID = 402 ( rtree PGUID "o" 8 3 rtgettuple rtinsert rtdelete - - - - rtbeginscan rtrescan rtendscan rtmarkpos rtrestrpos - - rtbuild - - ));
DATA(insert OID = 402 ( rtree PGUID "o" 8 3 rtgettuple rtinsert rtdelete - - - - rtbeginscan rtrescan rtendscan rtmarkpos rtrestrpos - - rtbuild - - rtcostestimate ));
DESCR("");
DATA(insert OID = 403 ( btree PGUID "o" 5 1 btgettuple btinsert btdelete - - - - btbeginscan btrescan btendscan btmarkpos btrestrpos - - btbuild - - ));
DATA(insert OID = 403 ( btree PGUID "o" 5 1 btgettuple btinsert btdelete - - - - btbeginscan btrescan btendscan btmarkpos btrestrpos - - btbuild - - btcostestimate ));
DESCR("");
#define BTREE_AM_OID 403
DATA(insert OID = 405 ( hash PGUID "o" 1 1 hashgettuple hashinsert hashdelete - - - - hashbeginscan hashrescan hashendscan hashmarkpos hashrestrpos - - hashbuild - - ));
DATA(insert OID = 405 ( hash PGUID "o" 1 1 hashgettuple hashinsert hashdelete - - - - hashbeginscan hashrescan hashendscan hashmarkpos hashrestrpos - - hashbuild - - hashcostestimate ));
DESCR("");
#define HASH_AM_OID 405
DATA(insert OID = 783 ( gist PGUID "o" 100 7 gistgettuple gistinsert gistdelete - - - - gistbeginscan gistrescan gistendscan gistmarkpos gistrestrpos - - gistbuild - - ));
DATA(insert OID = 783 ( gist PGUID "o" 100 7 gistgettuple gistinsert gistdelete - - - - gistbeginscan gistrescan gistendscan gistmarkpos gistrestrpos - - gistbuild - - gistcostestimate ));
DESCR("");
#endif /* PG_AM_H */
This diff is collapsed.
......@@ -6,7 +6,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
* $Id: pg_proc.h,v 1.114 2000/01/18 05:08:29 ishii Exp $
* $Id: pg_proc.h,v 1.115 2000/01/22 23:50:23 tgl Exp $
*
* NOTES
* The script catalog/genbki.sh reads this file and generates .bki
......@@ -211,17 +211,13 @@ DESCR("not equal");
DATA(insert OID = 89 ( version PGUID 11 f t f 0 f 25 "" 100 0 0 100 version - ));
DESCR("PostgreSQL version string");
DATA(insert OID = 1265 ( rtsel PGUID 11 f t f 7 f 701 "26 26 21 0 23 23 26" 100 0 0 100 rtsel - ));
DESCR("r-tree");
DATA(insert OID = 1266 ( rtnpage PGUID 11 f t f 7 f 701 "26 26 21 0 23 23 26" 100 0 0 100 rtnpage - ));
DESCR("r-tree");
DATA(insert OID = 1268 ( btreesel PGUID 11 f t f 7 f 701 "26 26 21 0 23 23 26" 100 0 0 100 btreesel - ));
DESCR("btree selectivity");
DATA(insert OID = 1265 ( rtcostestimate PGUID 11 f t f 6 f 0 "0 0 0 0 0 0" 100 0 0 100 rtcostestimate - ));
DESCR("r-tree cost estimator");
DATA(insert OID = 1268 ( btcostestimate PGUID 11 f t f 6 f 0 "0 0 0 0 0 0" 100 0 0 100 btcostestimate - ));
DESCR("btree cost estimator");
/* OIDS 100 - 199 */
DATA(insert OID = 1270 ( btreenpage PGUID 11 f t f 7 f 701 "26 26 21 0 23 23 26" 100 0 0 100 btreenpage - ));
DESCR("btree");
DATA(insert OID = 1272 ( eqsel PGUID 11 f t f 5 f 701 "26 26 21 0 23" 100 0 0 100 eqsel - ));
DESCR("general selectivity");
DATA(insert OID = 102 ( neqsel PGUID 11 f t f 5 f 701 "26 26 21 0 23" 100 0 0 100 neqsel - ));
......@@ -799,10 +795,8 @@ DESCR("convert name to char()");
DATA(insert OID = 409 ( bpchar_name PGUID 11 f t t 1 f 19 "1042" 100 0 0 100 bpchar_name - ));
DESCR("convert char() to name");
DATA(insert OID = 438 ( hashsel PGUID 11 f t f 7 f 701 "26 26 21 0 23 23 26" 100 0 0 100 hashsel - ));
DESCR("selectivity");
DATA(insert OID = 439 ( hashnpage PGUID 11 f t f 7 f 701 "26 26 21 0 23 23 26" 100 0 0 100 hashnpage - ));
DESCR("hash");
DATA(insert OID = 438 ( hashcostestimate PGUID 11 f t f 6 f 0 "0 0 0 0 0 0" 100 0 0 100 hashcostestimate - ));
DESCR("hash index cost estimator");
DATA(insert OID = 440 ( hashgettuple PGUID 11 f t f 2 f 23 "0" 100 0 0 100 hashgettuple - ));
DESCR("hash(internal)");
......@@ -1036,10 +1030,8 @@ DESCR("larger of two");
DATA(insert OID = 771 ( int2smaller PGUID 11 f t t 2 f 21 "21 21" 100 0 0 100 int2smaller - ));
DESCR("smaller of two");
DATA(insert OID = 772 ( gistsel PGUID 11 f t f 7 f 701 "26 26 21 0 23 23 26" 100 0 0 100 gistsel - ));
DESCR("gist selectivity");
DATA(insert OID = 773 ( gistnpage PGUID 11 f t f 7 f 701 "26 26 21 0 23 23 26" 100 0 0 100 gistnpage - ));
DESCR("gist");
DATA(insert OID = 772 ( gistcostestimate PGUID 11 f t f 6 f 0 "0 0 0 0 0 0" 100 0 0 100 gistcostestimate - ));
DESCR("gist cost estimator");
DATA(insert OID = 774 ( gistgettuple PGUID 11 f t f 2 f 23 "0" 100 0 0 100 gistgettuple - ));
DESCR("gist(internal)");
DATA(insert OID = 775 ( gistinsert PGUID 11 f t f 5 f 23 "0" 100 0 0 100 gistinsert - ));
......
......@@ -6,7 +6,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
* $Id: relation.h,v 1.40 2000/01/09 00:26:44 tgl Exp $
* $Id: relation.h,v 1.41 2000/01/22 23:50:25 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -109,6 +109,7 @@ typedef struct RelOptInfo
* indexkeys - List of base-relation attribute numbers that are index keys
* ordering - List of PG_OPERATOR OIDs which order the indexscan result
* relam - the OID of the pg_am of the index
* amcostestimate - OID of the relam's cost estimator
* indproc - OID of the function if a functional index, else 0
* indpred - index predicate if a partial index, else NULL
*
......@@ -132,6 +133,8 @@ typedef struct IndexOptInfo
Oid *ordering; /* OIDs of sort operators for each key */
Oid relam; /* OID of the access method (in pg_am) */
RegProcedure amcostestimate; /* OID of the access method's cost fcn */
Oid indproc; /* if a functional index */
List *indpred; /* if a partial index */
} IndexOptInfo;
......
......@@ -6,7 +6,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
* $Id: cost.h,v 1.25 2000/01/09 00:26:46 tgl Exp $
* $Id: cost.h,v 1.26 2000/01/22 23:50:26 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -20,23 +20,31 @@
#define PERBYTE_CPU 0
#define PERCALL_CPU 0
#define OUTIN_RATIO 100
/* defaults for costsize.c's Cost parameters */
/* NB: cost-estimation code should use the variables, not the constants! */
#define CPU_PAGE_WEIGHT 0.033
#define CPU_INDEX_PAGE_WEIGHT 0.017
/*
* prototypes for costsize.c
* routines to compute costs and sizes
*/
extern bool _enable_seqscan_;
extern bool _enable_indexscan_;
extern bool _enable_sort_;
extern bool _enable_nestloop_;
extern bool _enable_mergejoin_;
extern bool _enable_hashjoin_;
extern bool _enable_tidscan_;
extern Cost cpu_page_weight;
extern Cost cpu_index_page_weight;
extern Cost disable_cost;
extern bool enable_seqscan;
extern bool enable_indexscan;
extern bool enable_tidscan;
extern bool enable_sort;
extern bool enable_nestloop;
extern bool enable_mergejoin;
extern bool enable_hashjoin;
extern Cost cost_seqscan(RelOptInfo *baserel);
extern Cost cost_index(RelOptInfo *baserel, IndexOptInfo *index,
long expected_indexpages, Selectivity selec,
bool is_injoin);
extern Cost cost_index(Query *root, RelOptInfo *baserel, IndexOptInfo *index,
List *indexQuals, bool is_injoin);
extern Cost cost_tidscan(RelOptInfo *baserel, List *tideval);
extern Cost cost_sort(List *pathkeys, double tuples, int width);
extern Cost cost_nestloop(Path *outer_path, Path *inner_path,
......
......@@ -6,7 +6,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
* $Id: internal.h,v 1.24 2000/01/11 03:59:31 tgl Exp $
* $Id: internal.h,v 1.25 2000/01/22 23:50:27 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -25,14 +25,6 @@
*/
/*
* System-dependent tuning constants
*
*/
#define _CPU_PAGE_WEIGHT_ 0.033 /* CPU-heap-to-page cost weighting factor */
#define _CPU_INDEX_PAGE_WEIGHT_ 0.017 /* CPU-index-to-page cost
* weighting factor */
/*
* Size estimates
*
......@@ -60,7 +52,4 @@
/* used to be -1 */
#define _NONAME_RELATION_ID_ InvalidOid
/* GEQO switch according to number of relations in a query */
#define GEQO_RELS 11
#endif /* INTERNAL_H */
......@@ -7,7 +7,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
* $Id: paths.h,v 1.37 2000/01/09 00:26:47 tgl Exp $
* $Id: paths.h,v 1.38 2000/01/22 23:50:27 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -16,9 +16,16 @@
#include "nodes/relation.h"
/* default GEQO threshold (default value for geqo_rels) */
#define GEQO_RELS 11
/*
* allpaths.c
*/
extern bool enable_geqo;
extern int geqo_rels;
extern RelOptInfo *make_one_rel(Query *root, List *rels);
/*
......
......@@ -6,7 +6,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
* $Id: plancat.h,v 1.15 2000/01/09 00:26:47 tgl Exp $
* $Id: plancat.h,v 1.16 2000/01/22 23:50:27 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -30,10 +30,6 @@ extern Selectivity restriction_selectivity(Oid functionObjectId,
Datum constValue,
int constFlag);
extern void index_selectivity(Query *root, RelOptInfo *rel,
IndexOptInfo *index, List *indexquals,
long *idxPages, Selectivity *idxSelec);
extern Selectivity join_selectivity(Oid functionObjectId, Oid operatorObjectId,
Oid relationObjectId1, AttrNumber attributeNumber1,
Oid relationObjectId2, AttrNumber attributeNumber2);
......
......@@ -6,7 +6,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
* $Id: builtins.h,v 1.96 2000/01/22 14:20:55 petere Exp $
* $Id: builtins.h,v 1.97 2000/01/22 23:50:27 tgl Exp $
*
* NOTES
* This should normally only be included by fmgr.h.
......@@ -22,6 +22,8 @@
#ifndef BUILTINS_H
#define BUILTINS_H
#include "access/heapam.h" /* for HeapTuple */
#include "nodes/relation.h" /* for amcostestimate parameters */
#include "storage/itemptr.h"
#include "utils/array.h"
#include "utils/datetime.h"
......@@ -30,7 +32,6 @@
#include "utils/int8.h"
#include "utils/nabstime.h"
#include "utils/numeric.h"
#include "access/heapam.h" /* for HeapTuple */
/*
* Defined in adt/
......@@ -394,14 +395,23 @@ extern float64 eqjoinsel(Oid opid, Oid relid1, AttrNumber attno1, Oid relid2, At
extern float64 neqjoinsel(Oid opid, Oid relid1, AttrNumber attno1, Oid relid2, AttrNumber attno2);
extern float64 intltjoinsel(Oid opid, Oid relid1, AttrNumber attno1, Oid relid2, AttrNumber attno2);
extern float64 intgtjoinsel(Oid opid, Oid relid1, AttrNumber attno1, Oid relid2, AttrNumber attno2);
extern float64 btreesel(Oid operatorOid, Oid indrelid, AttrNumber attributeNumber, char *constValue, int32 constFlag, int32 nIndexKeys, Oid indexrelid);
extern float64 btreenpage(Oid operatorOid, Oid indrelid, AttrNumber attributeNumber, char *constValue, int32 constFlag, int32 nIndexKeys, Oid indexrelid);
extern float64 hashsel(Oid operatorOid, Oid indrelid, AttrNumber attributeNumber, char *constValue, int32 constFlag, int32 nIndexKeys, Oid indexrelid);
extern float64 hashnpage(Oid operatorOid, Oid indrelid, AttrNumber attributeNumber, char *constValue, int32 constFlag, int32 nIndexKeys, Oid indexrelid);
extern float64 rtsel(Oid operatorOid, Oid indrelid, AttrNumber attributeNumber, char *constValue, int32 constFlag, int32 nIndexKeys, Oid indexrelid);
extern float64 rtnpage(Oid operatorOid, Oid indrelid, AttrNumber attributeNumber, char *constValue, int32 constFlag, int32 nIndexKeys, Oid indexrelid);
extern float64 gistsel(Oid operatorObjectId, Oid indrelid, AttrNumber attributeNumber, char *constValue, int32 constFlag, int32 nIndexKeys, Oid indexrelid);
extern float64 gistnpage(Oid operatorObjectId, Oid indrelid, AttrNumber attributeNumber, char *constValue, int32 constFlag, int32 nIndexKeys, Oid indexrelid);
extern void btcostestimate(Query *root, RelOptInfo *rel,
IndexOptInfo *index, List *indexQuals,
Cost *indexAccessCost,
Selectivity *indexSelectivity);
extern void rtcostestimate(Query *root, RelOptInfo *rel,
IndexOptInfo *index, List *indexQuals,
Cost *indexAccessCost,
Selectivity *indexSelectivity);
extern void hashcostestimate(Query *root, RelOptInfo *rel,
IndexOptInfo *index, List *indexQuals,
Cost *indexAccessCost,
Selectivity *indexSelectivity);
extern void gistcostestimate(Query *root, RelOptInfo *rel,
IndexOptInfo *index, List *indexQuals,
Cost *indexAccessCost,
Selectivity *indexSelectivity);
/* tid.c */
extern ItemPointer tidin(const char *str);
......
......@@ -23,6 +23,8 @@
-- **************** pg_proc ****************
-- Look for illegal values in pg_proc fields.
-- NOTE: currently there are a few pg_proc entries that have prorettype = 0.
-- Someday that ought to be cleaned up.
SELECT p1.oid, p1.proname
FROM pg_proc as p1
......@@ -30,6 +32,7 @@ WHERE (p1.prolang = 0 OR p1.prorettype = 0 OR
p1.pronargs < 0 OR p1.pronargs > 9)
AND p1.proname !~ '^pl[^_]+_call_handler$'
AND p1.proname !~ '^RI_FKey_'
AND p1.proname !~ 'costestimate$'
AND p1.proname != 'update_pg_pwd';
-- Look for conflicting proc definitions (same names and input datatypes).
......@@ -416,7 +419,7 @@ WHERE p1.aggfinalfn = p2.oid AND
SELECT p1.oid
FROM pg_amop as p1
WHERE p1.amopid = 0 OR p1.amopclaid = 0 OR p1.amopopr = 0 OR
p1.amopstrategy <= 0 OR p1.amopselect = 0 OR p1.amopnpages = 0;
p1.amopstrategy <= 0;
-- Look for duplicate pg_amop entries
......@@ -459,36 +462,6 @@ WHERE p1.amopopr = p2.oid AND p1.amopclaid = p3.oid AND
p3.opcdeftype != 0 AND
(p3.opcdeftype != p2.oprleft OR p3.opcdeftype != p2.oprright);
-- Check that amopselect points to a proc with the right signature
-- to be an access-method selectivity estimator.
-- The proc signature we want is:
-- float8 proc(oid, oid, int2, <any>, int4, int4, oid)
SELECT p1.oid, p2.oid, p2.proname
FROM pg_amop AS p1, pg_proc AS p2
WHERE p1.amopselect = p2.oid AND
(p2.prorettype != 701 OR p2.proretset OR
p2.pronargs != 7 OR
p2.proargtypes[0] != 26 OR p2.proargtypes[1] != 26 OR
p2.proargtypes[2] != 21 OR p2.proargtypes[3] != 0 OR
p2.proargtypes[4] != 23 OR p2.proargtypes[5] != 23 OR
p2.proargtypes[6] != 26);
-- Check that amopnpages points to a proc with the right signature
-- to be an access-method page-count estimator.
-- The proc signature we want is:
-- float8 proc(oid, oid, int2, <any>, int4, int4, oid)
SELECT p1.oid, p2.oid, p2.proname
FROM pg_amop AS p1, pg_proc AS p2
WHERE p1.amopnpages = p2.oid AND
(p2.prorettype != 701 OR p2.proretset OR
p2.pronargs != 7 OR
p2.proargtypes[0] != 26 OR p2.proargtypes[1] != 26 OR
p2.proargtypes[2] != 21 OR p2.proargtypes[3] != 0 OR
p2.proargtypes[4] != 23 OR p2.proargtypes[5] != 23 OR
p2.proargtypes[6] != 26);
-- **************** pg_amproc ****************
-- Look for illegal values in pg_amproc fields
......
......@@ -7,7 +7,7 @@
--
-- Copyright (c) 1994, Regents of the University of California
--
-- $Id: complex.source,v 1.4 1998/03/01 04:52:59 scrappy Exp $
-- $Id: complex.source,v 1.5 2000/01/22 23:50:30 tgl Exp $
--
---------------------------------------------------------------------------
......@@ -184,42 +184,32 @@ WHERE o.oprleft = t.oid and o.oprright = t.oid
-- make sure we have the right operators
SELECT * from complex_ops_tmp;
INSERT INTO pg_amop (amopid, amopclaid, amopopr, amopstrategy,
amopselect, amopnpages)
SELECT am.oid, opcl.oid, c.opoid, 1,
'btreesel'::regproc, 'btreenpage'::regproc
INSERT INTO pg_amop (amopid, amopclaid, amopopr, amopstrategy)
SELECT am.oid, opcl.oid, c.opoid, 1
FROM pg_am am, pg_opclass opcl, complex_ops_tmp c
WHERE amname = 'btree' and opcname = 'complex_abs_ops'
and c.oprname = '<';
INSERT INTO pg_amop (amopid, amopclaid, amopopr, amopstrategy,
amopselect, amopnpages)
SELECT am.oid, opcl.oid, c.opoid, 2,
'btreesel'::regproc, 'btreenpage'::regproc
INSERT INTO pg_amop (amopid, amopclaid, amopopr, amopstrategy)
SELECT am.oid, opcl.oid, c.opoid, 2
FROM pg_am am, pg_opclass opcl, complex_ops_tmp c
WHERE amname = 'btree' and opcname = 'complex_abs_ops'
and c.oprname = '<=';
INSERT INTO pg_amop (amopid, amopclaid, amopopr, amopstrategy,
amopselect, amopnpages)
SELECT am.oid, opcl.oid, c.opoid, 3,
'btreesel'::regproc, 'btreenpage'::regproc
INSERT INTO pg_amop (amopid, amopclaid, amopopr, amopstrategy)
SELECT am.oid, opcl.oid, c.opoid, 3
FROM pg_am am, pg_opclass opcl, complex_ops_tmp c
WHERE amname = 'btree' and opcname = 'complex_abs_ops'
and c.oprname = '=';
INSERT INTO pg_amop (amopid, amopclaid, amopopr, amopstrategy,
amopselect, amopnpages)
SELECT am.oid, opcl.oid, c.opoid, 4,
'btreesel'::regproc, 'btreenpage'::regproc
INSERT INTO pg_amop (amopid, amopclaid, amopopr, amopstrategy)
SELECT am.oid, opcl.oid, c.opoid, 4
FROM pg_am am, pg_opclass opcl, complex_ops_tmp c
WHERE amname = 'btree' and opcname = 'complex_abs_ops'
and c.oprname = '>=';
INSERT INTO pg_amop (amopid, amopclaid, amopopr, amopstrategy,
amopselect, amopnpages)
SELECT am.oid, opcl.oid, c.opoid, 5,
'btreesel'::regproc, 'btreenpage'::regproc
INSERT INTO pg_amop (amopid, amopclaid, amopopr, amopstrategy)
SELECT am.oid, opcl.oid, c.opoid, 5
FROM pg_am am, pg_opclass opcl, complex_ops_tmp c
WHERE amname = 'btree' and opcname = 'complex_abs_ops'
and c.oprname = '>';
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment