aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/typecmds.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/commands/typecmds.c')
-rw-r--r--src/backend/commands/typecmds.c49
1 files changed, 32 insertions, 17 deletions
diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c
index c2fc59d1aa0..29ac5d569d7 100644
--- a/src/backend/commands/typecmds.c
+++ b/src/backend/commands/typecmds.c
@@ -2787,10 +2787,9 @@ validateDomainConstraint(Oid domainoid, char *ccbin)
* risk by using the weakest suitable lock (ShareLock for most callers).
*
* XXX the API for this is not sufficient to support checking domain values
- * that are inside composite types or arrays. Currently we just error out
- * if a composite type containing the target domain is stored anywhere.
- * There are not currently arrays of domains; if there were, we could take
- * the same approach, but it'd be nicer to fix it properly.
+ * that are inside container types, such as composite types, arrays, or
+ * ranges. Currently we just error out if a container type containing the
+ * target domain is stored anywhere.
*
* Generally used for retrieving a list of tests when adding
* new constraints to a domain.
@@ -2799,6 +2798,7 @@ static List *
get_rels_with_domain(Oid domainOid, LOCKMODE lockmode)
{
List *result = NIL;
+ char *domainTypeName = format_type_be(domainOid);
Relation depRel;
ScanKeyData key[2];
SysScanDesc depScan;
@@ -2806,6 +2806,9 @@ get_rels_with_domain(Oid domainOid, LOCKMODE lockmode)
Assert(lockmode != NoLock);
+ /* 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 domain. (We
* assume we can ignore refobjsubid for a domain.)
@@ -2832,20 +2835,32 @@ get_rels_with_domain(Oid domainOid, LOCKMODE lockmode)
Form_pg_attribute pg_att;
int ptr;
- /* Check for directly dependent types --- must be domains */
+ /* Check for directly dependent types */
if (pg_depend->classid == TypeRelationId)
{
- Assert(get_typtype(pg_depend->objid) == TYPTYPE_DOMAIN);
-
- /*
- * Recursively add dependent columns to the output list. This is
- * a bit inefficient since we may fail to combine RelToCheck
- * entries when attributes of the same rel have different derived
- * domain types, but it's probably not worth improving.
- */
- result = list_concat(result,
- get_rels_with_domain(pg_depend->objid,
- lockmode));
+ if (get_typtype(pg_depend->objid) == TYPTYPE_DOMAIN)
+ {
+ /*
+ * This is a sub-domain, so recursively add dependent columns
+ * to the output list. This is a bit inefficient since we may
+ * fail to combine RelToCheck entries when attributes of the
+ * same rel have different derived domain types, but it's
+ * probably not worth improving.
+ */
+ result = list_concat(result,
+ get_rels_with_domain(pg_depend->objid,
+ lockmode));
+ }
+ else
+ {
+ /*
+ * Otherwise, it is some container type using the domain, so
+ * fail if there are any columns of this type.
+ */
+ find_composite_type_dependencies(pg_depend->objid,
+ NULL,
+ domainTypeName);
+ }
continue;
}
@@ -2882,7 +2897,7 @@ get_rels_with_domain(Oid domainOid, LOCKMODE lockmode)
if (OidIsValid(rel->rd_rel->reltype))
find_composite_type_dependencies(rel->rd_rel->reltype,
NULL,
- format_type_be(domainOid));
+ domainTypeName);
/*
* Otherwise, we can ignore relations except those with both