Clean up syscache so that recursive invocation is safe, and remove error
authorTom Lane <tgl@sss.pgh.pa.us>
Fri, 10 Nov 2000 00:33:12 +0000 (00:33 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Fri, 10 Nov 2000 00:33:12 +0000 (00:33 +0000)
message about recursive use of a syscache.  Also remove most of the
specialized indexscan routines in indexing.c --- it turns out that
catcache.c is perfectly able to perform the indexscan for itself,
in fact has already looked up all the information needed to do so!
This should be faster as well as needing far less boilerplate code.

src/backend/access/transam/xact.c
src/backend/catalog/indexing.c
src/backend/utils/cache/catcache.c
src/backend/utils/cache/relcache.c
src/backend/utils/cache/syscache.c
src/include/catalog/indexing.h
src/include/utils/catcache.h

index a50eb39379f653434737631417acd9f7af259fcb..d20a94278049429da65a922960912a6928629190 100644 (file)
@@ -863,7 +863,6 @@ static void
 AtAbort_Cache(void)
 {
        RelationCacheAbort();
-       SystemCacheAbort();
        RegisterInvalid(false);
 }
 
index b84408263558b694be230c68b215d7c7451f125f..a651a7270b08baa9082e60aebd2765bbd46ecca8 100644 (file)
@@ -176,50 +176,6 @@ CatalogIndexInsert(Relation *idescs,
        }
 }
 
-/*
- * This is needed at initialization when reldescs for some of the crucial
- * system catalogs are created and nailed into the cache.
- */
-bool
-CatalogHasIndex(char *catName, Oid catId)
-{
-       Relation        pg_class;
-       HeapTuple       htup;
-       Form_pg_class pgRelP;
-       int                     i;
-
-       Assert(IsSystemRelationName(catName));
-
-       /*
-        * If we're bootstraping we don't have pg_class (or any indices).
-        */
-       if (IsBootstrapProcessingMode())
-               return false;
-
-       if (IsInitProcessingMode())
-       {
-               for (i = 0; IndexedCatalogNames[i] != NULL; i++)
-               {
-                       if (strcmp(IndexedCatalogNames[i], catName) == 0)
-                               return true;
-               }
-               return false;
-       }
-
-       pg_class = heap_openr(RelationRelationName, AccessShareLock);
-       htup = ClassOidIndexScan(pg_class, catId);
-       heap_close(pg_class, AccessShareLock);
-
-       if (!HeapTupleIsValid(htup))
-       {
-               elog(NOTICE, "CatalogHasIndex: no relation with oid %u", catId);
-               return false;
-       }
-
-       pgRelP = (Form_pg_class) GETSTRUCT(htup);
-       return pgRelP->relhasindex;
-}
-
 
 /*
  *     CatalogIndexFetchTuple() -- Get a tuple that satisfies a scan key
@@ -271,162 +227,12 @@ CatalogIndexFetchTuple(Relation heapRelation,
  */
 
 /*
- * The remainder of the file is for individual index scan routines.  Each
- * index should be scanned according to how it was defined during bootstrap
- * (that is, functional or normal) and what arguments the cache lookup
- * requires.  Each routine returns the heap tuple that qualifies.
+ * The remainder of the file is for individual index scan routines.
+ * These routines provide canned scanning code for certain widely-used
+ * indexes.  Most indexes don't need one of these.
  */
 
 
-HeapTuple
-AggregateNameTypeIndexScan(Relation heapRelation,
-                                                  Datum aggName, Datum aggType)
-{
-       Relation        idesc;
-       ScanKeyData skey[2];
-       HeapTuple       tuple;
-
-       ScanKeyEntryInitialize(&skey[0],
-                                                  (bits16) 0x0,
-                                                  (AttrNumber) 1,
-                                                  (RegProcedure) F_NAMEEQ,
-                                                  aggName);
-
-       ScanKeyEntryInitialize(&skey[1],
-                                                  (bits16) 0x0,
-                                                  (AttrNumber) 2,
-                                                  (RegProcedure) F_OIDEQ,
-                                                  aggType);
-
-       idesc = index_openr(AggregateNameTypeIndex);
-       tuple = CatalogIndexFetchTuple(heapRelation, idesc, skey, 2);
-
-       index_close(idesc);
-       return tuple;
-}
-
-
-HeapTuple
-AmNameIndexScan(Relation heapRelation, Datum amName)
-{
-       Relation        idesc;
-       ScanKeyData skey[1];
-       HeapTuple       tuple;
-
-       ScanKeyEntryInitialize(&skey[0],
-                                                  (bits16) 0x0,
-                                                  (AttrNumber) 1,
-                                                  (RegProcedure) F_NAMEEQ,
-                                                  amName);
-
-       idesc = index_openr(AmNameIndex);
-       tuple = CatalogIndexFetchTuple(heapRelation, idesc, skey, 1);
-
-       index_close(idesc);
-       return tuple;
-}
-
-
-HeapTuple
-AccessMethodOpidIndexScan(Relation heapRelation,
-                                                 Datum claid,
-                                                 Datum opopr,
-                                                 Datum opid)
-{
-       Relation        idesc;
-       ScanKeyData skey[3];
-       HeapTuple       tuple;
-
-       ScanKeyEntryInitialize(&skey[0],
-                                                  (bits16) 0x0,
-                                                  (AttrNumber) 1,
-                                                  (RegProcedure) F_OIDEQ,
-                                                  claid);
-
-       ScanKeyEntryInitialize(&skey[1],
-                                                  (bits16) 0x0,
-                                                  (AttrNumber) 2,
-                                                  (RegProcedure) F_OIDEQ,
-                                                  opopr);
-
-       ScanKeyEntryInitialize(&skey[2],
-                                                  (bits16) 0x0,
-                                                  (AttrNumber) 3,
-                                                  (RegProcedure) F_OIDEQ,
-                                                  opid);
-
-       idesc = index_openr(AccessMethodOpidIndex);
-       tuple = CatalogIndexFetchTuple(heapRelation, idesc, skey, 3);
-
-       index_close(idesc);
-       return tuple;
-}
-
-HeapTuple
-AccessMethodStrategyIndexScan(Relation heapRelation,
-                                                         Datum opid,
-                                                         Datum claid,
-                                                         Datum opstrategy)
-{
-       Relation        idesc;
-       ScanKeyData skey[3];
-       HeapTuple       tuple;
-
-       ScanKeyEntryInitialize(&skey[0],
-                                                  (bits16) 0x0,
-                                                  (AttrNumber) 1,
-                                                  (RegProcedure) F_OIDEQ,
-                                                  opid);
-
-       ScanKeyEntryInitialize(&skey[1],
-                                                  (bits16) 0x0,
-                                                  (AttrNumber) 2,
-                                                  (RegProcedure) F_OIDEQ,
-                                                  claid);
-
-       ScanKeyEntryInitialize(&skey[2],
-                                                  (bits16) 0x0,
-                                                  (AttrNumber) 3,
-                                                  (RegProcedure) F_INT2EQ,
-                                                  opstrategy);
-
-       idesc = index_openr(AccessMethodStrategyIndex);
-       tuple = CatalogIndexFetchTuple(heapRelation, idesc, skey, 3);
-
-       index_close(idesc);
-       return tuple;
-}
-
-
-HeapTuple
-AttributeRelidNameIndexScan(Relation heapRelation,
-                                                       Datum relid,
-                                                       Datum attname)
-{
-       Relation        idesc;
-       ScanKeyData skey[2];
-       HeapTuple       tuple;
-
-       ScanKeyEntryInitialize(&skey[0],
-                                                  (bits16) 0x0,
-                                                  (AttrNumber) 1,
-                                                  (RegProcedure) F_OIDEQ,
-                                                  relid);
-
-       ScanKeyEntryInitialize(&skey[1],
-                                                  (bits16) 0x0,
-                                                  (AttrNumber) 2,
-                                                  (RegProcedure) F_NAMEEQ,
-                                                  attname);
-
-       idesc = index_openr(AttributeRelidNameIndex);
-       tuple = CatalogIndexFetchTuple(heapRelation, idesc, skey, 2);
-
-       index_close(idesc);
-       return tuple;
-}
-
-
 HeapTuple
 AttributeRelidNumIndexScan(Relation heapRelation,
                                                   Datum relid,
@@ -450,148 +256,13 @@ AttributeRelidNumIndexScan(Relation heapRelation,
 
        idesc = index_openr(AttributeRelidNumIndex);
        tuple = CatalogIndexFetchTuple(heapRelation, idesc, skey, 2);
-
-       index_close(idesc);
-       return tuple;
-}
-
-
-HeapTuple
-OpclassDeftypeIndexScan(Relation heapRelation, Datum defType)
-{
-       Relation        idesc;
-       ScanKeyData skey[1];
-       HeapTuple       tuple;
-
-       ScanKeyEntryInitialize(&skey[0],
-                                                  (bits16) 0x0,
-                                                  (AttrNumber) 1,
-                                                  (RegProcedure) F_OIDEQ,
-                                                  defType);
-
-       idesc = index_openr(OpclassDeftypeIndex);
-       tuple = CatalogIndexFetchTuple(heapRelation, idesc, skey, 1);
-
-       index_close(idesc);
-       return tuple;
-}
-
-
-HeapTuple
-OpclassNameIndexScan(Relation heapRelation, Datum opcName)
-{
-       Relation        idesc;
-       ScanKeyData skey[1];
-       HeapTuple       tuple;
-
-       ScanKeyEntryInitialize(&skey[0],
-                                                  (bits16) 0x0,
-                                                  (AttrNumber) 1,
-                                                  (RegProcedure) F_NAMEEQ,
-                                                  opcName);
-
-       idesc = index_openr(OpclassNameIndex);
-       tuple = CatalogIndexFetchTuple(heapRelation, idesc, skey, 1);
-
-       index_close(idesc);
-       return tuple;
-}
-
-
-HeapTuple
-GroupNameIndexScan(Relation heapRelation, Datum groName)
-{
-       Relation        idesc;
-       ScanKeyData skey[1];
-       HeapTuple       tuple;
-
-       ScanKeyEntryInitialize(&skey[0],
-                                                  (bits16) 0x0,
-                                                  (AttrNumber) 1,
-                                                  (RegProcedure) F_NAMEEQ,
-                                                  groName);
-
-       idesc = index_openr(GroupNameIndex);
-       tuple = CatalogIndexFetchTuple(heapRelation, idesc, skey, 1);
-
-       index_close(idesc);
-       return tuple;
-}
-
-
-HeapTuple
-GroupSysidIndexScan(Relation heapRelation, Datum sysId)
-{
-       Relation        idesc;
-       ScanKeyData skey[1];
-       HeapTuple       tuple;
-
-       ScanKeyEntryInitialize(&skey[0],
-                                                  (bits16) 0x0,
-                                                  (AttrNumber) 1,
-                                                  (RegProcedure) F_INT4EQ,
-                                                  sysId);
-
-       idesc = index_openr(GroupSysidIndex);
-       tuple = CatalogIndexFetchTuple(heapRelation, idesc, skey, 1);
-
-       index_close(idesc);
-       return tuple;
-}
-
-
-HeapTuple
-IndexRelidIndexScan(Relation heapRelation, Datum relid)
-{
-       Relation        idesc;
-       ScanKeyData skey[1];
-       HeapTuple       tuple;
-
-       ScanKeyEntryInitialize(&skey[0],
-                                                  (bits16) 0x0,
-                                                  (AttrNumber) 1,
-                                                  (RegProcedure) F_OIDEQ,
-                                                  relid);
-
-       idesc = index_openr(IndexRelidIndex);
-       tuple = CatalogIndexFetchTuple(heapRelation, idesc, skey, 1);
-
-       index_close(idesc);
-       return tuple;
-}
-
-
-HeapTuple
-InheritsRelidSeqnoIndexScan(Relation heapRelation,
-                                                       Datum relid,
-                                                       Datum seqno)
-{
-       Relation        idesc;
-       ScanKeyData skey[2];
-       HeapTuple       tuple;
-
-       ScanKeyEntryInitialize(&skey[0],
-                                                  (bits16) 0x0,
-                                                  (AttrNumber) 1,
-                                                  (RegProcedure) F_OIDEQ,
-                                                  relid);
-
-       ScanKeyEntryInitialize(&skey[1],
-                                                  (bits16) 0x0,
-                                                  (AttrNumber) 2,
-                                                  (RegProcedure) F_INT4EQ,
-                                                  seqno);
-
-       idesc = index_openr(InheritsRelidSeqnoIndex);
-       tuple = CatalogIndexFetchTuple(heapRelation, idesc, skey, 2);
-
        index_close(idesc);
        return tuple;
 }
 
 
 HeapTuple
-LanguageNameIndexScan(Relation heapRelation, Datum lanName)
+ClassNameIndexScan(Relation heapRelation, Datum relName)
 {
        Relation        idesc;
        ScanKeyData skey[1];
@@ -601,18 +272,17 @@ LanguageNameIndexScan(Relation heapRelation, Datum lanName)
                                                   (bits16) 0x0,
                                                   (AttrNumber) 1,
                                                   (RegProcedure) F_NAMEEQ,
-                                                  lanName);
+                                                  relName);
 
-       idesc = index_openr(LanguageNameIndex);
+       idesc = index_openr(ClassNameIndex);
        tuple = CatalogIndexFetchTuple(heapRelation, idesc, skey, 1);
-
        index_close(idesc);
        return tuple;
 }
 
 
 HeapTuple
-LanguageOidIndexScan(Relation heapRelation, Datum lanId)
+ClassOidIndexScan(Relation heapRelation, Datum relId)
 {
        Relation        idesc;
        ScanKeyData skey[1];
@@ -622,357 +292,10 @@ LanguageOidIndexScan(Relation heapRelation, Datum lanId)
                                                   (bits16) 0x0,
                                                   (AttrNumber) 1,
                                                   (RegProcedure) F_OIDEQ,
-                                                  lanId);
+                                                  relId);
 
-       idesc = index_openr(LanguageOidIndex);
+       idesc = index_openr(ClassOidIndex);
        tuple = CatalogIndexFetchTuple(heapRelation, idesc, skey, 1);
-
-       index_close(idesc);
-       return tuple;
-}
-
-
-HeapTuple
-ListenerPidRelnameIndexScan(Relation heapRelation,
-                                                       Datum pid, Datum relName)
-{
-       Relation        idesc;
-       ScanKeyData skey[2];
-       HeapTuple       tuple;
-
-       ScanKeyEntryInitialize(&skey[0],
-                                                  (bits16) 0x0,
-                                                  (AttrNumber) 1,
-                                                  (RegProcedure) F_INT4EQ,
-                                                  pid);
-
-       ScanKeyEntryInitialize(&skey[1],
-                                                  (bits16) 0x0,
-                                                  (AttrNumber) 2,
-                                                  (RegProcedure) F_NAMEEQ,
-                                                  relName);
-
-       idesc = index_openr(ListenerPidRelnameIndex);
-       tuple = CatalogIndexFetchTuple(heapRelation, idesc, skey, 2);
-
-       index_close(idesc);
-       return tuple;
-}
-
-
-HeapTuple
-OperatorNameIndexScan(Relation heapRelation,
-                                         Datum oprName,
-                                         Datum oprLeft,
-                                         Datum oprRight,
-                                         Datum oprKind)
-{
-       Relation        idesc;
-       ScanKeyData skey[4];
-       HeapTuple       tuple;
-
-       ScanKeyEntryInitialize(&skey[0],
-                                                  (bits16) 0x0,
-                                                  (AttrNumber) 1,
-                                                  (RegProcedure) F_NAMEEQ,
-                                                  oprName);
-
-       ScanKeyEntryInitialize(&skey[1],
-                                                  (bits16) 0x0,
-                                                  (AttrNumber) 2,
-                                                  (RegProcedure) F_OIDEQ,
-                                                  oprLeft);
-
-       ScanKeyEntryInitialize(&skey[2],
-                                                  (bits16) 0x0,
-                                                  (AttrNumber) 3,
-                                                  (RegProcedure) F_OIDEQ,
-                                                  oprRight);
-
-       ScanKeyEntryInitialize(&skey[3],
-                                                  (bits16) 0x0,
-                                                  (AttrNumber) 4,
-                                                  (RegProcedure) F_CHAREQ,
-                                                  oprKind);
-
-       idesc = index_openr(OperatorNameIndex);
-       tuple = CatalogIndexFetchTuple(heapRelation, idesc, skey, 4);
-
-       index_close(idesc);
-       return tuple;
-}
-
-
-HeapTuple
-OperatorOidIndexScan(Relation heapRelation, Datum oprId)
-{
-       Relation        idesc;
-       ScanKeyData skey[1];
-       HeapTuple       tuple;
-
-       ScanKeyEntryInitialize(&skey[0],
-                                                  (bits16) 0x0,
-                                                  (AttrNumber) 1,
-                                                  (RegProcedure) F_OIDEQ,
-                                                  oprId);
-
-       idesc = index_openr(OperatorOidIndex);
-       tuple = CatalogIndexFetchTuple(heapRelation, idesc, skey, 1);
-
-       index_close(idesc);
-       return tuple;
-}
-
-
-HeapTuple
-ProcedureNameIndexScan(Relation heapRelation,
-                                          Datum procName,
-                                          Datum nargs,
-                                          Datum argTypes)
-{
-       Relation        idesc;
-       ScanKeyData skey[3];
-       HeapTuple       tuple;
-
-       ScanKeyEntryInitialize(&skey[0],
-                                                  (bits16) 0x0,
-                                                  (AttrNumber) 1,
-                                                  (RegProcedure) F_NAMEEQ,
-                                                  procName);
-
-       ScanKeyEntryInitialize(&skey[1],
-                                                  (bits16) 0x0,
-                                                  (AttrNumber) 2,
-                                                  (RegProcedure) F_INT2EQ,
-                                                  nargs);
-
-       ScanKeyEntryInitialize(&skey[2],
-                                                  (bits16) 0x0,
-                                                  (AttrNumber) 3,
-                                                  (RegProcedure) F_OIDVECTOREQ,
-                                                  argTypes);
-
-       idesc = index_openr(ProcedureNameIndex);
-       tuple = CatalogIndexFetchTuple(heapRelation, idesc, skey, 3);
-
-       index_close(idesc);
-       return tuple;
-}
-
-
-HeapTuple
-ProcedureOidIndexScan(Relation heapRelation, Datum procId)
-{
-       Relation        idesc;
-       ScanKeyData skey[1];
-       HeapTuple       tuple;
-
-       ScanKeyEntryInitialize(&skey[0],
-                                                  (bits16) 0x0,
-                                                  (AttrNumber) 1,
-                                                  (RegProcedure) F_OIDEQ,
-                                                  procId);
-
-       idesc = index_openr(ProcedureOidIndex);
-       tuple = CatalogIndexFetchTuple(heapRelation, idesc, skey, 1);
-
-       index_close(idesc);
-       return tuple;
-}
-
-
-HeapTuple
-ClassNameIndexScan(Relation heapRelation, Datum relName)
-{
-       Relation        idesc;
-       ScanKeyData skey[1];
-       HeapTuple       tuple;
-
-       ScanKeyEntryInitialize(&skey[0],
-                                                  (bits16) 0x0,
-                                                  (AttrNumber) 1,
-                                                  (RegProcedure) F_NAMEEQ,
-                                                  relName);
-
-       idesc = index_openr(ClassNameIndex);
-       tuple = CatalogIndexFetchTuple(heapRelation, idesc, skey, 1);
-
-       index_close(idesc);
-       return tuple;
-}
-
-
-HeapTuple
-ClassOidIndexScan(Relation heapRelation, Datum relId)
-{
-       Relation        idesc;
-       ScanKeyData skey[1];
-       HeapTuple       tuple;
-
-       ScanKeyEntryInitialize(&skey[0],
-                                                  (bits16) 0x0,
-                                                  (AttrNumber) 1,
-                                                  (RegProcedure) F_OIDEQ,
-                                                  relId);
-
-       idesc = index_openr(ClassOidIndex);
-       tuple = CatalogIndexFetchTuple(heapRelation, idesc, skey, 1);
-
-       index_close(idesc);
-       return tuple;
-}
-
-
-HeapTuple
-RewriteRulenameIndexScan(Relation heapRelation, Datum ruleName)
-{
-       Relation        idesc;
-       ScanKeyData skey[1];
-       HeapTuple       tuple;
-
-       ScanKeyEntryInitialize(&skey[0],
-                                                  (bits16) 0x0,
-                                                  (AttrNumber) 1,
-                                                  (RegProcedure) F_NAMEEQ,
-                                                  ruleName);
-
-       idesc = index_openr(RewriteRulenameIndex);
-       tuple = CatalogIndexFetchTuple(heapRelation, idesc, skey, 1);
-
-       index_close(idesc);
-       return tuple;
-}
-
-
-HeapTuple
-RewriteOidIndexScan(Relation heapRelation, Datum rewriteId)
-{
-       Relation        idesc;
-       ScanKeyData skey[1];
-       HeapTuple       tuple;
-
-       ScanKeyEntryInitialize(&skey[0],
-                                                  (bits16) 0x0,
-                                                  (AttrNumber) 1,
-                                                  (RegProcedure) F_OIDEQ,
-                                                  rewriteId);
-
-       idesc = index_openr(RewriteOidIndex);
-       tuple = CatalogIndexFetchTuple(heapRelation, idesc, skey, 1);
-
-       index_close(idesc);
-       return tuple;
-}
-
-
-HeapTuple
-ShadowNameIndexScan(Relation heapRelation, Datum useName)
-{
-       Relation        idesc;
-       ScanKeyData skey[1];
-       HeapTuple       tuple;
-
-       ScanKeyEntryInitialize(&skey[0],
-                                                  (bits16) 0x0,
-                                                  (AttrNumber) 1,
-                                                  (RegProcedure) F_NAMEEQ,
-                                                  useName);
-
-       idesc = index_openr(ShadowNameIndex);
-       tuple = CatalogIndexFetchTuple(heapRelation, idesc, skey, 1);
-
-       index_close(idesc);
-       return tuple;
-}
-
-
-HeapTuple
-ShadowSysidIndexScan(Relation heapRelation, Datum sysId)
-{
-       Relation        idesc;
-       ScanKeyData skey[1];
-       HeapTuple       tuple;
-
-       ScanKeyEntryInitialize(&skey[0],
-                                                  (bits16) 0x0,
-                                                  (AttrNumber) 1,
-                                                  (RegProcedure) F_INT4EQ,
-                                                  sysId);
-
-       idesc = index_openr(ShadowSysidIndex);
-       tuple = CatalogIndexFetchTuple(heapRelation, idesc, skey, 1);
-
-       index_close(idesc);
-       return tuple;
-}
-
-
-HeapTuple
-StatisticRelidAttnumIndexScan(Relation heapRelation,
-                                                         Datum relId,
-                                                         Datum attNum)
-{
-       Relation        idesc;
-       ScanKeyData skey[2];
-       HeapTuple       tuple;
-
-       ScanKeyEntryInitialize(&skey[0],
-                                                  (bits16) 0x0,
-                                                  (AttrNumber) 1,
-                                                  (RegProcedure) F_OIDEQ,
-                                                  relId);
-
-       ScanKeyEntryInitialize(&skey[1],
-                                                  (bits16) 0x0,
-                                                  (AttrNumber) 2,
-                                                  (RegProcedure) F_INT2EQ,
-                                                  attNum);
-
-       idesc = index_openr(StatisticRelidAttnumIndex);
-       tuple = CatalogIndexFetchTuple(heapRelation, idesc, skey, 2);
-
-       index_close(idesc);
-       return tuple;
-}
-
-
-HeapTuple
-TypeNameIndexScan(Relation heapRelation, Datum typeName)
-{
-       Relation        idesc;
-       ScanKeyData skey[1];
-       HeapTuple       tuple;
-
-       ScanKeyEntryInitialize(&skey[0],
-                                                  (bits16) 0x0,
-                                                  (AttrNumber) 1,
-                                                  (RegProcedure) F_NAMEEQ,
-                                                  typeName);
-
-       idesc = index_openr(TypeNameIndex);
-       tuple = CatalogIndexFetchTuple(heapRelation, idesc, skey, 1);
-
-       index_close(idesc);
-       return tuple;
-}
-
-
-HeapTuple
-TypeOidIndexScan(Relation heapRelation, Datum typeId)
-{
-       Relation        idesc;
-       ScanKeyData skey[1];
-       HeapTuple       tuple;
-
-       ScanKeyEntryInitialize(&skey[0],
-                                                  (bits16) 0x0,
-                                                  (AttrNumber) 1,
-                                                  (RegProcedure) F_OIDEQ,
-                                                  typeId);
-
-       idesc = index_openr(TypeOidIndex);
-       tuple = CatalogIndexFetchTuple(heapRelation, idesc, skey, 1);
-
        index_close(idesc);
        return tuple;
 }
