From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Sat, 20 Jan 2007 23:13:01 +0000 (+0000)
Subject: Simplify pg_am representation of ordering-capable access methods:
X-Git-Tag: REL8_3_BETA1~1471
X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=fcf4b146c697624a1b322def06db6b6aa1f1f481;p=postgresql

Simplify pg_am representation of ordering-capable access methods:
provide just a boolean 'amcanorder', instead of fields that specify the
sort operator strategy numbers.  We have decided to require ordering-capable
AMs to use btree-compatible strategy numbers, so the old fields are
overkill (and indeed misleading about what's allowed).
---

diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml
index 8a22a7b812..0911ae15b4 100644
--- a/doc/src/sgml/catalogs.sgml
+++ b/doc/src/sgml/catalogs.sgml
@@ -1,4 +1,4 @@
-<!-- $PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.141 2007/01/09 02:14:09 tgl Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.142 2007/01/20 23:13:01 tgl Exp $ -->
 <!--
  Documentation of the system catalogs, directed toward PostgreSQL developers
  -->
@@ -365,21 +365,10 @@
      </row>
 
      <row>
-      <entry><structfield>amorderstrategy</structfield></entry>
-      <entry><type>int2</type></entry>
-      <entry></entry>
-      <entry>Zero if the index offers no sort order, otherwise the strategy
-      number of the strategy operator that describes the default
-      (<literal>ASC</>) sort order</entry>
-     </row>
-
-     <row>
-      <entry><structfield>amdescorder</structfield></entry>
-      <entry><type>int2</type></entry>
+      <entry><structfield>amcanorder</structfield></entry>
+      <entry><type>bool</type></entry>
       <entry></entry>
-      <entry>Zero if the index offers no sort order, otherwise the strategy
-      number of the strategy operator that describes the <literal>DESC</>
-      sort order</entry>
+      <entry>Does the access method support ordered scans?</entry>
      </row>
 
      <row>
diff --git a/doc/src/sgml/indexam.sgml b/doc/src/sgml/indexam.sgml
index 658cdd7096..f8f3f1cc76 100644
--- a/doc/src/sgml/indexam.sgml
+++ b/doc/src/sgml/indexam.sgml
@@ -1,4 +1,4 @@
-<!-- $PostgreSQL: pgsql/doc/src/sgml/indexam.sgml,v 2.19 2006/12/23 00:43:08 tgl Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/indexam.sgml,v 2.20 2007/01/20 23:13:01 tgl Exp $ -->
 
 <chapter id="indexam">
  <title>Index Access Method Interface Definition</title>
@@ -442,6 +442,15 @@ amrestrpos (IndexScanDesc scan);
    the scan keys to a <quote>normalized</> form.
   </para>
 
+  <para>
+   Some access methods return index entries in a well-defined order, others
+   do not.  If entries are returned in sorted order, the access method should
+   set <structname>pg_am</>.<structfield>amcanorder</> true to indicate that
+   it supports ordered scans.
+   All such access methods must use btree-compatible strategy numbers for
+   their equality and ordering operators.
+  </para>
+
   <para>
    The <function>amgettuple</> function has a <literal>direction</> argument,
    which can be either <literal>ForwardScanDirection</> (the normal case)
@@ -451,8 +460,7 @@ amrestrpos (IndexScanDesc scan);
    the normal front-to-back direction, so <function>amgettuple</> must return
    the last matching tuple in the index, rather than the first one as it
    normally would.  (This will only occur for access
-   methods that advertise they support ordered scans by setting
-   <structname>pg_am</>.<structfield>amorderstrategy</> nonzero.)  After the
+   methods that advertise they support ordered scans.)  After the
    first call, <function>amgettuple</> must be prepared to advance the scan in
    either direction from the most recently returned entry.
   </para>
diff --git a/doc/src/sgml/xindex.sgml b/doc/src/sgml/xindex.sgml
index a95c8e7ac0..8fbea2cf7c 100644
--- a/doc/src/sgml/xindex.sgml
+++ b/doc/src/sgml/xindex.sgml
@@ -1,4 +1,4 @@
-<!-- $PostgreSQL: pgsql/doc/src/sgml/xindex.sgml,v 1.54 2007/01/09 02:14:10 tgl Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/xindex.sgml,v 1.55 2007/01/20 23:13:01 tgl Exp $ -->
 
 <sect1 id="xindex">
  <title>Interfacing Extensions To Indexes</title>
@@ -287,20 +287,6 @@
    return type <type>boolean</type>, since they must appear at the top
    level of a <literal>WHERE</> clause to be used with an index.
   </para>
