Commit d03e9873 authored by Tom Lane's avatar Tom Lane

Replace typtoout() and gettypelem() with a single routine,

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.
parent 77f54282
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -33,11 +33,15 @@ ...@@ -33,11 +33,15 @@
*/ */
/* ---------------- /* ----------------
* 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 int
typtoout(Oid type) getTypeOutAndElem(Oid type, Oid* typOutput, Oid* typElem)
{ {
HeapTuple typeTuple; HeapTuple typeTuple;
...@@ -46,26 +50,18 @@ typtoout(Oid type) ...@@ -46,26 +50,18 @@ typtoout(Oid type)
0, 0, 0); 0, 0, 0);
if (HeapTupleIsValid(typeTuple)) if (HeapTupleIsValid(typeTuple))
return (Oid) ((Form_pg_type) GETSTRUCT(typeTuple))->typoutput; {
Form_pg_type pt = (Form_pg_type) GETSTRUCT(typeTuple);
elog(ERROR, "typtoout: Cache lookup of type %d failed", type); *typOutput = (Oid) pt->typoutput;
return InvalidOid; *typElem = (Oid) pt->typelem;
} return OidIsValid(*typOutput);
}
Oid
gettypelem(Oid type)
{
HeapTuple typeTuple;
typeTuple = SearchSysCacheTuple(TYPOID,
ObjectIdGetDatum(type),
0, 0, 0);
if (HeapTupleIsValid(typeTuple)) elog(ERROR, "getTypeOutAndElem: Cache lookup of type %d failed", type);
return (Oid) ((Form_pg_type) GETSTRUCT(typeTuple))->typelem;
elog(ERROR, "typtoout: Cache lookup of type %d failed", type); *typOutput = InvalidOid;
return InvalidOid; *typElem = InvalidOid;
return 0;
} }
/* ---------------- /* ----------------
...@@ -77,19 +73,19 @@ printtup(HeapTuple tuple, TupleDesc typeinfo) ...@@ -77,19 +73,19 @@ printtup(HeapTuple tuple, TupleDesc typeinfo)
{ {
int i, int i,
j, j,
k; k,
outputlen;
char *outputstr; char *outputstr;
Datum attr; Datum attr;
bool isnull; bool isnull;
Oid typoutput; Oid typoutput,
typelem;
#ifdef MULTIBYTE #ifdef MULTIBYTE
unsigned char *p; unsigned char *p;
#endif #endif
/* ---------------- /* ----------------
* tell the frontend to expect new tuple data * tell the frontend to expect new tuple data (in ASCII style)
* ---------------- * ----------------
*/ */
pq_putnchar("D", 1); pq_putnchar("D", 1);
...@@ -127,28 +123,29 @@ printtup(HeapTuple tuple, TupleDesc typeinfo) ...@@ -127,28 +123,29 @@ printtup(HeapTuple tuple, TupleDesc typeinfo)
attr = heap_getattr(tuple, i + 1, typeinfo, &isnull); attr = heap_getattr(tuple, i + 1, typeinfo, &isnull);
if (isnull) if (isnull)
continue; continue;
if (getTypeOutAndElem((Oid) typeinfo->attrs[i]->atttypid,
typoutput = typtoout((Oid) typeinfo->attrs[i]->atttypid); &typoutput, &typelem))
if (OidIsValid(typoutput))
{ {
outputstr = fmgr(typoutput, attr, outputstr = fmgr(typoutput, attr, typelem,
gettypelem(typeinfo->attrs[i]->atttypid),
typeinfo->attrs[i]->atttypmod); typeinfo->attrs[i]->atttypmod);
#ifdef MULTIBYTE #ifdef MULTIBYTE
p = pg_server_to_client(outputstr, strlen(outputstr)); p = pg_server_to_client(outputstr, strlen(outputstr));
pq_putint(strlen(p) + VARHDRSZ, VARHDRSZ); outputlen = strlen(p);
pq_putnchar(p, strlen(p)); pq_putint(outputlen + VARHDRSZ, VARHDRSZ);
pq_putnchar(p, outputlen);
#else #else
pq_putint(strlen(outputstr) + VARHDRSZ, VARHDRSZ); outputlen = strlen(outputstr);
pq_putnchar(outputstr, strlen(outputstr)); pq_putint(outputlen + VARHDRSZ, VARHDRSZ);
pq_putnchar(outputstr, outputlen);
#endif #endif
pfree(outputstr); pfree(outputstr);
} }
else else
{ {
outputstr = "<unprintable>"; outputstr = "<unprintable>";
pq_putint(strlen(outputstr) + VARHDRSZ, VARHDRSZ); outputlen = strlen(outputstr);
pq_putnchar(outputstr, strlen(outputstr)); pq_putint(outputlen + VARHDRSZ, VARHDRSZ);
pq_putnchar(outputstr, outputlen);
} }
} }
} }
...@@ -202,17 +199,18 @@ debugtup(HeapTuple tuple, TupleDesc typeinfo) ...@@ -202,17 +199,18 @@ debugtup(HeapTuple tuple, TupleDesc typeinfo)
Datum attr; Datum attr;
char *value; char *value;
bool isnull; bool isnull;
Oid typoutput; Oid typoutput,
typelem;
for (i = 0; i < tuple->t_data->t_natts; ++i) for (i = 0; i < tuple->t_data->t_natts; ++i)
{ {
attr = heap_getattr(tuple, i + 1, typeinfo, &isnull); attr = heap_getattr(tuple, i + 1, typeinfo, &isnull);
typoutput = typtoout((Oid) typeinfo->attrs[i]->atttypid); if (isnull)
continue;
if (!isnull && OidIsValid(typoutput)) if (getTypeOutAndElem((Oid) typeinfo->attrs[i]->atttypid,
&typoutput, &typelem))
{ {
value = fmgr(typoutput, attr, value = fmgr(typoutput, attr, typelem,
gettypelem(typeinfo->attrs[i]->atttypid),
typeinfo->attrs[i]->atttypmod); typeinfo->attrs[i]->atttypmod);
printatt((unsigned) i + 1, typeinfo->attrs[i], value); printatt((unsigned) i + 1, typeinfo->attrs[i], value);
pfree(value); pfree(value);
...@@ -223,7 +221,6 @@ debugtup(HeapTuple tuple, TupleDesc typeinfo) ...@@ -223,7 +221,6 @@ debugtup(HeapTuple tuple, TupleDesc typeinfo)
/* ---------------- /* ----------------
* printtup_internal * printtup_internal
* Protocol expects either T, D, C, E, or N.
* We use a different data prefix, e.g. 'B' instead of 'D' to * We use a different data prefix, e.g. 'B' instead of 'D' to
* indicate a tuple in internal (binary) form. * indicate a tuple in internal (binary) form.
* *
...@@ -240,7 +237,7 @@ printtup_internal(HeapTuple tuple, TupleDesc typeinfo) ...@@ -240,7 +237,7 @@ printtup_internal(HeapTuple tuple, TupleDesc typeinfo)
bool isnull; 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); pq_putnchar("B", 1);
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
* columns. (ie. tuples from the same group are consecutive) * columns. (ie. tuples from the same group are consecutive)
* *
* IDENTIFICATION * 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, ...@@ -364,12 +364,14 @@ sameGroup(HeapTuple oldtuple,
*val2; *val2;
int i; int i;
AttrNumber att; AttrNumber att;
Oid typoutput; Oid typoutput,
typelem;
for (i = 0; i < numCols; i++) for (i = 0; i < numCols; i++)
{ {
att = grpColIdx[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, attr1 = heap_getattr(oldtuple,
att, att,
...@@ -386,11 +388,9 @@ sameGroup(HeapTuple oldtuple, ...@@ -386,11 +388,9 @@ sameGroup(HeapTuple oldtuple,
if (isNull1) /* both are null, they are equal */ if (isNull1) /* both are null, they are equal */
continue; continue;
val1 = fmgr(typoutput, attr1, val1 = fmgr(typoutput, attr1, typelem,
gettypelem(tupdesc->attrs[att - 1]->atttypid),
tupdesc->attrs[att - 1]->atttypmod); tupdesc->attrs[att - 1]->atttypmod);
val2 = fmgr(typoutput, attr2, val2 = fmgr(typoutput, attr2, typelem,
gettypelem(tupdesc->attrs[att - 1]->atttypid),
tupdesc->attrs[att - 1]->atttypmod); tupdesc->attrs[att - 1]->atttypmod);
/* /*
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * 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 @@ ...@@ -31,7 +31,7 @@
#include "executor/nodeUnique.h" #include "executor/nodeUnique.h"
#include "optimizer/clauses.h" #include "optimizer/clauses.h"
#include "access/heapam.h" #include "access/heapam.h"
#include "access/printtup.h" /* for typtoout() */ #include "access/printtup.h" /* for getTypeOutAndElem() */
#include "utils/builtins.h" /* for namecpy() */ #include "utils/builtins.h" /* for namecpy() */
/* ---------------------------------------------------------------- /* ----------------------------------------------------------------
...@@ -117,7 +117,8 @@ ExecUnique(Unique *node) ...@@ -117,7 +117,8 @@ ExecUnique(Unique *node)
char *uniqueAttr; char *uniqueAttr;
AttrNumber uniqueAttrNum; AttrNumber uniqueAttrNum;
TupleDesc tupDesc; TupleDesc tupDesc;
Oid typoutput; Oid typoutput,
typelem;
/* ---------------- /* ----------------
* get information from the node * get information from the node
...@@ -132,12 +133,14 @@ ExecUnique(Unique *node) ...@@ -132,12 +133,14 @@ ExecUnique(Unique *node)
if (uniqueAttr) if (uniqueAttr)
{ {
tupDesc = ExecGetResultType(uniquestate); tupDesc = ExecGetResultType(uniquestate);
typoutput = typtoout((Oid) tupDesc->attrs[uniqueAttrNum - 1]->atttypid); getTypeOutAndElem((Oid) tupDesc->attrs[uniqueAttrNum - 1]->atttypid,
&typoutput, &typelem);
} }
else else
{ /* keep compiler quiet */ { /* keep compiler quiet */
tupDesc = NULL; tupDesc = NULL;
typoutput = 0; typoutput = InvalidOid;
typelem = InvalidOid;
} }
/* ---------------- /* ----------------
...@@ -196,11 +199,9 @@ ExecUnique(Unique *node) ...@@ -196,11 +199,9 @@ ExecUnique(Unique *node)
{ {
if (isNull1) /* both are null, they are equal */ if (isNull1) /* both are null, they are equal */
continue; continue;
val1 = fmgr(typoutput, attr1, val1 = fmgr(typoutput, attr1, typelem,
gettypelem(tupDesc->attrs[uniqueAttrNum - 1]->atttypid),
tupDesc->attrs[uniqueAttrNum - 1]->atttypmod); tupDesc->attrs[uniqueAttrNum - 1]->atttypmod);
val2 = fmgr(typoutput, attr2, val2 = fmgr(typoutput, attr2, typelem,
gettypelem(tupDesc->attrs[uniqueAttrNum - 1]->atttypid),
tupDesc->attrs[uniqueAttrNum - 1]->atttypmod); tupDesc->attrs[uniqueAttrNum - 1]->atttypmod);
/* /*
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* spi.c-- * spi.c--
* Server Programming Interface * 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) ...@@ -409,7 +409,8 @@ SPI_getvalue(HeapTuple tuple, TupleDesc tupdesc, int fnumber)
{ {
Datum val; Datum val;
bool isnull; bool isnull;
Oid foutoid; Oid foutoid,
typelem;
SPI_result = 0; SPI_result = 0;
if (tuple->t_data->t_natts < fnumber || fnumber <= 0) if (tuple->t_data->t_natts < fnumber || fnumber <= 0)
...@@ -421,15 +422,14 @@ SPI_getvalue(HeapTuple tuple, TupleDesc tupdesc, int fnumber) ...@@ -421,15 +422,14 @@ SPI_getvalue(HeapTuple tuple, TupleDesc tupdesc, int fnumber)
val = heap_getattr(tuple, fnumber, tupdesc, &isnull); val = heap_getattr(tuple, fnumber, tupdesc, &isnull);
if (isnull) if (isnull)
return NULL; return NULL;
foutoid = typtoout((Oid) tupdesc->attrs[fnumber - 1]->atttypid); if (! getTypeOutAndElem((Oid) tupdesc->attrs[fnumber - 1]->atttypid,
if (!OidIsValid(foutoid)) &foutoid, &typelem))
{ {
SPI_result = SPI_ERROR_NOOUTFUNC; SPI_result = SPI_ERROR_NOOUTFUNC;
return NULL; return NULL;
} }
return (fmgr(foutoid, val, return (fmgr(foutoid, val, typelem,
gettypelem(tupdesc->attrs[fnumber - 1]->atttypid),
tupdesc->attrs[fnumber - 1]->atttypmod)); tupdesc->attrs[fnumber - 1]->atttypmod));
} }
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* *
* Copyright (c) 1994, Regents of the University of California * 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) ...@@ -213,7 +213,8 @@ be_printtup(HeapTuple tuple, TupleDesc typeinfo)
int i; int i;
Datum attr; Datum attr;
bool isnull; bool isnull;
Oid typoutput; Oid typoutput,
typelem;
PortalEntry *entry = NULL; PortalEntry *entry = NULL;
PortalBuffer *portal = NULL; PortalBuffer *portal = NULL;
...@@ -298,7 +299,8 @@ be_printtup(HeapTuple tuple, TupleDesc typeinfo) ...@@ -298,7 +299,8 @@ be_printtup(HeapTuple tuple, TupleDesc typeinfo)
for (i = 0; i < tuple->t_data->t_natts; i++) for (i = 0; i < tuple->t_data->t_natts; i++)
{ {
attr = heap_getattr(tuple, i + 1, typeinfo, &isnull); 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; lengths[i] = typeinfo->attrs[i]->attlen;
...@@ -311,11 +313,8 @@ be_printtup(HeapTuple tuple, TupleDesc typeinfo) ...@@ -311,11 +313,8 @@ be_printtup(HeapTuple tuple, TupleDesc typeinfo)
} }
if (!isnull && OidIsValid(typoutput)) if (!isnull && OidIsValid(typoutput))
{ values[i] = fmgr(typoutput, attr, typelem,
values[i] = fmgr(typoutput, attr,
gettypelem(typeinfo->attrs[i]->atttypid),
typeinfo->attrs[i]->atttypmod); typeinfo->attrs[i]->atttypmod);
}
else else
values[i] = NULL; values[i] = NULL;
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* *
* Copyright (c) 1994, Regents of the University of California * 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 $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -16,11 +16,10 @@ ...@@ -16,11 +16,10 @@
#include <access/htup.h> #include <access/htup.h>
#include <access/tupdesc.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 printtup(HeapTuple tuple, TupleDesc typeinfo);
extern void showatts(char *name, TupleDesc attinfo); extern void showatts(char *name, TupleDesc attinfo);
extern void debugtup(HeapTuple tuple, TupleDesc typeinfo); extern void debugtup(HeapTuple tuple, TupleDesc typeinfo);
extern void printtup_internal(HeapTuple tuple, TupleDesc typeinfo); extern void printtup_internal(HeapTuple tuple, TupleDesc typeinfo);
extern Oid gettypelem(Oid type);
#endif /* PRINTTUP_H */ #endif /* PRINTTUP_H */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment