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.
This commit is contained in:
parent
77f5428244
commit
d03e98737c
@ -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 $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -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
|
||||
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;
|
||||
{
|
||||
Form_pg_type pt = (Form_pg_type) GETSTRUCT(typeTuple);
|
||||
*typOutput = (Oid) pt->typoutput;
|
||||
*typElem = (Oid) pt->typelem;
|
||||
return OidIsValid(*typOutput);
|
||||
}
|
||||
|
||||
elog(ERROR, "typtoout: Cache lookup of type %d failed", type);
|
||||
return InvalidOid;
|
||||
}
|
||||
elog(ERROR, "getTypeOutAndElem: Cache lookup of type %d failed", type);
|
||||
|
||||
Oid
|
||||
gettypelem(Oid type)
|
||||
{
|
||||
HeapTuple typeTuple;
|
||||
|
||||
typeTuple = SearchSysCacheTuple(TYPOID,
|
||||
ObjectIdGetDatum(type),
|
||||
0, 0, 0);
|
||||
|
||||
if (HeapTupleIsValid(typeTuple))
|
||||
return (Oid) ((Form_pg_type) GETSTRUCT(typeTuple))->typelem;
|
||||
|
||||
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);
|
||||
|
@ -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);
|
||||
|
||||
/*
|
||||
|
@ -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);
|
||||
|
||||
/*
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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 $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -16,11 +16,10 @@
|
||||
#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 */
|
||||
|
Loading…
x
Reference in New Issue
Block a user