Commit 27a54ae2 authored by Tom Lane's avatar Tom Lane

Opclasses live in namespaces. I also took the opportunity to create

an 'opclass owner' column in pg_opclass.  Nothing is done with it at
present, but since there are plans to invent a CREATE OPERATOR CLASS
command soon, we'll probably want DROP OPERATOR CLASS too, which
suggests that a notion of ownership would be a good idea.
parent d85a81cb
...@@ -41,12 +41,15 @@ create function gint4_union(bytea, opaque) returns int4 as 'MODULE_PATHNAME' lan ...@@ -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'; create function gint4_same(opaque, opaque, opaque) returns opaque as 'MODULE_PATHNAME' language 'C';
-- add a new opclass -- add a new opclass
INSERT INTO pg_opclass (opcamid, opcname, opcintype, opckeytype, opcdefault) INSERT INTO pg_opclass (opcamid, opcname, opcnamespace, opcowner, opcintype, opcdefault, opckeytype)
SELECT pg_am.oid, 'gist_int4_ops', pg_type.oid, pg_key.oid, true VALUES (
FROM pg_type, pg_am, pg_type pg_key (SELECT oid FROM pg_am WHERE amname = 'gist'),
WHERE pg_type.typname = 'int4' and 'gist_int4_ops',
pg_key.typname = 'int4key' and (SELECT oid FROM pg_namespace WHERE nspname = 'pg_catalog'),
pg_am.amname='gist'; 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 SELECT o.oid AS opoid, o.oprname
...@@ -170,12 +173,16 @@ create function gts_union(bytea, opaque) returns int4 as 'MODULE_PATHNAME' langu ...@@ -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'; create function gts_same(opaque, opaque, opaque) returns opaque as 'MODULE_PATHNAME' language 'C';
INSERT INTO pg_opclass (opcamid, opcname, opcintype, opckeytype, opcdefault) -- add a new opclass
SELECT pg_am.oid, 'gist_timestamp_ops', pg_type.oid, pg_key.oid, true INSERT INTO pg_opclass (opcamid, opcname, opcnamespace, opcowner, opcintype, opcdefault, opckeytype)
FROM pg_type, pg_am, pg_type pg_key VALUES (
WHERE pg_type.typname = 'timestamp' and (SELECT oid FROM pg_am WHERE amname = 'gist'),
pg_key.typname = 'tskey' and 'gist_timestamp_ops',
pg_am.amname='gist'; (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 SELECT o.oid AS opoid, o.oprname
INTO TABLE timestamp_ops_tmp INTO TABLE timestamp_ops_tmp
......
...@@ -212,10 +212,12 @@ CREATE FUNCTION g_cube_same(cube, cube, opaque) RETURNS opaque ...@@ -212,10 +212,12 @@ CREATE FUNCTION g_cube_same(cube, cube, opaque) RETURNS opaque
-- register the default opclass for indexing -- 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 ( VALUES (
(SELECT oid FROM pg_am WHERE amname = 'gist'), (SELECT oid FROM pg_am WHERE amname = 'gist'),
'gist_cube_ops', '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'), (SELECT oid FROM pg_type WHERE typname = 'cube'),
true, true,
0); 0);
......
...@@ -144,10 +144,12 @@ CREATE FUNCTION g_int_same(_int4, _int4, opaque) RETURNS opaque ...@@ -144,10 +144,12 @@ CREATE FUNCTION g_int_same(_int4, _int4, opaque) RETURNS opaque
-- register the default opclass for indexing -- 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 ( VALUES (
(SELECT oid FROM pg_am WHERE amname = 'gist'), (SELECT oid FROM pg_am WHERE amname = 'gist'),
'gist__int_ops', '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'), (SELECT oid FROM pg_type WHERE typname = '_int4'),
true, true,
0); 0);
...@@ -300,10 +302,12 @@ CREATE FUNCTION g_intbig_same(_int4, _int4, opaque) RETURNS opaque ...@@ -300,10 +302,12 @@ CREATE FUNCTION g_intbig_same(_int4, _int4, opaque) RETURNS opaque
AS 'MODULE_PATHNAME' LANGUAGE 'c'; AS 'MODULE_PATHNAME' LANGUAGE 'c';
-- register the opclass for indexing (not as default) -- 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 ( VALUES (
(SELECT oid FROM pg_am WHERE amname = 'gist'), (SELECT oid FROM pg_am WHERE amname = 'gist'),
'gist__intbig_ops', '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'), (SELECT oid FROM pg_type WHERE typname = '_int4'),
false, false,
0); 0);
......
...@@ -21,11 +21,13 @@ create function gbox_union(bytea, opaque) returns box as 'MODULE_PATHNAME' langu ...@@ -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'; create function gbox_same(box, box, opaque) returns opaque as 'MODULE_PATHNAME' language 'C';
-- add a new opclass (non-default) -- add a new opclass
INSERT INTO pg_opclass (opcamid, opcname, opcnamespace, opcowner, opcintype, opcdefault, opckeytype)
VALUES ( VALUES (
(SELECT oid FROM pg_am WHERE amname = 'gist'), (SELECT oid FROM pg_am WHERE amname = 'gist'),
'gist_box_ops', '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'), (SELECT oid FROM pg_type WHERE typname = 'box'),
true, true,
0); 0);
...@@ -183,11 +185,13 @@ create function gpoly_consistent(opaque,polygon,int4) returns bool as 'MODULE_PA ...@@ -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'; create function gpoly_compress(opaque) returns opaque as 'MODULE_PATHNAME' language 'C';
-- add a new opclass (non-default) -- add a new opclass
INSERT INTO pg_opclass (opcamid, opcname, opcnamespace, opcowner, opcintype, opcdefault, opckeytype)
VALUES ( VALUES (
(SELECT oid FROM pg_am WHERE amname = 'gist'), (SELECT oid FROM pg_am WHERE amname = 'gist'),
'gist_poly_ops', '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'), (SELECT oid FROM pg_type WHERE typname = 'polygon'),
true, true,
(SELECT oid FROM pg_type WHERE typname = 'box')); (SELECT oid FROM pg_type WHERE typname = 'box'));
......
...@@ -236,10 +236,12 @@ CREATE FUNCTION gseg_same(seg, seg, opaque) RETURNS opaque ...@@ -236,10 +236,12 @@ CREATE FUNCTION gseg_same(seg, seg, opaque) RETURNS opaque
-- register the default opclass for indexing -- 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 ( VALUES (
(SELECT oid FROM pg_am WHERE amname = 'gist'), (SELECT oid FROM pg_am WHERE amname = 'gist'),
'gist_seg_ops', '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'), (SELECT oid FROM pg_type WHERE typname = 'seg'),
true, true,
0); 0);
......
...@@ -155,10 +155,12 @@ CREATE FUNCTION gtxtidx_union(bytea, opaque) RETURNS _int4 ...@@ -155,10 +155,12 @@ CREATE FUNCTION gtxtidx_union(bytea, opaque) RETURNS _int4
CREATE FUNCTION gtxtidx_same(gtxtidx, gtxtidx, opaque) RETURNS opaque CREATE FUNCTION gtxtidx_same(gtxtidx, gtxtidx, opaque) RETURNS opaque
AS 'MODULE_PATHNAME' LANGUAGE 'c'; 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 ( VALUES (
(SELECT oid FROM pg_am WHERE amname = 'gist'), (SELECT oid FROM pg_am WHERE amname = 'gist'),
'gist_txtidx_ops', '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'), (SELECT oid FROM pg_type WHERE typname = 'txtidx'),
true, true,
(SELECT oid FROM pg_type WHERE typname = 'gtxtidx')); (SELECT oid FROM pg_type WHERE typname = 'gtxtidx'));
......
<!-- <!--
$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 PostgreSQL documentation
--> -->
...@@ -280,10 +280,12 @@ SELECT oid FROM pg_am WHERE amname = 'btree'; ...@@ -280,10 +280,12 @@ SELECT oid FROM pg_am WHERE amname = 'btree';
<classname>pg_opclass</classname>: <classname>pg_opclass</classname>:
<programlisting> <programlisting>
INSERT INTO pg_opclass (opcamid, opcname, opcintype, opcdefault, opckeytype) INSERT INTO pg_opclass (opcamid, opcname, opcnamespace, opcowner, opcintype, opcdefault, opckeytype)
VALUES ( VALUES (
(SELECT oid FROM pg_am WHERE amname = 'btree'), (SELECT oid FROM pg_am WHERE amname = 'btree'),
'complex_abs_ops', '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'), (SELECT oid FROM pg_type WHERE typname = 'complex'),
true, true,
0); 0);
...@@ -292,9 +294,9 @@ SELECT oid, * ...@@ -292,9 +294,9 @@ SELECT oid, *
FROM pg_opclass FROM pg_opclass
WHERE opcname = 'complex_abs_ops'; WHERE opcname = 'complex_abs_ops';
oid | opcamid | opcname | opcintype | opcdefault | opckeytype oid | opcamid | opcname | opcnamespace | opcowner | opcintype | opcdefault | opckeytype
--------+---------+-----------------+-----------+------------+------------ --------+---------+-----------------+--------------+----------+-----------+------------+------------
277975 | 403 | complex_abs_ops | 277946 | t | 0 277975 | 403 | complex_abs_ops | 11 | 1 | 277946 | t | 0
(1 row) (1 row)
</programlisting> </programlisting>
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 * INTERFACE ROUTINES
* index_open - open an index relation by relation OID * index_open - open an index relation by relation OID
...@@ -498,10 +498,23 @@ index_getprocinfo(Relation irel, ...@@ -498,10 +498,23 @@ index_getprocinfo(Relation irel,
if (locinfo->fn_oid == InvalidOid) if (locinfo->fn_oid == InvalidOid)
{ {
RegProcedure *loc = irel->rd_support; RegProcedure *loc = irel->rd_support;
RegProcedure procId;
Assert(loc != NULL); 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; return locinfo;
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * 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: ...@@ -273,7 +273,7 @@ boot_index_param:
IndexElem *n = makeNode(IndexElem); IndexElem *n = makeNode(IndexElem);
n->name = LexIDStr($1); n->name = LexIDStr($1);
n->funcname = n->args = NIL; /* no func indexes */ n->funcname = n->args = NIL; /* no func indexes */
n->class = LexIDStr($2); n->opclass = makeList1(makeString(LexIDStr($2)));
$$ = n; $$ = n;
} }
; ;
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * 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] = ...@@ -60,7 +60,7 @@ char *Name_pg_largeobject_indices[Num_pg_largeobject_indices] =
char *Name_pg_namespace_indices[Num_pg_namespace_indices] = char *Name_pg_namespace_indices[Num_pg_namespace_indices] =
{NamespaceNameIndex, NamespaceOidIndex}; {NamespaceNameIndex, NamespaceOidIndex};
char *Name_pg_opclass_indices[Num_pg_opclass_indices] = char *Name_pg_opclass_indices[Num_pg_opclass_indices] =
{OpclassAmNameIndex, OpclassOidIndex}; {OpclassAmNameNspIndex, OpclassOidIndex};
char *Name_pg_operator_indices[Num_pg_operator_indices] = char *Name_pg_operator_indices[Num_pg_operator_indices] =
{OperatorOidIndex, OperatorNameNspIndex}; {OperatorOidIndex, OperatorNameNspIndex};
char *Name_pg_proc_indices[Num_pg_proc_indices] = char *Name_pg_proc_indices[Num_pg_proc_indices] =
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * 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 @@ ...@@ -27,6 +27,7 @@
#include "catalog/namespace.h" #include "catalog/namespace.h"
#include "catalog/pg_inherits.h" #include "catalog/pg_inherits.h"
#include "catalog/pg_namespace.h" #include "catalog/pg_namespace.h"
#include "catalog/pg_opclass.h"
#include "catalog/pg_operator.h" #include "catalog/pg_operator.h"
#include "catalog/pg_proc.h" #include "catalog/pg_proc.h"
#include "catalog/pg_shadow.h" #include "catalog/pg_shadow.h"
...@@ -311,6 +312,54 @@ TypenameGetTypid(const char *typname) ...@@ -311,6 +312,54 @@ TypenameGetTypid(const char *typname)
return InvalidOid; 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 * FuncnameGetCandidates
* Given a possibly-qualified function name and argument count, * Given a possibly-qualified function name and argument count,
...@@ -652,6 +701,123 @@ OpernameGetCandidates(List *names, char oprkind) ...@@ -652,6 +701,123 @@ OpernameGetCandidates(List *names, char oprkind)
return resultList; 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 * QualifiedNameGetCreationNamespace
* Given a possibly-qualified name for an object (in List-of-Values * Given a possibly-qualified name for an object (in List-of-Values
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 @@ ...@@ -31,7 +31,6 @@
#include "parser/parse_coerce.h" #include "parser/parse_coerce.h"
#include "parser/parse_func.h" #include "parser/parse_func.h"
#include "utils/builtins.h" #include "utils/builtins.h"
#include "utils/fmgroids.h"
#include "utils/lsyscache.h" #include "utils/lsyscache.h"
#include "utils/syscache.h" #include "utils/syscache.h"
...@@ -390,11 +389,14 @@ static Oid ...@@ -390,11 +389,14 @@ static Oid
GetAttrOpClass(IndexElem *attribute, Oid attrType, GetAttrOpClass(IndexElem *attribute, Oid attrType,
char *accessMethodName, Oid accessMethodId) char *accessMethodName, Oid accessMethodId)
{ {
char *catalogname;
char *schemaname = NULL;
char *opcname = NULL;
HeapTuple tuple; HeapTuple tuple;
Oid opClassId, Oid opClassId,
opInputType; opInputType;
if (attribute->class == NULL) if (attribute->opclass == NIL)
{ {
/* no operator class specified, so find the default */ /* no operator class specified, so find the default */
opClassId = GetDefaultOpClass(attrType, accessMethodId); opClassId = GetDefaultOpClass(attrType, accessMethodId);
...@@ -407,23 +409,79 @@ GetAttrOpClass(IndexElem *attribute, Oid attrType, ...@@ -407,23 +409,79 @@ GetAttrOpClass(IndexElem *attribute, Oid attrType,
} }
/* /*
* Find the index operator class and verify that it accepts this * Specific opclass name given, so look up the opclass.
* datatype. Note we will accept binary compatibility.
*/ */
tuple = SearchSysCache(CLAAMNAME,
ObjectIdGetDatum(accessMethodId), /* deconstruct the name list */
PointerGetDatum(attribute->class), switch (length(attribute->opclass))
0, 0); {
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)) if (!HeapTupleIsValid(tuple))
elog(ERROR, "DefineIndex: operator class \"%s\" not supported by access method \"%s\"", 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; opClassId = tuple->t_data->t_oid;
opInputType = ((Form_pg_opclass) GETSTRUCT(tuple))->opcintype; opInputType = ((Form_pg_opclass) GETSTRUCT(tuple))->opcintype;
ReleaseSysCache(tuple);
if (!IsBinaryCompatible(attrType, opInputType)) if (!IsBinaryCompatible(attrType, opInputType))
elog(ERROR, "operator class \"%s\" does not accept data type %s", 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; return opClassId;
} }
...@@ -431,10 +489,7 @@ GetAttrOpClass(IndexElem *attribute, Oid attrType, ...@@ -431,10 +489,7 @@ GetAttrOpClass(IndexElem *attribute, Oid attrType,
static Oid static Oid
GetDefaultOpClass(Oid attrType, Oid accessMethodId) GetDefaultOpClass(Oid attrType, Oid accessMethodId)
{ {
Relation relation; OpclassCandidateList opclass;
ScanKeyData entry[1];
HeapScanDesc scan;
HeapTuple tuple;
int nexact = 0; int nexact = 0;
int ncompatible = 0; int ncompatible = 0;
Oid exactOid = InvalidOid; Oid exactOid = InvalidOid;
...@@ -449,44 +504,32 @@ GetDefaultOpClass(Oid attrType, Oid accessMethodId) ...@@ -449,44 +504,32 @@ GetDefaultOpClass(Oid attrType, Oid accessMethodId)
* require the user to specify which one he wants. If we find more * 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. * 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 * The initial search is done by namespace.c so that we only consider
* scan on opcamid won't be very selective, the indexscan would * opclasses visible in the current namespace search path.
* probably actually be slower than heapscan.
*/ */
ScanKeyEntryInitialize(&entry[0], 0x0, for (opclass = OpclassGetCandidates(accessMethodId);
Anum_pg_opclass_opcamid, opclass != NULL;
F_OIDEQ, opclass = opclass->next)
ObjectIdGetDatum(accessMethodId));
relation = heap_openr(OperatorClassRelationName, AccessShareLock);
scan = heap_beginscan(relation, false, SnapshotNow, 1, entry);
while (HeapTupleIsValid(tuple = heap_getnext(scan, 0)))
{ {
Form_pg_opclass opclass = (Form_pg_opclass) GETSTRUCT(tuple);
if (opclass->opcdefault) if (opclass->opcdefault)
{ {
if (opclass->opcintype == attrType) if (opclass->opcintype == attrType)
{ {
nexact++; nexact++;
exactOid = tuple->t_data->t_oid; exactOid = opclass->oid;
} }
else if (IsBinaryCompatible(opclass->opcintype, attrType)) else if (IsBinaryCompatible(opclass->opcintype, attrType))
{ {
ncompatible++; ncompatible++;
compatibleOid = tuple->t_data->t_oid; compatibleOid = opclass->oid;
} }
} }
} }
heap_endscan(scan);
heap_close(relation, AccessShareLock);
if (nexact == 1) if (nexact == 1)
return exactOid; return exactOid;
if (nexact != 0) 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)); format_type_be(attrType));
if (ncompatible == 1) if (ncompatible == 1)
return compatibleOid; return compatibleOid;
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * 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) ...@@ -1714,8 +1714,7 @@ _copyIndexElem(IndexElem *from)
newnode->name = pstrdup(from->name); newnode->name = pstrdup(from->name);
Node_Copy(from, newnode, funcname); Node_Copy(from, newnode, funcname);
Node_Copy(from, newnode, args); Node_Copy(from, newnode, args);
if (from->class) Node_Copy(from, newnode, opclass);
newnode->class = pstrdup(from->class);
return newnode; return newnode;
} }
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * 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) ...@@ -1599,7 +1599,7 @@ _equalIndexElem(IndexElem *a, IndexElem *b)
return false; return false;
if (!equal(a->args, b->args)) if (!equal(a->args, b->args))
return false; return false;
if (!equalstr(a->class, b->class)) if (!equal(a->opclass, b->opclass))
return false; return false;
return true; return true;
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 * NOTES
* Every (plan) node in POSTGRES has an associated "out" routine which * Every (plan) node in POSTGRES has an associated "out" routine which
...@@ -217,8 +217,8 @@ _outIndexElem(StringInfo str, IndexElem *node) ...@@ -217,8 +217,8 @@ _outIndexElem(StringInfo str, IndexElem *node)
_outNode(str, node->funcname); _outNode(str, node->funcname);
appendStringInfo(str, " :args "); appendStringInfo(str, " :args ");
_outNode(str, node->args); _outNode(str, node->args);
appendStringInfo(str, " :class "); appendStringInfo(str, " :opclass ");
_outToken(str, node->class); _outNode(str, node->opclass);
} }
static void static void
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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) ...@@ -1209,7 +1209,7 @@ transformIndexConstraints(ParseState *pstate, CreateStmtContext *cxt)
iparam->name = pstrdup(key->name); iparam->name = pstrdup(key->name);
iparam->funcname = NIL; iparam->funcname = NIL;
iparam->args = NIL; iparam->args = NIL;
iparam->class = NULL; iparam->opclass = NIL;
index->indexParams = lappend(index->indexParams, iparam); index->indexParams = lappend(index->indexParams, iparam);
} }
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
* *
* *
* IDENTIFICATION * 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 * HISTORY
* AUTHOR DATE MAJOR EVENT * AUTHOR DATE MAJOR EVENT
...@@ -174,15 +174,15 @@ static bool set_name_needs_quotes(const char *name); ...@@ -174,15 +174,15 @@ static bool set_name_needs_quotes(const char *name);
%type <str> relation_name, copy_file_name, copy_delimiter, copy_null, %type <str> relation_name, copy_file_name, copy_delimiter, copy_null,
database_name, access_method_clause, access_method, attr_name, 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 <range> qualified_name, OptConstrFromTable
%type <str> opt_id, %type <str> opt_id,
all_Op, MathOp, opt_name, all_Op, MathOp, opt_name, SpecialRuleRelation
opt_class, SpecialRuleRelation
%type <str> opt_level, opt_encoding %type <str> opt_level, opt_encoding
%type <node> grantee %type <node> grantee
...@@ -2614,7 +2614,7 @@ func_index: func_name '(' name_list ')' opt_class ...@@ -2614,7 +2614,7 @@ func_index: func_name '(' name_list ')' opt_class
$$->name = NULL; $$->name = NULL;
$$->funcname = $1; $$->funcname = $1;
$$->args = $3; $$->args = $3;
$$->class = $5; $$->opclass = $5;
} }
; ;
...@@ -2624,11 +2624,11 @@ index_elem: attr_name opt_class ...@@ -2624,11 +2624,11 @@ index_elem: attr_name opt_class
$$->name = $1; $$->name = $1;
$$->funcname = NIL; $$->funcname = NIL;
$$->args = NIL; $$->args = NIL;
$$->class = $2; $$->opclass = $2;
} }
; ;
opt_class: class opt_class: any_name
{ {
/* /*
* Release 7.0 removed network_ops, timespan_ops, and * Release 7.0 removed network_ops, timespan_ops, and
...@@ -2643,17 +2643,24 @@ opt_class: class ...@@ -2643,17 +2643,24 @@ opt_class: class
* so suppress that too for awhile. I'm starting to * so suppress that too for awhile. I'm starting to
* think we need a better approach. tgl 2000/10/01 * think we need a better approach. tgl 2000/10/01
*/ */
if (strcmp($1, "network_ops") != 0 && if (length($1) == 1)
strcmp($1, "timespan_ops") != 0 && {
strcmp($1, "datetime_ops") != 0 && char *claname = strVal(lfirst($1));
strcmp($1, "lztext_ops") != 0 &&
strcmp($1, "timestamp_ops") != 0) if (strcmp(claname, "network_ops") != 0 &&
$$ = $1; strcmp(claname, "timespan_ops") != 0 &&
strcmp(claname, "datetime_ops") != 0 &&
strcmp(claname, "lztext_ops") != 0 &&
strcmp(claname, "timestamp_ops") != 0)
$$ = $1;
else
$$ = NIL;
}
else else
$$ = NULL; $$ = $1;
} }
| USING class { $$ = $2; } | USING any_name { $$ = $2; }
| /*EMPTY*/ { $$ = NULL; } | /*EMPTY*/ { $$ = NIL; }
; ;
/***************************************************************************** /*****************************************************************************
...@@ -5782,7 +5789,6 @@ name: ColId { $$ = $1; }; ...@@ -5782,7 +5789,6 @@ name: ColId { $$ = $1; };
database_name: ColId { $$ = $1; }; database_name: ColId { $$ = $1; };
access_method: ColId { $$ = $1; }; access_method: ColId { $$ = $1; };
attr_name: ColId { $$ = $1; }; attr_name: ColId { $$ = $1; };
class: ColId { $$ = $1; };
index_name: ColId { $$ = $1; }; index_name: ColId { $$ = $1; };
file_name: Sconst { $$ = $1; }; file_name: Sconst { $$ = $1; };
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 * NOTES
* These routines allow the parser/planner/executor to perform * These routines allow the parser/planner/executor to perform
...@@ -173,14 +173,14 @@ static const struct cachedesc cacheinfo[] = { ...@@ -173,14 +173,14 @@ static const struct cachedesc cacheinfo[] = {
0, 0,
0 0
}}, }},
{OperatorClassRelationName, /* CLAAMNAME */ {OperatorClassRelationName, /* CLAAMNAMENSP */
OpclassAmNameIndex, OpclassAmNameNspIndex,
0, 0,
2, 3,
{ {
Anum_pg_opclass_opcamid, Anum_pg_opclass_opcamid,
Anum_pg_opclass_opcname, Anum_pg_opclass_opcname,
0, Anum_pg_opclass_opcnamespace,
0 0
}}, }},
{OperatorClassRelationName, /* CLAOID */ {OperatorClassRelationName, /* CLAOID */
......
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 @@ ...@@ -53,6 +53,6 @@
*/ */
/* yyyymmddN */ /* yyyymmddN */
#define CATALOG_VERSION_NO 200204161 #define CATALOG_VERSION_NO 200204171
#endif #endif
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 @@ ...@@ -72,7 +72,7 @@
#define LargeObjectLOidPNIndex "pg_largeobject_loid_pn_index" #define LargeObjectLOidPNIndex "pg_largeobject_loid_pn_index"
#define NamespaceNameIndex "pg_namespace_nspname_index" #define NamespaceNameIndex "pg_namespace_nspname_index"
#define NamespaceOidIndex "pg_namespace_oid_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 OpclassOidIndex "pg_opclass_oid_index"
#define OperatorNameNspIndex "pg_operator_oprname_l_r_n_index" #define OperatorNameNspIndex "pg_operator_oprname_l_r_n_index"
#define OperatorOidIndex "pg_operator_oid_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 ...@@ -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_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_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_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_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_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)); 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));
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 ...@@ -32,6 +32,21 @@ typedef struct _FuncCandidateList
Oid args[1]; /* arg types --- VARIABLE LENGTH ARRAY */ Oid args[1]; /* arg types --- VARIABLE LENGTH ARRAY */
} *FuncCandidateList; /* VARIABLE LENGTH STRUCT */ } *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); extern Oid RangeVarGetRelid(const RangeVar *relation, bool failOK);
...@@ -41,10 +56,14 @@ extern Oid RelnameGetRelid(const char *relname); ...@@ -41,10 +56,14 @@ extern Oid RelnameGetRelid(const char *relname);
extern Oid TypenameGetTypid(const char *typname); extern Oid TypenameGetTypid(const char *typname);
extern Oid OpclassnameGetOpcid(Oid amid, const char *opcname);
extern FuncCandidateList FuncnameGetCandidates(List *names, int nargs); extern FuncCandidateList FuncnameGetCandidates(List *names, int nargs);
extern FuncCandidateList OpernameGetCandidates(List *names, char oprkind); extern FuncCandidateList OpernameGetCandidates(List *names, char oprkind);
extern OpclassCandidateList OpclassGetCandidates(Oid amid);
extern Oid QualifiedNameGetCreationNamespace(List *names, char **objname_p); extern Oid QualifiedNameGetCreationNamespace(List *names, char **objname_p);
extern RangeVar *makeRangeVarFromNameList(List *names); extern RangeVar *makeRangeVarFromNameList(List *names);
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 * NOTES
* the genbki.sh script reads this file and generates .bki * the genbki.sh script reads this file and generates .bki
...@@ -54,6 +54,8 @@ CATALOG(pg_opclass) ...@@ -54,6 +54,8 @@ CATALOG(pg_opclass)
{ {
Oid opcamid; /* index access method opclass is for */ Oid opcamid; /* index access method opclass is for */
NameData opcname; /* name of this opclass */ NameData opcname; /* name of this opclass */
Oid opcnamespace; /* namespace of this opclass */
int4 opcowner; /* opclass owner */
Oid opcintype; /* type of input data for opclass */ Oid opcintype; /* type of input data for opclass */
bool opcdefault; /* T if opclass is default for opcintype */ bool opcdefault; /* T if opclass is default for opcintype */
Oid opckeytype; /* type of index data, or InvalidOid */ Oid opckeytype; /* type of index data, or InvalidOid */
...@@ -70,71 +72,73 @@ typedef FormData_pg_opclass *Form_pg_opclass; ...@@ -70,71 +72,73 @@ typedef FormData_pg_opclass *Form_pg_opclass;
* compiler constants for 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_opcamid 1
#define Anum_pg_opclass_opcname 2 #define Anum_pg_opclass_opcname 2
#define Anum_pg_opclass_opcintype 3 #define Anum_pg_opclass_opcnamespace 3
#define Anum_pg_opclass_opcdefault 4 #define Anum_pg_opclass_opcowner 4
#define Anum_pg_opclass_opckeytype 5 #define Anum_pg_opclass_opcintype 5
#define Anum_pg_opclass_opcdefault 6
#define Anum_pg_opclass_opckeytype 7
/* ---------------- /* ----------------
* initial contents of pg_opclass * initial contents of pg_opclass
* ---------------- * ----------------
*/ */
DATA(insert OID = 421 ( 403 abstime_ops 702 t 0 )); DATA(insert OID = 421 ( 403 abstime_ops PGNSP PGUID 702 t 0 ));
DATA(insert OID = 422 ( 402 bigbox_ops 603 f 0 )); DATA(insert OID = 422 ( 402 bigbox_ops PGNSP PGUID 603 f 0 ));
DATA(insert OID = 423 ( 403 bit_ops 1560 t 0 )); DATA(insert OID = 423 ( 403 bit_ops PGNSP PGUID 1560 t 0 ));
DATA(insert OID = 424 ( 403 bool_ops 16 t 0 )); DATA(insert OID = 424 ( 403 bool_ops PGNSP PGUID 16 t 0 ));
DATA(insert OID = 425 ( 402 box_ops 603 t 0 )); DATA(insert OID = 425 ( 402 box_ops PGNSP PGUID 603 t 0 ));
DATA(insert OID = 426 ( 403 bpchar_ops 1042 t 0 )); DATA(insert OID = 426 ( 403 bpchar_ops PGNSP PGUID 1042 t 0 ));
DATA(insert OID = 427 ( 405 bpchar_ops 1042 t 0 )); DATA(insert OID = 427 ( 405 bpchar_ops PGNSP PGUID 1042 t 0 ));
DATA(insert OID = 428 ( 403 bytea_ops 17 t 0 )); DATA(insert OID = 428 ( 403 bytea_ops PGNSP PGUID 17 t 0 ));
DATA(insert OID = 429 ( 403 char_ops 18 t 0 )); DATA(insert OID = 429 ( 403 char_ops PGNSP PGUID 18 t 0 ));
DATA(insert OID = 431 ( 405 char_ops 18 t 0 )); DATA(insert OID = 431 ( 405 char_ops PGNSP PGUID 18 t 0 ));
DATA(insert OID = 432 ( 403 cidr_ops 650 t 0 )); DATA(insert OID = 432 ( 403 cidr_ops PGNSP PGUID 650 t 0 ));
DATA(insert OID = 433 ( 405 cidr_ops 650 t 0 )); DATA(insert OID = 433 ( 405 cidr_ops PGNSP PGUID 650 t 0 ));
DATA(insert OID = 434 ( 403 date_ops 1082 t 0 )); DATA(insert OID = 434 ( 403 date_ops PGNSP PGUID 1082 t 0 ));
DATA(insert OID = 435 ( 405 date_ops 1082 t 0 )); DATA(insert OID = 435 ( 405 date_ops PGNSP PGUID 1082 t 0 ));
DATA(insert OID = 1970 ( 403 float4_ops 700 t 0 )); DATA(insert OID = 1970 ( 403 float4_ops PGNSP PGUID 700 t 0 ));
DATA(insert OID = 1971 ( 405 float4_ops 700 t 0 )); DATA(insert OID = 1971 ( 405 float4_ops PGNSP PGUID 700 t 0 ));
DATA(insert OID = 1972 ( 403 float8_ops 701 t 0 )); DATA(insert OID = 1972 ( 403 float8_ops PGNSP PGUID 701 t 0 ));
DATA(insert OID = 1973 ( 405 float8_ops 701 t 0 )); DATA(insert OID = 1973 ( 405 float8_ops PGNSP PGUID 701 t 0 ));
DATA(insert OID = 1974 ( 403 inet_ops 869 t 0 )); DATA(insert OID = 1974 ( 403 inet_ops PGNSP PGUID 869 t 0 ));
DATA(insert OID = 1975 ( 405 inet_ops 869 t 0 )); DATA(insert OID = 1975 ( 405 inet_ops PGNSP PGUID 869 t 0 ));
DATA(insert OID = 1976 ( 403 int2_ops 21 t 0 )); DATA(insert OID = 1976 ( 403 int2_ops PGNSP PGUID 21 t 0 ));
#define INT2_BTREE_OPS_OID 1976 #define INT2_BTREE_OPS_OID 1976
DATA(insert OID = 1977 ( 405 int2_ops 21 t 0 )); DATA(insert OID = 1977 ( 405 int2_ops PGNSP PGUID 21 t 0 ));
DATA(insert OID = 1978 ( 403 int4_ops 23 t 0 )); DATA(insert OID = 1978 ( 403 int4_ops PGNSP PGUID 23 t 0 ));
#define INT4_BTREE_OPS_OID 1978 #define INT4_BTREE_OPS_OID 1978
DATA(insert OID = 1979 ( 405 int4_ops 23 t 0 )); DATA(insert OID = 1979 ( 405 int4_ops PGNSP PGUID 23 t 0 ));
DATA(insert OID = 1980 ( 403 int8_ops 20 t 0 )); DATA(insert OID = 1980 ( 403 int8_ops PGNSP PGUID 20 t 0 ));
DATA(insert OID = 1981 ( 405 int8_ops 20 t 0 )); DATA(insert OID = 1981 ( 405 int8_ops PGNSP PGUID 20 t 0 ));
DATA(insert OID = 1982 ( 403 interval_ops 1186 t 0 )); DATA(insert OID = 1982 ( 403 interval_ops PGNSP PGUID 1186 t 0 ));
DATA(insert OID = 1983 ( 405 interval_ops 1186 t 0 )); DATA(insert OID = 1983 ( 405 interval_ops PGNSP PGUID 1186 t 0 ));
DATA(insert OID = 1984 ( 403 macaddr_ops 829 t 0 )); DATA(insert OID = 1984 ( 403 macaddr_ops PGNSP PGUID 829 t 0 ));
DATA(insert OID = 1985 ( 405 macaddr_ops 829 t 0 )); DATA(insert OID = 1985 ( 405 macaddr_ops PGNSP PGUID 829 t 0 ));
DATA(insert OID = 1986 ( 403 name_ops 19 t 0 )); DATA(insert OID = 1986 ( 403 name_ops PGNSP PGUID 19 t 0 ));
DATA(insert OID = 1987 ( 405 name_ops 19 t 0 )); DATA(insert OID = 1987 ( 405 name_ops PGNSP PGUID 19 t 0 ));
DATA(insert OID = 1988 ( 403 numeric_ops 1700 t 0 )); DATA(insert OID = 1988 ( 403 numeric_ops PGNSP PGUID 1700 t 0 ));
DATA(insert OID = 1989 ( 403 oid_ops 26 t 0 )); DATA(insert OID = 1989 ( 403 oid_ops PGNSP PGUID 26 t 0 ));
#define OID_BTREE_OPS_OID 1989 #define OID_BTREE_OPS_OID 1989
DATA(insert OID = 1990 ( 405 oid_ops 26 t 0 )); DATA(insert OID = 1990 ( 405 oid_ops PGNSP PGUID 26 t 0 ));
DATA(insert OID = 1991 ( 403 oidvector_ops 30 t 0 )); DATA(insert OID = 1991 ( 403 oidvector_ops PGNSP PGUID 30 t 0 ));
DATA(insert OID = 1992 ( 405 oidvector_ops 30 t 0 )); DATA(insert OID = 1992 ( 405 oidvector_ops PGNSP PGUID 30 t 0 ));
DATA(insert OID = 1993 ( 402 poly_ops 604 t 0 )); DATA(insert OID = 1993 ( 402 poly_ops PGNSP PGUID 604 t 0 ));
DATA(insert OID = 1994 ( 403 text_ops 25 t 0 )); DATA(insert OID = 1994 ( 403 text_ops PGNSP PGUID 25 t 0 ));
DATA(insert OID = 1995 ( 405 text_ops 25 t 0 )); DATA(insert OID = 1995 ( 405 text_ops PGNSP PGUID 25 t 0 ));
DATA(insert OID = 1996 ( 403 time_ops 1083 t 0 )); DATA(insert OID = 1996 ( 403 time_ops PGNSP PGUID 1083 t 0 ));
DATA(insert OID = 1997 ( 405 time_ops 1083 t 0 )); DATA(insert OID = 1997 ( 405 time_ops PGNSP PGUID 1083 t 0 ));
DATA(insert OID = 1998 ( 403 timestamptz_ops 1184 t 0 )); DATA(insert OID = 1998 ( 403 timestamptz_ops PGNSP PGUID 1184 t 0 ));
DATA(insert OID = 1999 ( 405 timestamptz_ops 1184 t 0 )); DATA(insert OID = 1999 ( 405 timestamptz_ops PGNSP PGUID 1184 t 0 ));
DATA(insert OID = 2000 ( 403 timetz_ops 1266 t 0 )); DATA(insert OID = 2000 ( 403 timetz_ops PGNSP PGUID 1266 t 0 ));
DATA(insert OID = 2001 ( 405 timetz_ops 1266 t 0 )); DATA(insert OID = 2001 ( 405 timetz_ops PGNSP PGUID 1266 t 0 ));
DATA(insert OID = 2002 ( 403 varbit_ops 1562 t 0 )); DATA(insert OID = 2002 ( 403 varbit_ops PGNSP PGUID 1562 t 0 ));
DATA(insert OID = 2003 ( 403 varchar_ops 1043 t 0 )); DATA(insert OID = 2003 ( 403 varchar_ops PGNSP PGUID 1043 t 0 ));
DATA(insert OID = 2004 ( 405 varchar_ops 1043 t 0 )); DATA(insert OID = 2004 ( 405 varchar_ops PGNSP PGUID 1043 t 0 ));
DATA(insert OID = 2039 ( 403 timestamp_ops 1114 t 0 )); DATA(insert OID = 2039 ( 403 timestamp_ops PGNSP PGUID 1114 t 0 ));
DATA(insert OID = 2040 ( 405 timestamp_ops 1114 t 0 )); DATA(insert OID = 2040 ( 405 timestamp_ops PGNSP PGUID 1114 t 0 ));
#endif /* PG_OPCLASS_H */ #endif /* PG_OPCLASS_H */
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 ...@@ -401,7 +401,7 @@ typedef struct IndexElem
char *name; /* name of attribute to index, or NULL */ char *name; /* name of attribute to index, or NULL */
List *funcname; /* qualified name of function */ List *funcname; /* qualified name of function */
List *args; /* list of names of function arguments */ 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; } IndexElem;
/* /*
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 @@ ...@@ -36,7 +36,7 @@
#define AMPROCNUM 5 #define AMPROCNUM 5
#define ATTNAME 6 #define ATTNAME 6
#define ATTNUM 7 #define ATTNUM 7
#define CLAAMNAME 8 #define CLAAMNAMENSP 8
#define CLAOID 9 #define CLAOID 9
#define GRONAME 10 #define GRONAME 10
#define GROSYSID 11 #define GROSYSID 11
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
-- --
-- Copyright (c) 1994, Regents of the University of California -- 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 > ( ...@@ -170,10 +170,12 @@ CREATE OPERATOR > (
restrict = scalargtsel, join = scalargtjoinsel 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 ( VALUES (
(SELECT oid FROM pg_am WHERE amname = 'btree'), (SELECT oid FROM pg_am WHERE amname = 'btree'),
'complex_abs_ops', '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'), (SELECT oid FROM pg_type WHERE typname = 'complex'),
true, true,
0); 0);
......
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