Simplify pg_am representation of ordering-capable access methods:
authorTom Lane <tgl@sss.pgh.pa.us>
Sat, 20 Jan 2007 23:13:01 +0000 (23:13 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Sat, 20 Jan 2007 23:13:01 +0000 (23:13 +0000)
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).

doc/src/sgml/catalogs.sgml
doc/src/sgml/indexam.sgml
doc/src/sgml/xindex.sgml
src/backend/commands/indexcmds.c
src/backend/optimizer/util/plancat.c
src/backend/utils/adt/ruleutils.c
src/include/catalog/catversion.h
src/include/catalog/pg_am.h

index 8a22a7b81249d10923626bb3b7da9faf6ef9c936..0911ae15b46b6a18c6c183c422635a507c99a35f 100644 (file)
@@ -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
  -->
      </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>
index 658cdd709666270dd7e9adc72de613ab3cf4a847..f8f3f1cc76cb57ef286bb1ae7c78f3f75d22cec1 100644 (file)
@@ -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>
index a95c8e7ac04881492b25b10852bb1a8275212dbc..8fbea2cf7c0e24b35f90b5ac1ccd143cd319717c 100644 (file)
@@ -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>
    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">
index bbaa34f758a5d818f3191bed83eb99fa9c6b4701..2d51dfb11febd2e88a3d8d87943c92d87b65f889 100644 (file)
@@ -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);
index 9150f1d936f657019613b089c7da6a1e57570583..e52943a675e08ef36ce7f32bc52471fc9392b114 100644 (file)
@@ -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)
index 757077afe47b245c498253c9730cf323b232dcba..baef0100073a6902edf09caa6b473ae1fd02ec06 100644 (file)
@@ -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)
index 7e2b19cc9e895d2f50bacd80c7b003f4c45f21f2..0a561ac5dd60d3dbe4889c1d313c1eacc1d06e00 100644 (file)
@@ -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
index 80aad73130281a6eb95cd719b4792c84f38c7ca5..76f940a351641a5794df9da9b0e8f7601bc75b6e 100644 (file)
@@ -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