]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Fix handling of type tuple associated with a temp relation. We have
authorTom Lane <tgl@sss.pgh.pa.us>
Tue, 20 Jun 2000 01:41:22 +0000 (01:41 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Tue, 20 Jun 2000 01:41:22 +0000 (01:41 +0000)
to apply the tempname->realname mapping to type name lookup as well
as relation name lookup, else the type tuple will not be found when
wanted.  This fixes bugs like this one:
create temp table foo (f1 int);
select foo.f2 from foo;
ERROR:  Unable to locate type name 'foo' in catalog

src/backend/parser/parse_relation.c
src/backend/utils/cache/syscache.c

index 41065c69077263d826e980ff8cd2bb6889780ae5..cbb5f07fefaa00ab34da3dc8730701c370c03765 100644 (file)
@@ -8,13 +8,14 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/parser/parse_relation.c,v 1.43 2000/06/12 19:40:42 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/parser/parse_relation.c,v 1.44 2000/06/20 01:41:21 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
 #include <ctype.h>
 
 #include "postgres.h"
+
 #include "access/heapam.h"
 #include "access/htup.h"
 #include "catalog/pg_type.h"
 #include "utils/lsyscache.h"
 
 
+/*
+ * Information defining the "system" attributes of every relation.
+ */
 static struct
 {
-       char       *field;
-       int                     code;
+       char       *attrname;           /* name of system attribute */
+       int                     attrnum;                /* its attribute number (always < 0) */
+       Oid                     attrtype;               /* its type id */
 }                      special_attr[] =
 
 {
        {
-               "ctid", SelfItemPointerAttributeNumber
+               "ctid", SelfItemPointerAttributeNumber, TIDOID
        },
        {
-               "oid", ObjectIdAttributeNumber
+               "oid", ObjectIdAttributeNumber, OIDOID
        },
        {
-               "xmin", MinTransactionIdAttributeNumber
+               "xmin", MinTransactionIdAttributeNumber, XIDOID
        },
        {
-               "cmin", MinCommandIdAttributeNumber
+               "cmin", MinCommandIdAttributeNumber, CIDOID
        },
        {
-               "xmax", MaxTransactionIdAttributeNumber
+               "xmax", MaxTransactionIdAttributeNumber, XIDOID
        },
        {
-               "cmax", MaxCommandIdAttributeNumber
+               "cmax", MaxCommandIdAttributeNumber, CIDOID
        },
 };
 
-#define SPECIALS ((int) (sizeof(special_attr)/sizeof(*special_attr)))
+#define SPECIALS ((int) (sizeof(special_attr)/sizeof(special_attr[0])))
 
-static char *attnum_type[SPECIALS] = {
-       "tid",
-       "oid",
-       "xid",
-       "cid",
-       "xid",
-       "cid",
-};
 
 #ifdef NOT_USED
 /* refnameRangeTableEntries()
@@ -459,8 +456,8 @@ specialAttNum(char *a)
        int                     i;
 
        for (i = 0; i < SPECIALS; i++)
-               if (!strcmp(special_attr[i].field, a))
-                       return special_attr[i].code;
+               if (strcmp(special_attr[i].attrname, a) == 0)
+                       return special_attr[i].attrnum;
 
        return InvalidAttrNumber;
 }
@@ -485,10 +482,8 @@ attnameIsSet(Relation rd, char *name)
        /* First check if this is a system attribute */
        for (i = 0; i < SPECIALS; i++)
        {
-               if (!strcmp(special_attr[i].field, name))
-               {
+               if (strcmp(special_attr[i].attrname, name) == 0)
                        return false;           /* no sys attr is a set */
-               }
        }
        return get_attisset(RelationGetRelid(rd), name);
 }
@@ -516,13 +511,21 @@ attnumAttNelems(Relation rd, int attid)
 Oid
 attnumTypeId(Relation rd, int attid)
 {
-
        if (attid < 0)
-               return typeTypeId(typenameType(attnum_type[-attid - 1]));
+       {
+               int                     i;
+
+               for (i = 0; i < SPECIALS; i++)
+               {
+                       if (special_attr[i].attrnum == attid)
+                               return special_attr[i].attrtype;
+               }
+               /* negative but not a valid system attr? */
+               elog(ERROR, "attnumTypeId: bogus attribute number %d", attid);
+       }
 
        /*
-        * -1 because varattno (where attid comes from) returns one more than
-        * index
+        * -1 because attid is 1-based
         */
        return rd->rd_att->attrs[attid - 1]->atttypid;
 }
index ba9452b80e41c1cd43df54a6c74f09f4af4f3a09..e8f602c2ec2bb2c2a10113bc96e1aa8486cd008a 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/utils/cache/syscache.c,v 1.54 2000/06/17 04:56:33 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/utils/cache/syscache.c,v 1.55 2000/06/20 01:41:22 tgl Exp $
  *
  * NOTES
  *       These routines allow the parser/planner/executor to perform
@@ -482,14 +482,20 @@ SearchSysCacheTuple(int cacheId,/* cache selection code */
                                 cacheId);
        }
 
-       /* temp table name remapping */
-       if (cacheId == RELNAME)
+       /*
+        * If someone tries to look up a relname, translate temp relation
+        * names to real names.  Less obviously, apply the same translation
+        * to type names, so that the type tuple of a temp table will be found
+        * when sought.  This is a kluge ... temp table substitution should be
+        * happening at a higher level ...
+        */
+       if (cacheId == RELNAME || cacheId == TYPENAME)
        {
                char       *nontemp_relname;
 
-               if ((nontemp_relname =
-                        get_temp_rel_by_username(DatumGetPointer(key1))) != NULL)
-                       key1 = PointerGetDatum(nontemp_relname);
+               nontemp_relname = get_temp_rel_by_username(DatumGetCString(key1));
+               if (nontemp_relname != NULL)
+                       key1 = CStringGetDatum(nontemp_relname);
        }
 
        tp = SearchSysCache(SysCache[cacheId], key1, key2, key3, key4);