* Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/catalog/namespace.c,v 1.73 2004/12/31 21:59:38 pgsql Exp $
+ *       $PostgreSQL: pgsql/src/backend/catalog/namespace.c,v 1.73.4.1 2006/02/10 19:01:33 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
 }
 
 
-/*
- * 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.
 
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/commands/indexcmds.c,v 1.128 2004/12/31 21:59:41 pgsql Exp $
+ *       $PostgreSQL: pgsql/src/backend/commands/indexcmds.c,v 1.128.4.1 2006/02/10 19:01:33 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
 
 #include "postgres.h"
 
+#include "access/genam.h"
 #include "access/heapam.h"
 #include "catalog/catalog.h"
 #include "catalog/catname.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/relcache.h"
 #include "utils/syscache.h"
                                  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);
 
 
        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,
         * (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.
-        *
-        * 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.)
+        * 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.
         */
-       for (opclass = OpclassGetCandidates(accessMethodId);
-                opclass != NULL;
-                opclass = opclass->next)
+       rel = heap_openr(OperatorClassRelationName, AccessShareLock);
+
+       ScanKeyInit(&skey[0],
+                               Anum_pg_opclass_opcamid,
+                               BTEqualStrategyNumber, F_OIDEQ,
+                               ObjectIdGetDatum(am_id));
+
+       scan = systable_beginscan(rel, OpclassAmNameNspIndex, 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))));
+               errmsg("there are multiple default operator classes for data type %s",
+                          format_type_be(type_id))));
        if (ncompatible == 1)
                return compatibleOid;
 
 
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/utils/cache/typcache.c,v 1.11.4.1 2006/01/17 17:33:35 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/utils/cache/typcache.c,v 1.11.4.2 2006/02/10 19:01:33 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
 #include "postgres.h"
 
-#include "access/genam.h"
 #include "access/heapam.h"
 #include "access/hash.h"
 #include "access/nbtree.h"
 #include "catalog/catname.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"
 static int32 NextRecordTypmod = 0;             /* number of entries used */
 
 
-static Oid     lookup_default_opclass(Oid type_id, Oid am_id);
-
-
 /*
  * lookup_type_cache
  *
                                  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
                {
        return typentry;
 }
 
-/*
- * 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_openr(OperatorClassRelationName, AccessShareLock);
-
-       ScanKeyInit(&skey[0],
-                               Anum_pg_opclass_opcamid,
-                               BTEqualStrategyNumber, F_OIDEQ,
-                               ObjectIdGetDatum(am_id));
-
-       scan = systable_beginscan(rel, OpclassAmNameNspIndex, 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
  *
 
  * 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.35 2004/12/31 22:03:24 pgsql Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/namespace.h,v 1.35.4.1 2006/02/10 19:01:33 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 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);
 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);
 
 
  * 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.62 2004/12/31 22:03:28 pgsql Exp $
+ * $PostgreSQL: pgsql/src/include/commands/defrem.h,v 1.62.4.1 2006/02/10 19:01:33 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
                           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);