diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml
index cc28888efeb7e34eee3480721684766d540df257..d0edf22daa8b1d257469f963389411c735eec02d 100644
--- a/doc/src/sgml/catalogs.sgml
+++ b/doc/src/sgml/catalogs.sgml
@@ -1,6 +1,6 @@
 .\" 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
diff --git a/doc/src/sgml/xindex.sgml b/doc/src/sgml/xindex.sgml
index 771c30e4858a1aca741eb297cea58dfb78dd5dd6..e4d36e1cc5b3e54c8e600fdf60a2382bcce642ec 100644
--- a/doc/src/sgml/xindex.sgml
+++ b/doc/src/sgml/xindex.sgml
@@ -1,5 +1,5 @@
 <!--
-$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
diff --git a/src/backend/access/index/indexam.c b/src/backend/access/index/indexam.c
index dc08d10bc313df0bd28564c6bb4b02bb7c7fded6..3c286f6ec741570305acd5ff652f171614a9ca18 100644
--- a/src/backend/access/index/indexam.c
+++ b/src/backend/access/index/indexam.c
@@ -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
  *
diff --git a/src/backend/commands/variable.c b/src/backend/commands/variable.c
index 031512839c244876729f9aa6eded68b151bd45c1..52c4ed3552a1149254673abd6dea97f05c1d26aa 100644
--- a/src/backend/commands/variable.c
+++ b/src/backend/commands/variable.c
@@ -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;
 }
 
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index 241b8ca10353332d0c2edf047fc1ad0d6fd5436d..5cbea5516593e1ff8e80df8a6df3cac7e12ef30f 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -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);
 
diff --git a/src/backend/nodes/readfuncs.c b/src/backend/nodes/readfuncs.c
index 9c1219b7860fa218724220d0629e74cf2f35c3a2..8e6f68bdfd7d5ec383f036793fa52202b45b0dff 100644
--- a/src/backend/nodes/readfuncs.c
+++ b/src/backend/nodes/readfuncs.c
@@ -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)
diff --git a/src/backend/optimizer/path/_deadcode/xfunc.c b/src/backend/optimizer/path/_deadcode/xfunc.c
index 771cec3ecd92d9e5888242cb4487144e7094aa6d..82c26cee5f91b36c4fd07af0eec816dd847e90c2 100644
--- a/src/backend/optimizer/path/_deadcode/xfunc.c
+++ b/src/backend/optimizer/path/_deadcode/xfunc.c
@@ -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;
 	}
 }
 
diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c
index 1e357d4b8fda2694211eb03d56bdc6c519ac9c9b..5cae7651eeca4a8854c5dcac3f2b82ffee129037 100644
--- a/src/backend/optimizer/path/allpaths.c
+++ b/src/backend/optimizer/path/allpaths.c
@@ -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)
diff --git a/src/backend/optimizer/path/costsize.c b/src/backend/optimizer/path/costsize.c
index 8261e17c02e450915eef913e32678a04c2548298..5c0f54a73e2f7894b673e4e567da8416e7c82aed 100644
--- a/src/backend/optimizer/path/costsize.c
+++ b/src/backend/optimizer/path/costsize.c
@@ -5,20 +5,20 @@
  *
  * Path costs are measured in units of disk accesses: one page fetch
  * has cost 1.  The other primitive unit is the CPU time required to
- * process one tuple, which we set at "_cpu_page_weight_" of a page
+ * process one tuple, which we set at "cpu_page_weight" of a page
  * fetch.  Obviously, the CPU time per tuple depends on the query
  * involved, but the relative CPU and disk speeds of a given platform
  * are so variable that we are lucky if we can get useful numbers
- * at all.  _cpu_page_weight_ is user-settable, in case a particular
+ * at all.  cpu_page_weight is user-settable, in case a particular
  * user is clueful enough to have a better-than-default estimate
- * of the ratio for his platform.  There is also _cpu_index_page_weight_,
+ * of the ratio for his platform.  There is also cpu_index_page_weight,
  * the cost to process a tuple of an index during an index scan.
  *
  * 
  * Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/optimizer/path/costsize.c,v 1.47 2000/01/09 00:26:31 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/optimizer/path/costsize.c,v 1.48 2000/01/22 23:50:14 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -44,6 +44,20 @@
 #include "utils/lsyscache.h"
 
 
+Cost		cpu_page_weight = CPU_PAGE_WEIGHT;
+Cost		cpu_index_page_weight = CPU_INDEX_PAGE_WEIGHT;
+
+Cost		disable_cost = 100000000.0;
+
+bool		enable_seqscan = true;
+bool		enable_indexscan = true;
+bool		enable_tidscan = true;
+bool		enable_sort = true;
+bool		enable_nestloop = true;
+bool		enable_mergejoin = true;
+bool		enable_hashjoin = true;
+
+
 static void set_rel_width(Query *root, RelOptInfo *rel);
 static int	compute_attribute_width(TargetEntry *tlistentry);
 static double relation_byte_size(double tuples, int width);
@@ -51,19 +65,6 @@ static double page_size(double tuples, int width);
 static double base_log(double x, double b);
 
 
-Cost		_cpu_page_weight_ = _CPU_PAGE_WEIGHT_;
-Cost		_cpu_index_page_weight_ = _CPU_INDEX_PAGE_WEIGHT_;
-
-Cost		_disable_cost_ = 100000000.0;
-
-bool		_enable_seqscan_ = true;
-bool		_enable_indexscan_ = true;
-bool		_enable_sort_ = true;
-bool		_enable_nestloop_ = true;
-bool		_enable_mergejoin_ = true;
-bool		_enable_hashjoin_ = true;
-bool		_enable_tidscan_ = true;
-
 /*
  * cost_seqscan
  *	  Determines and returns the cost of scanning a relation sequentially.
@@ -84,8 +85,8 @@ cost_seqscan(RelOptInfo *baserel)
 	/* Should only be applied to base relations */
 	Assert(length(baserel->relids) == 1);
 