index 386b8f1b972f9cd6121282becf6fab74d53e0c79..289265b0c48be75d4e23da5d7972fd216578c723 100644 (file)
 #include "utils/syscache.h"
 
 static void CatCacheRemoveCTup(CatCache *cache, Dlelem *e);
-static Index CatalogCacheComputeHashIndex(CatCache *cacheInP);
-static Index CatalogCacheComputeTupleHashIndex(CatCache *cacheInOutP,
-                                                                 Relation relation,
-                                                                 HeapTuple tuple);
-static void CatalogCacheInitializeCache(CatCache *cache,
-                                                                               Relation relation);
+static Index CatalogCacheComputeHashIndex(CatCache *cache,
+                                                                                 ScanKey cur_skey);
+static Index CatalogCacheComputeTupleHashIndex(CatCache *cache,
+                                                                                          HeapTuple tuple);
+static void CatalogCacheInitializeCache(CatCache *cache);
 static Datum cc_hashname(PG_FUNCTION_ARGS);
 
 /* ----------------
@@ -155,25 +154,23 @@ CreateCacheMemoryContext(void)
 
 /* --------------------------------
  *             CatalogCacheInitializeCache
+ *
+ * This function does final initialization of a catcache: obtain the tuple
+ * descriptor and set up the hash and equality function links.  We assume
+ * that the relcache entry can be opened at this point!
  * --------------------------------
  */
 #ifdef CACHEDEBUG
 #define CatalogCacheInitializeCache_DEBUG1 \
