OSDN Git Service

new_relation_targetlist used to cause about 8 separate (and
authorTom Lane <tgl@sss.pgh.pa.us>
Sat, 29 May 1999 01:48:06 +0000 (01:48 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Sat, 29 May 1999 01:48:06 +0000 (01:48 +0000)
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.

src/backend/optimizer/prep/preptlist.c

index 0256fd4..c2ed4e0 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * 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 "utils/builtins.h"
+#include "utils/syscache.h"
 #include "utils/lsyscache.h"
 #include "utils/palloc.h"
 #include "parser/parse_type.h"
@@ -286,80 +287,95 @@ replace_matching_resname(List *new_tlist, List *old_tlist)
 static List *
 new_relation_targetlist(Oid relid, Index rt_index, NodeTag node_type)
 {
-       AttrNumber      attno;
        List       *t_list = NIL;
-       char       *attname;
-       int                     typlen;
-       Oid                     atttype = 0;
-       bool            attisset = false;
+       int                     natts = get_relnatts(relid);
+       AttrNumber      attno;
 
-       for (attno = 1; attno <= get_relnatts(relid); attno++)
+       for (attno = 1; attno <= natts; attno++)
        {
-               attname = get_attname(relid, attno);
-               atttype = get_atttype(relid, attno);
-
-               /*
-                * Since this is an append or replace, the size of any set
-                * attribute is the size of the OID used to represent it.
-                */
-               attisset = get_attisset(relid, attname);
-               if (attisset)
-                       typlen = typeLen(typeidType(OIDOID));
-               else
-                       typlen = get_typlen(atttype);
+               HeapTuple       tp;
+               Form_pg_attribute att_tup;
+               char       *attname;
+               Oid                     atttype;
+               int32           atttypmod;
+               bool            attisset;
+
+               tp = SearchSysCacheTuple(ATTNUM,
+                                                                ObjectIdGetDatum(relid),
+                                                                UInt16GetDatum(attno),
+                                                                0, 0);
+               if (! HeapTupleIsValid(tp))
+               {
+                       elog(ERROR, "new_relation_targetlist: no attribute tuple %u %d",
+                                relid, attno);
+               }
+               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)
                {
-                       case T_Const:
+                       case T_Const:           /* INSERT command */
                                {
                                        struct varlena *typedefault = get_typdefault(atttype);
-                                       int                     temp = 0;
-                                       Const      *temp2 = (Const *) NULL;
-                                       TargetEntry *temp3 = (TargetEntry *) NULL;
+                                       int                     typlen;
+                                       Const      *temp_const;
+                                       TargetEntry *temp_tle;
 
                                        if (typedefault == NULL)
-                                               temp = 0;
+                                               typlen = 0;
                                        else
-                                               temp = typlen;
-
-                                       temp2 = makeConst(atttype,
-                                                                         temp,
-                                                                         (Datum) typedefault,
-                                                               (typedefault == (struct varlena *) NULL),
-                                       /* XXX ? */
-                                                                         false,
-                                                                         false,        /* not a set */
-                                                                         false);
-
-                                       temp3 = makeTargetEntry(makeResdom(attno,
-                                                                                                          atttype,
-                                                                                                          -1,
-                                                                                                          attname,
-                                                                                                          0,
-                                                                                                          (Oid) 0,
-                                                                                                          false),
-                                                                                       (Node *) temp2);
-                                       t_list = lappend(t_list, temp3);
+                                       {
+                                               /*
+                                                * 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);
+                                       }
+
+                                       temp_const = makeConst(atttype,
+                                                                                  typlen,
+                                                                                  (Datum) typedefault,
+                                                                                  (typedefault == NULL),
+                                                                                  /* XXX ? */
+                                                                                  false,
+                                                                                  false, /* not a set */
+                                                                                  false);
+
+                                       temp_tle = makeTargetEntry(makeResdom(attno,
+                                                                                                                 atttype,
+                                                                                                                 -1,
+                                                                                                                 attname,
+                                                                                                                 0,
+                                                                                                                 (Oid) 0,
+                                                                                                                 false),
+                                                                                          (Node *) temp_const);
+                                       t_list = lappend(t_list, temp_tle);
                                        break;
                                }
-                       case T_Var:
+                       case T_Var:                     /* UPDATE command */
                                {
-                                       Var                *temp_var = (Var *) NULL;
-                                       TargetEntry *temp_list = NULL;
+                                       Var                *temp_var;
+                                       TargetEntry *temp_tle;
 
-                                       temp_var = makeVar(rt_index, attno, atttype,
-                                                                          get_atttypmod(relid, attno),
+                                       temp_var = makeVar(rt_index, attno, atttype, atttypmod,
                                                                           0, rt_index, attno);
 
-                                       temp_list = makeTargetEntry(makeResdom(attno,
-                                                                                                                  atttype,
-                                                                                        get_atttypmod(relid, attno),
-                                                                                                                  attname,
-                                                                                                                  0,
-                                                                                                                  (Oid) 0,
-                                                                                                                  false),
-                                                                                               (Node *) temp_var);
-                                       t_list = lappend(t_list, temp_list);
+                                       temp_tle = makeTargetEntry(makeResdom(attno,
+                                                                                                                 atttype,
+                                                                                                                 atttypmod,
+                                                                                                                 attname,
+                                                                                                                 0,
+                                                                                                                 (Oid) 0,
+                                                                                                                 false),
+                                                                                          (Node *) temp_var);
+                                       t_list = lappend(t_list, temp_tle);
                                        break;
                                }
                        default:                        /* do nothing */