8
8
*
9
9
*
10
10
* IDENTIFICATION
11
- * $PostgreSQL: pgsql/src/backend/commands/indexcmds.c,v 1.136 2005/11/22 18:17:09 momjian Exp $
11
+ * $PostgreSQL: pgsql/src/backend/commands/indexcmds.c,v 1.137 2006/02/10 19:01:12 tgl Exp $
12
12
*
13
13
*-------------------------------------------------------------------------
14
14
*/
15
15
16
16
#include "postgres.h"
17
17
18
+ #include "access/genam.h"
18
19
#include "access/heapam.h"
19
20
#include "catalog/catalog.h"
20
21
#include "catalog/dependency.h"
21
22
#include "catalog/heap.h"
22
23
#include "catalog/index.h"
23
- #include "catalog/namespace .h"
24
+ #include "catalog/indexing .h"
24
25
#include "catalog/pg_opclass.h"
25
- #include "catalog/pg_proc.h"
26
26
#include "catalog/pg_tablespace.h"
27
27
#include "commands/dbcommands.h"
28
28
#include "commands/defrem.h"
29
29
#include "commands/tablecmds.h"
30
30
#include "commands/tablespace.h"
31
- #include "executor/executor.h"
32
31
#include "mb/pg_wchar.h"
33
32
#include "miscadmin.h"
34
33
#include "optimizer/clauses.h"
35
- #include "optimizer/prep.h"
36
34
#include "parser/parsetree.h"
37
35
#include "parser/parse_coerce.h"
38
36
#include "parser/parse_expr.h"
39
37
#include "parser/parse_func.h"
40
38
#include "utils/acl.h"
41
39
#include "utils/builtins.h"
40
+ #include "utils/fmgroids.h"
42
41
#include "utils/lsyscache.h"
43
42
#include "utils/memutils.h"
44
43
#include "utils/relcache.h"
@@ -54,7 +53,6 @@ static void ComputeIndexAttrs(IndexInfo *indexInfo, Oid *classOidP,
54
53
bool isconstraint );
55
54
static Oid GetIndexOpClass (List * opclass , Oid attrType ,
56
55
char * accessMethodName , Oid accessMethodId );
57
- static Oid GetDefaultOpClass (Oid attrType , Oid accessMethodId );
58
56
static bool relationHasPrimaryKey (Relation rel );
59
57
60
58
@@ -658,17 +656,26 @@ GetIndexOpClass(List *opclass, Oid attrType,
658
656
return opClassId ;
659
657
}
660
658
661
- static Oid
662
- GetDefaultOpClass (Oid attrType , Oid accessMethodId )
659
+ /*
660
+ * GetDefaultOpClass
661
+ *
662
+ * Given the OIDs of a datatype and an access method, find the default
663
+ * operator class, if any. Returns InvalidOid if there is none.
664
+ */
665
+ Oid
666
+ GetDefaultOpClass (Oid type_id , Oid am_id )
663
667
{
664
- OpclassCandidateList opclass ;
665
668
int nexact = 0 ;
666
669
int ncompatible = 0 ;
667
670
Oid exactOid = InvalidOid ;
668
671
Oid compatibleOid = InvalidOid ;
672
+ Relation rel ;
673
+ ScanKeyData skey [1 ];
674
+ SysScanDesc scan ;
675
+ HeapTuple tup ;
669
676
670
677
/* If it's a domain, look at the base type instead */
671
- attrType = getBaseType (attrType );
678
+ type_id = getBaseType (type_id );
672
679
673
680
/*
674
681
* We scan through all the opclasses available for the access method,
@@ -678,37 +685,47 @@ GetDefaultOpClass(Oid attrType, Oid accessMethodId)
678
685
* We could find more than one binary-compatible match, in which case we
679
686
* require the user to specify which one he wants. If we find more than
680
687
* one exact match, then someone put bogus entries in pg_opclass.
681
- *
682
- * The initial search is done by namespace.c so that we only consider
683
- * opclasses visible in the current namespace search path. (See also
684
- * typcache.c, which applies the same logic, but over all opclasses.)
685
688
*/
686
- for (opclass = OpclassGetCandidates (accessMethodId );
687
- opclass != NULL ;
688
- opclass = opclass -> next )
689
+ rel = heap_open (OperatorClassRelationId , AccessShareLock );
690
+
691
+ ScanKeyInit (& skey [0 ],
692
+ Anum_pg_opclass_opcamid ,
693
+ BTEqualStrategyNumber , F_OIDEQ ,
694
+ ObjectIdGetDatum (am_id ));
695
+
696
+ scan = systable_beginscan (rel , OpclassAmNameNspIndexId , true,
697
+ SnapshotNow , 1 , skey );
698
+
699
+ while (HeapTupleIsValid (tup = systable_getnext (scan )))
689
700
{
701
+ Form_pg_opclass opclass = (Form_pg_opclass ) GETSTRUCT (tup );
702
+
690
703
if (opclass -> opcdefault )
691
704
{
692
- if (opclass -> opcintype == attrType )
705
+ if (opclass -> opcintype == type_id )
693
706
{
694
707
nexact ++ ;
695
- exactOid = opclass -> oid ;
708
+ exactOid = HeapTupleGetOid ( tup ) ;
696
709
}
697
- else if (IsBinaryCoercible (attrType , opclass -> opcintype ))
710
+ else if (IsBinaryCoercible (type_id , opclass -> opcintype ))
698
711
{
699
712
ncompatible ++ ;
700
- compatibleOid = opclass -> oid ;
713
+ compatibleOid = HeapTupleGetOid ( tup ) ;
701
714
}
702
715
}
703
716
}
704
717
718
+ systable_endscan (scan );
719
+
720
+ heap_close (rel , AccessShareLock );
721
+
705
722
if (nexact == 1 )
706
723
return exactOid ;
707
724
if (nexact != 0 )
708
725
ereport (ERROR ,
709
726
(errcode (ERRCODE_DUPLICATE_OBJECT ),
710
727
errmsg ("there are multiple default operator classes for data type %s" ,
711
- format_type_be (attrType ))));
728
+ format_type_be (type_id ))));
712
729
if (ncompatible == 1 )
713
730
return compatibleOid ;
714
731
0 commit comments