-
-  <para>
-   By the way, the <structfield>amorderstrategy</structfield> and
-   <structfield>amdescorder</structfield> columns in <classname>pg_am</> tell
-   whether the index method supports ordered scans.  Zeroes mean it doesn't;
-   if it does, <structfield>amorderstrategy</structfield> is the strategy
-   number that corresponds to the default ordering operator, and
-   <structfield>amdescorder</structfield> is the strategy number for the
-   ordering operator of an index column that has the <literal>DESC</> option.
-   For example, B-tree has <structfield>amorderstrategy</structfield> = 1,
-   which is its <quote>less than</quote> strategy number, and
-   <structfield>amdescorder</structfield> = 5, which is its
-   <quote>greater than</quote> strategy number.
-  </para>
  </sect2>
 
  <sect2 id="xindex-support">
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index bbaa34f758..2d51dfb11f 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/commands/indexcmds.c,v 1.152 2007/01/09 02:14:11 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/commands/indexcmds.c,v 1.153 2007/01/20 23:13:01 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -295,8 +295,7 @@ DefineIndex(RangeVar *heapRelation,
 		  errmsg("access method \"%s\" does not support multicolumn indexes",
 				 accessMethodName)));
 
-	amcanorder = (accessMethodForm->amorderstrategy > 0);
-
+	amcanorder = accessMethodForm->amcanorder;
 	amoptions = accessMethodForm->amoptions;
 
 	ReleaseSysCache(tuple);
diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c
index 9150f1d936..e52943a675 100644
--- a/src/backend/optimizer/util/plancat.c
+++ b/src/backend/optimizer/util/plancat.c
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/optimizer/util/plancat.c,v 1.131 2007/01/09 02:14:13 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/optimizer/util/plancat.c,v 1.132 2007/01/20 23:13:01 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -190,8 +190,10 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent,
 
 			/*
 			 * Fetch the ordering operators associated with the index, if any.
+			 * We expect that all ordering-capable indexes use btree's
+			 * strategy numbers for the ordering operators.
 			 */
-			if (indexRelation->rd_am->amorderstrategy > 0)
+			if (indexRelation->rd_am->amcanorder)
 			{
 				int			nstrat = indexRelation->rd_am->amstrategies;
 
@@ -203,17 +205,17 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent,
 
 					if (opt & INDOPTION_DESC)
 					{
-						fwdstrat = indexRelation->rd_am->amdescorder;
-						revstrat = indexRelation->rd_am->amorderstrategy;
+						fwdstrat = BTGreaterStrategyNumber;
+						revstrat = BTLessStrategyNumber;
 					}
 					else
 					{
-						fwdstrat = indexRelation->rd_am->amorderstrategy;
-						revstrat = indexRelation->rd_am->amdescorder;
+						fwdstrat = BTLessStrategyNumber;
+						revstrat = BTGreaterStrategyNumber;
 					}
 					/*
 					 * Index AM must have a fixed set of strategies for it
-					 * to make sense to specify amorderstrategy, so we
+					 * to make sense to specify amcanorder, so we
 					 * need not allow the case amstrategies == 0.
 					 */
 					if (fwdstrat > 0)
diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c
index 757077afe4..baef010007 100644
--- a/src/backend/utils/adt/ruleutils.c
+++ b/src/backend/utils/adt/ruleutils.c
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.244 2007/01/20 01:08:42 neilc Exp $
+ *	  $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.245 2007/01/20 23:13:01 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -767,7 +767,7 @@ pg_get_indexdef_worker(Oid indexrelid, int colno, int prettyFlags)
 							 &buf);
 
 		/* Add options if relevant */