-do { \
-       elog(DEBUG, "CatalogCacheInitializeCache: cache @%08lx", cache); \
-       if (relation) \
-               elog(DEBUG, "CatalogCacheInitializeCache: called w/relation(inval)"); \
-       else \
-               elog(DEBUG, "CatalogCacheInitializeCache: called w/relname %s", \
-                       cache->cc_relname) \
-} while(0)
+       elog(DEBUG, "CatalogCacheInitializeCache: cache @%p %s", cache, \
+                cache->cc_relname)
 
 #define CatalogCacheInitializeCache_DEBUG2 \
 do { \
                if (cache->cc_key[i] > 0) { \
-                       elog(DEBUG, "CatalogCacheInitializeCache: load %d/%d w/%d, %d", \
+                       elog(DEBUG, "CatalogCacheInitializeCache: load %d/%d w/%d, %u", \
                                i+1, cache->cc_nkeys, cache->cc_key[i], \
-                               relation->rd_att->attrs[cache->cc_key[i] - 1]->attlen); \
+                                tupdesc->attrs[cache->cc_key[i] - 1]->atttypid); \
                } else { \
                        elog(DEBUG, "CatalogCacheInitializeCache: load %d/%d w/%d", \
                                i+1, cache->cc_nkeys, cache->cc_key[i]); \
@@ -186,26 +183,21 @@ do { \
 #endif
 
 static void
-CatalogCacheInitializeCache(CatCache * cache,
-                                                       Relation relation)
+CatalogCacheInitializeCache(CatCache *cache)
 {
+       Relation        relation;
        MemoryContext oldcxt;
-       bool            didopen = false;
-       short           i;
        TupleDesc       tupdesc;
+       short           i;
 
        CatalogCacheInitializeCache_DEBUG1;
 
-       /* ----------------
-        *      If no relation was passed we must open it to get access to
-        *      its fields.
-        * ----------------
+       /*
+        * Open the relation without locking --- we only need the tupdesc,
+        * which we assume will never change ...
         */
-       if (!RelationIsValid(relation))
-       {
-               relation = heap_openr(cache->cc_relname, NoLock);
-               didopen = true;
-       }
+       relation = heap_openr(cache->cc_relname, NoLock);
+       Assert(RelationIsValid(relation));
 
        /* ----------------
         *      switch to the cache context so our allocations
@@ -218,16 +210,21 @@ CatalogCacheInitializeCache(CatCache * cache,
        oldcxt = MemoryContextSwitchTo(CacheMemoryContext);
 
        /* ----------------
-        *      initialize the cache's relation id and tuple descriptor
+        *      copy the relcache's tuple descriptor to permanent cache storage
         * ----------------
         */
-       Assert(RelationIsValid(relation));
-       cache->relationId = RelationGetRelid(relation);
        tupdesc = CreateTupleDescCopyConstr(RelationGetDescr(relation));
-       cache->cc_tupdesc = tupdesc;
 
-       CACHE3_elog(DEBUG, "CatalogCacheInitializeCache: relid %u, %d keys",
-                               cache->relationId, cache->cc_nkeys);
+       /* ----------------
+        *      return to the caller's memory context and close the rel
+        * ----------------
+        */
+       MemoryContextSwitchTo(oldcxt);
+
+       heap_close(relation, NoLock);
+
+       CACHE3_elog(DEBUG, "CatalogCacheInitializeCache: %s, %d keys",
+                               cache->cc_relname, cache->cc_nkeys);
 
        /* ----------------
         *      initialize cache's key information
@@ -235,65 +232,45 @@ CatalogCacheInitializeCache(CatCache * cache,
         */
        for (i = 0; i < cache->cc_nkeys; ++i)
        {
+               Oid                     keytype;
+
                CatalogCacheInitializeCache_DEBUG2;
 
                if (cache->cc_key[i] > 0)
                {
-                       Oid                     keytype = tupdesc->attrs[cache->cc_key[i] - 1]->atttypid;
+                       keytype = tupdesc->attrs[cache->cc_key[i] - 1]->atttypid;
+               }
+               else
+               {
+                       if (cache->cc_key[i] != ObjectIdAttributeNumber)
+                               elog(FATAL, "CatalogCacheInit: only sys attr supported is OID");
+                       keytype = OIDOID;
+               }
 
-                       cache->cc_hashfunc[i] = GetCCHashFunc(keytype);
+               cache->cc_hashfunc[i] = GetCCHashFunc(keytype);
+               /*
+                * If GetCCHashFunc liked the type, safe to index into eqproc[]
+                */
+               cache->cc_skey[i].sk_procedure = EQPROC(keytype);
 
-                       /*
-                        * If GetCCHashFunc liked the type, safe to index into
-                        * eqproc[]
-                        */
-                       cache->cc_skey[i].sk_procedure = EQPROC(keytype);
+               fmgr_info(cache->cc_skey[i].sk_procedure,
+                                 &cache->cc_skey[i].sk_func);
+               cache->cc_skey[i].sk_nargs = cache->cc_skey[i].sk_func.fn_nargs;
 
-                       fmgr_info(cache->cc_skey[i].sk_procedure,
-                                         &cache->cc_skey[i].sk_func);
-                       cache->cc_skey[i].sk_nargs = cache->cc_skey[i].sk_func.fn_nargs;
+               /* Initialize sk_attno suitably for index scans */
+               cache->cc_skey[i].sk_attno = i+1;
 
-                       CACHE4_elog(DEBUG, "CatalogCacheInit %s %d %x",
-                                               RelationGetRelationName(relation),
-                                               i,
-                                               cache);
-               }
+               CACHE4_elog(DEBUG, "CatalogCacheInit %s %d %p",
+                                       cache->cc_relname,
+                                       i,
+                                       cache);
        }
 
        /* ----------------
-        *      return to the caller's memory context
+        *      mark this cache fully initialized
         * ----------------
         */
-       MemoryContextSwitchTo(oldcxt);
-
-       /* ----------------
-        *      close the relation if we opened it
-        * ----------------
-        */
-       if (didopen)
-               heap_close(relation, NoLock);
-
-       /* ----------------
-        *      initialize index information for the cache.  this
-        *      should only be done once per cache.
-        * ----------------
-        */
-       if (cache->cc_indname != NULL && cache->indexId == InvalidOid)
-       {
-               if (!IsIgnoringSystemIndexes() && RelationGetForm(relation)->relhasindex)
-               {
-
-                       /*
-                        * If the index doesn't exist we are in trouble.
-                        */
-                       relation = index_openr(cache->cc_indname);
-                       Assert(relation);
-                       cache->indexId = RelationGetRelid(relation);
-                       index_close(relation);
-               }
-               else
-                       cache->cc_indname = NULL;
-       }
+       cache->cc_tupdesc = tupdesc;
 }
 
 /* --------------------------------
@@ -301,42 +278,42 @@ CatalogCacheInitializeCache(CatCache * cache,
  * --------------------------------
  */
 static Index
-CatalogCacheComputeHashIndex(CatCache * cacheInP)
+CatalogCacheComputeHashIndex(CatCache *cache, ScanKey cur_skey)
 {
        uint32          hashIndex = 0;
 
-       CACHE4_elog(DEBUG, "CatalogCacheComputeHashIndex %s %d %x",
-                               cacheInP->cc_relname,
-                               cacheInP->cc_nkeys,
-                               cacheInP);
+       CACHE4_elog(DEBUG, "CatalogCacheComputeHashIndex %s %d %p",
+                               cache->cc_relname,
+                               cache->cc_nkeys,
+                               cache);
 
-       switch (cacheInP->cc_nkeys)
+       switch (cache->cc_nkeys)
        {
                case 4:
                        hashIndex ^=
-                               DatumGetUInt32(DirectFunctionCall1(cacheInP->cc_hashfunc[3],
-                                                          cacheInP->cc_skey[3].sk_argument)) << 9;
+                               DatumGetUInt32(DirectFunctionCall1(cache->cc_hashfunc[3],
+                                                          cur_skey[3].sk_argument)) << 9;
                        /* FALLTHROUGH */
                case 3:
                        hashIndex ^=
-                               DatumGetUInt32(DirectFunctionCall1(cacheInP->cc_hashfunc[2],
-                                                          cacheInP->cc_skey[2].sk_argument)) << 6;
+                               DatumGetUInt32(DirectFunctionCall1(cache->cc_hashfunc[2],
+                                                          cur_skey[2].sk_argument)) << 6;
                        /* FALLTHROUGH */
                case 2:
                        hashIndex ^=
-                               DatumGetUInt32(DirectFunctionCall1(cacheInP->cc_hashfunc[1],
-                                                          cacheInP->cc_skey[1].sk_argument)) << 3;
+                               DatumGetUInt32(DirectFunctionCall1(cache->cc_hashfunc[1],
+                                                          cur_skey[1].sk_argument)) << 3;
                        /* FALLTHROUGH */
                case 1:
                        hashIndex ^=
-                               DatumGetUInt32(DirectFunctionCall1(cacheInP->cc_hashfunc[0],
-                                                          cacheInP->cc_skey[0].sk_argument));
+                               DatumGetUInt32(DirectFunctionCall1(cache->cc_hashfunc[0],
+                                                          cur_skey[0].sk_argument));
                        break;
                default:
-                       elog(FATAL, "CCComputeHashIndex: %d cc_nkeys", cacheInP->cc_nkeys);
+                       elog(FATAL, "CCComputeHashIndex: %d cc_nkeys", cache->cc_nkeys);
                        break;
        }
-       hashIndex %= (uint32) cacheInP->cc_size;
+       hashIndex %= (uint32) cache->cc_size;
        return (Index) hashIndex;
 }
 
@@ -345,65 +322,65 @@ CatalogCacheComputeHashIndex(CatCache * cacheInP)
  * --------------------------------
  */
 static Index
-CatalogCacheComputeTupleHashIndex(CatCache * cacheInOutP,
-                                                                 Relation relation,
+CatalogCacheComputeTupleHashIndex(CatCache *cache,
                                                                  HeapTuple tuple)
 {
+       ScanKeyData cur_skey[4];
        bool            isNull = false;
 
-       /* XXX is this really needed? */
-       if (cacheInOutP->relationId == InvalidOid)
-               CatalogCacheInitializeCache(cacheInOutP, relation);
+       /* Copy pre-initialized overhead data for scankey */
+       memcpy(cur_skey, cache->cc_skey, sizeof(cur_skey));
 
-       switch (cacheInOutP->cc_nkeys)
+       /* Now extract key fields from tuple, insert into scankey */
+       switch (cache->cc_nkeys)
        {
                case 4:
-                       cacheInOutP->cc_skey[3].sk_argument =
-                               (cacheInOutP->cc_key[3] == ObjectIdAttributeNumber)
-                               ? (Datum) tuple->t_data->t_oid
+                       cur_skey[3].sk_argument =
+                               (cache->cc_key[3] == ObjectIdAttributeNumber)
+                               ? ObjectIdGetDatum(tuple->t_data->t_oid)
                                : fastgetattr(tuple,
-                                                         cacheInOutP->cc_key[3],
-                                                         RelationGetDescr(relation),
+                                                         cache->cc_key[3],
+                                                         cache->cc_tupdesc,
                                                          &isNull);
                        Assert(!isNull);
                        /* FALLTHROUGH */
                case 3:
-                       cacheInOutP->cc_skey[2].sk_argument =
-                               (cacheInOutP->cc_key[2] == ObjectIdAttributeNumber)
-                               ? (Datum) tuple->t_data->t_oid
+                       cur_skey[2].sk_argument =
+                               (cache->cc_key[2] == ObjectIdAttributeNumber)
+                               ? ObjectIdGetDatum(tuple->t_data->t_oid)
                                : fastgetattr(tuple,
-                                                         cacheInOutP->cc_key[2],
-                                                         RelationGetDescr(relation),
+                                                         cache->cc_key[2],
+                                                         cache->cc_tupdesc,
                                                          &isNull);
                        Assert(!isNull);
                        /* FALLTHROUGH */
                case 2:
-                       cacheInOutP->cc_skey[1].sk_argument =
-                               (cacheInOutP->cc_key[1] == ObjectIdAttributeNumber)
-                               ? (Datum) tuple->t_data->t_oid
+                       cur_skey[1].sk_argument =
+                               (cache->cc_key[1] == ObjectIdAttributeNumber)
+                               ? ObjectIdGetDatum(tuple->t_data->t_oid)
                                : fastgetattr(tuple,
-                                                         cacheInOutP->cc_key[1],
-                                                         RelationGetDescr(relation),
+                                                         cache->cc_key[1],
+                                                         cache->cc_tupdesc,
                                                          &isNull);
                        Assert(!isNull);
                        /* FALLTHROUGH */
                case 1:
-                       cacheInOutP->cc_skey[0].sk_argument =
-                               (cacheInOutP->cc_key[0] == ObjectIdAttributeNumber)
-                               ? (Datum) tuple->t_data->t_oid
+                       cur_skey[0].sk_argument =
+                               (cache->cc_key[0] == ObjectIdAttributeNumber)
+                               ? ObjectIdGetDatum(tuple->t_data->t_oid)
                                : fastgetattr(tuple,
-                                                         cacheInOutP->cc_key[0],
-                                                         RelationGetDescr(relation),
+                                                         cache->cc_key[0],
+                                                         cache->cc_tupdesc,
                                                          &isNull);
                        Assert(!isNull);
                        break;
                default:
                        elog(FATAL, "CCComputeTupleHashIndex: %d cc_nkeys",
-                                cacheInOutP->cc_nkeys);
+                                cache->cc_nkeys);
                        break;
        }
 
-       return CatalogCacheComputeHashIndex(cacheInOutP);
+       return CatalogCacheComputeHashIndex(cache, cur_skey);
 }
 
 /* --------------------------------
@@ -506,8 +483,6 @@ CatalogCacheIdInvalidate(int cacheId,       /* XXX */
  *                                        public functions
  *
  *             ResetSystemCache
- *             SystemCacheAbort
- *             InitIndexedSysCache
  *             InitSysCache
  *             SearchSysCache
  *             RelationInvalidateCatalogCacheTuple
@@ -562,27 +537,6 @@ ResetSystemCache(void)
        CACHE1_elog(DEBUG, "end of ResetSystemCache call");
 }
 
-/* --------------------------------
- *             SystemCacheAbort
- *
- * This routine is called to clean up catcache state as needed during
- * transaction abort.
- * --------------------------------
- */
-void
-SystemCacheAbort(void)
-{
-       CatCache *cache;
-
-       /* ----------------
-        *      clear the "cache busy" flags, which may have been left set if we
-        *      elog'd out during a cache lookup attempt.
-        * ----------------
-        */
-       for (cache = Caches; PointerIsValid(cache); cache = cache->cc_next)
-               cache->busy = false;
-}
-
 /* --------------------------------
  *             SystemCacheRelationFlushed
  *
@@ -629,34 +583,24 @@ SystemCacheRelationFlushed(Oid relId)
 #ifdef CACHEDEBUG
 #define InitSysCache_DEBUG1 \
 do { \
-       elog(DEBUG, "InitSysCache: rid=%u id=%d nkeys=%d size=%d\n", \
-               cp->relationId, cp->id, cp->cc_nkeys, cp->cc_size); \
-       for (i = 0; i < nkeys; i += 1) \
-       { \
-               elog(DEBUG, "InitSysCache: key=%d skey=[%d %d %d %d]\n", \
-                        cp->cc_key[i], \
-                        cp->cc_skey[i].sk_flags, \
-                        cp->cc_skey[i].sk_attno, \
-                        cp->cc_skey[i].sk_procedure, \
-                        cp->cc_skey[i].sk_argument); \
-       } \
+       elog(DEBUG, "InitSysCache: rel=%s id=%d nkeys=%d size=%d\n", \
+               cp->cc_relname, cp->id, cp->cc_nkeys, cp->cc_size); \
 } while(0)
 
 #else
 #define InitSysCache_DEBUG1
 #endif
 
-CatCache   *
-InitSysCache(char *relname,
+CatCache *
+InitSysCache(int id,
+                        char *relname,
                         char *indname,
-                        int id,
                         int nkeys,
-                        int *key,
-                        ScanFunc iScanfuncP)
+                        int *key)
 {
        CatCache   *cp;
-       int                     i;
        MemoryContext oldcxt;
+       int                     i;
 
        /* ----------------
         *      first switch to the cache context so our allocations
@@ -714,46 +658,15 @@ InitSysCache(char *relname,
         *      cache's other internal fields.
         * ----------------
         */
-       cp->relationId = InvalidOid;
-       cp->indexId = InvalidOid;
        cp->cc_relname = relname;
        cp->cc_indname = indname;
        cp->cc_tupdesc = (TupleDesc) NULL;
        cp->id = id;
-       cp->busy = false;
        cp->cc_maxtup = MAXTUP;
        cp->cc_size = NCCBUCK;
        cp->cc_nkeys = nkeys;
-       cp->cc_iscanfunc = iScanfuncP;
-
-       /* ----------------
-        *      partially initialize the cache's key information
-        *      CatalogCacheInitializeCache() will do the rest
-        * ----------------
-        */
        for (i = 0; i < nkeys; ++i)
-       {
                cp->cc_key[i] = key[i];
-               if (!key[i])
-                       elog(FATAL, "InitSysCache: called with 0 key[%d]", i);
-               if (key[i] < 0)
-               {
-                       if (key[i] != ObjectIdAttributeNumber)
-                               elog(FATAL, "InitSysCache: called with %d key[%d]", key[i], i);
-                       else
-                       {
-                               cp->cc_hashfunc[i] = GetCCHashFunc(OIDOID);
-                               ScanKeyEntryInitialize(&cp->cc_skey[i],
-                                                                          (bits16) 0,
-                                                                          (AttrNumber) key[i],
-                                                                          (RegProcedure) F_OIDEQ,
-                                                                          (Datum) 0);
-                               continue;
-                       }
-               }
-
-               cp->cc_skey[i].sk_attno = key[i];
-       }
 
        /* ----------------
         *      all done.  new cache is initialized.  print some debugging
@@ -773,36 +686,34 @@ InitSysCache(char *relname,
 
 
 /* --------------------------------
- *             SearchSelfReferences
+ *             IndexScanOK
  *
- *             This call searches for self-referencing information,
- *             which causes infinite recursion in the system catalog cache.
- *             This code short-circuits the normal index lookup for cache loads
- *             in those cases and replaces it with a heap scan.
- *
- *             cache should already be initialized
+ *             This function checks for tuples that will be fetched by
+ *             IndexSupportInitialize() during relcache initialization for
+ *             certain system indexes that support critical syscaches.
+ *             We can't use an indexscan to fetch these, else we'll get into
+ *             infinite recursion.  A plain heap scan will work, however.
  * --------------------------------
  */
-static HeapTuple
-SearchSelfReferences(CatCache * cache)
+static bool
+IndexScanOK(CatCache *cache, ScanKey cur_skey)
 {
-       HeapTuple       ntp;
-       Relation        rel;
-
        if (cache->id == INDEXRELID)
        {
                static Oid      indexSelfOid = InvalidOid;
-               static HeapTuple indexSelfTuple = NULL;
 
+               /* One-time lookup of the OID of pg_index_indexrelid_index */
                if (!OidIsValid(indexSelfOid))
                {
+                       Relation        rel;
                        ScanKeyData key;
                        HeapScanDesc sd;
+                       HeapTuple       ntp;
 
-                       /* Find oid of pg_index_indexrelid_index */
                        rel = heap_openr(RelationRelationName, AccessShareLock);
                        ScanKeyEntryInitialize(&key, 0, Anum_pg_class_relname,
-                                                        F_NAMEEQ, PointerGetDatum(IndexRelidIndex));
+                                                                  F_NAMEEQ,
+                                                                  PointerGetDatum(IndexRelidIndex));
                        sd = heap_beginscan(rel, false, SnapshotNow, 1, &key);
                        ntp = heap_getnext(sd, 0);
                        if (!HeapTupleIsValid(ntp))
@@ -812,63 +723,22 @@ SearchSelfReferences(CatCache * cache)
                        heap_endscan(sd);
                        heap_close(rel, AccessShareLock);
                }
-               /* Looking for something other than pg_index_indexrelid_index? */
-               if ((Oid) cache->cc_skey[0].sk_argument != indexSelfOid)
-                       return (HeapTuple) 0;
 
-               /* Do we need to load our private copy of the tuple? */
-               if (!HeapTupleIsValid(indexSelfTuple))
-               {
-                       HeapScanDesc sd;
-                       MemoryContext oldcxt;
-
-                       rel = heap_open(cache->relationId, AccessShareLock);
-                       sd = heap_beginscan(rel, false, SnapshotNow, 1, cache->cc_skey);
-                       ntp = heap_getnext(sd, 0);
-                       if (!HeapTupleIsValid(ntp))
-                               elog(ERROR, "SearchSelfReferences: tuple not found");
-                       if (!CacheMemoryContext)
-                               CreateCacheMemoryContext();
-                       oldcxt = MemoryContextSwitchTo(CacheMemoryContext);
-                       indexSelfTuple = heap_copytuple(ntp);
-                       MemoryContextSwitchTo(oldcxt);
-                       heap_endscan(sd);
-                       heap_close(rel, AccessShareLock);
-               }
-               return indexSelfTuple;
+               /* Looking for pg_index_indexrelid_index? */
+               if (DatumGetObjectId(cur_skey[0].sk_argument) == indexSelfOid)
+                       return false;
        }
        else if (cache->id == OPEROID)
        {
-               /* bootstrapping this requires preloading a range of rows. bjm */
-               static HeapTuple operatorSelfTuple[MAX_OIDCMP - MIN_OIDCMP + 1];
-               Oid                     lookup_oid = (Oid) cache->cc_skey[0].sk_argument;
+               /* Looking for an OID comparison function? */
+               Oid                     lookup_oid = DatumGetObjectId(cur_skey[0].sk_argument);
 
-               if (lookup_oid < MIN_OIDCMP || lookup_oid > MAX_OIDCMP)
-                       return (HeapTuple) 0;
-
-               if (!HeapTupleIsValid(operatorSelfTuple[lookup_oid - MIN_OIDCMP]))
-               {
-                       HeapScanDesc sd;
-                       MemoryContext oldcxt;
-
-                       rel = heap_open(cache->relationId, AccessShareLock);
-                       sd = heap_beginscan(rel, false, SnapshotNow, 1, cache->cc_skey);
-                       ntp = heap_getnext(sd, 0);
-                       if (!HeapTupleIsValid(ntp))
-                               elog(ERROR, "SearchSelfReferences: tuple not found");
-                       if (!CacheMemoryContext)
-                               CreateCacheMemoryContext();
-                       oldcxt = MemoryContextSwitchTo(CacheMemoryContext);
-                       operatorSelfTuple[lookup_oid - MIN_OIDCMP] = heap_copytuple(ntp);
-                       MemoryContextSwitchTo(oldcxt);
-                       heap_endscan(sd);
-                       heap_close(rel, AccessShareLock);
-               }
-               return operatorSelfTuple[lookup_oid - MIN_OIDCMP];
+               if (lookup_oid >= MIN_OIDCMP && lookup_oid <= MAX_OIDCMP)
+                       return false;
        }
-       else
-               return (HeapTuple) 0;
 
+       /* Normal case, allow index scan */
+       return true;
 }
 
 /* --------------------------------
@@ -879,13 +749,14 @@ SearchSelfReferences(CatCache * cache)
  * --------------------------------
  */
 HeapTuple
