new_relation_targetlist used to cause about 8 separate (and

redundant) SearchSysCache searches per table column in an INSERT, which
accounted for a good percentage of the CPU time for INSERT ... VALUES().
Now it only does two searches in the typical case.
This commit is contained in:
Tom Lane 1999-05-29 01:48:06 +00:00
parent ce2586dbc9
commit b325dab67a
1 changed files with 71 additions and 55 deletions

View File

@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/prep/preptlist.c,v 1.21 1999/05/25 16:09:46 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/optimizer/prep/preptlist.c,v 1.22 1999/05/29 01:48:06 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -23,6 +23,7 @@
#include "nodes/makefuncs.h" #include "nodes/makefuncs.h"
#include "utils/builtins.h" #include "utils/builtins.h"
#include "utils/syscache.h"
#include "utils/lsyscache.h" #include "utils/lsyscache.h"
#include "utils/palloc.h" #include "utils/palloc.h"
#include "parser/parse_type.h" #include "parser/parse_type.h"
@ -286,80 +287,95 @@ replace_matching_resname(List *new_tlist, List *old_tlist)
static List * static List *
new_relation_targetlist(Oid relid, Index rt_index, NodeTag node_type) new_relation_targetlist(Oid relid, Index rt_index, NodeTag node_type)
{ {
AttrNumber attno;
List *t_list = NIL; List *t_list = NIL;
char *attname; int natts = get_relnatts(relid);
int typlen; AttrNumber attno;
Oid atttype = 0;
bool attisset = false;
for (attno = 1; attno <= get_relnatts(relid); attno++) for (attno = 1; attno <= natts; attno++)
{ {
attname = get_attname(relid, attno); HeapTuple tp;
atttype = get_atttype(relid, attno); Form_pg_attribute att_tup;
char *attname;
Oid atttype;
int32 atttypmod;
bool attisset;
/* tp = SearchSysCacheTuple(ATTNUM,
* Since this is an append or replace, the size of any set ObjectIdGetDatum(relid),
* attribute is the size of the OID used to represent it. UInt16GetDatum(attno),
*/ 0, 0);
attisset = get_attisset(relid, attname); if (! HeapTupleIsValid(tp))
if (attisset) {
typlen = typeLen(typeidType(OIDOID)); elog(ERROR, "new_relation_targetlist: no attribute tuple %u %d",
else relid, attno);
typlen = get_typlen(atttype); }
att_tup = (Form_pg_attribute) GETSTRUCT(tp);
attname = pstrdup(att_tup->attname.data);
atttype = att_tup->atttypid;
atttypmod = att_tup->atttypmod;
attisset = att_tup->attisset;
switch (node_type) switch (node_type)
{ {
case T_Const: case T_Const: /* INSERT command */
{ {
struct varlena *typedefault = get_typdefault(atttype); struct varlena *typedefault = get_typdefault(atttype);
int temp = 0; int typlen;
Const *temp2 = (Const *) NULL; Const *temp_const;
TargetEntry *temp3 = (TargetEntry *) NULL; TargetEntry *temp_tle;
if (typedefault == NULL) if (typedefault == NULL)
temp = 0; typlen = 0;
else else
temp = typlen; {
/*
* Since this is an append or replace, the size of
* any set attribute is the size of the OID used to
* represent it.
*/
if (attisset)
typlen = get_typlen(OIDOID);
else
typlen = get_typlen(atttype);
}
temp2 = makeConst(atttype, temp_const = makeConst(atttype,
temp, typlen,
(Datum) typedefault, (Datum) typedefault,
(typedefault == (struct varlena *) NULL), (typedefault == NULL),
/* XXX ? */ /* XXX ? */
false, false,
false, /* not a set */ false, /* not a set */
false); false);
temp3 = makeTargetEntry(makeResdom(attno, temp_tle = makeTargetEntry(makeResdom(attno,
atttype, atttype,
-1, -1,
attname, attname,
0, 0,
(Oid) 0, (Oid) 0,
false), false),
(Node *) temp2); (Node *) temp_const);
t_list = lappend(t_list, temp3); t_list = lappend(t_list, temp_tle);
break; break;
} }
case T_Var: case T_Var: /* UPDATE command */
{ {
Var *temp_var = (Var *) NULL; Var *temp_var;
TargetEntry *temp_list = NULL; TargetEntry *temp_tle;
temp_var = makeVar(rt_index, attno, atttype, temp_var = makeVar(rt_index, attno, atttype, atttypmod,
get_atttypmod(relid, attno),
0, rt_index, attno); 0, rt_index, attno);
temp_list = makeTargetEntry(makeResdom(attno, temp_tle = makeTargetEntry(makeResdom(attno,
atttype, atttype,
get_atttypmod(relid, attno), atttypmod,
attname, attname,
0, 0,
(Oid) 0, (Oid) 0,
false), false),
(Node *) temp_var); (Node *) temp_var);
t_list = lappend(t_list, temp_list); t_list = lappend(t_list, temp_tle);
break; break;
} }
default: /* do nothing */ default: /* do nothing */