Skip to content
Snippets Groups Projects
Commit d03e9873 authored by Tom Lane's avatar Tom Lane
Browse files

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
No related branches found
No related tags found
No related merge requests found
...@@ -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;
elog(ERROR, "typtoout: Cache lookup of type %d failed", type);
return InvalidOid;
}
Oid
gettypelem(Oid type)
{ {
HeapTuple typeTuple; Form_pg_type pt = (Form_pg_type) GETSTRUCT(typeTuple);
*typOutput = (Oid) pt->typoutput;
typeTuple = SearchSysCacheTuple(TYPOID, *typElem = (Oid) pt->typelem;
ObjectIdGetDatum(type), return OidIsValid(*typOutput);
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 */
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment