]> granicus.if.org Git - postgresql/commitdiff
Replace SearchSysCacheGetAttribute with SysCacheGetAttr, which fetches
authorTom Lane <tgl@sss.pgh.pa.us>
Sun, 23 Jan 2000 03:43:24 +0000 (03:43 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Sun, 23 Jan 2000 03:43:24 +0000 (03:43 +0000)
an attribute of a tuple previously fetched with SearchSysCacheTuple.
This avoids a lot of redundant cache lookups, particularly in selfuncs.c.
Also, remove SearchSysCacheStruct, which was unused and grotty.

src/backend/utils/adt/selfuncs.c
src/backend/utils/cache/fcache.c
src/backend/utils/cache/lsyscache.c
src/backend/utils/cache/syscache.c
src/include/utils/syscache.h

index 6af241f9a182c7e63c55f195aaaa81f737144426..5838fdc471ff2fa07bebb5bd6ccec56a8891dfa3 100644 (file)
@@ -14,7 +14,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/utils/adt/selfuncs.c,v 1.50 2000/01/23 02:06:56 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/utils/adt/selfuncs.c,v 1.51 2000/01/23 03:43:23 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -587,9 +587,6 @@ getattproperties(Oid relid, AttrNumber attnum,
  * commonval, loval, hival are returned as Datums holding the internal
  * representation of the values.  (Note that these should be pfree'd
  * after use if the data type is not by-value.)
- *
- * XXX currently, this does a linear search of pg_statistic because there
- * is no index nor syscache for pg_statistic.  FIX THIS!
  */
 static bool
 getattstatistics(Oid relid, AttrNumber attnum, Oid opid, Oid typid,
@@ -600,29 +597,26 @@ getattstatistics(Oid relid, AttrNumber attnum, Oid opid, Oid typid,
                                 Datum *loval,
                                 Datum *hival)
 {
-       Relation        rel;
-       bool            isnull;
        HeapTuple       tuple;
        HeapTuple       typeTuple;
        FmgrInfo        inputproc;
        Oid                     typelem;
+       bool            isnull;
 
-       rel = heap_openr(StatisticRelationName, AccessShareLock);
-
+       /* We assume that there will only be one entry in pg_statistic
+        * for the given rel/att.  Someday, VACUUM might store more than one...
+        */
        tuple = SearchSysCacheTuple(STATRELID,
-                                                                       ObjectIdGetDatum(relid),
-                                                                       Int16GetDatum((int16) attnum),
-                                                                       opid, 0);
+                                                               ObjectIdGetDatum(relid),
+                                                               Int16GetDatum((int16) attnum),
+                                                               opid,
+                                                               0);
        if (!HeapTupleIsValid(tuple))
        {
                /* no such stats entry */
-               heap_close(rel, AccessShareLock);
                return false;
        }
 
-       /* We assume that there will only be one entry in pg_statistic
-        * for the given rel/att.  Someday, VACUUM might store more than one...
-        */
        if (nullfrac)
                *nullfrac = ((Form_pg_statistic) GETSTRUCT(tuple))->stanullfrac;
        if (commonfrac)
@@ -639,14 +633,13 @@ getattstatistics(Oid relid, AttrNumber attnum, Oid opid, Oid typid,
        typelem = ((Form_pg_type) GETSTRUCT(typeTuple))->typelem;
 
        /* Values are variable-length fields, so cannot access as struct fields.
-        * Must do it the hard way with heap_getattr.
+        * Must do it the hard way with SysCacheGetAttr.
         */
        if (commonval)
        {
-               text *val = (text *) heap_getattr(tuple,
-                                                                                 Anum_pg_statistic_stacommonval,
-                                                                                 RelationGetDescr(rel),
-                                                                                 &isnull);
+               text *val = (text *) SysCacheGetAttr(STATRELID, tuple,
+                                                                                        Anum_pg_statistic_stacommonval,
+                                                                                        &isnull);
                if (isnull)
                {
                        elog(DEBUG, "getattstatistics: stacommonval is null");
@@ -663,10 +656,9 @@ getattstatistics(Oid relid, AttrNumber attnum, Oid opid, Oid typid,
 
        if (loval)
        {
-               text *val = (text *) heap_getattr(tuple,
-                                                                                 Anum_pg_statistic_staloval,
-                                                                                 RelationGetDescr(rel),
-                                                                                 &isnull);
+               text *val = (text *) SysCacheGetAttr(STATRELID, tuple,
+                                                                                        Anum_pg_statistic_staloval,
+                                                                                        &isnull);
                if (isnull)
                {
                        elog(DEBUG, "getattstatistics: staloval is null");
@@ -683,10 +675,9 @@ getattstatistics(Oid relid, AttrNumber attnum, Oid opid, Oid typid,
 
        if (hival)
        {
-               text *val = (text *) heap_getattr(tuple,
-                                                                                 Anum_pg_statistic_stahival,
-                                                                                 RelationGetDescr(rel),
-                                                                                 &isnull);
+               text *val = (text *) SysCacheGetAttr(STATRELID, tuple,
+                                                                                        Anum_pg_statistic_stahival,
+                                                                                        &isnull);
                if (isnull)
                {
                        elog(DEBUG, "getattstatistics: stahival is null");
@@ -701,7 +692,6 @@ getattstatistics(Oid relid, AttrNumber attnum, Oid opid, Oid typid,
                }
        }
 
-       heap_close(rel, AccessShareLock);
        return true;
 }
 
index 69ef78af096c51f78933316dc625800b7676a2a5..49a2642e8676406c0c1ba1bb552aacbc875c786a 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/utils/cache/Attic/fcache.c,v 1.27 1999/11/22 17:56:32 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/utils/cache/Attic/fcache.c,v 1.28 2000/01/23 03:43:24 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -74,13 +74,12 @@ init_fcache(Oid foid,
        Form_pg_proc procedureStruct;
        Form_pg_type typeStruct;
        FunctionCachePtr retval;
-       text       *tmp;
        int                     nargs;
+       text       *tmp;
+       bool            isNull;
 
        /* ----------------
-        *       get the procedure tuple corresponding to the given
-        *       functionOid.  If this fails, returnValue has been
-        *       pre-initialized to "null" so we just return it.
+        *       get the procedure tuple corresponding to the given functionOid
         * ----------------
         */
        retval = (FunctionCachePtr) palloc(sizeof(FunctionCache));
@@ -94,20 +93,13 @@ init_fcache(Oid foid,
                                                                                 0, 0, 0);
 
        if (!HeapTupleIsValid(procedureTuple))
-               elog(ERROR,
-                        "init_fcache: %s %u",
-                        "Cache lookup failed for procedure", foid);
+               elog(ERROR, "init_fcache: Cache lookup failed for procedure %u",
+                        foid);
 
-       /* ----------------
-        *       get the return type from the procedure tuple
-        * ----------------
-        */
        procedureStruct = (Form_pg_proc) GETSTRUCT(procedureTuple);
 
        /* ----------------
-        *       get the type tuple corresponding to the return type
-        *       If this fails, returnValue has been pre-initialized
-        *       to "null" so we just return it.
+        *       get the return type from the procedure tuple
         * ----------------
         */
        typeTuple = SearchSysCacheTuple(TYPEOID,
@@ -115,27 +107,24 @@ init_fcache(Oid foid,
                                                                        0, 0, 0);
 
        if (!HeapTupleIsValid(typeTuple))
-               elog(ERROR,
-                        "init_fcache: %s %u",
-                        "Cache lookup failed for type",
-                        (procedureStruct)->prorettype);
+               elog(ERROR, "init_fcache: Cache lookup failed for type %u",
+                        procedureStruct->prorettype);
+
+       typeStruct = (Form_pg_type) GETSTRUCT(typeTuple);
 
        /* ----------------
         *       get the type length and by-value from the type tuple and
         *       save the information in our one element cache.
         * ----------------
         */
-       typeStruct = (Form_pg_type) GETSTRUCT(typeTuple);
-
-       retval->typlen = (typeStruct)->typlen;
-       if ((typeStruct)->typrelid == InvalidOid)
+       retval->typlen = typeStruct->typlen;
+       if (typeStruct->typrelid == InvalidOid)
        {
                /* The return type is not a relation, so just use byval */
-               retval->typbyval = (typeStruct)->typbyval ? true : false;
+               retval->typbyval = typeStruct->typbyval;
        }
        else
        {
-
                /*
                 * This is a hack.      We assume here that any function returning a
                 * relation returns it by reference.  This needs to be fixed.
@@ -147,7 +136,7 @@ init_fcache(Oid foid,
        retval->func_state = (char *) NULL;
        retval->setArg = NULL;
        retval->hasSetArg = false;
-       retval->oneResult = !procedureStruct->proretset;
+       retval->oneResult = ! procedureStruct->proretset;
        retval->istrusted = procedureStruct->proistrusted;
 
        /*
@@ -157,8 +146,8 @@ init_fcache(Oid foid,
         * allocated by the executor (i.e. slots and tuples) is freed.
         */
        if ((retval->language == SQLlanguageId) &&
-               (retval->oneResult) &&
-               !(retval->typbyval))
+               retval->oneResult &&
+               ! retval->typbyval)
        {
                Form_pg_class relationStruct;
                HeapTuple       relationTuple;
@@ -198,7 +187,7 @@ init_fcache(Oid foid,
        {
                Oid                *argTypes;
 
-               retval->nullVect = (bool *) palloc((retval->nargs) * sizeof(bool));
+               retval->nullVect = (bool *) palloc(retval->nargs * sizeof(bool));
 
                if (retval->language == SQLlanguageId)
                {
@@ -230,43 +219,36 @@ init_fcache(Oid foid,
                retval->nullVect = (BoolPtr) NULL;
        }
 
-       /*
-        * XXX this is the first varlena in the struct.  If the order changes
-        * for some reason this will fail.
-        */
        if (procedureStruct->prolang == SQLlanguageId)
        {
-               retval->src = textout(&(procedureStruct->prosrc));
+               tmp = (text *) SysCacheGetAttr(PROCOID,
+                                                                          procedureTuple,
+                                                                          Anum_pg_proc_prosrc,
+                                                                          &isNull);
+               if (isNull)
+                       elog(ERROR, "init_fcache: null prosrc for procedure %u",
+                                foid);
+               retval->src = textout(tmp);
                retval->bin = (char *) NULL;
        }
        else
        {
-
-               /*
-                * I'm not sure that we even need to do this at all.
-                */
-
-               /*
-                * We do for untrusted functions.
-                */
-
+               retval->src = (char *) NULL;
                if (procedureStruct->proistrusted)
                        retval->bin = (char *) NULL;
                else
                {
-                       tmp = (text *)
-                               SearchSysCacheGetAttribute(PROCOID,
+                       tmp = (text *) SysCacheGetAttr(PROCOID,
+                                                                                  procedureTuple,
                                                                                   Anum_pg_proc_probin,
-                                                                                  ObjectIdGetDatum(foid),
-                                                                                  0, 0, 0);
+                                                                                  &isNull);
+                       if (isNull)
+                               elog(ERROR, "init_fcache: null probin for procedure %u",
+                                        foid);
                        retval->bin = textout(tmp);
                }
-               retval->src = (char *) NULL;
        }
 
-
-
-
        if (retval->language != SQLlanguageId)
        {
                fmgr_info(foid, &(retval->func));
@@ -275,7 +257,6 @@ init_fcache(Oid foid,
        else
                retval->func.fn_addr = (func_ptr) NULL;
 
-
        return retval;
 }
 
index 1c34486b7497d62042b79c7919187d50289f51c3..406c476182be476d7245ad3e5b1834e92c007daa 100644 (file)
@@ -6,7 +6,7 @@
  * Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v 1.37 1999/12/31 03:18:43 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v 1.38 2000/01/23 03:43:24 tgl Exp $
  *
  * NOTES
  *       Eventually, the index information should go through here, too.
@@ -617,35 +617,15 @@ get_typalign(Oid typid)
 Datum
 get_typdefault(Oid typid)
 {
-       struct varlena *typDefault;
-       int32           dataSize;
        HeapTuple       typeTuple;
        Form_pg_type type;
+       struct varlena *typDefault;
+       bool            isNull;
+       int32           dataSize;
        int32           typLen;
        bool            typByVal;
        Datum           returnValue;
 
-       /*
-        * First, see if there is a non-null typdefault field (usually there isn't)
-        */
-       typDefault = (struct varlena *)
-               SearchSysCacheGetAttribute(TYPEOID,
-                                                                  Anum_pg_type_typdefault,
-                                                                  ObjectIdGetDatum(typid),
-                                                                  0, 0, 0);
-
-       if (typDefault == NULL)
-               return PointerGetDatum(NULL);
-
-       dataSize = VARSIZE(typDefault) - VARHDRSZ;
-
-       /*
-        * Need the type's length and byVal fields.
-        *
-        * XXX silly to repeat the syscache search that SearchSysCacheGetAttribute
-        * just did --- but at present this path isn't taken often enough to
-        * make it worth fixing.
-        */
        typeTuple = SearchSysCacheTuple(TYPEOID,
                                                                        ObjectIdGetDatum(typid),
                                                                        0, 0, 0);
@@ -654,6 +634,22 @@ get_typdefault(Oid typid)
                elog(ERROR, "get_typdefault: failed to lookup type %u", typid);
 
        type = (Form_pg_type) GETSTRUCT(typeTuple);
+
+       /*
+        * First, see if there is a non-null typdefault field (usually there isn't)
+        */
+       typDefault = (struct varlena *) SysCacheGetAttr(TYPEOID,
+                                                                                                       typeTuple,
+                                                                                                       Anum_pg_type_typdefault,
+                                                                                                       &isNull);
+
+       if (isNull)
+               return PointerGetDatum(NULL);
+
+       /*
+        * Otherwise, extract/copy the value.
+        */
+       dataSize = VARSIZE(typDefault) - VARHDRSZ;
        typLen = type->typlen;
        typByVal = type->typbyval;
 
index 9c94c1e05a14380ca35d56f6d11746af8ba80eb8..0d4c1e3e056855cc81003c3812642834453add50 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/utils/cache/syscache.c,v 1.44 1999/11/24 17:09:27 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/utils/cache/syscache.c,v 1.45 2000/01/23 03:43:24 tgl Exp $
  *
  * NOTES
  *       These routines allow the parser/planner/executor to perform
@@ -535,140 +535,42 @@ SearchSysCacheTuple(int cacheId,/* cache selection code */
        return tp;
 }
 
-/*
- * SearchSysCacheStruct
- *       Fills 's' with the information retrieved by calling SearchSysCache()
- *       with arguments key1...key4.  Retrieves only the portion of the tuple
- *       which is not variable-length.
- *
- * NOTE: we are assuming that non-variable-length fields in the system
- *              catalogs will always be defined!
- *
- * Returns 1L if a tuple was found, 0L if not.
- */
-int32
-SearchSysCacheStruct(int cacheId,              /* cache selection code */
-                                        char *returnStruct,            /* (preallocated!) */
-                                        Datum key1,
-                                        Datum key2,
-                                        Datum key3,
-                                        Datum key4)
-{
-       HeapTuple       tp;
-
-       if (!PointerIsValid(returnStruct))
-       {
-               elog(ERROR, "SearchSysCacheStruct: No receiving struct");
-               return 0;
-       }
-       tp = SearchSysCacheTuple(cacheId, key1, key2, key3, key4);
-       if (!HeapTupleIsValid(tp))
-               return 0;
-       memcpy(returnStruct, (char *) GETSTRUCT(tp), cacheinfo[cacheId].size);
-       return 1;
-}
-
 
 /*
- * SearchSysCacheGetAttribute
- *       Returns the attribute corresponding to 'attributeNumber' for
- *       a given cached tuple.  This routine usually needs to be used for
- *       attributes that might be NULL or might be at a variable offset
- *       in the tuple.
+ * SysCacheGetAttr
+ *
+ *             Given a tuple previously fetched by SearchSysCacheTuple() or
+ *             SearchSysCacheTupleCopy(), extract a specific attribute.
  *
- * XXX This re-opens the relation, so this is slower than just pulling
- * fixed-location fields out of the struct returned by SearchSysCacheTuple.
+ * This is equivalent to using heap_getattr() on a tuple fetched
+ * from a non-cached relation.  Usually, this is only used for attributes
+ * that could be NULL or variable length; the fixed-size attributes in
+ * a system table are accessed just by mapping the tuple onto the C struct
+ * declarations from include/catalog/.
  *
- * [callers all assume this returns a (struct varlena *). -ay 10/94]
+ * As with heap_getattr(), if the attribute is of a pass-by-reference type
+ * then a pointer into the tuple data area is returned --- the caller must
+ * not modify or pfree the datum!
  */
-void *
-SearchSysCacheGetAttribute(int cacheId,
-                                                  AttrNumber attributeNumber,
-                                                  Datum key1,
-                                                  Datum key2,
-                                                  Datum key3,
-                                                  Datum key4)
+Datum
+SysCacheGetAttr(int cacheId, HeapTuple tup,
+                               AttrNumber attributeNumber,
+                               bool *isnull)
 {
-       HeapTuple       tp;
-       char       *cacheName;
-       Relation        relation;
-       int32           attributeLength,
-                               attributeByValue;
-       bool            isNull;
-       Datum           attributeValue;
-       void       *returnValue;
-
        /*
-        * Open the relation first, to ensure we are in sync with SI inval
-        * events --- we don't want the tuple found in the cache to be
-        * invalidated out from under us.
+        * We just need to get the TupleDesc out of the cache entry,
+        * and then we can apply heap_getattr().  We expect that the cache
+        * control data is currently valid --- if the caller just fetched
+        * the tuple, then it should be.
         */
-       cacheName = cacheinfo[cacheId].name;
-       relation = heap_openr(cacheName, AccessShareLock);
-
-       tp = SearchSysCacheTuple(cacheId, key1, key2, key3, key4);
-
-       if (!HeapTupleIsValid(tp))
-       {
-               heap_close(relation, AccessShareLock);
-#ifdef CACHEDEBUG
-               elog(DEBUG,
-                        "SearchSysCacheGetAttribute: Lookup in %s(%d) failed",
-                        cacheName, cacheId);
-#endif  /* defined(CACHEDEBUG) */
-               return NULL;
-       }
-
-       if (attributeNumber < 0 &&
-               attributeNumber > FirstLowInvalidHeapAttributeNumber)
-       {
-               attributeLength = heap_sysattrlen(attributeNumber);
-               attributeByValue = heap_sysattrbyval(attributeNumber);
-       }
-       else if (attributeNumber > 0 &&
-                        attributeNumber <= relation->rd_rel->relnatts)
-       {
-               attributeLength = relation->rd_att->attrs[attributeNumber - 1]->attlen;
-               attributeByValue = relation->rd_att->attrs[attributeNumber - 1]->attbyval;
-       }
-       else
-       {
-               heap_close(relation, AccessShareLock);
-               elog(ERROR,
-                        "SearchSysCacheGetAttribute: Bad attr # %d in %s(%d)",
-                        attributeNumber, cacheName, cacheId);
-               return NULL;
-       }
-
-       attributeValue = heap_getattr(tp,
-                                                                 attributeNumber,
-                                                                 RelationGetDescr(relation),
-                                                                 &isNull);
-
-       if (isNull)
-       {
-               /*
-                * Used to be an elog(DEBUG, ...) here and a claim that it should
-                * be a FATAL error, I don't think either is warranted -mer 6/9/92
-                */
-               heap_close(relation, AccessShareLock);
-               return NULL;
-       }
-
-       if (attributeByValue)
-               returnValue = (void *) attributeValue;
-       else
-       {
-               char       *tmp;
-               int                     size = (attributeLength < 0)
-               ? VARSIZE((struct varlena *) attributeValue)    /* variable length */
-               : attributeLength;              /* fixed length */
-
-               tmp = (char *) palloc(size);
-               memcpy(tmp, (void *) attributeValue, size);
-               returnValue = (void *) tmp;
-       }
-
-       heap_close(relation, AccessShareLock);
-       return returnValue;
+       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);
+
+       return heap_getattr(tup, attributeNumber,
+                                               SysCache[cacheId]->cc_tupdesc,
+                                               isnull);
 }
index 158a7bdb367ae60d86281c61943629bb3365cb97..a6acff02654419a60a6ec05cd83ffee25819f703 100644 (file)
@@ -8,7 +8,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: syscache.h,v 1.22 1999/11/24 16:52:50 momjian Exp $
+ * $Id: syscache.h,v 1.23 2000/01/23 03:43:22 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -81,10 +81,8 @@ extern HeapTuple SearchSysCacheTupleCopy(int cacheId,
                                                Datum key1, Datum key2, Datum key3, Datum key4);
 extern HeapTuple SearchSysCacheTuple(int cacheId,
                                        Datum key1, Datum key2, Datum key3, Datum key4);
-extern int32 SearchSysCacheStruct(int cacheId, char *returnStruct,
-                                        Datum key1, Datum key2, Datum key3, Datum key4);
-extern void *SearchSysCacheGetAttribute(int cacheId,
-                                                  AttrNumber attributeNumber,
-                                                Datum key1, Datum key2, Datum key3, Datum key4);
+extern Datum SysCacheGetAttr(int cacheId, HeapTuple tup,
+                                                        AttrNumber attributeNumber,
+                                                        bool *isnull);
 
 #endif  /* SYSCACHE_H */