-	if (!_enable_seqscan_)
-		temp += _disable_cost_;
+	if (!enable_seqscan)
+		temp += disable_cost;
 
 	if (lfirsti(baserel->relids) < 0)
 	{
@@ -97,7 +98,7 @@ cost_seqscan(RelOptInfo *baserel)
 	else
 	{
 		temp += baserel->pages;
-		temp += _cpu_page_weight_ * baserel->tuples;
+		temp += cpu_page_weight * baserel->tuples;
 	}
 
 	Assert(temp >= 0);
@@ -109,58 +110,54 @@ cost_seqscan(RelOptInfo *baserel)
  * cost_index
  *	  Determines and returns the cost of scanning a relation using an index.
  *
- *		disk = expected-index-pages + expected-data-pages
- *		cpu = CPU-INDEX-PAGE-WEIGHT * expected-index-tuples +
- *		      CPU-PAGE-WEIGHT * expected-data-tuples
+ *	  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
  * 'baserel' is the base relation the index is for
  * 'index' is the index to be used
- * 'expected_indexpages' is the estimated number of index pages that will
- *		be touched in the scan (this is computed by index-type-specific code)
- * 'selec' is the selectivity of the index, ie, the fraction of base-relation
- *		tuples that we will have to fetch and examine
+ * 'indexQuals' is the list of applicable qual clauses (implicit AND semantics)
  * 'is_injoin' is T if we are considering using the index scan as the inside
  *		of a nestloop join.
  *
- * NOTE: 'selec' should be calculated on the basis of indexqual conditions
- * only.  Any additional quals evaluated as qpquals may reduce the number
- * of returned tuples, but they won't reduce the number of tuples we have
- * to fetch from the table, so they don't reduce the scan cost.
+ * NOTE: 'indexQuals' must contain only clauses usable as index restrictions.
+ * Any additional quals evaluated as qpquals may reduce the number of returned
+ * tuples, but they won't reduce the number of tuples we have to fetch from
+ * the table, so they don't reduce the scan cost.
  */
 Cost
-cost_index(RelOptInfo *baserel,
+cost_index(Query *root,
+		   RelOptInfo *baserel,
 		   IndexOptInfo *index,
-		   long expected_indexpages,
-		   Selectivity selec,
+		   List *indexQuals,
 		   bool is_injoin)
 {
 	Cost		temp = 0;
-	double		reltuples = selec * baserel->tuples;
-	double		indextuples = selec * index->tuples;
+	Cost		indexAccessCost;
+	Selectivity	indexSelectivity;
+	double		reltuples;
 	double		relpages;
 
 	/* Should only be applied to base relations */
 	Assert(IsA(baserel, RelOptInfo) && IsA(index, IndexOptInfo));
 	Assert(length(baserel->relids) == 1);
 
-	if (!_enable_indexscan_ && !is_injoin)
-		temp += _disable_cost_;
+	if (!enable_indexscan && !is_injoin)
+		temp += disable_cost;
 
 	/*
-	 * We want to be sure we estimate the cost of an index scan as more
-	 * than the cost of a sequential scan (when selec == 1.0), even if we
-	 * don't have good stats.  So, disbelieve zero index size.
+	 * Call index-access-method-specific code to estimate the processing
+	 * cost for scanning the index, as well as the selectivity of the index
+	 * (ie, the fraction of main-table tuples we will have to retrieve).
 	 */
-	if (expected_indexpages <= 0)
-		expected_indexpages = 1;
-	if (indextuples <= 0.0)
-		indextuples = 1.0;
+	fmgr(index->amcostestimate, root, baserel, index, indexQuals,
+		 &indexAccessCost, &indexSelectivity);
 
-	/* expected index relation pages */
-	temp += expected_indexpages;
+	/* all costs for touching index itself included here */
+	temp += indexAccessCost;
 
 	/*--------------------
-	 * expected base relation pages
+	 * Estimate number of main-table tuples and pages touched.
 	 *
 	 * Worst case is that each tuple the index tells us to fetch comes
 	 * from a different base-rel page, in which case the I/O cost would be
@@ -178,6 +175,8 @@ cost_index(RelOptInfo *baserel,
 	 * So, we guess-and-hope that these sources of error will more or less
 	 * balance out.
 	 *
+	 * XXX need to add a penalty for nonsequential page fetches.
+	 *
 	 * XXX if the relation has recently been "clustered" using this index,
 	 * then in fact the target tuples will be highly nonuniformly distributed,
 	 * and we will be seriously overestimating the scan cost!  Currently we
@@ -186,16 +185,18 @@ cost_index(RelOptInfo *baserel,
 	 * effect.  Would be nice to do better someday.
 	 *--------------------
 	 */
+
+	reltuples = indexSelectivity * baserel->tuples;
+
 	relpages = reltuples;
 	if (baserel->pages > 0 && baserel->pages < relpages)
 		relpages = baserel->pages;
-	temp += relpages;
 
-	/* per index tuples */
-	temp += _cpu_index_page_weight_ * indextuples;
+	/* disk costs for main table */
+	temp += relpages;
 
-	/* per heap tuples */
-	temp += _cpu_page_weight_ * reltuples;
+	/* CPU costs for heap tuples */
+	temp += cpu_page_weight * reltuples;
 
 	Assert(temp >= 0);
 	return temp;
@@ -213,10 +214,10 @@ cost_tidscan(RelOptInfo *baserel, List *tideval)
 {
 	Cost	temp = 0;
 
-	if (!_enable_tidscan_)
-		temp += _disable_cost_;
+	if (!enable_tidscan)
+		temp += disable_cost;
 
-	temp += (1.0 + _cpu_page_weight_) * length(tideval);
+	temp += (1.0 + cpu_page_weight) * length(tideval);
 
 	return temp;
 }
@@ -227,7 +228,7 @@ cost_tidscan(RelOptInfo *baserel, List *tideval)
  *
  * If the total volume of data to sort is less than SortMem, we will do
  * an in-memory sort, which requires no I/O and about t*log2(t) tuple
- * comparisons for t tuples.  We use _cpu_index_page_weight as the cost
+ * comparisons for t tuples.  We use cpu_index_page_weight as the cost
  * of a tuple comparison (is this reasonable, or do we need another
  * basic parameter?).
  *
@@ -257,8 +258,8 @@ cost_sort(List *pathkeys, double tuples, int width)
 	double		nbytes = relation_byte_size(tuples, width);
 	long		sortmembytes = SortMem * 1024L;
 
-	if (!_enable_sort_)
-		temp += _disable_cost_;
+	if (!enable_sort)
+		temp += disable_cost;
 
 	/*
 	 * We want to be sure the cost of a sort is never estimated as zero,
@@ -268,7 +269,7 @@ cost_sort(List *pathkeys, double tuples, int width)
 	if (tuples < 2.0)
 		tuples = 2.0;
 
-	temp += _cpu_index_page_weight_ * tuples * base_log(tuples, 2.0);
+	temp += cpu_index_page_weight * tuples * base_log(tuples, 2.0);
 
 	if (nbytes > sortmembytes)
 	{
@@ -298,7 +299,7 @@ cost_result(double tuples, int width)
 	Cost		temp = 0;
 
 	temp += page_size(tuples, width);
-	temp += _cpu_page_weight_ * tuples;
+	temp += cpu_page_weight * tuples;
 	Assert(temp >= 0);
 	return temp;
 }
@@ -321,8 +322,8 @@ cost_nestloop(Path *outer_path,
 {
 	Cost		temp = 0;
 
-	if (!_enable_nestloop_)
-		temp += _disable_cost_;
+	if (!enable_nestloop)
+		temp += disable_cost;
 
 	temp += outer_path->path_cost;
 	temp += outer_path->parent->rows * inner_path->path_cost;
@@ -350,8 +351,8 @@ cost_mergejoin(Path *outer_path,
 {
 	Cost		temp = 0;
 
-	if (!_enable_mergejoin_)
-		temp += _disable_cost_;
+	if (!enable_mergejoin)
+		temp += disable_cost;
 
 	/* cost of source data */
 	temp += outer_path->path_cost + inner_path->path_cost;
@@ -372,8 +373,8 @@ cost_mergejoin(Path *outer_path,
 	 * underestimate if there are many equal-keyed tuples in either relation,
 	 * but we have no good way of estimating that...
 	 */
-	temp += _cpu_page_weight_ * (outer_path->parent->rows +
-								 inner_path->parent->rows);
+	temp += cpu_page_weight * (outer_path->parent->rows +
+							   inner_path->parent->rows);
 
 	Assert(temp >= 0);
 	return temp;
@@ -401,23 +402,23 @@ cost_hashjoin(Path *outer_path,
 												inner_path->parent->width);
 	long		hashtablebytes = SortMem * 1024L;
 
-	if (!_enable_hashjoin_)
-		temp += _disable_cost_;
+	if (!enable_hashjoin)
+		temp += disable_cost;
 
 	/* cost of source data */
 	temp += outer_path->path_cost + inner_path->path_cost;
 
 	/* cost of computing hash function: must do it once per tuple */
-	temp += _cpu_page_weight_ * (outer_path->parent->rows +
-								 inner_path->parent->rows);
+	temp += cpu_page_weight * (outer_path->parent->rows +
+							   inner_path->parent->rows);
 
 	/* the number of tuple comparisons needed is the number of outer
 	 * tuples times the typical hash bucket size, which we estimate
 	 * conservatively as the inner disbursion times the inner tuple
-	 * count.  The cost per comparison is set at _cpu_index_page_weight_;
+	 * count.  The cost per comparison is set at cpu_index_page_weight;
 	 * is that reasonable, or do we need another basic parameter?
 	 */
-	temp += _cpu_index_page_weight_ * outer_path->parent->rows *
+	temp += cpu_index_page_weight * outer_path->parent->rows *
 		(inner_path->parent->rows * innerdisbursion);
 
 	/*
diff --git a/src/backend/optimizer/path/indxpath.c b/src/backend/optimizer/path/indxpath.c
index 3c93ee67ac34a02a45dbd19281b0b0ca21c57155..7bb4a8eaeb1d83066413fb1e9c34c8b496e2d08b 100644
--- a/src/backend/optimizer/path/indxpath.c
+++ b/src/backend/optimizer/path/indxpath.c
@@ -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);
diff --git a/src/backend/optimizer/path/joinpath.c b/src/backend/optimizer/path/joinpath.c
index 5c7df62fa20e17d81d797caba64f3dd5850656f2..f29a5cc81631d9135f0041b8d0d8a0c6bf6f80fa 100644
--- a/src/backend/optimizer/path/joinpath.c
+++ b/src/backend/optimizer/path/joinpath.c
@@ -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,
diff --git a/src/backend/optimizer/path/orindxpath.c b/src/backend/optimizer/path/orindxpath.c
index f5813a27a8e25e68267a3cc495450953f0a99195..2831342fd886b6f7b42e8d6a0b0e280255e720d0 100644
--- a/src/backend/optimizer/path/orindxpath.c
+++ b/src/backend/optimizer/path/orindxpath.c
@@ -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)
diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c
index 7316a7946129a5f87b678770ea7f0c315e61869e..87d321feff7d637bd0d6e786ff21f8f075303a93 100644
--- a/src/backend/optimizer/plan/initsplan.c
+++ b/src/backend/optimizer/plan/initsplan.c
@@ -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);
 }
 
diff --git a/src/backend/optimizer/util/pathnode.c b/src/backend/optimizer/util/pathnode.c
index a2551391e00c77accdcd095ffc3ab3ec814ae34f..5c093acc9f5c12fe49c5965f7649f665c80b06ac 100644
--- a/src/backend/optimizer/util/pathnode.c
+++ b/src/backend/optimizer/util/pathnode.c
@@ -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);
 
+	indexquals = get_actual_clauses(restriction_clauses);
+	/* 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.  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.
+	 * We are making a pathnode for a single-scan indexscan; therefore,
+	 * both indexid and indexqual should be single-element lists.
 	 */
 	pathnode->indexid = lconsi(index->indexoid, NIL);
-	pathnode->indexqual = lcons(NIL, NIL);
+	pathnode->indexqual = lcons(indexquals, 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...
-		 */
-		lfirst(pathnode->indexqual) = indexquals;
-
-		index_selectivity(root,
-						  rel,
-						  index,
-						  indexquals,
-						  &npages,
-						  &selec);
-
-		pathnode->path.path_cost = cost_index(rel, index,
-											  npages, selec,
-											  false);
-	}
+	pathnode->path.path_cost = cost_index(root, rel, index, indexquals,
+										  false);
 
 	return pathnode;
 }
diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c
index 6468ef528fdb3fd55b5dece3f793ad033a8eae33..4c191f02b555f2cef55ca1c37974c599f8b9e32e 100644
--- a/src/backend/optimizer/util/plancat.c
+++ b/src/backend/optimizer/util/plancat.c
@@ -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
  *
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index 338d93a7ffae2078adc6602a8b1968dee8fa43a6..fb226fa41af69ee7bb64d12003fee212f6d1235c 100644
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -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");
 	}
 
 	/*
diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c
index 7ec3e4dc1b8cd8f798b7ac832964052bdeaf7d67..f1c458b761cf7286252a341b06ab87e089765758 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);
 }
diff --git a/src/include/access/genam.h b/src/include/access/genam.h
index 76200f215e2dbf2d8f6390ea679d5805c18be264..81b38da6cc16f0091ae6edb6379d4c7595fd7680 100644
--- a/src/include/access/genam.h
+++ b/src/include/access/genam.h
@@ -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,
diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h
index eca72916b883f15f0a646ed69c34f2945ed7e97f..d706d1f20a0168dcf5be88b16f265ddcfb02cdb8 100644
--- a/src/include/catalog/catversion.h
+++ b/src/include/catalog/catversion.h
@@ -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
diff --git a/src/include/catalog/pg_am.h b/src/include/catalog/pg_am.h
index 4ec5062ffa402131e06aec13104ec19d894c4f9d..2be6a7259bd6f74f173ce908832b1c434059409e 100644
--- a/src/include/catalog/pg_am.h
+++ b/src/include/catalog/pg_am.h
@@ -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 */
diff --git a/src/include/catalog/pg_amop.h b/src/include/catalog/pg_amop.h
index 93ed1d46936e7e1a7f71b2bf30c48025476e1a66..c6c71f526f23f28375d1d57b83aec1aff76617e1 100644
--- a/src/include/catalog/pg_amop.h
+++ b/src/include/catalog/pg_amop.h
@@ -7,7 +7,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: pg_amop.h,v 1.27 2000/01/10 16:13:20 momjian Exp $
+ * $Id: pg_amop.h,v 1.28 2000/01/22 23:50:23 tgl Exp $
  *
  * NOTES
  *	 the genbki.sh script reads this file and generates .bki
@@ -36,8 +36,6 @@ CATALOG(pg_amop)
 	Oid			amopclaid;
 	Oid			amopopr;
 	int2		amopstrategy;
-	regproc		amopselect;
-	regproc		amopnpages;
 } FormData_pg_amop;
 
 /* ----------------
@@ -51,14 +49,11 @@ typedef FormData_pg_amop *Form_pg_amop;
  *		compiler constants for pg_amop
  * ----------------
  */
-/* #define Name_pg_amop					"pg_amop" */
-#define Natts_pg_amop					6
+#define Natts_pg_amop					4
 #define Anum_pg_amop_amopid				1
 #define Anum_pg_amop_amopclaid			2
 #define Anum_pg_amop_amopopr			3
 #define Anum_pg_amop_amopstrategy		4
-#define Anum_pg_amop_amopselect			5
-#define Anum_pg_amop_amopnpages			6
 
 /* ----------------
  *		initial contents of pg_amop
@@ -69,326 +64,326 @@ typedef FormData_pg_amop *Form_pg_amop;
  *	rtree box_ops
  */
 
-DATA(insert OID = 0 (  402 422 493 1 rtsel rtnpage ));
-DATA(insert OID = 0 (  402 422 494 2 rtsel rtnpage ));
-DATA(insert OID = 0 (  402 422 500 3 rtsel rtnpage ));
-DATA(insert OID = 0 (  402 422 495 4 rtsel rtnpage ));
-DATA(insert OID = 0 (  402 422 496 5 rtsel rtnpage ));
-DATA(insert OID = 0 (  402 422 499 6 rtsel rtnpage ));
-DATA(insert OID = 0 (  402 422 498 7 rtsel rtnpage ));
-DATA(insert OID = 0 (  402 422 497 8 rtsel rtnpage ));
+DATA(insert OID = 0 (  402 422 493 1 ));
+DATA(insert OID = 0 (  402 422 494 2 ));
+DATA(insert OID = 0 (  402 422 500 3 ));
+DATA(insert OID = 0 (  402 422 495 4 ));
+DATA(insert OID = 0 (  402 422 496 5 ));
+DATA(insert OID = 0 (  402 422 499 6 ));
+DATA(insert OID = 0 (  402 422 498 7 ));
+DATA(insert OID = 0 (  402 422 497 8 ));
 
 /*
  *	rtree bigbox_ops
  */
 
-DATA(insert OID = 0 (  402 433 493 1 rtsel rtnpage ));
-DATA(insert OID = 0 (  402 433 494 2 rtsel rtnpage ));
-DATA(insert OID = 0 (  402 433 500 3 rtsel rtnpage ));
-DATA(insert OID = 0 (  402 433 495 4 rtsel rtnpage ));
-DATA(insert OID = 0 (  402 433 496 5 rtsel rtnpage ));
-DATA(insert OID = 0 (  402 433 499 6 rtsel rtnpage ));
-DATA(insert OID = 0 (  402 433 498 7 rtsel rtnpage ));
-DATA(insert OID = 0 (  402 433 497 8 rtsel rtnpage ));
+DATA(insert OID = 0 (  402 433 493 1 ));
+DATA(insert OID = 0 (  402 433 494 2 ));
+DATA(insert OID = 0 (  402 433 500 3 ));
+DATA(insert OID = 0 (  402 433 495 4 ));
+DATA(insert OID = 0 (  402 433 496 5 ));
+DATA(insert OID = 0 (  402 433 499 6 ));
+DATA(insert OID = 0 (  402 433 498 7 ));
+DATA(insert OID = 0 (  402 433 497 8 ));
 
 /*
  *	rtree poly_ops (supports polygons)
  */
 
-DATA(insert OID = 0 (  402 434 485 1 rtsel rtnpage ));
-DATA(insert OID = 0 (  402 434 486 2 rtsel rtnpage ));
-DATA(insert OID = 0 (  402 434 492 3 rtsel rtnpage ));
-DATA(insert OID = 0 (  402 434 487 4 rtsel rtnpage ));
-DATA(insert OID = 0 (  402 434 488 5 rtsel rtnpage ));
-DATA(insert OID = 0 (  402 434 491 6 rtsel rtnpage ));
-DATA(insert OID = 0 (  402 434 490 7 rtsel rtnpage ));
-DATA(insert OID = 0 (  402 434 489 8 rtsel rtnpage ));
+DATA(insert OID = 0 (  402 434 485 1 ));
+DATA(insert OID = 0 (  402 434 486 2 ));
+DATA(insert OID = 0 (  402 434 492 3 ));
+DATA(insert OID = 0 (  402 434 487 4 ));
+DATA(insert OID = 0 (  402 434 488 5 ));
+DATA(insert OID = 0 (  402 434 491 6 ));
+DATA(insert OID = 0 (  402 434 490 7 ));
+DATA(insert OID = 0 (  402 434 489 8 ));
 
 /*
  *	rtree circle_ops (supports circles)
  */
 
-DATA(insert OID = 0 (  402 714 1506 1 rtsel rtnpage ));
-DATA(insert OID = 0 (  402 714 1507 2 rtsel rtnpage ));
-DATA(insert OID = 0 (  402 714 1513 3 rtsel rtnpage ));
-DATA(insert OID = 0 (  402 714 1508 4 rtsel rtnpage ));
-DATA(insert OID = 0 (  402 714 1509 5 rtsel rtnpage ));
-DATA(insert OID = 0 (  402 714 1512 6 rtsel rtnpage ));
-DATA(insert OID = 0 (  402 714 1511 7 rtsel rtnpage ));
-DATA(insert OID = 0 (  402 714 1510 8 rtsel rtnpage ));
+DATA(insert OID = 0 (  402 714 1506 1 ));
+DATA(insert OID = 0 (  402 714 1507 2 ));
+DATA(insert OID = 0 (  402 714 1513 3 ));
+DATA(insert OID = 0 (  402 714 1508 4 ));
+DATA(insert OID = 0 (  402 714 1509 5 ));
+DATA(insert OID = 0 (  402 714 1512 6 ));
+DATA(insert OID = 0 (  402 714 1511 7 ));
+DATA(insert OID = 0 (  402 714 1510 8 ));
 
 /*
  *	nbtree int2_ops
  */
 
-DATA(insert OID = 0 (  403 421	95 1 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 421 522 2 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 421	94 3 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 421 524 4 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 421 520 5 btreesel btreenpage ));
+DATA(insert OID = 0 (  403 421	95 1 ));
+DATA(insert OID = 0 (  403 421 522 2 ));
+DATA(insert OID = 0 (  403 421	94 3 ));
+DATA(insert OID = 0 (  403 421 524 4 ));
+DATA(insert OID = 0 (  403 421 520 5 ));
 
 /*
  *	nbtree float8_ops
  */
 
-DATA(insert OID = 0 (  403 423 672 1 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 423 673 2 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 423 670 3 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 423 675 4 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 423 674 5 btreesel btreenpage ));
+DATA(insert OID = 0 (  403 423 672 1 ));
+DATA(insert OID = 0 (  403 423 673 2 ));
+DATA(insert OID = 0 (  403 423 670 3 ));
+DATA(insert OID = 0 (  403 423 675 4 ));
+DATA(insert OID = 0 (  403 423 674 5 ));
 
 /*
  *	nbtree int24_ops
  */
 
-DATA(insert OID = 0 (  403 424 534 1 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 424 540 2 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 424 532 3 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 424 542 4 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 424 536 5 btreesel btreenpage ));
+DATA(insert OID = 0 (  403 424 534 1 ));
+DATA(insert OID = 0 (  403 424 540 2 ));
+DATA(insert OID = 0 (  403 424 532 3 ));
+DATA(insert OID = 0 (  403 424 542 4 ));
+DATA(insert OID = 0 (  403 424 536 5 ));
 
 /*
  *	nbtree int42_ops
  */
 
-DATA(insert OID = 0 (  403 425 535 1 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 425 541 2 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 425 533 3 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 425 543 4 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 425 537 5 btreesel btreenpage ));
+DATA(insert OID = 0 (  403 425 535 1 ));
+DATA(insert OID = 0 (  403 425 541 2 ));
+DATA(insert OID = 0 (  403 425 533 3 ));
+DATA(insert OID = 0 (  403 425 543 4 ));
+DATA(insert OID = 0 (  403 425 537 5 ));
 
 /*
  *	nbtree int4_ops
  */
 
-DATA(insert OID = 0 (  403 426	97 1 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 426 523 2 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 426	96 3 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 426 525 4 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 426 521 5 btreesel btreenpage ));
+DATA(insert OID = 0 (  403 426	97 1 ));
+DATA(insert OID = 0 (  403 426 523 2 ));
+DATA(insert OID = 0 (  403 426	96 3 ));
+DATA(insert OID = 0 (  403 426 525 4 ));
+DATA(insert OID = 0 (  403 426 521 5 ));
 
 /*
  *	nbtree int8_ops
  */
 
-DATA(insert OID = 0 (  403 754 412 1 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 754 414 2 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 754 410 3 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 754 415 4 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 754 413 5 btreesel btreenpage ));
+DATA(insert OID = 0 (  403 754 412 1 ));
+DATA(insert OID = 0 (  403 754 414 2 ));
+DATA(insert OID = 0 (  403 754 410 3 ));
+DATA(insert OID = 0 (  403 754 415 4 ));
+DATA(insert OID = 0 (  403 754 413 5 ));
 
 /*
  *	nbtree oid_ops
  */
 
-DATA(insert OID = 0 (  403 427 609 1 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 427 611 2 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 427 607 3 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 427 612 4 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 427 610 5 btreesel btreenpage ));
+DATA(insert OID = 0 (  403 427 609 1 ));
+DATA(insert OID = 0 (  403 427 611 2 ));
+DATA(insert OID = 0 (  403 427 607 3 ));
+DATA(insert OID = 0 (  403 427 612 4 ));
+DATA(insert OID = 0 (  403 427 610 5 ));
 
 /*
  *	nbtree oidvector_ops
  */
 
-DATA(insert OID = 0 (  403 435	645 1 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 435	647 2 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 435	649 3 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 435	648 4 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 435	646 5 btreesel btreenpage ));
+DATA(insert OID = 0 (  403 435	645 1 ));
+DATA(insert OID = 0 (  403 435	647 2 ));
+DATA(insert OID = 0 (  403 435	649 3 ));
+DATA(insert OID = 0 (  403 435	648 4 ));
+DATA(insert OID = 0 (  403 435	646 5 ));
 
 /*
  *	nbtree float4_ops
  */
 
-DATA(insert OID = 0 (  403 428 622 1 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 428 624 2 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 428 620 3 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 428 625 4 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 428 623 5 btreesel btreenpage ));
+DATA(insert OID = 0 (  403 428 622 1 ));
+DATA(insert OID = 0 (  403 428 624 2 ));
+DATA(insert OID = 0 (  403 428 620 3 ));
+DATA(insert OID = 0 (  403 428 625 4 ));
+DATA(insert OID = 0 (  403 428 623 5 ));
 
 /*
  *	nbtree char_ops
  */
 
-DATA(insert OID = 0 (  403 429 631 1 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 429 632 2 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 429 92 3 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 429 634 4 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 429 633 5 btreesel btreenpage ));
+DATA(insert OID = 0 (  403 429 631 1 ));
+DATA(insert OID = 0 (  403 429 632 2 ));
+DATA(insert OID = 0 (  403 429 92 3 ));
+DATA(insert OID = 0 (  403 429 634 4 ));
+DATA(insert OID = 0 (  403 429 633 5 ));
 
 /*
  *	nbtree name_ops
  */
 
-DATA(insert OID = 0 (  403 1181 660 1 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 1181 661 2 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 1181 93 3 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 1181 663 4 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 1181 662 5 btreesel btreenpage ));
+DATA(insert OID = 0 (  403 1181 660 1 ));
+DATA(insert OID = 0 (  403 1181 661 2 ));
+DATA(insert OID = 0 (  403 1181 93 3 ));
+DATA(insert OID = 0 (  403 1181 663 4 ));
+DATA(insert OID = 0 (  403 1181 662 5 ));
 
 /*
  *	nbtree text_ops
  */
 
-DATA(insert OID = 0 (  403 431 664 1 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 431 665 2 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 431 98 3 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 431 667 4 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 431 666 5 btreesel btreenpage ));
+DATA(insert OID = 0 (  403 431 664 1 ));
+DATA(insert OID = 0 (  403 431 665 2 ));
+DATA(insert OID = 0 (  403 431 98 3 ));
+DATA(insert OID = 0 (  403 431 667 4 ));
+DATA(insert OID = 0 (  403 431 666 5 ));
 
 /*
  *	nbtree abstime_ops
  */
 
-DATA(insert OID = 0 (  403 432 562 1 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 432 564 2 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 432 560 3 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 432 565 4 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 432 563 5 btreesel btreenpage ));
+DATA(insert OID = 0 (  403 432 562 1 ));
+DATA(insert OID = 0 (  403 432 564 2 ));
+DATA(insert OID = 0 (  403 432 560 3 ));
+DATA(insert OID = 0 (  403 432 565 4 ));
+DATA(insert OID = 0 (  403 432 563 5 ));
 
 /*
  *	nbtree bpchar_ops
  */
 
-DATA(insert OID = 0 (  403 1076 1058 1 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 1076 1059 2 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 1076 1054 3 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 1076 1061 4 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 1076 1060 5 btreesel btreenpage ));
+DATA(insert OID = 0 (  403 1076 1058 1 ));
+DATA(insert OID = 0 (  403 1076 1059 2 ));
+DATA(insert OID = 0 (  403 1076 1054 3 ));
+DATA(insert OID = 0 (  403 1076 1061 4 ));
+DATA(insert OID = 0 (  403 1076 1060 5 ));
 
 /*
  *	nbtree varchar_ops
  */
 
-DATA(insert OID = 0 (  403 1077 1066 1 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 1077 1067 2 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 1077 1062 3 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 1077 1069 4 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 1077 1068 5 btreesel btreenpage ));
+DATA(insert OID = 0 (  403 1077 1066 1 ));
+DATA(insert OID = 0 (  403 1077 1067 2 ));
+DATA(insert OID = 0 (  403 1077 1062 3 ));
+DATA(insert OID = 0 (  403 1077 1069 4 ));
+DATA(insert OID = 0 (  403 1077 1068 5 ));
 
 /*
  *	nbtree date_ops
  */
 
-DATA(insert OID = 0 (  403 1114 1095 1 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 1114 1096 2 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 1114 1093 3 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 1114 1098 4 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 1114 1097 5 btreesel btreenpage ));
+DATA(insert OID = 0 (  403 1114 1095 1 ));
+DATA(insert OID = 0 (  403 1114 1096 2 ));
+DATA(insert OID = 0 (  403 1114 1093 3 ));
+DATA(insert OID = 0 (  403 1114 1098 4 ));
+DATA(insert OID = 0 (  403 1114 1097 5 ));
 
 
 /*
  *	nbtree time_ops
  */
 
-DATA(insert OID = 0 (  403 1115 1110 1 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 1115 1111 2 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 1115 1108 3 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 1115 1113 4 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 1115 1112 5 btreesel btreenpage ));
+DATA(insert OID = 0 (  403 1115 1110 1 ));
+DATA(insert OID = 0 (  403 1115 1111 2 ));
+DATA(insert OID = 0 (  403 1115 1108 3 ));
+DATA(insert OID = 0 (  403 1115 1113 4 ));
+DATA(insert OID = 0 (  403 1115 1112 5 ));
 
 /*
  *	nbtree datetime_ops
  */
 
-DATA(insert OID = 0 (  403 1312 1322 1 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 1312 1323 2 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 1312 1320 3 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 1312 1325 4 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 1312 1324 5 btreesel btreenpage ));
+DATA(insert OID = 0 (  403 1312 1322 1 ));
+DATA(insert OID = 0 (  403 1312 1323 2 ));
+DATA(insert OID = 0 (  403 1312 1320 3 ));
+DATA(insert OID = 0 (  403 1312 1325 4 ));
+DATA(insert OID = 0 (  403 1312 1324 5 ));
 
 /*
  *	nbtree timespan_ops
  */
 
-DATA(insert OID = 0 (  403 1313 1332 1 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 1313 1333 2 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 1313 1330 3 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 1313 1335 4 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 1313 1334 5 btreesel btreenpage ));
+DATA(insert OID = 0 (  403 1313 1332 1 ));
+DATA(insert OID = 0 (  403 1313 1333 2 ));
+DATA(insert OID = 0 (  403 1313 1330 3 ));
+DATA(insert OID = 0 (  403 1313 1335 4 ));
+DATA(insert OID = 0 (  403 1313 1334 5 ));
 
 /*
  *	nbtree macaddr
  */
 
-DATA(insert OID = 0 (  403 810 1222 1 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 810 1223 2 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 810 1220 3 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 810 1225 4 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 810 1224 5 btreesel btreenpage ));
+DATA(insert OID = 0 (  403 810 1222 1 ));
+DATA(insert OID = 0 (  403 810 1223 2 ));
+DATA(insert OID = 0 (  403 810 1220 3 ));
+DATA(insert OID = 0 (  403 810 1225 4 ));
+DATA(insert OID = 0 (  403 810 1224 5 ));
 
 /*
  *	nbtree inet
  */
 
-DATA(insert OID = 0 (  403 935 1203 1 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 935 1204 2 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 935 1201 3 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 935 1206 4 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 935 1205 5 btreesel btreenpage ));
+DATA(insert OID = 0 (  403 935 1203 1 ));
+DATA(insert OID = 0 (  403 935 1204 2 ));
+DATA(insert OID = 0 (  403 935 1201 3 ));
+DATA(insert OID = 0 (  403 935 1206 4 ));
+DATA(insert OID = 0 (  403 935 1205 5 ));
 
 /*
  *	nbtree cidr
  */
 
-DATA(insert OID = 0 (  403 652 822 1 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 652 823 2 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 652 820 3 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 652 825 4 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 652 824 5 btreesel btreenpage ));
+DATA(insert OID = 0 (  403 652 822 1 ));
+DATA(insert OID = 0 (  403 652 823 2 ));
+DATA(insert OID = 0 (  403 652 820 3 ));
+DATA(insert OID = 0 (  403 652 825 4 ));
+DATA(insert OID = 0 (  403 652 824 5 ));
 
 /*
  *	nbtree numeric
  */
 
-DATA(insert OID = 0 (  403 1768 1754 1 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 1768 1755 2 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 1768 1752 3 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 1768 1757 4 btreesel btreenpage ));
-DATA(insert OID = 0 (  403 1768 1756 5 btreesel btreenpage ));
+DATA(insert OID = 0 (  403 1768 1754 1 ));
+DATA(insert OID = 0 (  403 1768 1755 2 ));
+DATA(insert OID = 0 (  403 1768 1752 3 ));
+DATA(insert OID = 0 (  403 1768 1757 4 ));
+DATA(insert OID = 0 (  403 1768 1756 5 ));
 
 /*
  *	hash table _ops
  */
 
 /* int2_ops */
-DATA(insert OID = 0 (  405	421   94 1 hashsel hashnpage ));
+DATA(insert OID = 0 (  405	421   94 1 ));
 /* float8_ops */
-DATA(insert OID = 0 (  405	423  670 1 hashsel hashnpage ));
+DATA(insert OID = 0 (  405	423  670 1 ));
 /* int4_ops */
-DATA(insert OID = 0 (  405	426   96 1 hashsel hashnpage ));
+DATA(insert OID = 0 (  405	426   96 1 ));
 /* int8_ops */
-DATA(insert OID = 0 (  405	754  410 1 hashsel hashnpage ));
+DATA(insert OID = 0 (  405	754  410 1 ));
 /* oid_ops */
-DATA(insert OID = 0 (  405	427  607 1 hashsel hashnpage ));
+DATA(insert OID = 0 (  405	427  607 1 ));
 /* oidvector_ops */
-DATA(insert OID = 0 (  405	435  649 1 hashsel hashnpage ));
+DATA(insert OID = 0 (  405	435  649 1 ));
 /* float4_ops */
-DATA(insert OID = 0 (  405	428  620 1 hashsel hashnpage ));
+DATA(insert OID = 0 (  405	428  620 1 ));
 /* char_ops */
-DATA(insert OID = 0 (  405	429   92 1 hashsel hashnpage ));
+DATA(insert OID = 0 (  405	429   92 1 ));
 /* name_ops */
-DATA(insert OID = 0 (  405 1181   93 1 hashsel hashnpage ));
+DATA(insert OID = 0 (  405 1181   93 1 ));
 /* text_ops */
-DATA(insert OID = 0 (  405	431   98 1 hashsel hashnpage ));
+DATA(insert OID = 0 (  405	431   98 1 ));
 /* bpchar_ops */
-DATA(insert OID = 0 (  405 1076 1054 1 hashsel hashnpage ));
+DATA(insert OID = 0 (  405 1076 1054 1 ));
 /* varchar_ops */
-DATA(insert OID = 0 (  405 1077 1062 1 hashsel hashnpage ));
+DATA(insert OID = 0 (  405 1077 1062 1 ));
 /* date_ops */
-DATA(insert OID = 0 (  405 1114 1093 1 hashsel hashnpage ));
+DATA(insert OID = 0 (  405 1114 1093 1 ));
 /* time_ops */
-DATA(insert OID = 0 (  405 1115 1108 1 hashsel hashnpage ));
+DATA(insert OID = 0 (  405 1115 1108 1 ));
 /* datetime_ops */
-DATA(insert OID = 0 (  405 1312 1320 1 hashsel hashnpage ));
+DATA(insert OID = 0 (  405 1312 1320 1 ));
 /* timespan_ops */
-DATA(insert OID = 0 (  405 1313 1330 1 hashsel hashnpage ));
+DATA(insert OID = 0 (  405 1313 1330 1 ));
 /* macaddr_ops */
-DATA(insert OID = 0 (  405 810 1220 1 hashsel hashnpage ));
+DATA(insert OID = 0 (  405 810 1220 1 ));
 /* inet_ops */
-DATA(insert OID = 0 (  405 935 1201 1 hashsel hashnpage ));
+DATA(insert OID = 0 (  405 935 1201 1 ));
 /* cidr_ops */
-DATA(insert OID = 0 (  405 652 820 1 hashsel hashnpage ));
+DATA(insert OID = 0 (  405 652 820 1 ));
 
 #endif	 /* PG_AMOP_H */
diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h
index 583d53e081fbc8a0b2a0361910d276e66d7be7fc..0fffcf3657ac97bb101480f46c240ad232d24f95 100644
--- a/src/include/catalog/pg_proc.h
+++ b/src/include/catalog/pg_proc.h
@@ -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 - ));
diff --git a/src/include/nodes/relation.h b/src/include/nodes/relation.h
index 55850cef5e15219677a3534e623e2c6fc59ec882..98fb51911109152373907c1e410ef078593df732 100644
--- a/src/include/nodes/relation.h
+++ b/src/include/nodes/relation.h
@@ -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;
diff --git a/src/include/optimizer/cost.h b/src/include/optimizer/cost.h
index c654b6953e75814a9b4fa7ff1495ec8834d0cf77..9c16fc8fea6ff510f3b86105385ddc1cd7930b4d 100644
--- a/src/include/optimizer/cost.h
+++ b/src/include/optimizer/cost.h
@@ -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,
diff --git a/src/include/optimizer/internal.h b/src/include/optimizer/internal.h
index 14051ca81ae8934e181deb0d9b22c07900f94ef8..e89b244a3973fe622e8677888516ef3ae15a3b8a 100644
--- a/src/include/optimizer/internal.h
+++ b/src/include/optimizer/internal.h
@@ -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 */
diff --git a/src/include/optimizer/paths.h b/src/include/optimizer/paths.h
index a3f6bad36be6b82e878b42aa5af3f0ddd61d9071..1556941c4b95abf7de9fec2917dc89583aacf15a 100644
--- a/src/include/optimizer/paths.h
+++ b/src/include/optimizer/paths.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);
 
 /*
diff --git a/src/include/optimizer/plancat.h b/src/include/optimizer/plancat.h
index 307b51c3f4280a98ef9eb7b4b5cbcd5fec7646ee..024cfd6999e3271cb4e6b79711a294e663ed62d8 100644
--- a/src/include/optimizer/plancat.h
+++ b/src/include/optimizer/plancat.h
@@ -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);
diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h
index 1be8ee549521cb7e6a24e3d3467bde49d4fdb5c0..ae6e3daf62d6cf010566e135c63ee12bd92e23a4 100644
--- a/src/include/utils/builtins.h
+++ b/src/include/utils/builtins.h
@@ -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);
diff --git a/src/test/regress/sql/opr_sanity.sql b/src/test/regress/sql/opr_sanity.sql
index 9964f5c1e12ced383951249ce853f15f4baf16af..e378171fd870cf5c5c2a4669113a5a047c3492be 100644
--- a/src/test/regress/sql/opr_sanity.sql
+++ b/src/test/regress/sql/opr_sanity.sql
@@ -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
diff --git a/src/tutorial/complex.source b/src/tutorial/complex.source
index bae3192198b76fc26dec765f65e60cbb4c137a30..847ec1a21884feeb24866db0a60c2b1d99722099 100644
--- a/src/tutorial/complex.source
+++ b/src/tutorial/complex.source
@@ -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 = '>';