@@ -143,9 +143,7 @@ coerce_type(ParseState *pstate, Node *node,
143143}
144144if (targetTypeId == ANYOID ||
145145targetTypeId == ANYELEMENTOID ||
146- targetTypeId == ANYNONARRAYOID ||
147- (targetTypeId == ANYARRAYOID && inputTypeId != UNKNOWNOID )||
148- (targetTypeId == ANYENUMOID && inputTypeId != UNKNOWNOID ))
146+ targetTypeId == ANYNONARRAYOID )
149147{
150148/*
151149 * Assume can_coerce_type verified that implicit coercion is okay.
@@ -154,15 +152,48 @@ coerce_type(ParseState *pstate, Node *node,
154152 * it's OK to treat an UNKNOWN constant as a valid input for a
155153 * function accepting ANY, ANYELEMENT, or ANYNONARRAY.This should be
156154 * all right, since an UNKNOWN value is still a perfectly valid Datum.
157- * However an UNKNOWN value is definitely *not* an array, and so we
158- * mustn't accept it for ANYARRAY. (Instead, we will call anyarray_in
159- * below, which will produce an error.) Likewise, UNKNOWN input is no
160- * good for ANYENUM.
161155 *
162- * NB: we do NOT want a RelabelType here.
156+ * NB: we do NOT want a RelabelType here: the exposed type of the
157+ * function argument must be its actual type, not the polymorphic
158+ * pseudotype.
163159 */
164160return node ;
165161}
162+ if (targetTypeId == ANYARRAYOID ||
163+ targetTypeId == ANYENUMOID )
164+ {
165+ /*
166+ * Assume can_coerce_type verified that implicit coercion is okay.
167+ *
168+ * These cases are unlike the ones above because the exposed type of
169+ * the argument must be an actual array or enum type. In particular
170+ * the argument must *not* be an UNKNOWN constant. If it is, we just
171+ * fall through; below, we'll call anyarray_in or anyenum_in, which
172+ * will produce an error. Also, if what we have is a domain over
173+ * array or enum, we have to relabel it to its base type.
174+ *
175+ * Note: currently, we can't actually see a domain-over-enum here,
176+ * since the other functions in this file will not match such a
177+ * parameter to ANYENUM. But that should get changed eventually.
178+ */
179+ if (inputTypeId != UNKNOWNOID )
180+ {
181+ Oid baseTypeId = getBaseType (inputTypeId );
182+
183+ if (baseTypeId != inputTypeId )
184+ {
185+ RelabelType * r = makeRelabelType ((Expr * )node ,
186+ baseTypeId ,-1 ,
187+ InvalidOid ,
188+ cformat );
189+
190+ r -> location = location ;
191+ return (Node * )r ;
192+ }
193+ /* Not a domain type, so return it as-is */
194+ return node ;
195+ }
196+ }
166197if (inputTypeId == UNKNOWNOID && IsA (node ,Const ))
167198{
168199/*
@@ -1257,6 +1288,11 @@ coerce_to_common_type(ParseState *pstate, Node *node,
12571288 * (This is a no-op if used in combination with ANYARRAY or ANYENUM, but
12581289 * is an extra restriction if not.)
12591290 *
1291+ * Domains over arrays match ANYARRAY, and are immediately flattened to their
1292+ * base type. (Thus, for example, we will consider it a match if one ANYARRAY
1293+ * argument is a domain over int4[] while another one is just int4[].) Also
1294+ * notice that such a domain does *not* match ANYNONARRAY.
1295+ *
12601296 * If we have UNKNOWN input (ie, an untyped literal) for any polymorphic
12611297 * argument, assume it is okay.
12621298 *
@@ -1309,6 +1345,7 @@ check_generic_type_consistency(Oid *actual_arg_types,
13091345{
13101346if (actual_type == UNKNOWNOID )
13111347continue ;
1348+ actual_type = getBaseType (actual_type );/* flatten domains */
13121349if (OidIsValid (array_typeid )&& actual_type != array_typeid )
13131350return false;
13141351array_typeid = actual_type ;
@@ -1346,8 +1383,8 @@ check_generic_type_consistency(Oid *actual_arg_types,
13461383
13471384if (have_anynonarray )
13481385{
1349- /* require the element type to not be an array */
1350- if (type_is_array (elem_typeid ))
1386+ /* require the element type to not be an arrayor domain over array */
1387+ if (type_is_array_domain (elem_typeid ))
13511388return false;
13521389}
13531390
@@ -1406,6 +1443,10 @@ check_generic_type_consistency(Oid *actual_arg_types,
14061443 * (This is a no-op if used in combination with ANYARRAY or ANYENUM, but
14071444 * is an extra restriction if not.)
14081445 *
1446+ * Domains over arrays match ANYARRAY arguments, and are immediately flattened
1447+ * to their base type. (In particular, if the return type is also ANYARRAY,
1448+ * we'll set it to the base type not the domain type.)
1449+ *
14091450 * When allow_poly is false, we are not expecting any of the actual_arg_types
14101451 * to be polymorphic, and we should not return a polymorphic result type
14111452 * either.When allow_poly is true, it is okay to have polymorphic "actual"
@@ -1485,6 +1526,7 @@ enforce_generic_type_consistency(Oid *actual_arg_types,
14851526}
14861527if (allow_poly && decl_type == actual_type )
14871528continue ;/* no new information here */
1529+ actual_type = getBaseType (actual_type );/* flatten domains */
14881530if (OidIsValid (array_typeid )&& actual_type != array_typeid )
14891531ereport (ERROR ,
14901532(errcode (ERRCODE_DATATYPE_MISMATCH ),
@@ -1557,8 +1599,8 @@ enforce_generic_type_consistency(Oid *actual_arg_types,
15571599
15581600if (have_anynonarray && elem_typeid != ANYELEMENTOID )
15591601{
1560- /* require the element type to not be an array */
1561- if (type_is_array (elem_typeid ))
1602+ /* require the element type to not be an arrayor domain over array */
1603+ if (type_is_array_domain (elem_typeid ))
15621604ereport (ERROR ,
15631605(errcode (ERRCODE_DATATYPE_MISMATCH ),
15641606errmsg ("type matched to anynonarray is an array type: %s" ,
@@ -1655,15 +1697,19 @@ resolve_generic_type(Oid declared_type,
16551697{
16561698if (context_declared_type == ANYARRAYOID )
16571699{
1658- /* Use actual type, but it must be an array */
1659- Oid array_typelem = get_element_type (context_actual_type );
1700+ /*
1701+ * Use actual type, but it must be an array; or if it's a domain
1702+ * over array, use the base array type.
1703+ */
1704+ Oid context_base_type = getBaseType (context_actual_type );
1705+ Oid array_typelem = get_element_type (context_base_type );
16601706
16611707if (!OidIsValid (array_typelem ))
16621708ereport (ERROR ,
16631709(errcode (ERRCODE_DATATYPE_MISMATCH ),
16641710errmsg ("argument declared \"anyarray\" is not an array but type %s" ,
1665- format_type_be (context_actual_type ))));
1666- return context_actual_type ;
1711+ format_type_be (context_base_type ))));
1712+ return context_base_type ;
16671713}
16681714else if (context_declared_type == ANYELEMENTOID ||
16691715context_declared_type == ANYNONARRAYOID ||
@@ -1687,13 +1733,14 @@ resolve_generic_type(Oid declared_type,
16871733if (context_declared_type == ANYARRAYOID )
16881734{
16891735/* Use the element type corresponding to actual type */
1690- Oid array_typelem = get_element_type (context_actual_type );
1736+ Oid context_base_type = getBaseType (context_actual_type );
1737+ Oid array_typelem = get_element_type (context_base_type );
16911738
16921739if (!OidIsValid (array_typelem ))
16931740ereport (ERROR ,
16941741(errcode (ERRCODE_DATATYPE_MISMATCH ),
16951742errmsg ("argument declared \"anyarray\" is not an array but type %s" ,
1696- format_type_be (context_actual_type ))));
1743+ format_type_be (context_base_type ))));
16971744return array_typelem ;
16981745}
16991746else if (context_declared_type == ANYELEMENTOID ||
@@ -1796,12 +1843,12 @@ IsBinaryCoercible(Oid srctype, Oid targettype)
17961843
17971844/* Also accept any array type as coercible to ANYARRAY */
17981845if (targettype == ANYARRAYOID )
1799- if (type_is_array (srctype ))
1846+ if (type_is_array_domain (srctype ))
18001847return true;
18011848
18021849/* Also accept any non-array type as coercible to ANYNONARRAY */
18031850if (targettype == ANYNONARRAYOID )
1804- if (!type_is_array (srctype ))
1851+ if (!type_is_array_domain (srctype ))
18051852return true;
18061853
18071854/* Also accept any enum type as coercible to ANYENUM */