aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/catalog/namespace.c115
-rw-r--r--src/backend/commands/indexcmds.c61
-rw-r--r--src/backend/utils/cache/typcache.c101
-rw-r--r--src/include/catalog/namespace.h18
-rw-r--r--src/include/commands/defrem.h3
5 files changed, 50 insertions, 248 deletions
diff --git a/src/backend/catalog/namespace.c b/src/backend/catalog/namespace.c
index 0f04bd0ba3c..fe61ee242ee 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
- * $PostgreSQL: pgsql/src/backend/catalog/namespace.c,v 1.80 2005/11/22 18:17:08 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/catalog/namespace.c,v 1.81 2006/02/10 19:01:12 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -912,119 +912,6 @@ OperatorIsVisible(Oid oprid)
/*
- * 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);
-
- recomputeNamespacePath();
-
- 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;
- ListCell *nsp;
-
- /* Consider only opclasses that are in the search path */
- foreach(nsp, namespaceSearchPath)
- {
- if (opcform->opcnamespace == lfirst_oid(nsp))
- break;
- pathpos++;
- }
- if (nsp == NULL)
- 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 = HeapTupleGetOid(opctup);
- 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 = HeapTupleGetOid(opctup);
- newResult->opcintype = opcform->opcintype;
- newResult->opcdefault = opcform->opcdefault;
- newResult->opckeytype = opcform->opckeytype;
- newResult->next = resultList;
- resultList = newResult;
- }
-
- ReleaseSysCacheList(catlist);
-
- return resultList;
-}
-
-/*
* OpclassnameGetOpcid
* Try to resolve an unqualified index opclass name.
* Returns OID if opclass found in search path, else InvalidOid.
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index 4a425d4eb23..aa6ed6f9c22 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -8,37 +8,36 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/indexcmds.c,v 1.136 2005/11/22 18:17:09 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/indexcmds.c,v 1.137 2006/02/10 19:01:12 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
+#include "access/genam.h"
#include "access/heapam.h"
#include "catalog/catalog.h"
#include "catalog/dependency.h"
#include "catalog/heap.h"
#include "catalog/index.h"
-#include "catalog/namespace.h"
+#include "catalog/indexing.h"
#include "catalog/pg_opclass.h"
-#include "catalog/pg_proc.h"
#include "catalog/pg_tablespace.h"
#include "commands/dbcommands.h"
#include "commands/defrem.h"
#include "commands/tablecmds.h"
#include "commands/tablespace.h"
-#include "executor/executor.h"
#include "mb/pg_wchar.h"
#include "miscadmin.h"
#include "optimizer/clauses.h"
-#include "optimizer/prep.h"
#include "parser/parsetree.h"
#include "parser/parse_coerce.h"
#include "parser/parse_expr.h"
#include "parser/parse_func.h"
#include "utils/acl.h"
#include "utils/builtins.h"
+#include "utils/fmgroids.h"
#include "utils/lsyscache.h"
#include "utils/memutils.h"
#include "utils/relcache.h"
@@ -54,7 +53,6 @@ static void ComputeIndexAttrs(IndexInfo *indexInfo, Oid *classOidP,
bool isconstraint);
static Oid GetIndexOpClass(List *opclass, Oid attrType,
char *accessMethodName, Oid accessMethodId);
-static Oid GetDefaultOpClass(Oid attrType, Oid accessMethodId);
static bool relationHasPrimaryKey(Relation rel);
@@ -658,17 +656,26 @@ GetIndexOpClass(List *opclass, Oid attrType,
return opClassId;
}
-static Oid
-GetDefaultOpClass(Oid attrType, Oid accessMethodId)
+/*
+ * GetDefaultOpClass
+ *
+ * Given the OIDs of a datatype and an access method, find the default
+ * operator class, if any. Returns InvalidOid if there is none.
+ */
+Oid
+GetDefaultOpClass(Oid type_id, Oid am_id)
{
- OpclassCandidateList opclass;
int nexact = 0;
int ncompatible = 0;
Oid exactOid = InvalidOid;
Oid compatibleOid = InvalidOid;
+ Relation rel;
+ ScanKeyData skey[1];
+ SysScanDesc scan;
+ HeapTuple tup;
/* If it's a domain, look at the base type instead */
- attrType = getBaseType(attrType);
+ type_id = getBaseType(type_id);
/*
* We scan through all the opclasses available for the access method,
@@ -678,37 +685,47 @@ GetDefaultOpClass(Oid attrType, Oid accessMethodId)
* We could find more than one binary-compatible match, in which case we
* 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.
- *
- * The initial search is done by namespace.c so that we only consider
- * opclasses visible in the current namespace search path. (See also
- * typcache.c, which applies the same logic, but over all opclasses.)
*/
- for (opclass = OpclassGetCandidates(accessMethodId);
- opclass != NULL;
- opclass = opclass->next)
+ rel = heap_open(OperatorClassRelationId, AccessShareLock);
+
+ ScanKeyInit(&skey[0],
+ Anum_pg_opclass_opcamid,
+ BTEqualStrategyNumber, F_OIDEQ,
+ ObjectIdGetDatum(am_id));
+
+ scan = systable_beginscan(rel, OpclassAmNameNspIndexId, true,
+ SnapshotNow, 1, skey);
+
+ while (HeapTupleIsValid(tup = systable_getnext(scan)))
{
+ Form_pg_opclass opclass = (Form_pg_opclass) GETSTRUCT(tup);
+
if (opclass->opcdefault)
{
- if (opclass->opcintype == attrType)
+ if (opclass->opcintype == type_id)
{
nexact++;
- exactOid = opclass->oid;
+ exactOid = HeapTupleGetOid(tup);
}
- else if (IsBinaryCoercible(attrType, opclass->opcintype))
+ else if (IsBinaryCoercible(type_id, opclass->opcintype))
{
ncompatible++;
- compatibleOid = opclass->oid;
+ compatibleOid = HeapTupleGetOid(tup);
}
}
}
+ systable_endscan(scan);
+
+ heap_close(rel, AccessShareLock);
+
if (nexact == 1)
return exactOid;
if (nexact != 0)
ereport(ERROR,
(errcode(ERRCODE_DUPLICATE_OBJECT),
errmsg("there are multiple default operator classes for data type %s",
- format_type_be(attrType))));
+ format_type_be(type_id))));
if (ncompatible == 1)
return compatibleOid;
diff --git a/src/backend/utils/cache/typcache.c b/src/backend/utils/cache/typcache.c
index 9726bd499bd..af03e2a7b0b 100644
--- a/src/backend/utils/cache/typcache.c
+++ b/src/backend/utils/cache/typcache.c
@@ -36,23 +36,19 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/cache/typcache.c,v 1.16 2005/11/22 18:17:24 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/cache/typcache.c,v 1.17 2006/02/10 19:01:12 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
-#include "access/genam.h"
#include "access/heapam.h"
#include "access/hash.h"
#include "access/nbtree.h"
-#include "catalog/indexing.h"
-#include "catalog/pg_am.h"
-#include "catalog/pg_opclass.h"
-#include "parser/parse_coerce.h"
+#include "catalog/pg_type.h"
+#include "commands/defrem.h"
#include "utils/builtins.h"
#include "utils/catcache.h"
-#include "utils/fmgroids.h"
#include "utils/hsearch.h"
#include "utils/lsyscache.h"
#include "utils/syscache.h"
@@ -92,9 +88,6 @@ static int32 RecordCacheArrayLen = 0; /* allocated length of array */
static int32 NextRecordTypmod = 0; /* number of entries used */
-static Oid lookup_default_opclass(Oid type_id, Oid am_id);
-
-
/*
* lookup_type_cache
*
@@ -177,14 +170,14 @@ lookup_type_cache(Oid type_id, int flags)
TYPECACHE_EQ_OPR_FINFO | TYPECACHE_CMP_PROC_FINFO)) &&
typentry->btree_opc == InvalidOid)
{
- typentry->btree_opc = lookup_default_opclass(type_id,
- BTREE_AM_OID);
+ typentry->btree_opc = GetDefaultOpClass(type_id,
+ BTREE_AM_OID);
/* Only care about hash opclass if no btree opclass... */
if (typentry->btree_opc == InvalidOid)
{
if (typentry->hash_opc == InvalidOid)
- typentry->hash_opc = lookup_default_opclass(type_id,
- HASH_AM_OID);
+ typentry->hash_opc = GetDefaultOpClass(type_id,
+ HASH_AM_OID);
}
else
{
@@ -290,86 +283,6 @@ lookup_type_cache(Oid type_id, int flags)
}
/*
- * lookup_default_opclass
- *
- * Given the OIDs of a datatype and an access method, find the default
- * operator class, if any. Returns InvalidOid if there is none.
- */
-static Oid
-lookup_default_opclass(Oid type_id, Oid am_id)
-{
- int nexact = 0;
- int ncompatible = 0;
- Oid exactOid = InvalidOid;
- Oid compatibleOid = InvalidOid;
- Relation rel;
- ScanKeyData skey[1];
- SysScanDesc scan;
- HeapTuple tup;
-
- /* If it's a domain, look at the base type instead */
- type_id = getBaseType(type_id);
-
- /*
- * We scan through all the opclasses available for the access method,
- * looking for one that is marked default and matches the target type
- * (either exactly or binary-compatibly, but prefer an exact match).
- *
- * We could find more than one binary-compatible match, in which case we
- * 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.
- *
- * This is the same logic as GetDefaultOpClass() in indexcmds.c, except
- * that we consider all opclasses, regardless of the current search path.
- */
- rel = heap_open(OperatorClassRelationId, AccessShareLock);
-
- ScanKeyInit(&skey[0],
- Anum_pg_opclass_opcamid,
- BTEqualStrategyNumber, F_OIDEQ,
- ObjectIdGetDatum(am_id));
-
- scan = systable_beginscan(rel, OpclassAmNameNspIndexId, true,
- SnapshotNow, 1, skey);
-
- while (HeapTupleIsValid(tup = systable_getnext(scan)))
- {
- Form_pg_opclass opclass = (Form_pg_opclass) GETSTRUCT(tup);
-
- if (opclass->opcdefault)
- {
- if (opclass->opcintype == type_id)
- {
- nexact++;
- exactOid = HeapTupleGetOid(tup);
- }
- else if (IsBinaryCoercible(type_id, opclass->opcintype))
- {
- ncompatible++;
- compatibleOid = HeapTupleGetOid(tup);
- }
- }
- }
-
- systable_endscan(scan);
-
- heap_close(rel, AccessShareLock);
-
- if (nexact == 1)
- return exactOid;
- if (nexact != 0)
- ereport(ERROR,
- (errcode(ERRCODE_DUPLICATE_OBJECT),
- errmsg("there are multiple default operator classes for data type %s",
- format_type_be(type_id))));
- if (ncompatible == 1)
- return compatibleOid;
-
- return InvalidOid;
-}
-
-
-/*
* lookup_rowtype_tupdesc
*
* Given a typeid/typmod that should describe a known composite type,
diff --git a/src/include/catalog/namespace.h b/src/include/catalog/namespace.h
index d3f0dc98098..4f2d1ef5061 100644
--- a/src/include/catalog/namespace.h
+++ b/src/include/catalog/namespace.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/catalog/namespace.h,v 1.37 2005/10/15 02:49:42 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/namespace.h,v 1.38 2006/02/10 19:01:12 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -32,21 +32,6 @@ 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 data indexed by opclass */
- bool opcdefault; /* T if opclass is default for opcintype */
- Oid opckeytype; /* type of data in index, or InvalidOid */
-} *OpclassCandidateList;
-
extern Oid RangeVarGetRelid(const RangeVar *relation, bool failOK);
extern Oid RangeVarGetCreationNamespace(const RangeVar *newRelation);
@@ -62,7 +47,6 @@ extern bool FunctionIsVisible(Oid funcid);
extern FuncCandidateList OpernameGetCandidates(List *names, char oprkind);
extern bool OperatorIsVisible(Oid oprid);
-extern OpclassCandidateList OpclassGetCandidates(Oid amid);
extern Oid OpclassnameGetOpcid(Oid amid, const char *opcname);
extern bool OpclassIsVisible(Oid opcid);
diff --git a/src/include/commands/defrem.h b/src/include/commands/defrem.h
index 39603cf31f2..230bd63765c 100644
--- a/src/include/commands/defrem.h
+++ b/src/include/commands/defrem.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/commands/defrem.h,v 1.69 2005/11/21 12:49:32 alvherre Exp $
+ * $PostgreSQL: pgsql/src/include/commands/defrem.h,v 1.70 2006/02/10 19:01:12 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -42,6 +42,7 @@ extern char *makeObjectName(const char *name1, const char *name2,
const char *label);
extern char *ChooseRelationName(const char *name1, const char *name2,
const char *label, Oid namespace);
+extern Oid GetDefaultOpClass(Oid type_id, Oid am_id);
/* commands/functioncmds.c */
extern void CreateFunction(CreateFunctionStmt *stmt);