new_relation_targetlist used to cause about 8 separate (and
authorTom Lane
Sat, 29 May 1999 01:48:06 +0000 (01:48 +0000)
committerTom Lane
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 0256fd483b0f1c296c233dbb01f016e025d2a969..c2ed4e0df1f47743953b8d91dc1b22c79e224ca6 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 */