mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-12-21 08:29:39 +08:00
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:
parent
4a0c3a6142
commit
da395b56cd
@ -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",
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
56
src/backend/utils/cache/lsyscache.c
vendored
56
src/backend/utils/cache/lsyscache.c
vendored
@ -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
|
||||
*
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user