Replace typtoout() and gettypelem() with a single routine,
authorTom Lane
Sun, 24 Jan 1999 05:40:49 +0000 (05:40 +0000)
committerTom Lane
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 641ef80126b4b5052f54fd401d76e126f5437f94..d8feb3a812829f219b4ac5b1d2e57edb391ee2a9 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/access/common/printtup.c,v 1.37 1998/12/12 22:04:09 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/access/common/printtup.c,v 1.38 1999/01/24 05:40:47 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
  */
 
 /* ----------------
- *     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 = "";
-           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 54cf97ca3e1c47624b6dd13bf4f77bc51bbe4505..0f86f73a2b12fef31ab105ff177f7229f9e446d7 100644 (file)
@@ -13,7 +13,7 @@
  *   columns. (ie. tuples from the same group are consecutive)
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/executor/nodeGroup.c,v 1.23 1998/11/27 19:52:01 vadim Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/executor/nodeGroup.c,v 1.24 1999/01/24 05:40:47 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -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 c04c44fa0d1b60ff131ae50bde043d556c7eb3fb..999362ab69da0db5634e3b57fb820424e2a5d3cb 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/executor/nodeUnique.c,v 1.18 1998/11/27 19:52:03 vadim Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/executor/nodeUnique.c,v 1.19 1999/01/24 05:40:48 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -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 125a36241ad519e0b906f7acadadd07c2fb572f8..5620cf789162fcf9149d12ff5d7732880b201ae8 100644 (file)
@@ -3,7 +3,7 @@
  * spi.c--
  *             Server Programming Interface
  *
- * $Id: spi.c,v 1.29 1998/12/14 05:18:51 scrappy Exp $
+ * $Id: spi.c,v 1.30 1999/01/24 05:40:48 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -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 116fb0c80bf382b9abc209d822fb10333e4d8d65..70d01e4dcf8fe178816b47387f9f245d3910b7b5 100644 (file)
@@ -6,7 +6,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- *  $Id: be-dumpdata.c,v 1.19 1998/12/14 06:50:23 scrappy Exp $
+ *  $Id: be-dumpdata.c,v 1.20 1999/01/24 05:40:49 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -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 4b7aa7c2dd612bea89ddd734628179577f589585..0b4f7b0f0425cc36ef33df9d0611cf092984fef1 100644 (file)
@@ -6,7 +6,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: printtup.h,v 1.5 1998/09/01 04:34:22 momjian Exp $
+ * $Id: printtup.h,v 1.6 1999/01/24 05:40:46 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
 #include 
 #include 
 
-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 */