-		if (amrec->amorderstrategy > 0)
+		if (amrec->amcanorder)
 		{
 			/* if it supports sort ordering, report DESC and NULLS opts */
 			if (opt & INDOPTION_DESC)
diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h
index 7e2b19cc9e..0a561ac5dd 100644
--- a/src/include/catalog/catversion.h
+++ b/src/include/catalog/catversion.h
@@ -37,7 +37,7 @@
  * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.374 2007/01/20 21:47:10 neilc Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.375 2007/01/20 23:13:01 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -53,6 +53,6 @@
  */
 
 /*							yyyymmddN */
-#define CATALOG_VERSION_NO	200701202
+#define CATALOG_VERSION_NO	200701203
 
 #endif
diff --git a/src/include/catalog/pg_am.h b/src/include/catalog/pg_am.h
index 80aad73130..76f940a351 100644
--- a/src/include/catalog/pg_am.h
+++ b/src/include/catalog/pg_am.h
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/catalog/pg_am.h,v 1.49 2007/01/09 02:14:15 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_am.h,v 1.50 2007/01/20 23:13:01 tgl Exp $
  *
  * NOTES
  *		the genbki.sh script reads this file and generates .bki
@@ -45,12 +45,7 @@ CATALOG(pg_am,2601)
 								 * strategy assignments. */
 	int2		amsupport;		/* total number of support functions that this
 								 * AM uses */
-	int2		amorderstrategy;/* if this AM has a sort order, the strategy
-								 * number of the default (ASC) sort operator.
-								 * Zero if AM is not ordered. */
-	int2		amdescorder;	/* if this AM has a sort order, the strategy
-								 * number of the DESC sort operator.
-								 * Zero if AM is not ordered. */
+	bool		amcanorder;		/* does AM support ordered scan results? */
 	bool		amcanunique;	/* does AM support UNIQUE indexes? */
 	bool		amcanmulticol;	/* does AM support multi-column indexes? */
 	bool		amoptionalkey;	/* can query omit key for the first column? */
@@ -83,47 +78,46 @@ typedef FormData_pg_am *Form_pg_am;
  *		compiler constants for pg_am
  * ----------------
  */
-#define Natts_pg_am						24
+#define Natts_pg_am						23
 #define Anum_pg_am_amname				1
 #define Anum_pg_am_amstrategies			2
 #define Anum_pg_am_amsupport			3
-#define Anum_pg_am_amorderstrategy		4
-#define Anum_pg_am_amdescorder			5
-#define Anum_pg_am_amcanunique			6
-#define Anum_pg_am_amcanmulticol		7
-#define Anum_pg_am_amoptionalkey		8
-#define Anum_pg_am_amindexnulls			9
-#define Anum_pg_am_amstorage			10
-#define Anum_pg_am_amclusterable		11
-#define Anum_pg_am_aminsert				12
-#define Anum_pg_am_ambeginscan			13
-#define Anum_pg_am_amgettuple			14
-#define Anum_pg_am_amgetmulti			15
-#define Anum_pg_am_amrescan				16
-#define Anum_pg_am_amendscan			17
-#define Anum_pg_am_ammarkpos			18
-#define Anum_pg_am_amrestrpos			19
-#define Anum_pg_am_ambuild				20
-#define Anum_pg_am_ambulkdelete			21
-#define Anum_pg_am_amvacuumcleanup		22
-#define Anum_pg_am_amcostestimate		23
-#define Anum_pg_am_amoptions			24
+#define Anum_pg_am_amcanorder			4
+#define Anum_pg_am_amcanunique			5
+#define Anum_pg_am_amcanmulticol		6
+#define Anum_pg_am_amoptionalkey		7
+#define Anum_pg_am_amindexnulls			8
+#define Anum_pg_am_amstorage			9
+#define Anum_pg_am_amclusterable		10
+#define Anum_pg_am_aminsert				11
+#define Anum_pg_am_ambeginscan			12
+#define Anum_pg_am_amgettuple			13
+#define Anum_pg_am_amgetmulti			14
+#define Anum_pg_am_amrescan				15
+#define Anum_pg_am_amendscan			16
+#define Anum_pg_am_ammarkpos			17
+#define Anum_pg_am_amrestrpos			18
+#define Anum_pg_am_ambuild				19
+#define Anum_pg_am_ambulkdelete			20
+#define Anum_pg_am_amvacuumcleanup		21
+#define Anum_pg_am_amcostestimate		22
+#define Anum_pg_am_amoptions			23
 
 /* ----------------
  *		initial contents of pg_am
  * ----------------
  */
 
-DATA(insert OID = 403 (  btree	5 1 1 5 t t t t f t btinsert btbeginscan btgettuple btgetmulti btrescan btendscan btmarkpos btrestrpos btbuild btbulkdelete btvacuumcleanup btcostestimate btoptions ));
+DATA(insert OID = 403 (  btree	5 1 t t t t t f t btinsert btbeginscan btgettuple btgetmulti btrescan btendscan btmarkpos btrestrpos btbuild btbulkdelete btvacuumcleanup btcostestimate btoptions ));
 DESCR("b-tree index access method");
 #define BTREE_AM_OID 403
-DATA(insert OID = 405 (  hash	1 1 0 0 f f f f f f hashinsert hashbeginscan hashgettuple hashgetmulti hashrescan hashendscan hashmarkpos hashrestrpos hashbuild hashbulkdelete hashvacuumcleanup hashcostestimate hashoptions ));
+DATA(insert OID = 405 (  hash	1 1 f f f f f f f hashinsert hashbeginscan hashgettuple hashgetmulti hashrescan hashendscan hashmarkpos hashrestrpos hashbuild hashbulkdelete hashvacuumcleanup hashcostestimate hashoptions ));
 DESCR("hash index access method");
 #define HASH_AM_OID 405
-DATA(insert OID = 783 (  gist	0 7 0 0 f t t t t t gistinsert gistbeginscan gistgettuple gistgetmulti gistrescan gistendscan gistmarkpos gistrestrpos gistbuild gistbulkdelete gistvacuumcleanup gistcostestimate gistoptions ));
+DATA(insert OID = 783 (  gist	0 7 f f t t t t t gistinsert gistbeginscan gistgettuple gistgetmulti gistrescan gistendscan gistmarkpos gistrestrpos gistbuild gistbulkdelete gistvacuumcleanup gistcostestimate gistoptions ));
 DESCR("GiST index access method");
 #define GIST_AM_OID 783
-DATA(insert OID = 2742 (  gin	0 4 0 0 f f f f t f gininsert ginbeginscan gingettuple gingetmulti ginrescan ginendscan ginmarkpos ginrestrpos ginbuild ginbulkdelete ginvacuumcleanup gincostestimate ginoptions ));
+DATA(insert OID = 2742 (  gin	0 4 f f f f f t f gininsert ginbeginscan gingettuple gingetmulti ginrescan ginendscan ginmarkpos ginrestrpos ginbuild ginbulkdelete ginvacuumcleanup gincostestimate ginoptions ));
 DESCR("GIN index access method");
 #define GIN_AM_OID 2742