88 *
99 *
1010 * IDENTIFICATION
11- * $PostgreSQL: pgsql/src/backend/parser/parse_coerce.c,v 2.160 2008/01/01 19:45:50 momjian Exp $
11+ * $PostgreSQL: pgsql/src/backend/parser/parse_coerce.c,v 2.161 2008/01/11 18:39:40 tgl Exp $
1212 *
1313 *-------------------------------------------------------------------------
1414 */
@@ -1255,22 +1255,27 @@ check_generic_type_consistency(Oid *actual_arg_types,
12551255 * we add the extra condition that the ANYELEMENT type must not be an array.
12561256 * (This is a no-op if used in combination with ANYARRAY or ANYENUM, but
12571257 * is an extra restriction if not.)
1258+ *
1259+ * When allow_poly is false, we are not expecting any of the actual_arg_types
1260+ * to be polymorphic, and we should not return a polymorphic result type
1261+ * either. When allow_poly is true, it is okay to have polymorphic "actual"
1262+ * arg types, and we can return ANYARRAY or ANYELEMENT as the result. (This
1263+ * case is currently used only to check compatibility of an aggregate's
1264+ * declaration with the underlying transfn.)
12581265 */
12591266Oid
12601267enforce_generic_type_consistency (Oid * actual_arg_types ,
12611268Oid * declared_arg_types ,
12621269int nargs ,
1263- Oid rettype )
1270+ Oid rettype ,
1271+ bool allow_poly )
12641272{
12651273int j ;
12661274bool have_generics = false;
12671275bool have_unknowns = false;
12681276Oid elem_typeid = InvalidOid ;
12691277Oid array_typeid = InvalidOid ;
12701278Oid array_typelem ;
1271- bool have_anyelement = (rettype == ANYELEMENTOID ||
1272- rettype == ANYNONARRAYOID ||
1273- rettype == ANYENUMOID );
12741279bool have_anynonarray = (rettype == ANYNONARRAYOID );
12751280bool have_anyenum = (rettype == ANYENUMOID );
12761281
@@ -1287,7 +1292,7 @@ enforce_generic_type_consistency(Oid *actual_arg_types,
12871292decl_type == ANYNONARRAYOID ||
12881293decl_type == ANYENUMOID )
12891294{
1290- have_generics = have_anyelement = true;
1295+ have_generics = true;
12911296if (decl_type == ANYNONARRAYOID )
12921297have_anynonarray = true;
12931298else if (decl_type == ANYENUMOID )
@@ -1297,6 +1302,8 @@ enforce_generic_type_consistency(Oid *actual_arg_types,
12971302have_unknowns = true;
12981303continue ;
12991304}
1305+ if (allow_poly && decl_type == actual_type )
1306+ continue ;/* no new information here */
13001307if (OidIsValid (elem_typeid )&& actual_type != elem_typeid )
13011308ereport (ERROR ,
13021309(errcode (ERRCODE_DATATYPE_MISMATCH ),
@@ -1314,6 +1321,8 @@ enforce_generic_type_consistency(Oid *actual_arg_types,
13141321have_unknowns = true;
13151322continue ;
13161323}
1324+ if (allow_poly && decl_type == actual_type )
1325+ continue ;/* no new information here */
13171326if (OidIsValid (array_typeid )&& actual_type != array_typeid )
13181327ereport (ERROR ,
13191328(errcode (ERRCODE_DATATYPE_MISMATCH ),
@@ -1335,20 +1344,12 @@ enforce_generic_type_consistency(Oid *actual_arg_types,
13351344/* Get the element type based on the array type, if we have one */
13361345if (OidIsValid (array_typeid ))
13371346{
1338- if (array_typeid == ANYARRAYOID && !have_anyelement )
1339- {
1340- /* Special case for ANYARRAY input: okay iff no ANYELEMENT */
1341- array_typelem = InvalidOid ;
1342- }
1343- else
1344- {
1345- array_typelem = get_element_type (array_typeid );
1346- if (!OidIsValid (array_typelem ))
1347- ereport (ERROR ,
1348- (errcode (ERRCODE_DATATYPE_MISMATCH ),
1349- errmsg ("argument declared \"anyarray\" is not an array but type %s" ,
1350- format_type_be (array_typeid ))));
1351- }
1347+ array_typelem = get_element_type (array_typeid );
1348+ if (!OidIsValid (array_typelem ))
1349+ ereport (ERROR ,
1350+ (errcode (ERRCODE_DATATYPE_MISMATCH ),
1351+ errmsg ("argument declared \"anyarray\" is not an array but type %s" ,
1352+ format_type_be (array_typeid ))));
13521353
13531354if (!OidIsValid (elem_typeid ))
13541355{
@@ -1370,13 +1371,21 @@ enforce_generic_type_consistency(Oid *actual_arg_types,
13701371}
13711372else if (!OidIsValid (elem_typeid ))
13721373{
1373- /* Only way to get here is if all the generic args are UNKNOWN */
1374- ereport (ERROR ,
1375- (errcode (ERRCODE_DATATYPE_MISMATCH ),
1376- errmsg ("could not determine polymorphic type because input has type \"unknown\"" )));
1374+ if (allow_poly )
1375+ {
1376+ array_typeid = ANYARRAYOID ;
1377+ elem_typeid = ANYELEMENTOID ;
1378+ }
1379+ else
1380+ {
1381+ /* Only way to get here is if all the generic args are UNKNOWN */
1382+ ereport (ERROR ,
1383+ (errcode (ERRCODE_DATATYPE_MISMATCH ),
1384+ errmsg ("could not determine polymorphic type because input has type \"unknown\"" )));
1385+ }
13771386}
13781387
1379- if (have_anynonarray )
1388+ if (have_anynonarray && elem_typeid != ANYELEMENTOID )
13801389{
13811390/* require the element type to not be an array */
13821391if (type_is_array (elem_typeid ))
@@ -1386,7 +1395,7 @@ enforce_generic_type_consistency(Oid *actual_arg_types,
13861395format_type_be (elem_typeid ))));
13871396}
13881397
1389- if (have_anyenum )
1398+ if (have_anyenum && elem_typeid != ANYELEMENTOID )
13901399{
13911400/* require the element type to be an enum */
13921401if (!type_is_enum (elem_typeid ))