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
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
-- 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);
-- 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);
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);
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);
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'));
-- 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);
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'));
<!--
-$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
-->
<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);
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>
*
*
* 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
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;
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
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;
}
;
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
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] =
* 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 $
*
*-------------------------------------------------------------------------
*/
#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"
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,
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
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
#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"
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);
}
/*
- * 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;
}
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;
* 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;
* 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 $
*
*-------------------------------------------------------------------------
*/
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;
}
* 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 $
*
*-------------------------------------------------------------------------
*/
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;
* 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
_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
* 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 $
*
*-------------------------------------------------------------------------
*/
iparam->name = pstrdup(key->name);
iparam->funcname = NIL;
iparam->args = NIL;
- iparam->class = NULL;
+ iparam->opclass = NIL;
index->indexParams = lappend(index->indexParams, iparam);
}
*
*
* 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
%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
$$->name = NULL;
$$->funcname = $1;
$$->args = $3;
- $$->class = $5;
+ $$->opclass = $5;
}
;
$$->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
* 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; }
;
/*****************************************************************************
database_name: ColId { $$ = $1; };
access_method: ColId { $$ = $1; };
attr_name: ColId { $$ = $1; };
-class: ColId { $$ = $1; };
index_name: ColId { $$ = $1; };
file_name: Sconst { $$ = $1; };
*
*
* 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
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 */
* 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 $
*
*-------------------------------------------------------------------------
*/
*/
/* yyyymmddN */
-#define CATALOG_VERSION_NO 200204161
+#define CATALOG_VERSION_NO 200204171
#endif
* 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 $
*
*-------------------------------------------------------------------------
*/
#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"
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));
* 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 $
*
*-------------------------------------------------------------------------
*/
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);
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);
* 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
{
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 */
* 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 */
* 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 $
*
*-------------------------------------------------------------------------
*/
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;
/*
* 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 $
*
*-------------------------------------------------------------------------
*/
#define AMPROCNUM 5
#define ATTNAME 6
#define ATTNUM 7
-#define CLAAMNAME 8
+#define CLAAMNAMENSP 8
#define CLAOID 9
#define GRONAME 10
#define GROSYSID 11
--
-- 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 $
--
---------------------------------------------------------------------------
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);