Commit 996659f2 authored by Tom Lane's avatar Tom Lane

Fix handling of type tuple associated with a temp relation. We have

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
parent a1dfaef6
...@@ -8,13 +8,14 @@ ...@@ -8,13 +8,14 @@
* *
* *
* IDENTIFICATION * 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 <ctype.h>
#include "postgres.h" #include "postgres.h"
#include "access/heapam.h" #include "access/heapam.h"
#include "access/htup.h" #include "access/htup.h"
#include "catalog/pg_type.h" #include "catalog/pg_type.h"
...@@ -27,43 +28,39 @@ ...@@ -27,43 +28,39 @@
#include "utils/lsyscache.h" #include "utils/lsyscache.h"
/*
* Information defining the "system" attributes of every relation.
*/
static struct static struct
{ {
char *field; char *attrname; /* name of system attribute */
int code; int attrnum; /* its attribute number (always < 0) */
Oid attrtype; /* its type id */
} special_attr[] = } 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 #ifdef NOT_USED
/* refnameRangeTableEntries() /* refnameRangeTableEntries()
...@@ -459,8 +456,8 @@ specialAttNum(char *a) ...@@ -459,8 +456,8 @@ specialAttNum(char *a)
int i; int i;
for (i = 0; i < SPECIALS; i++) for (i = 0; i < SPECIALS; i++)
if (!strcmp(special_attr[i].field, a)) if (strcmp(special_attr[i].attrname, a) == 0)
return special_attr[i].code; return special_attr[i].attrnum;
return InvalidAttrNumber; return InvalidAttrNumber;
} }
...@@ -485,11 +482,9 @@ attnameIsSet(Relation rd, char *name) ...@@ -485,11 +482,9 @@ attnameIsSet(Relation rd, char *name)
/* First check if this is a system attribute */ /* First check if this is a system attribute */
for (i = 0; i < SPECIALS; i++) 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 false; /* no sys attr is a set */
} }
}
return get_attisset(RelationGetRelid(rd), name); return get_attisset(RelationGetRelid(rd), name);
} }
#endif #endif
...@@ -516,13 +511,21 @@ attnumAttNelems(Relation rd, int attid) ...@@ -516,13 +511,21 @@ attnumAttNelems(Relation rd, int attid)
Oid Oid
attnumTypeId(Relation rd, int attid) attnumTypeId(Relation rd, int attid)
{ {
if (attid < 0) 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 * -1 because attid is 1-based
* index
*/ */
return rd->rd_att->attrs[attid - 1]->atttypid; return rd->rd_att->attrs[attid - 1]->atttypid;
} }
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 * NOTES
* These routines allow the parser/planner/executor to perform * These routines allow the parser/planner/executor to perform
...@@ -482,14 +482,20 @@ SearchSysCacheTuple(int cacheId,/* cache selection code */ ...@@ -482,14 +482,20 @@ SearchSysCacheTuple(int cacheId,/* cache selection code */
cacheId); 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; char *nontemp_relname;
if ((nontemp_relname = nontemp_relname = get_temp_rel_by_username(DatumGetCString(key1));
get_temp_rel_by_username(DatumGetPointer(key1))) != NULL) if (nontemp_relname != NULL)
key1 = PointerGetDatum(nontemp_relname); key1 = CStringGetDatum(nontemp_relname);
} }
tp = SearchSysCache(SysCache[cacheId], key1, key2, key3, key4); tp = SearchSysCache(SysCache[cacheId], key1, key2, key3, key4);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment