aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/tablecmds.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/commands/tablecmds.c')
-rw-r--r--src/backend/commands/tablecmds.c49
1 files changed, 31 insertions, 18 deletions
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 1b8d4b3d17e..2afde0abd8b 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -4849,13 +4849,18 @@ ATTypedTableRecursion(List **wqueue, Relation rel, AlterTableCmd *cmd,
/*
* find_composite_type_dependencies
*
- * Check to see if a composite type is being used as a column in some
- * other table (possibly nested several levels deep in composite types!).
+ * Check to see if the type "typeOid" is being used as a column in some table
+ * (possibly nested several levels deep in composite types, arrays, etc!).
* Eventually, we'd like to propagate the check or rewrite operation
- * into other such tables, but for now, just error out if we find any.
+ * into such tables, but for now, just error out if we find any.
*
- * Caller should provide either a table name or a type name (not both) to
- * report in the error message, if any.
+ * Caller should provide either the associated relation of a rowtype,
+ * or a type name (not both) for use in the error message, if any.
+ *
+ * Note that "typeOid" is not necessarily a composite type; it could also be
+ * another container type such as an array or range, or a domain over one of
+ * these things. The name of this function is therefore somewhat historical,
+ * but it's not worth changing.
*
* We assume that functions and views depending on the type are not reasons
* to reject the ALTER. (How safe is this really?)
@@ -4868,11 +4873,13 @@ find_composite_type_dependencies(Oid typeOid, Relation origRelation,
ScanKeyData key[2];
SysScanDesc depScan;
HeapTuple depTup;
- Oid arrayOid;
+
+ /* since this function recurses, it could be driven to stack overflow */
+ check_stack_depth();
/*
- * We scan pg_depend to find those things that depend on the rowtype. (We
- * assume we can ignore refobjsubid for a rowtype.)
+ * We scan pg_depend to find those things that depend on the given type.
+ * (We assume we can ignore refobjsubid for a type.)
*/
depRel = heap_open(DependRelationId, AccessShareLock);
@@ -4894,8 +4901,22 @@ find_composite_type_dependencies(Oid typeOid, Relation origRelation,
Relation rel;
Form_pg_attribute att;
- /* Ignore dependees that aren't user columns of relations */
- /* (we assume system columns are never of rowtypes) */
+ /* Check for directly dependent types */
+ if (pg_depend->classid == TypeRelationId)
+ {
+ /*
+ * This must be an array, domain, or range containing the given
+ * type, so recursively check for uses of this type. Note that
+ * any error message will mention the original type not the
+ * container; this is intentional.
+ */
+ find_composite_type_dependencies(pg_depend->objid,
+ origRelation, origTypeName);
+ continue;
+ }
+
+ /* Else, ignore dependees that aren't user columns of relations */
+ /* (we assume system columns are never of interesting types) */
if (pg_depend->classid != RelationRelationId ||
pg_depend->objsubid <= 0)
continue;
@@ -4952,14 +4973,6 @@ find_composite_type_dependencies(Oid typeOid, Relation origRelation,
systable_endscan(depScan);
relation_close(depRel, AccessShareLock);
-
- /*
- * If there's an array type for the rowtype, must check for uses of it,
- * too.
- */
- arrayOid = get_array_type(typeOid);
- if (OidIsValid(arrayOid))
- find_composite_type_dependencies(arrayOid, origRelation, origTypeName);
}