Florian G. Pflug wrote:
> While trying to create a domain over an array type to enforce a certain
> shape or certain contents of an array (like the array being only
> one-dimensional or not containing NULLs), I've stumbled over what I
> believe to be a bug in postgresql 8.4
> 
> It seems that check constraints on domains are *not* executed for
> literals of the domain-over-array-type - in other words, for expressions
> like:
> array[...]::<my-domain-over-array-type>.
> 
> They are, however, executed if I first force the array to be of the base
> type, and then cast it to the array type.
> ...
> I still have the feeling that this a bug, though. First, because it
> leaves you with no way at guarantee that values of a given domain always
> fulfill certain constraints. And second because "array[...]::arraytype"
> at least *looks* like a cast, and hence should behave like one too.

Agreed, it's a bug. A simpler example is just:

postgres=# create  domain myintarray as int[] check (value[1] < 10);
CREATE DOMAIN
postgres=# SELECT array['20']::myintarray; -- should fail
 array
───────
 {20}
(1 row)

There's a special case in transformExpr function to handle the
"ARRAY[...]::arraytype" construct, which skips the usual type-casting
and just constructs an ArrayExpr with the right target type. However,
it's not taking into account that the target type can be a domain.

Attached patch fixes that. Anyone see a problem with it?

-- 
  Heikki Linnakangas
  EnterpriseDB   http://www.enterprisedb.com
diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c
index 04127bd..8ca4a2f 100644
--- a/src/backend/parser/parse_expr.c
+++ b/src/backend/parser/parse_expr.c
@@ -169,6 +169,20 @@ transformExpr(ParseState *pstate, Node *expr)
 													targetType,
 													elementType,
 													targetTypmod);
+
+						/*
+						 * If the target array type is a domain, we still need
+						 * to check the domain constraint. (coerce_to_domain
+						 * is a no-op otherwise)
+						 */
+						result = coerce_to_domain(result,
+												  InvalidOid,
+												  -1,
+												  targetType,
+												  COERCE_IMPLICIT_CAST,
+												  tc->location,
+												  false,
+												  true);
 						break;
 					}
 
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to