Tweak heap.c to refuse attempts to create table columns of standalone

composite types.  Add a couple more lsyscache.c routines to support this,
and make use of them in some other places that were doing lookups the
hard way.
This commit is contained in:
Tom Lane 2002-09-19 23:40:56 +00:00
parent 4a0c3a6142
commit da395b56cd
6 changed files with 88 additions and 53 deletions

View File

@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/dependency.c,v 1.10 2002/09/11 14:48:54 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/catalog/dependency.c,v 1.11 2002/09/19 23:40:56 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -552,20 +552,7 @@ doDeletion(const ObjectAddress *object)
{
case OCLASS_CLASS:
{
HeapTuple relTup;
char relKind;
/*
* Need the relkind to figure out how to drop.
*/
relTup = SearchSysCache(RELOID,
ObjectIdGetDatum(object->objectId),
0, 0, 0);
if (!HeapTupleIsValid(relTup))
elog(ERROR, "doDeletion: Relation %u does not exist",
object->objectId);
relKind = ((Form_pg_class) GETSTRUCT(relTup))->relkind;
ReleaseSysCache(relTup);
char relKind = get_rel_relkind(object->objectId);
if (relKind == RELKIND_INDEX)
{
@ -1504,6 +1491,10 @@ getRelationDescription(StringInfo buffer, Oid relid)
appendStringInfo(buffer, "view %s",
relname);
break;
case RELKIND_COMPOSITE_TYPE:
appendStringInfo(buffer, "composite type %s",
relname);
break;
default:
/* shouldn't get here */
appendStringInfo(buffer, "relation %s",

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.228 2002/09/19 22:48:33 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.229 2002/09/19 23:40:56 tgl Exp $
*
*
* INTERFACE ROUTINES
@ -384,20 +384,33 @@ CheckAttributeNames(TupleDesc tupdesc, char relkind)
* Warn user, but don't fail, if column to be created has UNKNOWN type
* (usually as a result of a 'retrieve into' - jolly)
*
* Refuse any attempt to create a pseudo-type column.
* Refuse any attempt to create a pseudo-type column or one that uses
* a standalone composite type. (Eventually we should probably refuse
* all references to complex types, but for now there's still some
* Berkeley-derived code that thinks it can do this...)
*/
for (i = 0; i < natts; i++)
{
Oid att_type = tupdesc->attrs[i]->atttypid;
char att_typtype = get_typtype(att_type);
if (att_type == UNKNOWNOID)
elog(WARNING, "Attribute \"%s\" has an unknown type"
"\n\tProceeding with relation creation anyway",
NameStr(tupdesc->attrs[i]->attname));
if (get_typtype(att_type) == 'p')
if (att_typtype == 'p')
elog(ERROR, "Attribute \"%s\" has pseudo-type %s",
NameStr(tupdesc->attrs[i]->attname),
format_type_be(att_type));
if (att_typtype == 'c')
{
Oid typrelid = get_typ_typrelid(att_type);
if (get_rel_relkind(typrelid) == RELKIND_COMPOSITE_TYPE)
elog(ERROR, "Attribute \"%s\" has composite type %s",
NameStr(tupdesc->attrs[i]->attname),
format_type_be(att_type));
}
}
}

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.88 2002/09/18 21:35:20 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.89 2002/09/19 23:40:56 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -535,21 +535,14 @@ void
RemoveIndex(RangeVar *relation, DropBehavior behavior)
{
Oid indOid;
HeapTuple tuple;
char relkind;
ObjectAddress object;
indOid = RangeVarGetRelid(relation, false);
tuple = SearchSysCache(RELOID,
ObjectIdGetDatum(indOid),
0, 0, 0);
if (!HeapTupleIsValid(tuple))
elog(ERROR, "index \"%s\" does not exist", relation->relname);
if (((Form_pg_class) GETSTRUCT(tuple))->relkind != RELKIND_INDEX)
relkind = get_rel_relkind(indOid);
if (relkind != RELKIND_INDEX)
elog(ERROR, "relation \"%s\" is of type \"%c\"",
relation->relname, ((Form_pg_class) GETSTRUCT(tuple))->relkind);
ReleaseSysCache(tuple);
relation->relname, relkind);
object.classId = RelOid_pg_class;
object.objectId = indOid;
@ -616,7 +609,6 @@ void
ReindexTable(RangeVar *relation, bool force)
{
Oid heapOid;
HeapTuple tuple;
char relkind;
/*
@ -628,19 +620,12 @@ ReindexTable(RangeVar *relation, bool force)
elog(ERROR, "REINDEX cannot run inside a BEGIN/END block");
heapOid = RangeVarGetRelid(relation, false);
tuple = SearchSysCache(RELOID,
ObjectIdGetDatum(heapOid),
0, 0, 0);
if (!HeapTupleIsValid(tuple))
elog(ERROR, "table \"%s\" does not exist", relation->relname);
relkind = ((Form_pg_class) GETSTRUCT(tuple))->relkind;
relkind = get_rel_relkind(heapOid);
if (relkind != RELKIND_RELATION && relkind != RELKIND_TOASTVALUE)
elog(ERROR, "relation \"%s\" is of type \"%c\"",
relation->relname, relkind);
ReleaseSysCache(tuple);
if (!reindex_relation(heapOid, force))
elog(WARNING, "table \"%s\" wasn't reindexed", relation->relname);
}

View File

@ -3,7 +3,7 @@
* back to source text
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.123 2002/09/19 22:48:33 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.124 2002/09/19 23:40:56 tgl Exp $
*
* This software is copyrighted by Jan Wieck - Hamburg.
*
@ -2087,24 +2087,14 @@ get_rule_expr(Node *node, deparse_context *context,
{
FieldSelect *fselect = (FieldSelect *) node;
Oid argType = exprType(fselect->arg);
HeapTuple typetup;
Form_pg_type typeStruct;
Oid typrelid;
char *fieldname;
/* lookup arg type and get the field name */
typetup = SearchSysCache(TYPEOID,
ObjectIdGetDatum(argType),
0, 0, 0);
if (!HeapTupleIsValid(typetup))
elog(ERROR, "cache lookup of type %u failed",
argType);
typeStruct = (Form_pg_type) GETSTRUCT(typetup);
typrelid = typeStruct->typrelid;
typrelid = get_typ_typrelid(argType);
if (!OidIsValid(typrelid))
elog(ERROR, "Argument type %s of FieldSelect is not a tuple type",
format_type_be(argType));
ReleaseSysCache(typetup);
fieldname = get_relid_attribute_name(typrelid,
fselect->fieldnum);

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v 1.84 2002/09/18 21:35:23 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v 1.85 2002/09/19 23:40:56 tgl Exp $
*
* NOTES
* Eventually, the index information should go through here, too.
@ -776,6 +776,33 @@ get_rel_type_id(Oid relid)
return InvalidOid;
}
/*
* get_rel_relkind
*
* Returns the relkind associated with a given relation.
*/
char
get_rel_relkind(Oid relid)
{
HeapTuple tp;
tp = SearchSysCache(RELOID,
ObjectIdGetDatum(relid),
0, 0, 0);
if (HeapTupleIsValid(tp))
{
Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
char result;
result = reltup->relkind;
ReleaseSysCache(tp);
return result;
}
else
return '\0';
}
/* ---------- TYPE CACHE ---------- */
/*
@ -1153,6 +1180,33 @@ get_typtype(Oid typid)
return '\0';
}
/*
* get_typ_typrelid
*
* Given the type OID, get the typrelid (InvalidOid if not a complex
* type).
*/
Oid
get_typ_typrelid(Oid typid)
{
HeapTuple tp;
tp = SearchSysCache(TYPEOID,
ObjectIdGetDatum(typid),
0, 0, 0);
if (HeapTupleIsValid(tp))
{
Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
Oid result;
result = typtup->typrelid;
ReleaseSysCache(tp);
return result;
}
else
return InvalidOid;
}
/*
* getTypeInputInfo
*

View File

@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: lsyscache.h,v 1.63 2002/09/18 21:35:25 tgl Exp $
* $Id: lsyscache.h,v 1.64 2002/09/19 23:40:56 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -45,6 +45,7 @@ extern Oid get_system_catalog_relid(const char *catname);
extern char *get_rel_name(Oid relid);
extern Oid get_rel_namespace(Oid relid);
extern Oid get_rel_type_id(Oid relid);
extern char get_rel_relkind(Oid relid);
extern bool get_typisdefined(Oid typid);
extern int16 get_typlen(Oid typid);
extern bool get_typbyval(Oid typid);
@ -54,6 +55,7 @@ extern void get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval,
extern char get_typstorage(Oid typid);
extern Node *get_typdefault(Oid typid);
extern char get_typtype(Oid typid);
extern Oid get_typ_typrelid(Oid typid);
extern void getTypeInputInfo(Oid type, Oid *typInput, Oid *typElem);
extern bool getTypeOutputInfo(Oid type, Oid *typOutput, Oid *typElem,
bool *typIsVarlena);