-SearchSysCache(CatCache * cache,
+SearchSysCache(CatCache *cache,
                           Datum v1,
                           Datum v2,
                           Datum v3,
                           Datum v4)
 {
-       unsigned        hash;
+       ScanKeyData cur_skey[4];
+       Index           hash;
        CatCTup    *ct = NULL;
        CatCTup    *nct;
        CatCTup    *nct2;
@@ -898,29 +769,24 @@ SearchSysCache(CatCache * cache,
         *      one-time startup overhead
         * ----------------
         */
-       if (cache->relationId == InvalidOid)
-               CatalogCacheInitializeCache(cache, NULL);
+       if (cache->cc_tupdesc == NULL)
+               CatalogCacheInitializeCache(cache);
 
        /* ----------------
         *      initialize the search key information
         * ----------------
         */
-       cache->cc_skey[0].sk_argument = v1;
-       cache->cc_skey[1].sk_argument = v2;
-       cache->cc_skey[2].sk_argument = v3;
-       cache->cc_skey[3].sk_argument = v4;
-
-       /*
-        * resolve self referencing informtion
-        */
-       if ((ntp = SearchSelfReferences(cache)) != NULL)
-               return ntp;
+       memcpy(cur_skey, cache->cc_skey, sizeof(cur_skey));
+       cur_skey[0].sk_argument = v1;
+       cur_skey[1].sk_argument = v2;
+       cur_skey[2].sk_argument = v3;
+       cur_skey[3].sk_argument = v4;
 
        /* ----------------
         *      find the hash bucket in which to look for the tuple
         * ----------------
         */
-       hash = CatalogCacheComputeHashIndex(cache);
+       hash = CatalogCacheComputeHashIndex(cache, cur_skey);
 
        /* ----------------
         *      scan the hash bucket until we find a match or exhaust our tuples
@@ -941,7 +807,7 @@ SearchSysCache(CatCache * cache,
                HeapKeyTest(ct->ct_tup,
                                        cache->cc_tupdesc,
                                        cache->cc_nkeys,
-                                       cache->cc_skey,
+                                       cur_skey,
                                        res);
                if (res)
                        break;
@@ -975,73 +841,89 @@ SearchSysCache(CatCache * cache,
         *      retrieve it directly from the relation.  If it's found,
         *      we add it to the cache.
         *
-        *      To guard against possible infinite recursion, we mark this cache
-        *      "busy" while trying to load a new entry for it.  It is OK to
-        *      recursively invoke SearchSysCache for a different cache, but
-        *      a recursive call for the same cache will error out.  (We could
-        *      store the specific key(s) being looked for, and consider only
-        *      a recursive request for the same key to be an error, but this
-        *      simple scheme is sufficient for now.)
+        *      NOTE: it is possible for recursive cache lookups to occur while
+        *      reading the relation --- for example, due to shared-cache-inval
+        *      messages being processed during heap_open().  This is OK.  It's
+        *      even possible for one of those lookups to find and enter the
+        *      very same tuple we are trying to fetch here.  If that happens,
+        *      we will enter a second copy of the tuple into the cache.  The
+        *      first copy will never be referenced again, and will eventually
+        *      age out of the cache, so there's no functional problem.  This case
+        *      is rare enough that it's not worth expending extra cycles to detect.
         * ----------------
         */
 
-       if (cache->busy)
-               elog(ERROR, "SearchSysCache: recursive use of cache %d", cache->id);
-       cache->busy = true;
-
        /* ----------------
         *      open the relation associated with the cache
         * ----------------
         */
-       relation = heap_open(cache->relationId, AccessShareLock);
-       CACHE2_elog(DEBUG, "SearchSysCache(%s)",
-                               RelationGetRelationName(relation));
+       relation = heap_openr(cache->cc_relname, AccessShareLock);
 
        /* ----------------
         *      Scan the relation to find the tuple.  If there's an index, and
-        *      if this isn't bootstrap (initdb) time, use the index.
+        *      if it's safe to do so, use the index.  Else do a heap scan.
         * ----------------
         */
-       CACHE1_elog(DEBUG, "SearchSysCache: performing scan");
+       ntp = NULL;
 
-       if ((RelationGetForm(relation))->relhasindex
-               && !IsIgnoringSystemIndexes())
+       if ((RelationGetForm(relation))->relhasindex &&
+               !IsIgnoringSystemIndexes() &&
+               IndexScanOK(cache, cur_skey))
        {
-               HeapTuple       indextp;
-
-               /* We call the scanfunc with all four arguments to satisfy the
-                * declared prototype, even though the function will likely not
-                * use all four.
-                */
-               indextp = cache->cc_iscanfunc(relation, v1, v2, v3, v4);
-
-               /* ----------
-                *      If we got a tuple copy it into our context.  wieck - 10/18/1996
-                *      And free the tuple that was allocated in the
-                *      transaction's context.   tgl - 02/03/2000
-                * ----------
-                */
-               if (HeapTupleIsValid(indextp))
+               Relation        idesc;
+               IndexScanDesc isd;
+               RetrieveIndexResult indexRes;
+               HeapTupleData tuple;
+               Buffer          buffer;
+
+               CACHE2_elog(DEBUG, "SearchSysCache(%s): performing index scan",
+                                       cache->cc_relname);
+
+               idesc = index_openr(cache->cc_indname);
+               isd = index_beginscan(idesc, false, cache->cc_nkeys, cur_skey);
+               tuple.t_datamcxt = CurrentMemoryContext;
+               tuple.t_data = NULL;
+               while ((indexRes = index_getnext(isd, ForwardScanDirection)))
                {
-                       oldcxt = MemoryContextSwitchTo(CacheMemoryContext);
-                       ntp = heap_copytuple(indextp);
-                       MemoryContextSwitchTo(oldcxt);
-                       heap_freetuple(indextp);
+                       tuple.t_self = indexRes->heap_iptr;
+                       heap_fetch(relation, SnapshotNow, &tuple, &buffer);
+                       pfree(indexRes);
+                       if (tuple.t_data != NULL)
+                       {
+                               /* Copy tuple into our context */
+                               oldcxt = MemoryContextSwitchTo(CacheMemoryContext);
+                               ntp = heap_copytuple(&tuple);
+                               MemoryContextSwitchTo(oldcxt);
+                               ReleaseBuffer(buffer);
+                               break;
+                       }
                }
+               index_endscan(isd);
+               index_close(idesc);
        }
        else
        {
                HeapScanDesc sd;
+               int                     i;
+
+               CACHE2_elog(DEBUG, "SearchSysCache(%s): performing heap scan",
+                                       cache->cc_relname);
+
+               /*
+                * For a heap scan, sk_attno has to be set to the heap attribute
+                * number(s), not the index attribute numbers.
+                */
+               for (i = 0; i < cache->cc_nkeys; ++i)
+                       cur_skey[i].sk_attno = cache->cc_key[i];
 
                sd = heap_beginscan(relation, 0, SnapshotNow,
-                                                       cache->cc_nkeys, cache->cc_skey);
+                                                       cache->cc_nkeys, cur_skey);
 
                ntp = heap_getnext(sd, 0);
 
-
                if (HeapTupleIsValid(ntp))
                {
-                       CACHE1_elog(DEBUG, "SearchSysCache: found tuple");
+                       /* Copy tuple into our context */
                        oldcxt = MemoryContextSwitchTo(CacheMemoryContext);
                        ntp = heap_copytuple(ntp);
                        MemoryContextSwitchTo(oldcxt);
@@ -1051,8 +933,6 @@ SearchSysCache(CatCache * cache,
                heap_endscan(sd);
        }
 
-       cache->busy = false;
-
        /* ----------------
         *      scan is complete.  if tup is valid, we can add it to the cache.
         *      note we have already copied it into the cache memory context.
@@ -1067,6 +947,8 @@ SearchSysCache(CatCache * cache,
                 */
                Dlelem     *lru_elt;
 
+               CACHE1_elog(DEBUG, "SearchSysCache: found tuple");
+
                oldcxt = MemoryContextSwitchTo(CacheMemoryContext);
 
                /*
@@ -1104,17 +986,16 @@ SearchSysCache(CatCache * cache,
                        if (ct != nct)          /* shouldn't be possible, but be safe... */
                        {
                                CACHE2_elog(DEBUG, "SearchSysCache(%s): Overflow, LRU removal",
-                                                       RelationGetRelationName(relation));
+                                                       cache->cc_relname);
 
                                CatCacheRemoveCTup(cache, elt);
                        }
                }
 
                CACHE4_elog(DEBUG, "SearchSysCache(%s): Contains %d/%d tuples",
-                                       RelationGetRelationName(relation),
-                                       cache->cc_ntup, cache->cc_maxtup);
+                                       cache->cc_relname, cache->cc_ntup, cache->cc_maxtup);
                CACHE3_elog(DEBUG, "SearchSysCache(%s): put in bucket %d",
-                                       RelationGetRelationName(relation), hash);
+                                       cache->cc_relname, hash);
        }
 
        /* ----------------
@@ -1141,7 +1022,6 @@ RelationInvalidateCatalogCacheTuple(Relation relation,
                                                          void (*function) (int, Index, ItemPointer))
 {
        CatCache   *ccp;
-       Oid                     relationId;
 
        /* ----------------
         *      sanity checks
@@ -1159,15 +1039,18 @@ RelationInvalidateCatalogCacheTuple(Relation relation,
         *                 in the proper hash bucket
         * ----------------
         */
