mirror of
https://github.com/postgres/postgres.git
synced 2025-04-25 21:42:33 +03:00
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:
parent
ce2586dbc9
commit
b325dab67a
@ -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 */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user