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 @@ - + @@ -365,21 +365,10 @@ - amorderstrategy - int2 + amcanorder + bool - Zero if the index offers no sort order, otherwise the strategy - number of the strategy operator that describes the default - (ASC) sort order - - - - amdescorder - int2 - - Zero if the index offers no sort order, otherwise the strategy - number of the strategy operator that describes the DESC - sort order + Does the access method support ordered scans? 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 @@ - + Index Access Method Interface Definition @@ -442,6 +442,15 @@ amrestrpos (IndexScanDesc scan); the scan keys to a normalized form. + + 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 pg_am.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. + + The amgettuple function has a direction argument, which can be either ForwardScanDirection (the normal case) @@ -451,8 +460,7 @@ amrestrpos (IndexScanDesc scan); the normal front-to-back direction, so 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 - pg_am.amorderstrategy nonzero.) After the + methods that advertise they support ordered scans.) After the first call, amgettuple must be prepared to advance the scan in either direction from the most recently returned entry. 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 @@ - + Interfacing Extensions To Indexes @@ -287,20 +287,6 @@ return type boolean, since they must appear at the top level of a WHERE clause to be used with an index. - - - By the way, the amorderstrategy and - amdescorder columns in pg_am tell - whether the index method supports ordered scans. Zeroes mean it doesn't; - if it does, amorderstrategy is the strategy - number that corresponds to the default ordering operator, and - amdescorder is the strategy number for the - ordering operator of an index column that has the DESC option. - For example, B-tree has amorderstrategy = 1, - which is its less than strategy number, and - amdescorder = 5, which is its - greater than strategy number. - 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