Replace typtoout() and gettypelem() with a single routine,
authorTom Lane <tgl@sss.pgh.pa.us>
Sun, 24 Jan 1999 05:40:49 +0000 (05:40 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Sun, 24 Jan 1999 05:40:49 +0000 (05:40 +0000)
so that fetching an attribute value needs only one SearchSysCacheTuple call
instead of two redundant searches.  This speeds up a large SELECT by about
ten percent, and probably will help GROUP BY and SELECT DISTINCT too.

src/backend/access/common/printtup.c
src/backend/executor/nodeGroup.c
src/backend/executor/nodeUnique.c
src/backend/executor/spi.c
src/backend/libpq/be-dumpdata.c
src/include/access/printtup.h

index 0313ba9c801d7965606b4efc4699c61dfd28493a..66fa13d3399664524cc4eb3c79930fb3889361bb 100644 (file)
  */
 
 /* ----------------
- *             typtoout - used by printtup and debugtup
+ *             getTypeOutAndElem -- get both typoutput and typelem for a type
+ *
+ * We used to fetch these with two separate function calls,
+ * typtoout() and gettypelem(), which each called SearchSysCacheTuple.
+ * This way takes half the time.
  * ----------------
  */
-Oid
-typtoout(Oid type)
+int
+getTypeOutAndElem(Oid type, Oid* typOutput, Oid* typElem)
 {
        HeapTuple       typeTuple;
 
@@ -46,26 +50,18 @@ typtoout(Oid type)
                                                                        0, 0, 0);
 
        if (HeapTupleIsValid(typeTuple))
-               return (Oid) ((Form_pg_type) GETSTRUCT(typeTuple))->typoutput;
-
-       elog(ERROR, "typtoout: Cache lookup of type %d failed", type);
-       return InvalidOid;
-}
-
-Oid
-gettypelem(Oid type)
-{
-       HeapTuple       typeTuple;
-
-       typeTuple = SearchSysCacheTuple(TYPOID,
-                                                                       ObjectIdGetDatum(type),
-                                                                       0, 0, 0);
+       {
+               Form_pg_type pt = (Form_pg_type) GETSTRUCT(typeTuple);
+               *typOutput = (Oid) pt->typoutput;
+               *typElem = (Oid) pt->typelem;
+               return OidIsValid(*typOutput);
+       }
 
-       if (HeapTupleIsValid(typeTuple))
-               return (Oid) ((Form_pg_type) GETSTRUCT(typeTuple))->typelem;
+       elog(ERROR, "getTypeOutAndElem: Cache lookup of type %d failed", type);
 
-       elog(ERROR, "typtoout: Cache lookup of type %d failed", type);
-       return InvalidOid;
+       *typOutput = InvalidOid;
+       *typElem = InvalidOid;
+       return 0;
 }
 
 /* ----------------
@@ -77,19 +73,19 @@ printtup(HeapTuple tuple, TupleDesc typeinfo)
 {
        int                     i,
                                j,
-                               k;
+                               k,
+                               outputlen;
        char       *outputstr;
        Datum           attr;
        bool            isnull;
-       Oid                     typoutput;
-
+       Oid                     typoutput,
+                               typelem;
 #ifdef MULTIBYTE
        unsigned char *p;
-
 #endif
 
        /* ----------------
-        *      tell the frontend to expect new tuple data
+        *      tell the frontend to expect new tuple data (in ASCII style)
         * ----------------
         */
        pq_putnchar("D", 1);
@@ -127,28 +123,29 @@ printtup(HeapTuple tuple, TupleDesc typeinfo)
                attr = heap_getattr(tuple, i + 1, typeinfo, &isnull);
                if (isnull)
                        continue;
-
-               typoutput = typtoout((Oid) typeinfo->attrs[i]->atttypid);
-               if (OidIsValid(typoutput))
+               if (getTypeOutAndElem((Oid) typeinfo->attrs[i]->atttypid,
+                                                         &typoutput, &typelem))
                {
-                       outputstr = fmgr(typoutput, attr,
-                                                        gettypelem(typeinfo->attrs[i]->atttypid),
+                       outputstr = fmgr(typoutput, attr, typelem,
                                                         typeinfo->attrs[i]->atttypmod);
 #ifdef MULTIBYTE
                        p = pg_server_to_client(outputstr, strlen(outputstr));
-                       pq_putint(strlen(p) + VARHDRSZ, VARHDRSZ);
-                       pq_putnchar(p, strlen(p));
+                       outputlen = strlen(p);
+                       pq_putint(outputlen + VARHDRSZ, VARHDRSZ);
+                       pq_putnchar(p, outputlen);
 #else
-                       pq_putint(strlen(outputstr) + VARHDRSZ, VARHDRSZ);
-                       pq_putnchar(outputstr, strlen(outputstr));
+                       outputlen = strlen(outputstr);
+                       pq_putint(outputlen + VARHDRSZ, VARHDRSZ);
+                       pq_putnchar(outputstr, outputlen);
 #endif
                        pfree(outputstr);
                }
                else
                {
                        outputstr = "<unprintable>";
-                       pq_putint(strlen(outputstr) + VARHDRSZ, VARHDRSZ);
-                       pq_putnchar(outputstr, strlen(outputstr));
+                       outputlen = strlen(outputstr);
+                       pq_putint(outputlen + VARHDRSZ, VARHDRSZ);
+                       pq_putnchar(outputstr, outputlen);
                }
        }
 }