-       relationId = RelationGetRelid(relation);
 
        for (ccp = Caches; ccp; ccp = ccp->cc_next)
        {
-               if (relationId != ccp->relationId)
+               if (strcmp(ccp->cc_relname, RelationGetRelationName(relation)) != 0)
                        continue;
 
+               /* Just in case cache hasn't finished initialization yet... */
+               if (ccp->cc_tupdesc == NULL)
+                       CatalogCacheInitializeCache(ccp);
+
                (*function) (ccp->id,
-                                CatalogCacheComputeTupleHashIndex(ccp, relation, tuple),
+                                        CatalogCacheComputeTupleHashIndex(ccp, tuple),
                                         &tuple->t_self);
        }
 }
index bc0d6ef82032e9c4fd388f021e573ed7d1b05bb5..4be4e9245a1134fa0573c1b4b848448c36ee44a7 100644 (file)
  *             careful....
  *
  */
+#include "postgres.h"
+
 #include <sys/types.h>
 #include <errno.h>
 #include <sys/file.h>
 #include <fcntl.h>
 #include <unistd.h>
 
-#include "postgres.h"
-
-#include "utils/builtins.h"
 #include "access/genam.h"
 #include "access/heapam.h"
 #include "access/istrat.h"
@@ -55,6 +54,7 @@
 #include "lib/hasht.h"
 #include "miscadmin.h"
 #include "storage/smgr.h"
+#include "utils/builtins.h"
 #include "utils/catcache.h"
 #include "utils/fmgroids.h"
 #include "utils/memutils.h"
@@ -1127,7 +1127,9 @@ IndexedAccessMethodInitialize(Relation relation)
  *             This is a special cut-down version of RelationBuildDesc()
  *             used by RelationCacheInitialize() in initializing the relcache.
  *             The relation descriptor is built just from the supplied parameters,
- *             without actually looking at any system table entries.
+ *             without actually looking at any system table entries.  We cheat
+ *             quite a lot since we only need to work for a few basic system
+ *             catalogs...
  *
  * NOTE: we assume we are already switched into CacheMemoryContext.
  * --------------------------------
@@ -1219,7 +1221,7 @@ formrdesc(char *relationName,
        RelationGetRelid(relation) = relation->rd_att->attrs[0]->attrelid;
 
        /* ----------------
-        *      initialize the relation lock manager information
+        *      initialize the relation's lock manager and RelFileNode information
         * ----------------
         */
        RelationInitLockInfo(relation);         /* see lmgr.c */
@@ -1232,22 +1234,29 @@ formrdesc(char *relationName,
                relation->rd_rel->relfilenode = RelationGetRelid(relation);
 
        /* ----------------
-        *      add new reldesc to relcache
+        *      initialize the rel-has-index flag, using hardwired knowledge
         * ----------------
         */
-       RelationCacheInsert(relation);
+       relation->rd_rel->relhasindex = false;
 
-       /*
-        * Determining this requires a scan on pg_class, but to do the scan
-        * the rdesc for pg_class must already exist.  Therefore we must do
-        * the check (and possible set) after cache insertion.
-        *
-        * XXX I believe the above comment is misguided; we should be running
-        * in bootstrap or init processing mode here, and CatalogHasIndex
-        * relies on hard-wired info in those cases.
+       /* In bootstrap mode, we have no indexes */
+       if (!IsBootstrapProcessingMode())
+       {
+               for (i = 0; IndexedCatalogNames[i] != NULL; i++)
+               {
+                       if (strcmp(IndexedCatalogNames[i], relationName) == 0)
+                       {
+                               relation->rd_rel->relhasindex = true;
+                               break;
+                       }
+               }
+       }
+
+       /* ----------------
+        *      add new reldesc to relcache
+        * ----------------
         */
-       relation->rd_rel->relhasindex =
-               CatalogHasIndex(relationName, RelationGetRelid(relation));
+       RelationCacheInsert(relation);
 }
 
 
index 6e8a8f5267ea52958bb588011243780d13e35ad3..9bc6291c7707f7d543673d80a5e58eb5446b6d6d 100644 (file)
 
        Add your entry to the cacheinfo[] array below.  All cache lists are
        alphabetical, so add it in the proper place.  Specify the relation
-       name, number of arguments, argument attribute numbers, index name,
-       and index lookup function.
+       name, index name, number of keys, and key attribute numbers.
 
        In include/catalog/indexing.h, add a define for the number of indexes
        on the relation, add define(s) for the index name(s), add an extern
-       array to hold the index names, define the index lookup function
-       prototype, and use DECLARE_UNIQUE_INDEX to define the index.  Cache
-       lookups return only one row, so the index should be unique.
+       array to hold the index names, and use DECLARE_UNIQUE_INDEX to define
+       the index.  Cache lookups return only one row, so the index should be
+       unique in most cases.
 
        In backend/catalog/indexing.c, initialize the relation array with
-       the index names for the relation, and create the index lookup function.
-       Pick one that has similar arguments and copy that one, but keep the
-       function names in the same order as the cache list for clarity.
+       the index names for the relation.
 
        Finally, any place your relation gets heap_insert() or
        heap_update calls, include code to do a CatalogIndexInsert() to update
 struct cachedesc
 {
        char       *name;                       /* name of the relation being cached */
+       char       *indname;            /* name of index relation for this cache */
        int                     nkeys;                  /* # of keys needed for cache lookup */
        int                     key[4];                 /* attribute numbers of key attrs */
-       char       *indname;            /* name of index relation for this cache */
-       ScanFunc        iScanFunc;              /* function to handle index scans */
 };
 
 static struct cachedesc cacheinfo[] = {
        {AggregateRelationName,         /* AGGNAME */
+        AggregateNameTypeIndex,
                2,
                {
                        Anum_pg_aggregate_aggname,
                        Anum_pg_aggregate_aggbasetype,
                        0,
                        0
-               },
-       AggregateNameTypeIndex,
-       (ScanFunc) AggregateNameTypeIndexScan},
+               }},
        {AccessMethodRelationName,      /* AMNAME */
+        AmNameIndex,
                1,
                {
                        Anum_pg_am_amname,
                        0,
                        0,
                        0
-               },
-       AmNameIndex,
-       (ScanFunc) AmNameIndexScan},
+               }},
        {AccessMethodOperatorRelationName,      /* AMOPOPID */
+        AccessMethodOpidIndex,
                3,
                {
                        Anum_pg_amop_amopclaid,
                        Anum_pg_amop_amopopr,
                        Anum_pg_amop_amopid,
                        0
-               },
-       AccessMethodOpidIndex,
-       (ScanFunc) AccessMethodOpidIndexScan},
+               }},
        {AccessMethodOperatorRelationName,      /* AMOPSTRATEGY */
+        AccessMethodStrategyIndex,
                3,
                {
                        Anum_pg_amop_amopid,
                        Anum_pg_amop_amopclaid,
                        Anum_pg_amop_amopstrategy,
                        0
-               },
-       AccessMethodStrategyIndex,
-       (ScanFunc) AccessMethodStrategyIndexScan},
+               }},
        {AttributeRelationName,         /* ATTNAME */
+        AttributeRelidNameIndex,
                2,
                {
                        Anum_pg_attribute_attrelid,
                        Anum_pg_attribute_attname,
                        0,
                        0
-               },
-       AttributeRelidNameIndex,
-       (ScanFunc) AttributeRelidNameIndexScan},
+               }},
        {AttributeRelationName,         /* ATTNUM */
+        AttributeRelidNumIndex,
                2,
                {
                        Anum_pg_attribute_attrelid,
                        Anum_pg_attribute_attnum,
                        0,
                        0
-               },
-       AttributeRelidNumIndex,
-       (ScanFunc) AttributeRelidNumIndexScan},
+               }},
        {OperatorClassRelationName, /* CLADEFTYPE */
+        OpclassDeftypeIndex,
                1,
                {
                        Anum_pg_opclass_opcdeftype,
                        0,
                        0,
                        0
-               },
-       OpclassDeftypeIndex,
-       (ScanFunc) OpclassDeftypeIndexScan},
+               }},
        {OperatorClassRelationName, /* CLANAME */
+        OpclassNameIndex,
                1,
                {
                        Anum_pg_opclass_opcname,
                        0,
                        0,
                        0
-               },
-       OpclassNameIndex,
-       (ScanFunc) OpclassNameIndexScan},
+               }},
        {GroupRelationName,                     /* GRONAME */
+        GroupNameIndex,
                1,
                {
                        Anum_pg_group_groname,
                        0,
                        0,
                        0
-               },
-       GroupNameIndex,
-       (ScanFunc) GroupNameIndexScan},
+               }},
        {GroupRelationName,                     /* GROSYSID */
+        GroupSysidIndex,
                1,
                {
                        Anum_pg_group_grosysid,
                        0,
                        0,
                        0
-               },
-       GroupSysidIndex,
-       (ScanFunc) GroupSysidIndexScan},
+               }},
        {IndexRelationName,                     /* INDEXRELID */
+        IndexRelidIndex,
                1,
                {
                        Anum_pg_index_indexrelid,
                        0,
                        0,
                        0
-               },
-       IndexRelidIndex,
-       (ScanFunc) IndexRelidIndexScan},
+               }},
        {InheritsRelationName,          /* INHRELID */
+        InheritsRelidSeqnoIndex,
                2,
                {
                        Anum_pg_inherits_inhrelid,
                        Anum_pg_inherits_inhseqno,
                        0,
                        0
-               },
-       InheritsRelidSeqnoIndex,
-       (ScanFunc) InheritsRelidSeqnoIndexScan},
+               }},
        {LanguageRelationName,          /* LANGNAME */
+        LanguageNameIndex,
                1,
                {
                        Anum_pg_language_lanname,
                        0,
                        0,
                        0
-               },
-       LanguageNameIndex,
-       (ScanFunc) LanguageNameIndexScan},
+               }},
        {LanguageRelationName,          /* LANGOID */
+        LanguageOidIndex,
                1,
                {
                        ObjectIdAttributeNumber,
                        0,
                        0,
                        0
-               },
-       LanguageOidIndex,
-       (ScanFunc) LanguageOidIndexScan},
+               }},
        {ListenerRelationName,          /* LISTENREL */
+        ListenerPidRelnameIndex,
                2,
                {
                        Anum_pg_listener_pid,
                        Anum_pg_listener_relname,
                        0,
                        0
-               },
-       ListenerPidRelnameIndex,
-       (ScanFunc) ListenerPidRelnameIndexScan},
+               }},
        {OperatorRelationName,          /* OPERNAME */
+        OperatorNameIndex,
                4,
                {
                        Anum_pg_operator_oprname,
                        Anum_pg_operator_oprleft,
                        Anum_pg_operator_oprright,
                        Anum_pg_operator_oprkind
-               },
-       OperatorNameIndex,
-       (ScanFunc) OperatorNameIndexScan},
+               }},
        {OperatorRelationName,          /* OPEROID */
+        OperatorOidIndex,
                1,
                {
                        ObjectIdAttributeNumber,
                        0,
                        0,
                        0
-               },
-       OperatorOidIndex,
-       (ScanFunc) OperatorOidIndexScan},
+               }},
        {ProcedureRelationName,         /* PROCNAME */
+        ProcedureNameIndex,
                3,
                {
                        Anum_pg_proc_proname,
                        Anum_pg_proc_pronargs,
                        Anum_pg_proc_proargtypes,
                        0
-               },
-       ProcedureNameIndex,
-       (ScanFunc) ProcedureNameIndexScan},
+               }},
        {ProcedureRelationName,         /* PROCOID */
+        ProcedureOidIndex,
                1,
                {
                        ObjectIdAttributeNumber,
                        0,
                        0,
                        0
-               },
-       ProcedureOidIndex,
-       (ScanFunc) ProcedureOidIndexScan},
+               }},
        {RelationRelationName,          /* RELNAME */
+        ClassNameIndex,
                1,
                {
                        Anum_pg_class_relname,
                        0,
                        0,
                        0
-               },
-       ClassNameIndex,
-       (ScanFunc) ClassNameIndexScan},
+               }},
        {RelationRelationName,          /* RELOID */
+        ClassOidIndex,
                1,
                {
                        ObjectIdAttributeNumber,
                        0,
                        0,
                        0
-               },
-       ClassOidIndex,
-       (ScanFunc) ClassOidIndexScan},
+               }},
        {RewriteRelationName,           /* REWRITENAME */
+        RewriteRulenameIndex,
                1,
                {
                        Anum_pg_rewrite_rulename,
                        0,
                        0,
                        0
-               },
-       RewriteRulenameIndex,
-       (ScanFunc) RewriteRulenameIndexScan},
+               }},
        {RewriteRelationName,           /* RULEOID */
+        RewriteOidIndex,
                1,
                {
                        ObjectIdAttributeNumber,
                        0,
                        0,
                        0
-               },
-       RewriteOidIndex,
-       (ScanFunc) RewriteOidIndexScan},
+               }},
        {ShadowRelationName,            /* SHADOWNAME */
+        ShadowNameIndex,
                1,
                {
                        Anum_pg_shadow_usename,
                        0,
                        0,
                        0
-               },
-       ShadowNameIndex,
-       (ScanFunc) ShadowNameIndexScan},
+               }},
        {ShadowRelationName,            /* SHADOWSYSID */
+        ShadowSysidIndex,
                1,
                {
                        Anum_pg_shadow_usesysid,
                        0,
                        0,
                        0
-               },
-       ShadowSysidIndex,
-       (ScanFunc) ShadowSysidIndexScan},
+               }},
        {StatisticRelationName,         /* STATRELID */
+        StatisticRelidAttnumIndex,
                2,
                {
                        Anum_pg_statistic_starelid,
                        Anum_pg_statistic_staattnum,
                        0,
                        0
-               },
-       StatisticRelidAttnumIndex,
-       (ScanFunc) StatisticRelidAttnumIndexScan},
+               }},
        {TypeRelationName,                      /* TYPENAME */
+        TypeNameIndex,
                1,
                {
                        Anum_pg_type_typname,
                        0,
                        0,
                        0
-               },
-       TypeNameIndex,
-       (ScanFunc) TypeNameIndexScan},
+               }},
        {TypeRelationName,                      /* TYPEOID */
+        TypeOidIndex,
                1,
                {
                        ObjectIdAttributeNumber,
                        0,
                        0,
                        0
-               },
-       TypeOidIndex,
-       (ScanFunc) TypeOidIndexScan}
+               }}
 };
 
 static CatCache *SysCache[lengthof(cacheinfo)];
@@ -412,12 +380,11 @@ InitCatalogCache()
                {
                        Assert(!PointerIsValid(SysCache[cacheId]));
 
-                       SysCache[cacheId] = InitSysCache(cacheinfo[cacheId].name,
+                       SysCache[cacheId] = InitSysCache(cacheId,
+                                                                                        cacheinfo[cacheId].name,
                                                                                         cacheinfo[cacheId].indname,
-                                                                                        cacheId,
                                                                                         cacheinfo[cacheId].nkeys,
-                                                                                        cacheinfo[cacheId].key,
-                                                                                  cacheinfo[cacheId].iScanFunc);
+                                                                                        cacheinfo[cacheId].key);
                        if (!PointerIsValid(SysCache[cacheId]))
                        {
                                elog(ERROR,
@@ -469,12 +436,11 @@ SearchSysCacheTuple(int cacheId,/* cache selection code */
 
        if (!PointerIsValid(SysCache[cacheId]))
        {
-               SysCache[cacheId] = InitSysCache(cacheinfo[cacheId].name,
+               SysCache[cacheId] = InitSysCache(cacheId,
+                                                                                cacheinfo[cacheId].name,
                                                                                 cacheinfo[cacheId].indname,
-                                                                                cacheId,
                                                                                 cacheinfo[cacheId].nkeys,
-                                                                                cacheinfo[cacheId].key,
-                                                                                cacheinfo[cacheId].iScanFunc);
+                                                                                cacheinfo[cacheId].key);
                if (!PointerIsValid(SysCache[cacheId]))
                        elog(ERROR,
                                 "InitCatalogCache: Can't init cache %s(%d)",
@@ -569,7 +535,6 @@ SysCacheGetAttr(int cacheId, HeapTuple tup,
        if (cacheId < 0 || cacheId >= SysCacheSize)
                elog(ERROR, "SysCacheGetAttr: Bad cache id %d", cacheId);
        if (!PointerIsValid(SysCache[cacheId]) ||
-               SysCache[cacheId]->relationId == InvalidOid ||
                !PointerIsValid(SysCache[cacheId]->cc_tupdesc))
                elog(ERROR, "SysCacheGetAttr: missing cache data for id %d", cacheId);
 
index 6bd142ad8ae838062a3e9c86a3e319cc5e10b17d..6961ec846f80f24077e72cea254b776dd967490f 100644 (file)
@@ -1,7 +1,7 @@
 /*-------------------------------------------------------------------------
  *
  * indexing.h
- *       This include provides some definitions to support indexing
+ *       This file provides some definitions to support indexing
  *       on system catalogs
  *
  *
@@ -116,55 +116,15 @@ extern void CatalogOpenIndices(int nIndices, char **names, Relation *idescs);
 extern void CatalogCloseIndices(int nIndices, Relation *idescs);
 extern void CatalogIndexInsert(Relation *idescs, int nIndices,
                                                           Relation heapRelation, HeapTuple heapTuple);
-extern bool CatalogHasIndex(char *catName, Oid catId);
 
 /*
- * Functions for each index to perform the necessary scan on a cache miss.
+ * Canned functions for indexscans on certain system indexes.
  * All index-value arguments should be passed as Datum for portability!
  */
-extern HeapTuple AccessMethodOpidIndexScan(Relation heapRelation,
-                                                 Datum claid, Datum opopr, Datum opid);
-extern HeapTuple AccessMethodStrategyIndexScan(Relation heapRelation,
-                                                         Datum opid, Datum claid, Datum opstrategy);
-extern HeapTuple AggregateNameTypeIndexScan(Relation heapRelation,
-                                                  Datum aggName, Datum aggType);
-extern HeapTuple AmNameIndexScan(Relation heapRelation, Datum amName);
-extern HeapTuple AttributeRelidNameIndexScan(Relation heapRelation,
-                                                       Datum relid, Datum attname);
 extern HeapTuple AttributeRelidNumIndexScan(Relation heapRelation,
-                                                  Datum relid, Datum attnum);
-extern HeapTuple ClassNameIndexScan(Relation heapRelation, Datum relName);
+                                                                                       Datum relid, Datum attnum);
 extern HeapTuple ClassNameIndexScan(Relation heapRelation, Datum relName);
 extern HeapTuple ClassOidIndexScan(Relation heapRelation, Datum relId);
-extern HeapTuple GroupNameIndexScan(Relation heapRelation, Datum groName);
-extern HeapTuple GroupSysidIndexScan(Relation heapRelation, Datum sysId);
-extern HeapTuple IndexRelidIndexScan(Relation heapRelation, Datum relid);
-extern HeapTuple InheritsRelidSeqnoIndexScan(Relation heapRelation,
-                                                                                        Datum relid, Datum seqno);
-extern HeapTuple LanguageNameIndexScan(Relation heapRelation, Datum lanName);
-extern HeapTuple LanguageOidIndexScan(Relation heapRelation, Datum lanId);
-extern HeapTuple ListenerPidRelnameIndexScan(Relation heapRelation,
-                                                                                        Datum pid, Datum relName);
-extern HeapTuple OpclassDeftypeIndexScan(Relation heapRelation, Datum defType);
-extern HeapTuple OpclassNameIndexScan(Relation heapRelation, Datum opcName);
-extern HeapTuple OperatorNameIndexScan(Relation heapRelation,
-                                                                          Datum oprName, Datum oprLeft,
-                                                                          Datum oprRight, Datum oprKind);
-extern HeapTuple OperatorOidIndexScan(Relation heapRelation, Datum oprId);
-extern HeapTuple ProcedureNameIndexScan(Relation heapRelation,
-                                          Datum procName, Datum nargs, Datum argTypes);
-extern HeapTuple ProcedureOidIndexScan(Relation heapRelation, Datum procId);
-extern HeapTuple RewriteOidIndexScan(Relation heapRelation, Datum rewriteId);
-extern HeapTuple RewriteRulenameIndexScan(Relation heapRelation,
-                                                                                 Datum ruleName);
-extern HeapTuple ShadowNameIndexScan(Relation heapRelation, Datum useName);
-extern HeapTuple ShadowSysidIndexScan(Relation heapRelation, Datum sysId);
-extern HeapTuple StatisticRelidAttnumIndexScan(Relation heapRelation,
-                                                         Datum relId, Datum attNum);
-extern HeapTuple TypeNameIndexScan(Relation heapRelation, Datum typeName);
-extern HeapTuple TypeOidIndexScan(Relation heapRelation, Datum typeId);
-
-
 
 
 /*
index 9c0a9872bc93a7bb8bb6a6fb62f925bcda7c9fe8..a26f62ae73a2ca4a8a87cdee956b20ccdf3cb3a4 100644 (file)
@@ -3,6 +3,12 @@
  * catcache.h
  *       Low-level catalog cache definitions.
  *
+ * NOTE: every catalog cache must have a corresponding unique index on
+ * the system table that it caches --- ie, the index must match the keys
+ * used to do lookups in this cache.  All cache fetches are done with
+ * indexscans (under normal conditions).  The index should be unique to
+ * guarantee that there can only be one matching row for a key combination.
+ *
  *
  * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
  * Portions Copyright (c) 1994, Regents of the University of California
 #include "lib/dllist.h"
 
 /*
- * Functions that implement index scans for caches must match this signature
- * (except we allow unused key arguments to be omitted --- is that really
- * portable?)
- */
-typedef HeapTuple (*ScanFunc) (Relation heapRelation,
-                                                          Datum key1,
-                                                          Datum key2,
-                                                          Datum key3,
-                                                          Datum key4);
-
-/*
- *             struct catctup:                 tuples in the cache.
+ *             struct catctup:                 individual tuple in the cache.
  *             struct catcache:                information for managing a cache.
  */
 
@@ -53,22 +48,18 @@ typedef struct catctup
 
 typedef struct catcache
 {
-       Oid                     relationId;
-       Oid                     indexId;
-       char       *cc_relname;         /* relation name for defered open */
-       char       *cc_indname;         /* index name for defered open */
-       ScanFunc        cc_iscanfunc;   /* index scan function */
-       TupleDesc       cc_tupdesc;             /* tuple descriptor from reldesc */
-       int                     id;                             /* XXX could be improved -hirohama */
-       bool            busy;                   /* for detecting recursive lookups */
-       short           cc_ntup;                /* # of tuples in this cache    */
+       int                     id;                             /* cache identifier --- see syscache.h */
+       struct catcache *cc_next;       /* link to next catcache */
+       char       *cc_relname;         /* name of relation the tuples come from */
+       char       *cc_indname;         /* name of index matching cache keys */
+       TupleDesc       cc_tupdesc;             /* tuple descriptor (copied from reldesc) */
+       short           cc_ntup;                /* # of tuples in this cache */
        short           cc_maxtup;              /* max # of tuples allowed (LRU) */
-       short           cc_nkeys;
-       short           cc_size;
+       short           cc_size;                /* # of hash buckets in this cache */
+       short           cc_nkeys;               /* number of keys (1..4) */
        short           cc_key[4];              /* AttrNumber of each key */
        PGFunction      cc_hashfunc[4]; /* hash function to use for each key */
-       ScanKeyData cc_skey[4];
-       struct catcache *cc_next;
+       ScanKeyData cc_skey[4];         /* precomputed key info for indexscans */
        Dllist     *cc_lrulist;         /* LRU list, most recent first */
        Dllist     *cc_cache[NCCBUCK + 1];      /* hash buckets */
 } CatCache;
@@ -79,17 +70,17 @@ typedef struct catcache
 extern MemoryContext CacheMemoryContext;
 
 extern void CreateCacheMemoryContext(void);
-extern void CatalogCacheIdInvalidate(int cacheId, Index hashIndex,
-                                                ItemPointer pointer);
-extern void ResetSystemCache(void);
-extern void SystemCacheRelationFlushed(Oid relId);
-extern void SystemCacheAbort(void);
-extern CatCache *InitSysCache(char *relname, char *indname, int id,
-                                                         int nkeys, int *key,
-                                                         ScanFunc iScanfuncP);
-extern HeapTuple SearchSysCache(CatCache * cache,
+
+extern CatCache *InitSysCache(int id, char *relname, char *indname,
+                                                         int nkeys, int *key);
+extern HeapTuple SearchSysCache(CatCache *cache,
                                                                Datum v1, Datum v2,
                                                                Datum v3, Datum v4);
+
+extern void ResetSystemCache(void);
+extern void SystemCacheRelationFlushed(Oid relId);
+extern void CatalogCacheIdInvalidate(int cacheId, Index hashIndex,
+                                                                        ItemPointer pointer);
 extern void RelationInvalidateCatalogCacheTuple(Relation relation,
                                                                HeapTuple tuple,
                                                                void (*function) (int, Index, ItemPointer));