Commit 93b4f0ff authored by Tom Lane's avatar Tom Lane

Set pg_am.amstrategies to zero for index AMs that don't have fixed

operator strategy numbers, ie, GiST and GIN.  This is almost cosmetic
enough to not need a catversion bump, but since the opr_sanity regression
test has to change in sync with the catalog entry, I figured I'd better
do one.
parent 6b4fe046
<!-- $PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.137 2006/11/12 06:25:37 neilc Exp $ --> <!-- $PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.138 2006/12/18 18:56:28 tgl Exp $ -->
<!-- <!--
Documentation of the system catalogs, directed toward PostgreSQL developers Documentation of the system catalogs, directed toward PostgreSQL developers
--> -->
...@@ -347,7 +347,9 @@ ...@@ -347,7 +347,9 @@
<entry><structfield>amstrategies</structfield></entry> <entry><structfield>amstrategies</structfield></entry>
<entry><type>int2</type></entry> <entry><type>int2</type></entry>
<entry></entry> <entry></entry>
<entry>Number of operator strategies for this access method</entry> <entry>Number of operator strategies for this access method,
or zero if access method does not have a fixed set of operator
strategies</entry>
</row> </row>
<row> <row>
......
...@@ -9,12 +9,14 @@ ...@@ -9,12 +9,14 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/opclasscmds.c,v 1.49 2006/10/04 00:29:51 momjian Exp $ * $PostgreSQL: pgsql/src/backend/commands/opclasscmds.c,v 1.50 2006/12/18 18:56:28 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
#include "postgres.h" #include "postgres.h"
#include <limits.h>
#include "access/genam.h" #include "access/genam.h"
#include "access/heapam.h" #include "access/heapam.h"
#include "catalog/dependency.h" #include "catalog/dependency.h"
...@@ -73,8 +75,8 @@ DefineOpClass(CreateOpClassStmt *stmt) ...@@ -73,8 +75,8 @@ DefineOpClass(CreateOpClassStmt *stmt)
storageoid, /* storage datatype oid, if any */ storageoid, /* storage datatype oid, if any */
namespaceoid, /* namespace to create opclass in */ namespaceoid, /* namespace to create opclass in */
opclassoid; /* oid of opclass we create */ opclassoid; /* oid of opclass we create */
int numOperators, /* amstrategies value */ int maxOpNumber, /* amstrategies value */
numProcs; /* amsupport value */ maxProcNumber; /* amsupport value */
bool amstorage; /* amstorage flag */ bool amstorage; /* amstorage flag */
List *operators; /* OpClassMember list for operators */ List *operators; /* OpClassMember list for operators */
List *procedures; /* OpClassMember list for support procs */ List *procedures; /* OpClassMember list for support procs */
...@@ -112,8 +114,11 @@ DefineOpClass(CreateOpClassStmt *stmt) ...@@ -112,8 +114,11 @@ DefineOpClass(CreateOpClassStmt *stmt)
amoid = HeapTupleGetOid(tup); amoid = HeapTupleGetOid(tup);
pg_am = (Form_pg_am) GETSTRUCT(tup); pg_am = (Form_pg_am) GETSTRUCT(tup);
numOperators = pg_am->amstrategies; maxOpNumber = pg_am->amstrategies;
numProcs = pg_am->amsupport; /* if amstrategies is zero, just enforce that op numbers fit in int16 */
if (maxOpNumber <= 0)
maxOpNumber = SHRT_MAX;
maxProcNumber = pg_am->amsupport;
amstorage = pg_am->amstorage; amstorage = pg_am->amstorage;
/* XXX Should we make any privilege check against the AM? */ /* XXX Should we make any privilege check against the AM? */
...@@ -176,12 +181,12 @@ DefineOpClass(CreateOpClassStmt *stmt) ...@@ -176,12 +181,12 @@ DefineOpClass(CreateOpClassStmt *stmt)
switch (item->itemtype) switch (item->itemtype)
{ {
case OPCLASS_ITEM_OPERATOR: case OPCLASS_ITEM_OPERATOR:
if (item->number <= 0 || item->number > numOperators) if (item->number <= 0 || item->number > maxOpNumber)
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION), (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
errmsg("invalid operator number %d," errmsg("invalid operator number %d,"
" must be between 1 and %d", " must be between 1 and %d",
item->number, numOperators))); item->number, maxOpNumber)));
if (item->args != NIL) if (item->args != NIL)
{ {
TypeName *typeName1 = (TypeName *) linitial(item->args); TypeName *typeName1 = (TypeName *) linitial(item->args);
...@@ -220,12 +225,12 @@ DefineOpClass(CreateOpClassStmt *stmt) ...@@ -220,12 +225,12 @@ DefineOpClass(CreateOpClassStmt *stmt)
addClassMember(&operators, member, false); addClassMember(&operators, member, false);
break; break;
case OPCLASS_ITEM_FUNCTION: case OPCLASS_ITEM_FUNCTION:
if (item->number <= 0 || item->number > numProcs) if (item->number <= 0 || item->number > maxProcNumber)
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION), (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
errmsg("invalid procedure number %d," errmsg("invalid procedure number %d,"
" must be between 1 and %d", " must be between 1 and %d",
item->number, numProcs))); item->number, maxProcNumber)));
funcOid = LookupFuncNameTypeNames(item->name, item->args, funcOid = LookupFuncNameTypeNames(item->name, item->args,
false); false);
#ifdef NOT_USED #ifdef NOT_USED
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/optimizer/util/plancat.c,v 1.127 2006/10/04 00:29:55 momjian Exp $ * $PostgreSQL: pgsql/src/backend/optimizer/util/plancat.c,v 1.128 2006/12/18 18:56:28 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -190,10 +190,17 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, ...@@ -190,10 +190,17 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent,
* Fetch the ordering operators associated with the index, if any. * Fetch the ordering operators associated with the index, if any.
*/ */
amorderstrategy = indexRelation->rd_am->amorderstrategy; amorderstrategy = indexRelation->rd_am->amorderstrategy;
if (amorderstrategy != 0) if (amorderstrategy > 0)
{ {
int oprindex = amorderstrategy - 1; int oprindex = amorderstrategy - 1;
/*
* Index AM must have a fixed set of strategies for it to
* make sense to specify amorderstrategy, so we need not
* allow the case amstrategies == 0.
*/
Assert(oprindex < indexRelation->rd_am->amstrategies);
for (i = 0; i < ncolumns; i++) for (i = 0; i < ncolumns; i++)
{ {
info->ordering[i] = indexRelation->rd_operator[oprindex]; info->ordering[i] = indexRelation->rd_operator[oprindex];
......
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.362 2006/12/10 22:13:26 tgl Exp $ * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.363 2006/12/18 18:56:28 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -53,6 +53,6 @@ ...@@ -53,6 +53,6 @@
*/ */
/* yyyymmddN */ /* yyyymmddN */
#define CATALOG_VERSION_NO 200612101 #define CATALOG_VERSION_NO 200612181
#endif #endif
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/catalog/pg_am.h,v 1.46 2006/07/31 20:09:05 tgl Exp $ * $PostgreSQL: pgsql/src/include/catalog/pg_am.h,v 1.47 2006/12/18 18:56:29 tgl Exp $
* *
* NOTES * NOTES
* the genbki.sh script reads this file and generates .bki * the genbki.sh script reads this file and generates .bki
...@@ -40,7 +40,9 @@ CATALOG(pg_am,2601) ...@@ -40,7 +40,9 @@ CATALOG(pg_am,2601)
{ {
NameData amname; /* access method name */ NameData amname; /* access method name */
int2 amstrategies; /* total NUMBER of strategies (operators) by int2 amstrategies; /* total NUMBER of strategies (operators) by
* which we can traverse/search this AM */ * which we can traverse/search this AM.
* Zero if AM does not have a fixed set of
* strategy assignments. */
int2 amsupport; /* total NUMBER of support functions that this int2 amsupport; /* total NUMBER of support functions that this
* AM uses */ * AM uses */
int2 amorderstrategy;/* if this AM has a sort order, the strategy int2 amorderstrategy;/* if this AM has a sort order, the strategy
...@@ -114,10 +116,10 @@ DESCR("b-tree index access method"); ...@@ -114,10 +116,10 @@ DESCR("b-tree index access method");
DATA(insert OID = 405 ( hash 1 1 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 0 f f f f f f hashinsert hashbeginscan hashgettuple hashgetmulti hashrescan hashendscan hashmarkpos hashrestrpos hashbuild hashbulkdelete hashvacuumcleanup hashcostestimate hashoptions ));
DESCR("hash index access method"); DESCR("hash index access method");
#define HASH_AM_OID 405 #define HASH_AM_OID 405
DATA(insert OID = 783 ( gist 100 7 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 0 f t t t t t gistinsert gistbeginscan gistgettuple gistgetmulti gistrescan gistendscan gistmarkpos gistrestrpos gistbuild gistbulkdelete gistvacuumcleanup gistcostestimate gistoptions ));
DESCR("GiST index access method"); DESCR("GiST index access method");
#define GIST_AM_OID 783 #define GIST_AM_OID 783
DATA(insert OID = 2742 ( gin 100 4 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 0 f f f f t f gininsert ginbeginscan gingettuple gingetmulti ginrescan ginendscan ginmarkpos ginrestrpos ginbuild ginbulkdelete ginvacuumcleanup gincostestimate ginoptions ));
DESCR("GIN index access method"); DESCR("GIN index access method");
#define GIN_AM_OID 2742 #define GIN_AM_OID 2742
......
...@@ -773,7 +773,7 @@ WHERE p1.amopclaid = 0 OR p1.amopstrategy <= 0 OR p1.amopopr = 0; ...@@ -773,7 +773,7 @@ WHERE p1.amopclaid = 0 OR p1.amopstrategy <= 0 OR p1.amopopr = 0;
SELECT p1.amopclaid, p1.amopopr, p2.oid, p2.amname SELECT p1.amopclaid, p1.amopopr, p2.oid, p2.amname
FROM pg_amop AS p1, pg_am AS p2, pg_opclass AS p3 FROM pg_amop AS p1, pg_am AS p2, pg_opclass AS p3
WHERE p1.amopclaid = p3.oid AND p3.opcamid = p2.oid AND WHERE p1.amopclaid = p3.oid AND p3.opcamid = p2.oid AND
p1.amopstrategy > p2.amstrategies; p1.amopstrategy > p2.amstrategies AND p2.amstrategies <> 0;
amopclaid | amopopr | oid | amname amopclaid | amopopr | oid | amname
-----------+---------+-----+-------- -----------+---------+-----+--------
(0 rows) (0 rows)
...@@ -781,12 +781,11 @@ WHERE p1.amopclaid = p3.oid AND p3.opcamid = p2.oid AND ...@@ -781,12 +781,11 @@ WHERE p1.amopclaid = p3.oid AND p3.opcamid = p2.oid AND
-- Detect missing pg_amop entries: should have as many strategy operators -- Detect missing pg_amop entries: should have as many strategy operators
-- as AM expects for each opclass for the AM. When nondefault subtypes are -- as AM expects for each opclass for the AM. When nondefault subtypes are
-- present, enforce condition separately for each subtype. -- present, enforce condition separately for each subtype.
-- We have to exclude GiST and GIN, unfortunately, since they haven't got -- We can't check this for AMs with variable strategy sets.
-- any fixed requirements about strategy operators.
SELECT p1.oid, p1.amname, p2.oid, p2.opcname, p3.amopsubtype SELECT p1.oid, p1.amname, p2.oid, p2.opcname, p3.amopsubtype
FROM pg_am AS p1, pg_opclass AS p2, pg_amop AS p3 FROM pg_am AS p1, pg_opclass AS p2, pg_amop AS p3
WHERE p2.opcamid = p1.oid AND p3.amopclaid = p2.oid AND WHERE p2.opcamid = p1.oid AND p3.amopclaid = p2.oid AND
p1.amname != 'gist' AND p1.amname != 'gin' AND p1.amstrategies <> 0 AND
p1.amstrategies != (SELECT count(*) FROM pg_amop AS p4 p1.amstrategies != (SELECT count(*) FROM pg_amop AS p4
WHERE p4.amopclaid = p2.oid AND WHERE p4.amopclaid = p2.oid AND
p4.amopsubtype = p3.amopsubtype); p4.amopsubtype = p3.amopsubtype);
......
...@@ -642,18 +642,17 @@ WHERE p1.amopclaid = 0 OR p1.amopstrategy <= 0 OR p1.amopopr = 0; ...@@ -642,18 +642,17 @@ WHERE p1.amopclaid = 0 OR p1.amopstrategy <= 0 OR p1.amopopr = 0;
SELECT p1.amopclaid, p1.amopopr, p2.oid, p2.amname SELECT p1.amopclaid, p1.amopopr, p2.oid, p2.amname
FROM pg_amop AS p1, pg_am AS p2, pg_opclass AS p3 FROM pg_amop AS p1, pg_am AS p2, pg_opclass AS p3
WHERE p1.amopclaid = p3.oid AND p3.opcamid = p2.oid AND WHERE p1.amopclaid = p3.oid AND p3.opcamid = p2.oid AND
p1.amopstrategy > p2.amstrategies; p1.amopstrategy > p2.amstrategies AND p2.amstrategies <> 0;
-- Detect missing pg_amop entries: should have as many strategy operators -- Detect missing pg_amop entries: should have as many strategy operators
-- as AM expects for each opclass for the AM. When nondefault subtypes are -- as AM expects for each opclass for the AM. When nondefault subtypes are
-- present, enforce condition separately for each subtype. -- present, enforce condition separately for each subtype.
-- We have to exclude GiST and GIN, unfortunately, since they haven't got -- We can't check this for AMs with variable strategy sets.
-- any fixed requirements about strategy operators.
SELECT p1.oid, p1.amname, p2.oid, p2.opcname, p3.amopsubtype SELECT p1.oid, p1.amname, p2.oid, p2.opcname, p3.amopsubtype
FROM pg_am AS p1, pg_opclass AS p2, pg_amop AS p3 FROM pg_am AS p1, pg_opclass AS p2, pg_amop AS p3
WHERE p2.opcamid = p1.oid AND p3.amopclaid = p2.oid AND WHERE p2.opcamid = p1.oid AND p3.amopclaid = p2.oid AND
p1.amname != 'gist' AND p1.amname != 'gin' AND p1.amstrategies <> 0 AND
p1.amstrategies != (SELECT count(*) FROM pg_amop AS p4 p1.amstrategies != (SELECT count(*) FROM pg_amop AS p4
WHERE p4.amopclaid = p2.oid AND WHERE p4.amopclaid = p2.oid AND
p4.amopsubtype = p3.amopsubtype); p4.amopsubtype = p3.amopsubtype);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment