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).
This commit is contained in:
Tom Lane 2007-01-20 23:13:01 +00:00
parent c82cc604f5
commit fcf4b146c6
8 changed files with 58 additions and 80 deletions

View 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
-->
@ -365,21 +365,10 @@
</row>
<row>
<entry><structfield>amorderstrategy</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 default
(<literal>ASC</>) sort order</entry>
</row>
<row>
<entry><structfield>amdescorder</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 <literal>DESC</>
sort order</entry>
<entry>Does the access method support ordered scans?</entry>
</row>
<row>

View 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>

View 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>
@ -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">

View 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);

View 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)

View 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)

View 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

View 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