@@ -202,17 +199,18 @@ debugtup(HeapTuple tuple, TupleDesc typeinfo)
        Datum           attr;
        char       *value;
        bool            isnull;
-       Oid                     typoutput;
+       Oid                     typoutput,
+                               typelem;
 
        for (i = 0; i < tuple->t_data->t_natts; ++i)
        {
                attr = heap_getattr(tuple, i + 1, typeinfo, &isnull);
-               typoutput = typtoout((Oid) typeinfo->attrs[i]->atttypid);
-
-               if (!isnull && OidIsValid(typoutput))
+               if (isnull)
+                       continue;
+               if (getTypeOutAndElem((Oid) typeinfo->attrs[i]->atttypid,
+                                                         &typoutput, &typelem))
                {
-                       value = fmgr(typoutput, attr,
-                                                gettypelem(typeinfo->attrs[i]->atttypid),
+                       value = fmgr(typoutput, attr, typelem,
                                                 typeinfo->attrs[i]->atttypmod);
                        printatt((unsigned) i + 1, typeinfo->attrs[i], value);
                        pfree(value);
@@ -223,7 +221,6 @@ debugtup(HeapTuple tuple, TupleDesc typeinfo)
 
 /* ----------------
  *             printtup_internal
- *             Protocol expects either T, D, C, E, or N.
  *             We use a different data prefix, e.g. 'B' instead of 'D' to
  *             indicate a tuple in internal (binary) form.
  *
@@ -240,7 +237,7 @@ printtup_internal(HeapTuple tuple, TupleDesc typeinfo)
        bool            isnull;
 
        /* ----------------
-        *      tell the frontend to expect new tuple data
+        *      tell the frontend to expect new tuple data (in binary style)
         * ----------------
         */
        pq_putnchar("B", 1);
index 57c461035b1960f6d22f90708789dcf531add654..0f7367ee639479934ad37bc33d456985a1590ee6 100644 (file)
@@ -364,12 +364,14 @@ sameGroup(HeapTuple oldtuple,
                           *val2;
        int                     i;
        AttrNumber      att;
-       Oid                     typoutput;
+       Oid                     typoutput,
+                               typelem;
 
        for (i = 0; i < numCols; i++)
        {
                att = grpColIdx[i];
-               typoutput = typtoout((Oid) tupdesc->attrs[att - 1]->atttypid);
+               getTypeOutAndElem((Oid) tupdesc->attrs[att - 1]->atttypid,
+                                                 &typoutput, &typelem);
 
                attr1 = heap_getattr(oldtuple,
                                                         att,
@@ -386,11 +388,9 @@ sameGroup(HeapTuple oldtuple,
                        if (isNull1)            /* both are null, they are equal */
                                continue;
 
-                       val1 = fmgr(typoutput, attr1,
-                                               gettypelem(tupdesc->attrs[att - 1]->atttypid),
+                       val1 = fmgr(typoutput, attr1, typelem,
                                                tupdesc->attrs[att - 1]->atttypmod);
-                       val2 = fmgr(typoutput, attr2,
-                                               gettypelem(tupdesc->attrs[att - 1]->atttypid),
+                       val2 = fmgr(typoutput, attr2, typelem,
                                                tupdesc->attrs[att - 1]->atttypmod);
 
                        /*
index 05d79df35514e10e1205ea00b398a8c8241da761..4a4bbdb2d6b87ff99658cb8cc3fa6649617403d9 100644 (file)
@@ -31,7 +31,7 @@
 #include "executor/nodeUnique.h"
 #include "optimizer/clauses.h"
 #include "access/heapam.h"
-#include "access/printtup.h"   /* for typtoout() */
+#include "access/printtup.h"   /* for getTypeOutAndElem() */
 #include "utils/builtins.h"            /* for namecpy() */
 
 /* ----------------------------------------------------------------
@@ -117,7 +117,8 @@ ExecUnique(Unique *node)
        char       *uniqueAttr;
        AttrNumber      uniqueAttrNum;
        TupleDesc       tupDesc;
-       Oid                     typoutput;
+       Oid                     typoutput,
+                               typelem;
 
        /* ----------------
         *      get information from the node
@@ -132,12 +133,14 @@ ExecUnique(Unique *node)
        if (uniqueAttr)
        {
                tupDesc = ExecGetResultType(uniquestate);
-               typoutput = typtoout((Oid) tupDesc->attrs[uniqueAttrNum - 1]->atttypid);
+               getTypeOutAndElem((Oid) tupDesc->attrs[uniqueAttrNum - 1]->atttypid,
+                                                 &typoutput, &typelem);
        }
        else
        {                                                       /* keep compiler quiet */
                tupDesc = NULL;
-               typoutput = 0;
+               typoutput = InvalidOid;
+               typelem = InvalidOid;
        }
 
        /* ----------------
@@ -196,11 +199,9 @@ ExecUnique(Unique *node)
                        {
                                if (isNull1)    /* both are null, they are equal */
                                        continue;
-                               val1 = fmgr(typoutput, attr1,
-                                gettypelem(tupDesc->attrs[uniqueAttrNum - 1]->atttypid),
+                               val1 = fmgr(typoutput, attr1, typelem,
                                                        tupDesc->attrs[uniqueAttrNum - 1]->atttypmod);
-                               val2 = fmgr(typoutput, attr2,
-                                gettypelem(tupDesc->attrs[uniqueAttrNum - 1]->atttypid),
+                               val2 = fmgr(typoutput, attr2, typelem,
                                                        tupDesc->attrs[uniqueAttrNum - 1]->atttypmod);
 
                                /*
index b4912d01ce673f3d68b45bdb7fa7838150267144..bb27f07764000ebf18fc5116b7feb8f1969b37ed 100644 (file)
@@ -409,7 +409,8 @@ SPI_getvalue(HeapTuple tuple, TupleDesc tupdesc, int fnumber)
 {
        Datum           val;
        bool            isnull;
-       Oid                     foutoid;
+       Oid                     foutoid,
+                               typelem;
 
        SPI_result = 0;
        if (tuple->t_data->t_natts < fnumber || fnumber <= 0)
@@ -421,15 +422,14 @@ SPI_getvalue(HeapTuple tuple, TupleDesc tupdesc, int fnumber)
        val = heap_getattr(tuple, fnumber, tupdesc, &isnull);
        if (isnull)
                return NULL;
-       foutoid = typtoout((Oid) tupdesc->attrs[fnumber - 1]->atttypid);
-       if (!OidIsValid(foutoid))
+       if (! getTypeOutAndElem((Oid) tupdesc->attrs[fnumber - 1]->atttypid,
+                                                       &foutoid, &typelem))
        {
                SPI_result = SPI_ERROR_NOOUTFUNC;
                return NULL;
        }
 
-       return (fmgr(foutoid, val,
-                                gettypelem(tupdesc->attrs[fnumber - 1]->atttypid),
+       return (fmgr(foutoid, val, typelem,
                                 tupdesc->attrs[fnumber - 1]->atttypmod));
 }
 
index 1b70dde6e912484c047341a0ff592105e18a0b87..173110dfd58c6cce69d44b17e10519c9a237a309 100644 (file)
@@ -213,7 +213,8 @@ be_printtup(HeapTuple tuple, TupleDesc typeinfo)
        int                     i;
        Datum           attr;
        bool            isnull;
-       Oid                     typoutput;
+       Oid                     typoutput,
+                               typelem;
 
        PortalEntry *entry = NULL;
        PortalBuffer *portal = NULL;
@@ -298,7 +299,8 @@ be_printtup(HeapTuple tuple, TupleDesc typeinfo)
        for (i = 0; i < tuple->t_data->t_natts; i++)
        {
                attr = heap_getattr(tuple, i + 1, typeinfo, &isnull);
-               typoutput = typtoout((Oid) typeinfo->attrs[i]->atttypid);
+               getTypeOutAndElem((Oid) typeinfo->attrs[i]->atttypid,
+                                                 &typoutput, &typelem);
 
                lengths[i] = typeinfo->attrs[i]->attlen;
 
@@ -311,11 +313,8 @@ be_printtup(HeapTuple tuple, TupleDesc typeinfo)
                }
 
                if (!isnull && OidIsValid(typoutput))
-               {
-                       values[i] = fmgr(typoutput, attr,
-                                                        gettypelem(typeinfo->attrs[i]->atttypid),
+                       values[i] = fmgr(typoutput, attr, typelem,
                                                         typeinfo->attrs[i]->atttypmod);
-               }
                else
                        values[i] = NULL;
 
index 42a71dde0c33df546a9d1cb6f7f3d090fa7b8fd9..f9131d48b88271c7e1c833a90623911e62d81d37 100644 (file)
 #include <access/htup.h>
 #include <access/tupdesc.h>
 
-extern Oid     typtoout(Oid type);
+extern int     getTypeOutAndElem(Oid type, Oid* typOutput, Oid* typElem);
 extern void printtup(HeapTuple tuple, TupleDesc typeinfo);
 extern void showatts(char *name, TupleDesc attinfo);
 extern void debugtup(HeapTuple tuple, TupleDesc typeinfo);
 extern void printtup_internal(HeapTuple tuple, TupleDesc typeinfo);
-extern Oid     gettypelem(Oid type);
 
 #endif  /* PRINTTUP_H */