diff --git a/contrib/btree_gist/btree_gist.sql.in b/contrib/btree_gist/btree_gist.sql.in index 7089f1d3b56c5a43bbfce719cd9f0015de850d7d..98b868afc7283db8c33ed694a9bb387a6bb7caa6 100644 --- a/contrib/btree_gist/btree_gist.sql.in +++ b/contrib/btree_gist/btree_gist.sql.in @@ -41,12 +41,15 @@ create function gint4_union(bytea, opaque) returns int4 as 'MODULE_PATHNAME' lan create function gint4_same(opaque, opaque, opaque) returns opaque as 'MODULE_PATHNAME' language 'C'; -- add a new opclass -INSERT INTO pg_opclass (opcamid, opcname, opcintype, opckeytype, opcdefault) - SELECT pg_am.oid, 'gist_int4_ops', pg_type.oid, pg_key.oid, true - FROM pg_type, pg_am, pg_type pg_key - WHERE pg_type.typname = 'int4' and - pg_key.typname = 'int4key' and - pg_am.amname='gist'; +INSERT INTO pg_opclass (opcamid, opcname, opcnamespace, opcowner, opcintype, opcdefault, opckeytype) + VALUES ( + (SELECT oid FROM pg_am WHERE amname = 'gist'), + 'gist_int4_ops', + (SELECT oid FROM pg_namespace WHERE nspname = 'pg_catalog'), + 1, -- UID of superuser is hardwired to 1 as of PG 7.3 + (SELECT oid FROM pg_type WHERE typname = 'int4'), + true, + (SELECT oid FROM pg_type WHERE typname = 'int4key')); SELECT o.oid AS opoid, o.oprname @@ -170,12 +173,16 @@ create function gts_union(bytea, opaque) returns int4 as 'MODULE_PATHNAME' langu create function gts_same(opaque, opaque, opaque) returns opaque as 'MODULE_PATHNAME' language 'C'; -INSERT INTO pg_opclass (opcamid, opcname, opcintype, opckeytype, opcdefault) - SELECT pg_am.oid, 'gist_timestamp_ops', pg_type.oid, pg_key.oid, true - FROM pg_type, pg_am, pg_type pg_key - WHERE pg_type.typname = 'timestamp' and - pg_key.typname = 'tskey' and - pg_am.amname='gist'; +-- add a new opclass +INSERT INTO pg_opclass (opcamid, opcname, opcnamespace, opcowner, opcintype, opcdefault, opckeytype) + VALUES ( + (SELECT oid FROM pg_am WHERE amname = 'gist'), + 'gist_timestamp_ops', + (SELECT oid FROM pg_namespace WHERE nspname = 'pg_catalog'), + 1, -- UID of superuser is hardwired to 1 as of PG 7.3 + (SELECT oid FROM pg_type WHERE typname = 'timestamp'), + true, + (SELECT oid FROM pg_type WHERE typname = 'tskey')); SELECT o.oid AS opoid, o.oprname INTO TABLE timestamp_ops_tmp diff --git a/contrib/cube/cube.sql.in b/contrib/cube/cube.sql.in index 00994d39a007c4b4c028719553777fb83f59fe20..a1a78ca9f58676ab678326e85498a4988d368333 100644 --- a/contrib/cube/cube.sql.in +++ b/contrib/cube/cube.sql.in @@ -212,10 +212,12 @@ CREATE FUNCTION g_cube_same(cube, cube, opaque) RETURNS opaque -- register the default opclass for indexing -INSERT INTO pg_opclass (opcamid, opcname, opcintype, opcdefault, opckeytype) +INSERT INTO pg_opclass (opcamid, opcname, opcnamespace, opcowner, opcintype, opcdefault, opckeytype) VALUES ( (SELECT oid FROM pg_am WHERE amname = 'gist'), 'gist_cube_ops', + (SELECT oid FROM pg_namespace WHERE nspname = 'pg_catalog'), + 1, -- UID of superuser is hardwired to 1 as of PG 7.3 (SELECT oid FROM pg_type WHERE typname = 'cube'), true, 0); diff --git a/contrib/intarray/_int.sql.in b/contrib/intarray/_int.sql.in index 61f2cbd3f6f32b0a05dd84367e9ae515cab0b546..60a4972984b813aadae0f9a485eb759285c33d61 100644 --- a/contrib/intarray/_int.sql.in +++ b/contrib/intarray/_int.sql.in @@ -144,10 +144,12 @@ CREATE FUNCTION g_int_same(_int4, _int4, opaque) RETURNS opaque -- register the default opclass for indexing -INSERT INTO pg_opclass (opcamid, opcname, opcintype, opcdefault, opckeytype) +INSERT INTO pg_opclass (opcamid, opcname, opcnamespace, opcowner, opcintype, opcdefault, opckeytype) VALUES ( (SELECT oid FROM pg_am WHERE amname = 'gist'), 'gist__int_ops', + (SELECT oid FROM pg_namespace WHERE nspname = 'pg_catalog'), + 1, -- UID of superuser is hardwired to 1 as of PG 7.3 (SELECT oid FROM pg_type WHERE typname = '_int4'), true, 0); @@ -300,10 +302,12 @@ CREATE FUNCTION g_intbig_same(_int4, _int4, opaque) RETURNS opaque AS 'MODULE_PATHNAME' LANGUAGE 'c'; -- register the opclass for indexing (not as default) -INSERT INTO pg_opclass (opcamid, opcname, opcintype, opcdefault, opckeytype) +INSERT INTO pg_opclass (opcamid, opcname, opcnamespace, opcowner, opcintype, opcdefault, opckeytype) VALUES ( (SELECT oid FROM pg_am WHERE amname = 'gist'), 'gist__intbig_ops', + (SELECT oid FROM pg_namespace WHERE nspname = 'pg_catalog'), + 1, -- UID of superuser is hardwired to 1 as of PG 7.3 (SELECT oid FROM pg_type WHERE typname = '_int4'), false, 0); diff --git a/contrib/rtree_gist/rtree_gist.sql.in b/contrib/rtree_gist/rtree_gist.sql.in index df9bb823f09cce239bb7c55d1aae470f5d87916a..0d1770381f4e374f465fd5f6a3165a7b3a7421b8 100644 --- a/contrib/rtree_gist/rtree_gist.sql.in +++ b/contrib/rtree_gist/rtree_gist.sql.in @@ -21,11 +21,13 @@ create function gbox_union(bytea, opaque) returns box as 'MODULE_PATHNAME' langu create function gbox_same(box, box, opaque) returns opaque as 'MODULE_PATHNAME' language 'C'; --- add a new opclass (non-default) -INSERT INTO pg_opclass (opcamid, opcname, opcintype, opcdefault, opckeytype) +-- add a new opclass +INSERT INTO pg_opclass (opcamid, opcname, opcnamespace, opcowner, opcintype, opcdefault, opckeytype) VALUES ( (SELECT oid FROM pg_am WHERE amname = 'gist'), 'gist_box_ops', + (SELECT oid FROM pg_namespace WHERE nspname = 'pg_catalog'), + 1, -- UID of superuser is hardwired to 1 as of PG 7.3 (SELECT oid FROM pg_type WHERE typname = 'box'), true, 0); @@ -183,11 +185,13 @@ create function gpoly_consistent(opaque,polygon,int4) returns bool as 'MODULE_PA create function gpoly_compress(opaque) returns opaque as 'MODULE_PATHNAME' language 'C'; --- add a new opclass (non-default) -INSERT INTO pg_opclass (opcamid, opcname, opcintype, opcdefault, opckeytype) +-- add a new opclass +INSERT INTO pg_opclass (opcamid, opcname, opcnamespace, opcowner, opcintype, opcdefault, opckeytype) VALUES ( (SELECT oid FROM pg_am WHERE amname = 'gist'), 'gist_poly_ops', + (SELECT oid FROM pg_namespace WHERE nspname = 'pg_catalog'), + 1, -- UID of superuser is hardwired to 1 as of PG 7.3 (SELECT oid FROM pg_type WHERE typname = 'polygon'), true, (SELECT oid FROM pg_type WHERE typname = 'box')); diff --git a/contrib/seg/seg.sql.in b/contrib/seg/seg.sql.in index 74739dfc5cfcc809d75531a39860f0ad8fbc1ec4..f8acddeb3520b2d7e8e2f1b9ec757703faca1169 100644 --- a/contrib/seg/seg.sql.in +++ b/contrib/seg/seg.sql.in @@ -236,10 +236,12 @@ CREATE FUNCTION gseg_same(seg, seg, opaque) RETURNS opaque -- register the default opclass for indexing -INSERT INTO pg_opclass (opcamid, opcname, opcintype, opcdefault, opckeytype) +INSERT INTO pg_opclass (opcamid, opcname, opcnamespace, opcowner, opcintype, opcdefault, opckeytype) VALUES ( (SELECT oid FROM pg_am WHERE amname = 'gist'), 'gist_seg_ops', + (SELECT oid FROM pg_namespace WHERE nspname = 'pg_catalog'), + 1, -- UID of superuser is hardwired to 1 as of PG 7.3 (SELECT oid FROM pg_type WHERE typname = 'seg'), true, 0); diff --git a/contrib/tsearch/tsearch.sql.in b/contrib/tsearch/tsearch.sql.in index 48a5ae27e62183027b6db5447141bafc22f8996c..e53793cf718610039f7e04247cae6ccd53da8c14 100644 --- a/contrib/tsearch/tsearch.sql.in +++ b/contrib/tsearch/tsearch.sql.in @@ -155,10 +155,12 @@ CREATE FUNCTION gtxtidx_union(bytea, opaque) RETURNS _int4 CREATE FUNCTION gtxtidx_same(gtxtidx, gtxtidx, opaque) RETURNS opaque AS 'MODULE_PATHNAME' LANGUAGE 'c'; -INSERT INTO pg_opclass (opcamid, opcname, opcintype, opcdefault, opckeytype) +INSERT INTO pg_opclass (opcamid, opcname, opcnamespace, opcowner, opcintype, opcdefault, opckeytype) VALUES ( (SELECT oid FROM pg_am WHERE amname = 'gist'), 'gist_txtidx_ops', + (SELECT oid FROM pg_namespace WHERE nspname = 'pg_catalog'), + 1, -- UID of superuser is hardwired to 1 as of PG 7.3 (SELECT oid FROM pg_type WHERE typname = 'txtidx'), true, (SELECT oid FROM pg_type WHERE typname = 'gtxtidx')); diff --git a/doc/src/sgml/xindex.sgml b/doc/src/sgml/xindex.sgml index 6a9062914113c06037ae7bc3b622049cf09ea9a5..dcb5f9b65170e8f0cd8d7f3e1ca61691fbdf17e6 100644 --- a/doc/src/sgml/xindex.sgml +++ b/doc/src/sgml/xindex.sgml @@ -1,5 +1,5 @@ <!-- -$Header: /cvsroot/pgsql/doc/src/sgml/xindex.sgml,v 1.23 2002/03/27 19:19:23 petere Exp $ +$Header: /cvsroot/pgsql/doc/src/sgml/xindex.sgml,v 1.24 2002/04/17 20:57:56 tgl Exp $ PostgreSQL documentation --> @@ -280,10 +280,12 @@ SELECT oid FROM pg_am WHERE amname = 'btree'; <classname>pg_opclass</classname>: <programlisting> -INSERT INTO pg_opclass (opcamid, opcname, opcintype, opcdefault, opckeytype) +INSERT INTO pg_opclass (opcamid, opcname, opcnamespace, opcowner, opcintype, opcdefault, opckeytype) VALUES ( (SELECT oid FROM pg_am WHERE amname = 'btree'), 'complex_abs_ops', + (SELECT oid FROM pg_namespace WHERE nspname = 'pg_catalog'), + 1, -- UID of superuser is hardwired to 1 as of PG 7.3 (SELECT oid FROM pg_type WHERE typname = 'complex'), true, 0); @@ -292,9 +294,9 @@ SELECT oid, * FROM pg_opclass WHERE opcname = 'complex_abs_ops'; - oid | opcamid | opcname | opcintype | opcdefault | opckeytype ---------+---------+-----------------+-----------+------------+------------ - 277975 | 403 | complex_abs_ops | 277946 | t | 0 + oid | opcamid | opcname | opcnamespace | opcowner | opcintype | opcdefault | opckeytype +--------+---------+-----------------+--------------+----------+-----------+------------+------------ + 277975 | 403 | complex_abs_ops | 11 | 1 | 277946 | t | 0 (1 row) </programlisting> diff --git a/src/backend/access/index/indexam.c b/src/backend/access/index/indexam.c index ea043afb341c2925d72b8969fbba55a47b8a6541..ce2c8e62f45cd7b3134f299c5915decd515101f2 100644 --- a/src/backend/access/index/indexam.c +++ b/src/backend/access/index/indexam.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/index/indexam.c,v 1.56 2002/03/26 19:15:14 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/index/indexam.c,v 1.57 2002/04/17 20:57:56 tgl Exp $ * * INTERFACE ROUTINES * index_open - open an index relation by relation OID @@ -498,10 +498,23 @@ index_getprocinfo(Relation irel, if (locinfo->fn_oid == InvalidOid) { RegProcedure *loc = irel->rd_support; + RegProcedure procId; Assert(loc != NULL); - fmgr_info_cxt(loc[procindex], locinfo, irel->rd_indexcxt); + procId = loc[procindex]; + + /* + * Complain if function was not found during IndexSupportInitialize. + * This should not happen unless the system tables contain bogus + * entries for the index opclass. (If an AM wants to allow a + * support function to be optional, it can use index_getprocid.) + */ + if (!RegProcedureIsValid(procId)) + elog(ERROR, "Missing support function %d for attribute %d of index %s", + procnum, attnum, RelationGetRelationName(irel)); + + fmgr_info_cxt(procId, locinfo, irel->rd_indexcxt); } return locinfo; diff --git a/src/backend/bootstrap/bootparse.y b/src/backend/bootstrap/bootparse.y index b5d039f9355ef63831e56edcf35786f811afee7c..e98eae3a423fffeeb28d539ec2e378f05a862d09 100644 --- a/src/backend/bootstrap/bootparse.y +++ b/src/backend/bootstrap/bootparse.y @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/bootstrap/bootparse.y,v 1.44 2002/04/09 20:35:46 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/bootstrap/bootparse.y,v 1.45 2002/04/17 20:57:56 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -273,7 +273,7 @@ boot_index_param: IndexElem *n = makeNode(IndexElem); n->name = LexIDStr($1); n->funcname = n->args = NIL; /* no func indexes */ - n->class = LexIDStr($2); + n->opclass = makeList1(makeString(LexIDStr($2))); $$ = n; } ; diff --git a/src/backend/catalog/indexing.c b/src/backend/catalog/indexing.c index 7bfede27b5ce77a407bf2f9686680a80ec76f5d1..203df67f628edf35dae10d0fa8157dd983a83a83 100644 --- a/src/backend/catalog/indexing.c +++ b/src/backend/catalog/indexing.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/catalog/indexing.c,v 1.89 2002/04/16 23:08:10 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/catalog/indexing.c,v 1.90 2002/04/17 20:57:56 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -60,7 +60,7 @@ char *Name_pg_largeobject_indices[Num_pg_largeobject_indices] = char *Name_pg_namespace_indices[Num_pg_namespace_indices] = {NamespaceNameIndex, NamespaceOidIndex}; char *Name_pg_opclass_indices[Num_pg_opclass_indices] = -{OpclassAmNameIndex, OpclassOidIndex}; +{OpclassAmNameNspIndex, OpclassOidIndex}; char *Name_pg_operator_indices[Num_pg_operator_indices] = {OperatorOidIndex, OperatorNameNspIndex}; char *Name_pg_proc_indices[Num_pg_proc_indices] = diff --git a/src/backend/catalog/namespace.c b/src/backend/catalog/namespace.c index 15fdb01ed31cec5296a05492cf87b304464e6ed9..0a3aefeaf0fa0b483b92fa8ccf803245fdcace86 100644 --- a/src/backend/catalog/namespace.c +++ b/src/backend/catalog/namespace.c @@ -13,7 +13,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/catalog/namespace.c,v 1.10 2002/04/16 23:08:10 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/catalog/namespace.c,v 1.11 2002/04/17 20:57:56 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -27,6 +27,7 @@ #include "catalog/namespace.h" #include "catalog/pg_inherits.h" #include "catalog/pg_namespace.h" +#include "catalog/pg_opclass.h" #include "catalog/pg_operator.h" #include "catalog/pg_proc.h" #include "catalog/pg_shadow.h" @@ -311,6 +312,54 @@ TypenameGetTypid(const char *typname) return InvalidOid; } +/* + * OpclassnameGetOpcid + * Try to resolve an unqualified index opclass name. + * Returns OID if opclass found in search path, else InvalidOid. + * + * This is essentially the same as TypenameGetTypid, but we have to have + * an extra argument for the index AM OID. + */ +Oid +OpclassnameGetOpcid(Oid amid, const char *opcname) +{ + Oid opcid; + List *lptr; + + /* + * If system namespace is not in path, implicitly search it before path + */ + if (!pathContainsSystemNamespace) + { + opcid = GetSysCacheOid(CLAAMNAMENSP, + ObjectIdGetDatum(amid), + PointerGetDatum(opcname), + ObjectIdGetDatum(PG_CATALOG_NAMESPACE), + 0); + if (OidIsValid(opcid)) + return opcid; + } + + /* + * Else search the path + */ + foreach(lptr, namespaceSearchPath) + { + Oid namespaceId = (Oid) lfirsti(lptr); + + opcid = GetSysCacheOid(CLAAMNAMENSP, + ObjectIdGetDatum(amid), + PointerGetDatum(opcname), + ObjectIdGetDatum(namespaceId), + 0); + if (OidIsValid(opcid)) + return opcid; + } + + /* Not found in path */ + return InvalidOid; +} + /* * FuncnameGetCandidates * Given a possibly-qualified function name and argument count, @@ -652,6 +701,123 @@ OpernameGetCandidates(List *names, char oprkind) return resultList; } +/* + * OpclassGetCandidates + * Given an index access method OID, retrieve a list of all the + * opclasses for that AM that are visible in the search path. + * + * NOTE: the opcname_tmp field in the returned structs should not be used + * by callers, because it points at syscache entries that we release at + * the end of this routine. If any callers needed the name information, + * we could pstrdup() the names ... but at present it'd be wasteful. + */ +OpclassCandidateList +OpclassGetCandidates(Oid amid) +{ + OpclassCandidateList resultList = NULL; + CatCList *catlist; + int i; + + /* Search syscache by AM OID only */ + catlist = SearchSysCacheList(CLAAMNAMENSP, 1, + ObjectIdGetDatum(amid), + 0, 0, 0); + + for (i = 0; i < catlist->n_members; i++) + { + HeapTuple opctup = &catlist->members[i]->tuple; + Form_pg_opclass opcform = (Form_pg_opclass) GETSTRUCT(opctup); + int pathpos = 0; + OpclassCandidateList newResult; + + /* Consider only opclasses that are in the search path */ + if (pathContainsSystemNamespace || + !IsSystemNamespace(opcform->opcnamespace)) + { + List *nsp; + + foreach(nsp, namespaceSearchPath) + { + pathpos++; + if (opcform->opcnamespace == (Oid) lfirsti(nsp)) + break; + } + if (nsp == NIL) + continue; /* opclass is not in search path */ + } + + /* + * Okay, it's in the search path, but does it have the same name + * as something we already accepted? If so, keep + * only the one that appears earlier in the search path. + * + * If we have an ordered list from SearchSysCacheList (the + * normal case), then any conflicting opclass must immediately + * adjoin this one in the list, so we only need to look at + * the newest result item. If we have an unordered list, + * we have to scan the whole result list. + */ + if (resultList) + { + OpclassCandidateList prevResult; + + if (catlist->ordered) + { + if (strcmp(NameStr(opcform->opcname), + resultList->opcname_tmp) == 0) + prevResult = resultList; + else + prevResult = NULL; + } + else + { + for (prevResult = resultList; + prevResult; + prevResult = prevResult->next) + { + if (strcmp(NameStr(opcform->opcname), + prevResult->opcname_tmp) == 0) + break; + } + } + if (prevResult) + { + /* We have a match with a previous result */ + Assert(pathpos != prevResult->pathpos); + if (pathpos > prevResult->pathpos) + continue; /* keep previous result */ + /* replace previous result */ + prevResult->opcname_tmp = NameStr(opcform->opcname); + prevResult->pathpos = pathpos; + prevResult->oid = opctup->t_data->t_oid; + prevResult->opcintype = opcform->opcintype; + prevResult->opcdefault = opcform->opcdefault; + prevResult->opckeytype = opcform->opckeytype; + continue; + } + } + + /* + * Okay to add it to result list + */ + newResult = (OpclassCandidateList) + palloc(sizeof(struct _OpclassCandidateList)); + newResult->opcname_tmp = NameStr(opcform->opcname); + newResult->pathpos = pathpos; + newResult->oid = opctup->t_data->t_oid; + newResult->opcintype = opcform->opcintype; + newResult->opcdefault = opcform->opcdefault; + newResult->opckeytype = opcform->opckeytype; + newResult->next = resultList; + resultList = newResult; + } + + ReleaseSysCacheList(catlist); + + return resultList; +} + + /* * QualifiedNameGetCreationNamespace * Given a possibly-qualified name for an object (in List-of-Values diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c index 297d5e726633576c1ad5d30ba724986b0536162e..14889a4f0c30b1ea5cebeb7aa512dcea682d594e 100644 --- a/src/backend/commands/indexcmds.c +++ b/src/backend/commands/indexcmds.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.70 2002/04/12 20:38:22 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.71 2002/04/17 20:57:56 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -31,7 +31,6 @@ #include "parser/parse_coerce.h" #include "parser/parse_func.h" #include "utils/builtins.h" -#include "utils/fmgroids.h" #include "utils/lsyscache.h" #include "utils/syscache.h" @@ -390,11 +389,14 @@ static Oid GetAttrOpClass(IndexElem *attribute, Oid attrType, char *accessMethodName, Oid accessMethodId) { + char *catalogname; + char *schemaname = NULL; + char *opcname = NULL; HeapTuple tuple; Oid opClassId, opInputType; - if (attribute->class == NULL) + if (attribute->opclass == NIL) { /* no operator class specified, so find the default */ opClassId = GetDefaultOpClass(attrType, accessMethodId); @@ -407,23 +409,79 @@ GetAttrOpClass(IndexElem *attribute, Oid attrType, } /* - * Find the index operator class and verify that it accepts this - * datatype. Note we will accept binary compatibility. + * Specific opclass name given, so look up the opclass. */ - tuple = SearchSysCache(CLAAMNAME, - ObjectIdGetDatum(accessMethodId), - PointerGetDatum(attribute->class), - 0, 0); + + /* deconstruct the name list */ + switch (length(attribute->opclass)) + { + case 1: + opcname = strVal(lfirst(attribute->opclass)); + break; + case 2: + schemaname = strVal(lfirst(attribute->opclass)); + opcname = strVal(lsecond(attribute->opclass)); + break; + case 3: + catalogname = strVal(lfirst(attribute->opclass)); + schemaname = strVal(lsecond(attribute->opclass)); + opcname = strVal(lfirst(lnext(lnext(attribute->opclass)))); + /* + * We check the catalog name and then ignore it. + */ + if (strcmp(catalogname, DatabaseName) != 0) + elog(ERROR, "Cross-database references are not implemented"); + break; + default: + elog(ERROR, "Improper opclass name (too many dotted names)"); + break; + } + + if (schemaname) + { + /* Look in specific schema only */ + Oid namespaceId; + + namespaceId = GetSysCacheOid(NAMESPACENAME, + CStringGetDatum(schemaname), + 0, 0, 0); + if (!OidIsValid(namespaceId)) + elog(ERROR, "Namespace \"%s\" does not exist", + schemaname); + tuple = SearchSysCache(CLAAMNAMENSP, + ObjectIdGetDatum(accessMethodId), + PointerGetDatum(opcname), + ObjectIdGetDatum(namespaceId), + 0); + } + else + { + /* Unqualified opclass name, so search the search path */ + opClassId = OpclassnameGetOpcid(accessMethodId, opcname); + if (!OidIsValid(opClassId)) + elog(ERROR, "DefineIndex: operator class \"%s\" not supported by access method \"%s\"", + opcname, accessMethodName); + tuple = SearchSysCache(CLAOID, + ObjectIdGetDatum(opClassId), + 0, 0, 0); + } + if (!HeapTupleIsValid(tuple)) elog(ERROR, "DefineIndex: operator class \"%s\" not supported by access method \"%s\"", - attribute->class, accessMethodName); + NameListToString(attribute->opclass), accessMethodName); + + /* + * Verify that the index operator class accepts this + * datatype. Note we will accept binary compatibility. + */ opClassId = tuple->t_data->t_oid; opInputType = ((Form_pg_opclass) GETSTRUCT(tuple))->opcintype; - ReleaseSysCache(tuple); if (!IsBinaryCompatible(attrType, opInputType)) elog(ERROR, "operator class \"%s\" does not accept data type %s", - attribute->class, format_type_be(attrType)); + NameListToString(attribute->opclass), format_type_be(attrType)); + + ReleaseSysCache(tuple); return opClassId; } @@ -431,10 +489,7 @@ GetAttrOpClass(IndexElem *attribute, Oid attrType, static Oid GetDefaultOpClass(Oid attrType, Oid accessMethodId) { - Relation relation; - ScanKeyData entry[1]; - HeapScanDesc scan; - HeapTuple tuple; + OpclassCandidateList opclass; int nexact = 0; int ncompatible = 0; Oid exactOid = InvalidOid; @@ -449,44 +504,32 @@ GetDefaultOpClass(Oid attrType, Oid accessMethodId) * require the user to specify which one he wants. If we find more * than one exact match, then someone put bogus entries in pg_opclass. * - * We could use an indexscan here, but since pg_opclass is small and a - * scan on opcamid won't be very selective, the indexscan would - * probably actually be slower than heapscan. + * The initial search is done by namespace.c so that we only consider + * opclasses visible in the current namespace search path. */ - ScanKeyEntryInitialize(&entry[0], 0x0, - Anum_pg_opclass_opcamid, - F_OIDEQ, - ObjectIdGetDatum(accessMethodId)); - - relation = heap_openr(OperatorClassRelationName, AccessShareLock); - scan = heap_beginscan(relation, false, SnapshotNow, 1, entry); - - while (HeapTupleIsValid(tuple = heap_getnext(scan, 0))) + for (opclass = OpclassGetCandidates(accessMethodId); + opclass != NULL; + opclass = opclass->next) { - Form_pg_opclass opclass = (Form_pg_opclass) GETSTRUCT(tuple); - if (opclass->opcdefault) { if (opclass->opcintype == attrType) { nexact++; - exactOid = tuple->t_data->t_oid; + exactOid = opclass->oid; } else if (IsBinaryCompatible(opclass->opcintype, attrType)) { ncompatible++; - compatibleOid = tuple->t_data->t_oid; + compatibleOid = opclass->oid; } } } - heap_endscan(scan); - heap_close(relation, AccessShareLock); - if (nexact == 1) return exactOid; if (nexact != 0) - elog(ERROR, "pg_opclass contains multiple default opclasses for data tyype %s", + elog(ERROR, "pg_opclass contains multiple default opclasses for data type %s", format_type_be(attrType)); if (ncompatible == 1) return compatibleOid; diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c index 40e1dea79e3be7e735e1ddadb8971d448be6246f..8417f7a716c59afc3429e5839336e299fd53f138 100644 --- a/src/backend/nodes/copyfuncs.c +++ b/src/backend/nodes/copyfuncs.c @@ -15,7 +15,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.178 2002/04/16 23:08:10 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.179 2002/04/17 20:57:56 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -1714,8 +1714,7 @@ _copyIndexElem(IndexElem *from) newnode->name = pstrdup(from->name); Node_Copy(from, newnode, funcname); Node_Copy(from, newnode, args); - if (from->class) - newnode->class = pstrdup(from->class); + Node_Copy(from, newnode, opclass); return newnode; } diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c index 245d72fc01445cfff63098d6ed7685ad8b608823..58f6b5a5d6353aa7c2cd6297053cbd5d352747f0 100644 --- a/src/backend/nodes/equalfuncs.c +++ b/src/backend/nodes/equalfuncs.c @@ -20,7 +20,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.126 2002/04/16 23:08:10 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.127 2002/04/17 20:57:56 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -1599,7 +1599,7 @@ _equalIndexElem(IndexElem *a, IndexElem *b) return false; if (!equal(a->args, b->args)) return false; - if (!equalstr(a->class, b->class)) + if (!equal(a->opclass, b->opclass)) return false; return true; diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c index 65a501c429a832ab1559151811eb1c290b07c698..24238565d55c2bd2fba2ba90edbe57d407537475 100644 --- a/src/backend/nodes/outfuncs.c +++ b/src/backend/nodes/outfuncs.c @@ -5,7 +5,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.155 2002/04/16 23:08:10 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.156 2002/04/17 20:57:56 tgl Exp $ * * NOTES * Every (plan) node in POSTGRES has an associated "out" routine which @@ -217,8 +217,8 @@ _outIndexElem(StringInfo str, IndexElem *node) _outNode(str, node->funcname); appendStringInfo(str, " :args "); _outNode(str, node->args); - appendStringInfo(str, " :class "); - _outToken(str, node->class); + appendStringInfo(str, " :opclass "); + _outNode(str, node->opclass); } static void diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c index 6a68adfff375d45e6fa5d8b27bd542638da09e59..b3b8859d12623a3731d9771859e0ed8c8d699944 100644 --- a/src/backend/parser/analyze.c +++ b/src/backend/parser/analyze.c @@ -6,7 +6,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.230 2002/04/16 23:08:11 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.231 2002/04/17 20:57:56 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -1209,7 +1209,7 @@ transformIndexConstraints(ParseState *pstate, CreateStmtContext *cxt) iparam->name = pstrdup(key->name); iparam->funcname = NIL; iparam->args = NIL; - iparam->class = NULL; + iparam->opclass = NIL; index->indexParams = lappend(index->indexParams, iparam); } diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 26b1be11d821795c5200f41cedea8d65e7d55036..774f9fa743cbcbed648c72541d9da042805883c8 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -11,7 +11,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.302 2002/04/16 23:08:11 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.303 2002/04/17 20:57:56 tgl Exp $ * * HISTORY * AUTHOR DATE MAJOR EVENT @@ -174,15 +174,15 @@ static bool set_name_needs_quotes(const char *name); %type <str> relation_name, copy_file_name, copy_delimiter, copy_null, database_name, access_method_clause, access_method, attr_name, - class, index_name, name, function_name, file_name + index_name, name, function_name, file_name -%type <list> func_name, handler_name, qual_Op, qual_all_Op, OptUseOp +%type <list> func_name, handler_name, qual_Op, qual_all_Op, OptUseOp, + opt_class %type <range> qualified_name, OptConstrFromTable %type <str> opt_id, - all_Op, MathOp, opt_name, - opt_class, SpecialRuleRelation + all_Op, MathOp, opt_name, SpecialRuleRelation %type <str> opt_level, opt_encoding %type <node> grantee @@ -2614,7 +2614,7 @@ func_index: func_name '(' name_list ')' opt_class $$->name = NULL; $$->funcname = $1; $$->args = $3; - $$->class = $5; + $$->opclass = $5; } ; @@ -2624,11 +2624,11 @@ index_elem: attr_name opt_class $$->name = $1; $$->funcname = NIL; $$->args = NIL; - $$->class = $2; + $$->opclass = $2; } ; -opt_class: class +opt_class: any_name { /* * Release 7.0 removed network_ops, timespan_ops, and @@ -2643,17 +2643,24 @@ opt_class: class * so suppress that too for awhile. I'm starting to * think we need a better approach. tgl 2000/10/01 */ - if (strcmp($1, "network_ops") != 0 && - strcmp($1, "timespan_ops") != 0 && - strcmp($1, "datetime_ops") != 0 && - strcmp($1, "lztext_ops") != 0 && - strcmp($1, "timestamp_ops") != 0) - $$ = $1; + if (length($1) == 1) + { + char *claname = strVal(lfirst($1)); + + if (strcmp(claname, "network_ops") != 0 && + strcmp(claname, "timespan_ops") != 0 && + strcmp(claname, "datetime_ops") != 0 && + strcmp(claname, "lztext_ops") != 0 && + strcmp(claname, "timestamp_ops") != 0) + $$ = $1; + else + $$ = NIL; + } else - $$ = NULL; + $$ = $1; } - | USING class { $$ = $2; } - | /*EMPTY*/ { $$ = NULL; } + | USING any_name { $$ = $2; } + | /*EMPTY*/ { $$ = NIL; } ; /***************************************************************************** @@ -5782,7 +5789,6 @@ name: ColId { $$ = $1; }; database_name: ColId { $$ = $1; }; access_method: ColId { $$ = $1; }; attr_name: ColId { $$ = $1; }; -class: ColId { $$ = $1; }; index_name: ColId { $$ = $1; }; file_name: Sconst { $$ = $1; }; diff --git a/src/backend/utils/cache/syscache.c b/src/backend/utils/cache/syscache.c index 720d19225c6b597cb4d303be009fc9cfed250c1c..5deea860897597358751efdb40cb07b3be8f2e62 100644 --- a/src/backend/utils/cache/syscache.c +++ b/src/backend/utils/cache/syscache.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/cache/syscache.c,v 1.77 2002/04/16 23:08:11 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/cache/syscache.c,v 1.78 2002/04/17 20:57:56 tgl Exp $ * * NOTES * These routines allow the parser/planner/executor to perform @@ -173,14 +173,14 @@ static const struct cachedesc cacheinfo[] = { 0, 0 }}, - {OperatorClassRelationName, /* CLAAMNAME */ - OpclassAmNameIndex, + {OperatorClassRelationName, /* CLAAMNAMENSP */ + OpclassAmNameNspIndex, 0, - 2, + 3, { Anum_pg_opclass_opcamid, Anum_pg_opclass_opcname, - 0, + Anum_pg_opclass_opcnamespace, 0 }}, {OperatorClassRelationName, /* CLAOID */ diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index 4b0d011b3d6b49c751fe810669f4541a74e23cda..492c3e9b3fe1a0a2255b377f9bc38c651335c59f 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -37,7 +37,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: catversion.h,v 1.116 2002/04/16 23:08:11 tgl Exp $ + * $Id: catversion.h,v 1.117 2002/04/17 20:57:56 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -53,6 +53,6 @@ */ /* yyyymmddN */ -#define CATALOG_VERSION_NO 200204161 +#define CATALOG_VERSION_NO 200204171 #endif diff --git a/src/include/catalog/indexing.h b/src/include/catalog/indexing.h index 4ca83c5427385bdf33cafb40cac816de1196e1f8..b2b3f1f39c718ab335e58a309abb0f8cdeb6e6cb 100644 --- a/src/include/catalog/indexing.h +++ b/src/include/catalog/indexing.h @@ -8,7 +8,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: indexing.h,v 1.63 2002/04/16 23:08:11 tgl Exp $ + * $Id: indexing.h,v 1.64 2002/04/17 20:57:56 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -72,7 +72,7 @@ #define LargeObjectLOidPNIndex "pg_largeobject_loid_pn_index" #define NamespaceNameIndex "pg_namespace_nspname_index" #define NamespaceOidIndex "pg_namespace_oid_index" -#define OpclassAmNameIndex "pg_opclass_am_name_index" +#define OpclassAmNameNspIndex "pg_opclass_am_name_nsp_index" #define OpclassOidIndex "pg_opclass_oid_index" #define OperatorNameNspIndex "pg_operator_oprname_l_r_n_index" #define OperatorOidIndex "pg_operator_oid_index" @@ -169,7 +169,7 @@ DECLARE_UNIQUE_INDEX(pg_language_oid_index on pg_language using btree(oid oid_op DECLARE_UNIQUE_INDEX(pg_largeobject_loid_pn_index on pg_largeobject using btree(loid oid_ops, pageno int4_ops)); DECLARE_UNIQUE_INDEX(pg_namespace_nspname_index on pg_namespace using btree(nspname name_ops)); DECLARE_UNIQUE_INDEX(pg_namespace_oid_index on pg_namespace using btree(oid oid_ops)); -DECLARE_UNIQUE_INDEX(pg_opclass_am_name_index on pg_opclass using btree(opcamid oid_ops, opcname name_ops)); +DECLARE_UNIQUE_INDEX(pg_opclass_am_name_nsp_index on pg_opclass using btree(opcamid oid_ops, opcname name_ops, opcnamespace oid_ops)); DECLARE_UNIQUE_INDEX(pg_opclass_oid_index on pg_opclass using btree(oid oid_ops)); DECLARE_UNIQUE_INDEX(pg_operator_oid_index on pg_operator using btree(oid oid_ops)); DECLARE_UNIQUE_INDEX(pg_operator_oprname_l_r_n_index on pg_operator using btree(oprname name_ops, oprleft oid_ops, oprright oid_ops, oprnamespace oid_ops)); diff --git a/src/include/catalog/namespace.h b/src/include/catalog/namespace.h index d69e1da58b7678873b1bdbc1b85c27edcc4931c2..148fc210a889ed7d31df486432884703ae26efd7 100644 --- a/src/include/catalog/namespace.h +++ b/src/include/catalog/namespace.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: namespace.h,v 1.8 2002/04/16 23:08:11 tgl Exp $ + * $Id: namespace.h,v 1.9 2002/04/17 20:57:56 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -32,6 +32,21 @@ typedef struct _FuncCandidateList Oid args[1]; /* arg types --- VARIABLE LENGTH ARRAY */ } *FuncCandidateList; /* VARIABLE LENGTH STRUCT */ +/* + * This structure holds a list of opclass candidates found by namespace + * lookup. + */ +typedef struct _OpclassCandidateList +{ + struct _OpclassCandidateList *next; + char *opcname_tmp; /* for internal use of namespace lookup */ + int pathpos; /* for internal use of namespace lookup */ + Oid oid; /* the opclass's OID */ + Oid opcintype; /* type of input data for opclass */ + bool opcdefault; /* T if opclass is default for opcintype */ + Oid opckeytype; /* type of index data, or InvalidOid */ +} *OpclassCandidateList; + extern Oid RangeVarGetRelid(const RangeVar *relation, bool failOK); @@ -41,10 +56,14 @@ extern Oid RelnameGetRelid(const char *relname); extern Oid TypenameGetTypid(const char *typname); +extern Oid OpclassnameGetOpcid(Oid amid, const char *opcname); + extern FuncCandidateList FuncnameGetCandidates(List *names, int nargs); extern FuncCandidateList OpernameGetCandidates(List *names, char oprkind); +extern OpclassCandidateList OpclassGetCandidates(Oid amid); + extern Oid QualifiedNameGetCreationNamespace(List *names, char **objname_p); extern RangeVar *makeRangeVarFromNameList(List *names); diff --git a/src/include/catalog/pg_opclass.h b/src/include/catalog/pg_opclass.h index 2e25e366c64a421dcea784b02b9d302c27d1f7d3..edb29267d6266ef018a0f883ece38c6f89cd1f34 100644 --- a/src/include/catalog/pg_opclass.h +++ b/src/include/catalog/pg_opclass.h @@ -26,7 +26,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: pg_opclass.h,v 1.43 2001/11/05 17:46:32 momjian Exp $ + * $Id: pg_opclass.h,v 1.44 2002/04/17 20:57:56 tgl Exp $ * * NOTES * the genbki.sh script reads this file and generates .bki @@ -54,6 +54,8 @@ CATALOG(pg_opclass) { Oid opcamid; /* index access method opclass is for */ NameData opcname; /* name of this opclass */ + Oid opcnamespace; /* namespace of this opclass */ + int4 opcowner; /* opclass owner */ Oid opcintype; /* type of input data for opclass */ bool opcdefault; /* T if opclass is default for opcintype */ Oid opckeytype; /* type of index data, or InvalidOid */ @@ -70,71 +72,73 @@ typedef FormData_pg_opclass *Form_pg_opclass; * compiler constants for pg_opclass * ---------------- */ -#define Natts_pg_opclass 5 +#define Natts_pg_opclass 7 #define Anum_pg_opclass_opcamid 1 #define Anum_pg_opclass_opcname 2 -#define Anum_pg_opclass_opcintype 3 -#define Anum_pg_opclass_opcdefault 4 -#define Anum_pg_opclass_opckeytype 5 +#define Anum_pg_opclass_opcnamespace 3 +#define Anum_pg_opclass_opcowner 4 +#define Anum_pg_opclass_opcintype 5 +#define Anum_pg_opclass_opcdefault 6 +#define Anum_pg_opclass_opckeytype 7 /* ---------------- * initial contents of pg_opclass * ---------------- */ -DATA(insert OID = 421 ( 403 abstime_ops 702 t 0 )); -DATA(insert OID = 422 ( 402 bigbox_ops 603 f 0 )); -DATA(insert OID = 423 ( 403 bit_ops 1560 t 0 )); -DATA(insert OID = 424 ( 403 bool_ops 16 t 0 )); -DATA(insert OID = 425 ( 402 box_ops 603 t 0 )); -DATA(insert OID = 426 ( 403 bpchar_ops 1042 t 0 )); -DATA(insert OID = 427 ( 405 bpchar_ops 1042 t 0 )); -DATA(insert OID = 428 ( 403 bytea_ops 17 t 0 )); -DATA(insert OID = 429 ( 403 char_ops 18 t 0 )); -DATA(insert OID = 431 ( 405 char_ops 18 t 0 )); -DATA(insert OID = 432 ( 403 cidr_ops 650 t 0 )); -DATA(insert OID = 433 ( 405 cidr_ops 650 t 0 )); -DATA(insert OID = 434 ( 403 date_ops 1082 t 0 )); -DATA(insert OID = 435 ( 405 date_ops 1082 t 0 )); -DATA(insert OID = 1970 ( 403 float4_ops 700 t 0 )); -DATA(insert OID = 1971 ( 405 float4_ops 700 t 0 )); -DATA(insert OID = 1972 ( 403 float8_ops 701 t 0 )); -DATA(insert OID = 1973 ( 405 float8_ops 701 t 0 )); -DATA(insert OID = 1974 ( 403 inet_ops 869 t 0 )); -DATA(insert OID = 1975 ( 405 inet_ops 869 t 0 )); -DATA(insert OID = 1976 ( 403 int2_ops 21 t 0 )); +DATA(insert OID = 421 ( 403 abstime_ops PGNSP PGUID 702 t 0 )); +DATA(insert OID = 422 ( 402 bigbox_ops PGNSP PGUID 603 f 0 )); +DATA(insert OID = 423 ( 403 bit_ops PGNSP PGUID 1560 t 0 )); +DATA(insert OID = 424 ( 403 bool_ops PGNSP PGUID 16 t 0 )); +DATA(insert OID = 425 ( 402 box_ops PGNSP PGUID 603 t 0 )); +DATA(insert OID = 426 ( 403 bpchar_ops PGNSP PGUID 1042 t 0 )); +DATA(insert OID = 427 ( 405 bpchar_ops PGNSP PGUID 1042 t 0 )); +DATA(insert OID = 428 ( 403 bytea_ops PGNSP PGUID 17 t 0 )); +DATA(insert OID = 429 ( 403 char_ops PGNSP PGUID 18 t 0 )); +DATA(insert OID = 431 ( 405 char_ops PGNSP PGUID 18 t 0 )); +DATA(insert OID = 432 ( 403 cidr_ops PGNSP PGUID 650 t 0 )); +DATA(insert OID = 433 ( 405 cidr_ops PGNSP PGUID 650 t 0 )); +DATA(insert OID = 434 ( 403 date_ops PGNSP PGUID 1082 t 0 )); +DATA(insert OID = 435 ( 405 date_ops PGNSP PGUID 1082 t 0 )); +DATA(insert OID = 1970 ( 403 float4_ops PGNSP PGUID 700 t 0 )); +DATA(insert OID = 1971 ( 405 float4_ops PGNSP PGUID 700 t 0 )); +DATA(insert OID = 1972 ( 403 float8_ops PGNSP PGUID 701 t 0 )); +DATA(insert OID = 1973 ( 405 float8_ops PGNSP PGUID 701 t 0 )); +DATA(insert OID = 1974 ( 403 inet_ops PGNSP PGUID 869 t 0 )); +DATA(insert OID = 1975 ( 405 inet_ops PGNSP PGUID 869 t 0 )); +DATA(insert OID = 1976 ( 403 int2_ops PGNSP PGUID 21 t 0 )); #define INT2_BTREE_OPS_OID 1976 -DATA(insert OID = 1977 ( 405 int2_ops 21 t 0 )); -DATA(insert OID = 1978 ( 403 int4_ops 23 t 0 )); +DATA(insert OID = 1977 ( 405 int2_ops PGNSP PGUID 21 t 0 )); +DATA(insert OID = 1978 ( 403 int4_ops PGNSP PGUID 23 t 0 )); #define INT4_BTREE_OPS_OID 1978 -DATA(insert OID = 1979 ( 405 int4_ops 23 t 0 )); -DATA(insert OID = 1980 ( 403 int8_ops 20 t 0 )); -DATA(insert OID = 1981 ( 405 int8_ops 20 t 0 )); -DATA(insert OID = 1982 ( 403 interval_ops 1186 t 0 )); -DATA(insert OID = 1983 ( 405 interval_ops 1186 t 0 )); -DATA(insert OID = 1984 ( 403 macaddr_ops 829 t 0 )); -DATA(insert OID = 1985 ( 405 macaddr_ops 829 t 0 )); -DATA(insert OID = 1986 ( 403 name_ops 19 t 0 )); -DATA(insert OID = 1987 ( 405 name_ops 19 t 0 )); -DATA(insert OID = 1988 ( 403 numeric_ops 1700 t 0 )); -DATA(insert OID = 1989 ( 403 oid_ops 26 t 0 )); +DATA(insert OID = 1979 ( 405 int4_ops PGNSP PGUID 23 t 0 )); +DATA(insert OID = 1980 ( 403 int8_ops PGNSP PGUID 20 t 0 )); +DATA(insert OID = 1981 ( 405 int8_ops PGNSP PGUID 20 t 0 )); +DATA(insert OID = 1982 ( 403 interval_ops PGNSP PGUID 1186 t 0 )); +DATA(insert OID = 1983 ( 405 interval_ops PGNSP PGUID 1186 t 0 )); +DATA(insert OID = 1984 ( 403 macaddr_ops PGNSP PGUID 829 t 0 )); +DATA(insert OID = 1985 ( 405 macaddr_ops PGNSP PGUID 829 t 0 )); +DATA(insert OID = 1986 ( 403 name_ops PGNSP PGUID 19 t 0 )); +DATA(insert OID = 1987 ( 405 name_ops PGNSP PGUID 19 t 0 )); +DATA(insert OID = 1988 ( 403 numeric_ops PGNSP PGUID 1700 t 0 )); +DATA(insert OID = 1989 ( 403 oid_ops PGNSP PGUID 26 t 0 )); #define OID_BTREE_OPS_OID 1989 -DATA(insert OID = 1990 ( 405 oid_ops 26 t 0 )); -DATA(insert OID = 1991 ( 403 oidvector_ops 30 t 0 )); -DATA(insert OID = 1992 ( 405 oidvector_ops 30 t 0 )); -DATA(insert OID = 1993 ( 402 poly_ops 604 t 0 )); -DATA(insert OID = 1994 ( 403 text_ops 25 t 0 )); -DATA(insert OID = 1995 ( 405 text_ops 25 t 0 )); -DATA(insert OID = 1996 ( 403 time_ops 1083 t 0 )); -DATA(insert OID = 1997 ( 405 time_ops 1083 t 0 )); -DATA(insert OID = 1998 ( 403 timestamptz_ops 1184 t 0 )); -DATA(insert OID = 1999 ( 405 timestamptz_ops 1184 t 0 )); -DATA(insert OID = 2000 ( 403 timetz_ops 1266 t 0 )); -DATA(insert OID = 2001 ( 405 timetz_ops 1266 t 0 )); -DATA(insert OID = 2002 ( 403 varbit_ops 1562 t 0 )); -DATA(insert OID = 2003 ( 403 varchar_ops 1043 t 0 )); -DATA(insert OID = 2004 ( 405 varchar_ops 1043 t 0 )); -DATA(insert OID = 2039 ( 403 timestamp_ops 1114 t 0 )); -DATA(insert OID = 2040 ( 405 timestamp_ops 1114 t 0 )); +DATA(insert OID = 1990 ( 405 oid_ops PGNSP PGUID 26 t 0 )); +DATA(insert OID = 1991 ( 403 oidvector_ops PGNSP PGUID 30 t 0 )); +DATA(insert OID = 1992 ( 405 oidvector_ops PGNSP PGUID 30 t 0 )); +DATA(insert OID = 1993 ( 402 poly_ops PGNSP PGUID 604 t 0 )); +DATA(insert OID = 1994 ( 403 text_ops PGNSP PGUID 25 t 0 )); +DATA(insert OID = 1995 ( 405 text_ops PGNSP PGUID 25 t 0 )); +DATA(insert OID = 1996 ( 403 time_ops PGNSP PGUID 1083 t 0 )); +DATA(insert OID = 1997 ( 405 time_ops PGNSP PGUID 1083 t 0 )); +DATA(insert OID = 1998 ( 403 timestamptz_ops PGNSP PGUID 1184 t 0 )); +DATA(insert OID = 1999 ( 405 timestamptz_ops PGNSP PGUID 1184 t 0 )); +DATA(insert OID = 2000 ( 403 timetz_ops PGNSP PGUID 1266 t 0 )); +DATA(insert OID = 2001 ( 405 timetz_ops PGNSP PGUID 1266 t 0 )); +DATA(insert OID = 2002 ( 403 varbit_ops PGNSP PGUID 1562 t 0 )); +DATA(insert OID = 2003 ( 403 varchar_ops PGNSP PGUID 1043 t 0 )); +DATA(insert OID = 2004 ( 405 varchar_ops PGNSP PGUID 1043 t 0 )); +DATA(insert OID = 2039 ( 403 timestamp_ops PGNSP PGUID 1114 t 0 )); +DATA(insert OID = 2040 ( 405 timestamp_ops PGNSP PGUID 1114 t 0 )); #endif /* PG_OPCLASS_H */ diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index 7fe606825e40c4545a836f4c55af68c9c9273387..ba9ed9aa8de14e18343f5319ce4261a9519ff90a 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: parsenodes.h,v 1.170 2002/04/16 23:08:12 tgl Exp $ + * $Id: parsenodes.h,v 1.171 2002/04/17 20:57:57 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -401,7 +401,7 @@ typedef struct IndexElem char *name; /* name of attribute to index, or NULL */ List *funcname; /* qualified name of function */ List *args; /* list of names of function arguments */ - char *class; /* name of desired opclass; NULL = default */ + List *opclass; /* name of desired opclass; NIL = default */ } IndexElem; /* diff --git a/src/include/utils/syscache.h b/src/include/utils/syscache.h index e567a8b22b67bf99ab4f0f7cd5b41fcc96b10853..dbe50b37be63045b5b9edf1fa8f676fdacce0333 100644 --- a/src/include/utils/syscache.h +++ b/src/include/utils/syscache.h @@ -9,7 +9,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: syscache.h,v 1.45 2002/04/16 23:08:12 tgl Exp $ + * $Id: syscache.h,v 1.46 2002/04/17 20:57:57 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -36,7 +36,7 @@ #define AMPROCNUM 5 #define ATTNAME 6 #define ATTNUM 7 -#define CLAAMNAME 8 +#define CLAAMNAMENSP 8 #define CLAOID 9 #define GRONAME 10 #define GROSYSID 11 diff --git a/src/tutorial/complex.source b/src/tutorial/complex.source index c30e048f3cb22777ebc18108f4ce183c643c5f94..6fbaaf89dbd98590f109539e3f849b746ab33374 100644 --- a/src/tutorial/complex.source +++ b/src/tutorial/complex.source @@ -7,7 +7,7 @@ -- -- Copyright (c) 1994, Regents of the University of California -- --- $Id: complex.source,v 1.11 2001/10/26 20:45:33 tgl Exp $ +-- $Id: complex.source,v 1.12 2002/04/17 20:57:57 tgl Exp $ -- --------------------------------------------------------------------------- @@ -170,10 +170,12 @@ CREATE OPERATOR > ( restrict = scalargtsel, join = scalargtjoinsel ); -INSERT INTO pg_opclass (opcamid, opcname, opcintype, opcdefault, opckeytype) +INSERT INTO pg_opclass (opcamid, opcname, opcnamespace, opcowner, opcintype, opcdefault, opckeytype) VALUES ( (SELECT oid FROM pg_am WHERE amname = 'btree'), 'complex_abs_ops', + (SELECT oid FROM pg_namespace WHERE nspname = 'pg_catalog'), + 1, -- UID of superuser is hardwired to 1 as of PG 7.3 (SELECT oid FROM pg_type WHERE typname = 'complex'), true, 0);