mirror of
https://github.com/postgres/postgres.git
synced 2025-06-17 17:02:08 +03:00
Tighten ALTER FOREIGN TABLE .. SET DATA TYPE checks.
If the foreign table's rowtype is being used as the type of a column in another table, we can't just up and change its data type. This was already checked for composite types and ordinary tables, but we previously failed to enforce it for foreign tables.
This commit is contained in:
@ -3391,8 +3391,8 @@ ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap, LOCKMODE lockmode)
|
||||
*/
|
||||
if (newrel)
|
||||
find_composite_type_dependencies(oldrel->rd_rel->reltype,
|
||||
RelationGetRelationName(oldrel),
|
||||
NULL);
|
||||
oldrel->rd_rel->relkind,
|
||||
RelationGetRelationName(oldrel));
|
||||
|
||||
/*
|
||||
* Generate the constraint and default execution states
|
||||
@ -3860,9 +3860,8 @@ ATTypedTableRecursion(List **wqueue, Relation rel, AlterTableCmd *cmd,
|
||||
* to reject the ALTER. (How safe is this really?)
|
||||
*/
|
||||
void
|
||||
find_composite_type_dependencies(Oid typeOid,
|
||||
const char *origTblName,
|
||||
const char *origTypeName)
|
||||
find_composite_type_dependencies(Oid typeOid, char origRelkind,
|
||||
const char *origRelname)
|
||||
{
|
||||
Relation depRel;
|
||||
ScanKeyData key[2];
|
||||
@ -3905,20 +3904,19 @@ find_composite_type_dependencies(Oid typeOid,
|
||||
|
||||
if (rel->rd_rel->relkind == RELKIND_RELATION)
|
||||
{
|
||||
if (origTblName)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("cannot alter table \"%s\" because column \"%s\".\"%s\" uses its rowtype",
|
||||
origTblName,
|
||||
RelationGetRelationName(rel),
|
||||
NameStr(att->attname))));
|
||||
const char *msg;
|
||||
if (origRelkind == RELKIND_COMPOSITE_TYPE)
|
||||
msg = gettext_noop("cannot alter type \"%s\" because column \"%s\".\"%s\" uses it");
|
||||
else if (origRelkind == RELKIND_FOREIGN_TABLE)
|
||||
msg = gettext_noop("cannot alter foreign table \"%s\" because column \"%s\".\"%s\" uses its rowtype");
|
||||
else
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("cannot alter type \"%s\" because column \"%s\".\"%s\" uses it",
|
||||
origTypeName,
|
||||
RelationGetRelationName(rel),
|
||||
NameStr(att->attname))));
|
||||
msg = gettext_noop("cannot alter table \"%s\" because column \"%s\".\"%s\" uses its rowtype");
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg(msg,
|
||||
origRelname,
|
||||
RelationGetRelationName(rel),
|
||||
NameStr(att->attname))));
|
||||
}
|
||||
else if (OidIsValid(rel->rd_rel->reltype))
|
||||
{
|
||||
@ -3927,7 +3925,7 @@ find_composite_type_dependencies(Oid typeOid,
|
||||
* recursively check for indirect dependencies via its rowtype.
|
||||
*/
|
||||
find_composite_type_dependencies(rel->rd_rel->reltype,
|
||||
origTblName, origTypeName);
|
||||
origRelkind, origRelname);
|
||||
}
|
||||
|
||||
relation_close(rel, AccessShareLock);
|
||||
@ -3943,7 +3941,7 @@ find_composite_type_dependencies(Oid typeOid,
|
||||
*/
|
||||
arrayOid = get_array_type(typeOid);
|
||||
if (OidIsValid(arrayOid))
|
||||
find_composite_type_dependencies(arrayOid, origTblName, origTypeName);
|
||||
find_composite_type_dependencies(arrayOid, origRelkind, origRelname);
|
||||
}
|
||||
|
||||
|
||||
@ -6444,14 +6442,15 @@ ATPrepAlterColumnType(List **wqueue,
|
||||
errmsg("ALTER TYPE USING is not supported on foreign tables")));
|
||||
}
|
||||
|
||||
if (tab->relkind == RELKIND_COMPOSITE_TYPE)
|
||||
if (tab->relkind == RELKIND_COMPOSITE_TYPE
|
||||
|| tab->relkind == RELKIND_FOREIGN_TABLE)
|
||||
{
|
||||
/*
|
||||
* For composite types, do this check now. Tables will check
|
||||
* it later when the table is being rewritten.
|
||||
*/
|
||||
find_composite_type_dependencies(rel->rd_rel->reltype,
|
||||
NULL,
|
||||
rel->rd_rel->relkind,
|
||||
RelationGetRelationName(rel));
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user