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
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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:
|
case OCLASS_CLASS:
|
||||||
{
|
{
|
||||||
HeapTuple relTup;
|
char relKind = get_rel_relkind(object->objectId);
|
||||||
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);
|
|
||||||
|
|
||||||
if (relKind == RELKIND_INDEX)
|
if (relKind == RELKIND_INDEX)
|
||||||
{
|
{
|
||||||
@ -1504,6 +1491,10 @@ getRelationDescription(StringInfo buffer, Oid relid)
|
|||||||
appendStringInfo(buffer, "view %s",
|
appendStringInfo(buffer, "view %s",
|
||||||
relname);
|
relname);
|
||||||
break;
|
break;
|
||||||
|
case RELKIND_COMPOSITE_TYPE:
|
||||||
|
appendStringInfo(buffer, "composite type %s",
|
||||||
|
relname);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
/* shouldn't get here */
|
/* shouldn't get here */
|
||||||
appendStringInfo(buffer, "relation %s",
|
appendStringInfo(buffer, "relation %s",
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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
|
* 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
|
* Warn user, but don't fail, if column to be created has UNKNOWN type
|
||||||
* (usually as a result of a 'retrieve into' - jolly)
|
* (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++)
|
for (i = 0; i < natts; i++)
|
||||||
{
|
{
|
||||||
Oid att_type = tupdesc->attrs[i]->atttypid;
|
Oid att_type = tupdesc->attrs[i]->atttypid;
|
||||||
|
char att_typtype = get_typtype(att_type);
|
||||||
|
|
||||||
if (att_type == UNKNOWNOID)
|
if (att_type == UNKNOWNOID)
|
||||||
elog(WARNING, "Attribute \"%s\" has an unknown type"
|
elog(WARNING, "Attribute \"%s\" has an unknown type"
|
||||||
"\n\tProceeding with relation creation anyway",
|
"\n\tProceeding with relation creation anyway",
|
||||||
NameStr(tupdesc->attrs[i]->attname));
|
NameStr(tupdesc->attrs[i]->attname));
|
||||||
if (get_typtype(att_type) == 'p')
|
if (att_typtype == 'p')
|
||||||
elog(ERROR, "Attribute \"%s\" has pseudo-type %s",
|
elog(ERROR, "Attribute \"%s\" has pseudo-type %s",
|
||||||
NameStr(tupdesc->attrs[i]->attname),
|
NameStr(tupdesc->attrs[i]->attname),
|
||||||
format_type_be(att_type));
|
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
|
* 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)
|
RemoveIndex(RangeVar *relation, DropBehavior behavior)
|
||||||
{
|
{
|
||||||
Oid indOid;
|
Oid indOid;
|
||||||
HeapTuple tuple;
|
char relkind;
|
||||||
ObjectAddress object;
|
ObjectAddress object;
|
||||||
|
|
||||||
indOid = RangeVarGetRelid(relation, false);
|
indOid = RangeVarGetRelid(relation, false);
|
||||||
tuple = SearchSysCache(RELOID,
|
relkind = get_rel_relkind(indOid);
|
||||||
ObjectIdGetDatum(indOid),
|
if (relkind != RELKIND_INDEX)
|
||||||
0, 0, 0);
|
|
||||||
if (!HeapTupleIsValid(tuple))
|
|
||||||
elog(ERROR, "index \"%s\" does not exist", relation->relname);
|
|
||||||
|
|
||||||
if (((Form_pg_class) GETSTRUCT(tuple))->relkind != RELKIND_INDEX)
|
|
||||||
elog(ERROR, "relation \"%s\" is of type \"%c\"",
|
elog(ERROR, "relation \"%s\" is of type \"%c\"",
|
||||||
relation->relname, ((Form_pg_class) GETSTRUCT(tuple))->relkind);
|
relation->relname, relkind);
|
||||||
|
|
||||||
ReleaseSysCache(tuple);
|
|
||||||
|
|
||||||
object.classId = RelOid_pg_class;
|
object.classId = RelOid_pg_class;
|
||||||
object.objectId = indOid;
|
object.objectId = indOid;
|
||||||
@ -616,7 +609,6 @@ void
|
|||||||
ReindexTable(RangeVar *relation, bool force)
|
ReindexTable(RangeVar *relation, bool force)
|
||||||
{
|
{
|
||||||
Oid heapOid;
|
Oid heapOid;
|
||||||
HeapTuple tuple;
|
|
||||||
char relkind;
|
char relkind;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -628,19 +620,12 @@ ReindexTable(RangeVar *relation, bool force)
|
|||||||
elog(ERROR, "REINDEX cannot run inside a BEGIN/END block");
|
elog(ERROR, "REINDEX cannot run inside a BEGIN/END block");
|
||||||
|
|
||||||
heapOid = RangeVarGetRelid(relation, false);
|
heapOid = RangeVarGetRelid(relation, false);
|
||||||
tuple = SearchSysCache(RELOID,
|
relkind = get_rel_relkind(heapOid);
|
||||||
ObjectIdGetDatum(heapOid),
|
|
||||||
0, 0, 0);
|
|
||||||
if (!HeapTupleIsValid(tuple))
|
|
||||||
elog(ERROR, "table \"%s\" does not exist", relation->relname);
|
|
||||||
relkind = ((Form_pg_class) GETSTRUCT(tuple))->relkind;
|
|
||||||
|
|
||||||
if (relkind != RELKIND_RELATION && relkind != RELKIND_TOASTVALUE)
|
if (relkind != RELKIND_RELATION && relkind != RELKIND_TOASTVALUE)
|
||||||
elog(ERROR, "relation \"%s\" is of type \"%c\"",
|
elog(ERROR, "relation \"%s\" is of type \"%c\"",
|
||||||
relation->relname, relkind);
|
relation->relname, relkind);
|
||||||
|
|
||||||
ReleaseSysCache(tuple);
|
|
||||||
|
|
||||||
if (!reindex_relation(heapOid, force))
|
if (!reindex_relation(heapOid, force))
|
||||||
elog(WARNING, "table \"%s\" wasn't reindexed", relation->relname);
|
elog(WARNING, "table \"%s\" wasn't reindexed", relation->relname);
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* back to source text
|
* back to source text
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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.
|
* This software is copyrighted by Jan Wieck - Hamburg.
|
||||||
*
|
*
|
||||||
@ -2087,24 +2087,14 @@ get_rule_expr(Node *node, deparse_context *context,
|
|||||||
{
|
{
|
||||||
FieldSelect *fselect = (FieldSelect *) node;
|
FieldSelect *fselect = (FieldSelect *) node;
|
||||||
Oid argType = exprType(fselect->arg);
|
Oid argType = exprType(fselect->arg);
|
||||||
HeapTuple typetup;
|
|
||||||
Form_pg_type typeStruct;
|
|
||||||
Oid typrelid;
|
Oid typrelid;
|
||||||
char *fieldname;
|
char *fieldname;
|
||||||
|
|
||||||
/* lookup arg type and get the field name */
|
/* lookup arg type and get the field name */
|
||||||
typetup = SearchSysCache(TYPEOID,
|
typrelid = get_typ_typrelid(argType);
|
||||||
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;
|
|
||||||
if (!OidIsValid(typrelid))
|
if (!OidIsValid(typrelid))
|
||||||
elog(ERROR, "Argument type %s of FieldSelect is not a tuple type",
|
elog(ERROR, "Argument type %s of FieldSelect is not a tuple type",
|
||||||
format_type_be(argType));
|
format_type_be(argType));
|
||||||
ReleaseSysCache(typetup);
|
|
||||||
fieldname = get_relid_attribute_name(typrelid,
|
fieldname = get_relid_attribute_name(typrelid,
|
||||||
fselect->fieldnum);
|
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
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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
|
* NOTES
|
||||||
* Eventually, the index information should go through here, too.
|
* Eventually, the index information should go through here, too.
|
||||||
@ -776,6 +776,33 @@ get_rel_type_id(Oid relid)
|
|||||||
return InvalidOid;
|
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 ---------- */
|
/* ---------- TYPE CACHE ---------- */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1153,6 +1180,33 @@ get_typtype(Oid typid)
|
|||||||
return '\0';
|
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
|
* getTypeInputInfo
|
||||||
*
|
*
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* 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 char *get_rel_name(Oid relid);
|
||||||
extern Oid get_rel_namespace(Oid relid);
|
extern Oid get_rel_namespace(Oid relid);
|
||||||
extern Oid get_rel_type_id(Oid relid);
|
extern Oid get_rel_type_id(Oid relid);
|
||||||
|
extern char get_rel_relkind(Oid relid);
|
||||||
extern bool get_typisdefined(Oid typid);
|
extern bool get_typisdefined(Oid typid);
|
||||||
extern int16 get_typlen(Oid typid);
|
extern int16 get_typlen(Oid typid);
|
||||||
extern bool get_typbyval(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 char get_typstorage(Oid typid);
|
||||||
extern Node *get_typdefault(Oid typid);
|
extern Node *get_typdefault(Oid typid);
|
||||||
extern char get_typtype(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 void getTypeInputInfo(Oid type, Oid *typInput, Oid *typElem);
|
||||||
extern bool getTypeOutputInfo(Oid type, Oid *typOutput, Oid *typElem,
|
extern bool getTypeOutputInfo(Oid type, Oid *typOutput, Oid *typElem,
|
||||||
bool *typIsVarlena);
|
bool *typIsVarlena);
|
||||||
|
Loading…
Reference in New Issue
Block a user