@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $ PostgreSQL : pgsql / src / backend / parser / parse_coerce . c , v 2.160 2008 / 01 / 01 19 : 45 : 50 momjian Exp $
* $ PostgreSQL : pgsql / src / backend / parser / parse_coerce . c , v 2.161 2008 / 01 / 11 18 : 39 : 40 tgl Exp $
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*/
@ -1255,12 +1255,20 @@ check_generic_type_consistency(Oid *actual_arg_types,
* we add the extra condition that the ANYELEMENT type must not be an array .
* ( This is a no - op if used in combination with ANYARRAY or ANYENUM , but
* is an extra restriction if not . )
*
* When allow_poly is false , we are not expecting any of the actual_arg_types
* to be polymorphic , and we should not return a polymorphic result type
* either . When allow_poly is true , it is okay to have polymorphic " actual "
* arg types , and we can return ANYARRAY or ANYELEMENT as the result . ( This
* case is currently used only to check compatibility of an aggregate ' s
* declaration with the underlying transfn . )
*/
Oid
enforce_generic_type_consistency ( Oid * actual_arg_types ,
Oid * declared_arg_types ,
int nargs ,
Oid rettype )
Oid rettype ,
bool allow_poly )
{
int j ;
bool have_generics = false ;
@ -1268,9 +1276,6 @@ enforce_generic_type_consistency(Oid *actual_arg_types,
Oid elem_typeid = InvalidOid ;
Oid array_typeid = InvalidOid ;
Oid array_typelem ;
bool have_anyelement = ( rettype = = ANYELEMENTOID | |
rettype = = ANYNONARRAYOID | |
rettype = = ANYENUMOID ) ;
bool have_anynonarray = ( rettype = = ANYNONARRAYOID ) ;
bool have_anyenum = ( rettype = = ANYENUMOID ) ;
@ -1287,7 +1292,7 @@ enforce_generic_type_consistency(Oid *actual_arg_types,
decl_type = = ANYNONARRAYOID | |
decl_type = = ANYENUMOID )
{
have_generics = have_anyelement = true ;
have_generics = true ;
if ( decl_type = = ANYNONARRAYOID )
have_anynonarray = true ;
else if ( decl_type = = ANYENUMOID )
@ -1297,6 +1302,8 @@ enforce_generic_type_consistency(Oid *actual_arg_types,
have_unknowns = true ;
continue ;
}
if ( allow_poly & & decl_type = = actual_type )
continue ; /* no new information here */
if ( OidIsValid ( elem_typeid ) & & actual_type ! = elem_typeid )
ereport ( ERROR ,
( errcode ( ERRCODE_DATATYPE_MISMATCH ) ,
@ -1314,6 +1321,8 @@ enforce_generic_type_consistency(Oid *actual_arg_types,
have_unknowns = true ;
continue ;
}
if ( allow_poly & & decl_type = = actual_type )
continue ; /* no new information here */
if ( OidIsValid ( array_typeid ) & & actual_type ! = array_typeid )
ereport ( ERROR ,
( errcode ( ERRCODE_DATATYPE_MISMATCH ) ,
@ -1335,20 +1344,12 @@ enforce_generic_type_consistency(Oid *actual_arg_types,
/* Get the element type based on the array type, if we have one */
if ( OidIsValid ( array_typeid ) )
{
if ( array_typeid = = ANYARRAYOID & & ! have_anyelement )
{
/* Special case for ANYARRAY input: okay iff no ANYELEMENT */
array_typelem = InvalidOid ;
}
else
{
array_typelem = get_element_type ( array_typeid ) ;
if ( ! OidIsValid ( array_typelem ) )
ereport ( ERROR ,
( errcode ( ERRCODE_DATATYPE_MISMATCH ) ,
errmsg ( " argument declared \" anyarray \" is not an array but type %s " ,
format_type_be ( array_typeid ) ) ) ) ;
}
array_typelem = get_element_type ( array_typeid ) ;
if ( ! OidIsValid ( array_typelem ) )
ereport ( ERROR ,
( errcode ( ERRCODE_DATATYPE_MISMATCH ) ,
errmsg ( " argument declared \" anyarray \" is not an array but type %s " ,
format_type_be ( array_typeid ) ) ) ) ;
if ( ! OidIsValid ( elem_typeid ) )
{
@ -1370,13 +1371,21 @@ enforce_generic_type_consistency(Oid *actual_arg_types,
}
else if ( ! OidIsValid ( elem_typeid ) )
{
/* Only way to get here is if all the generic args are UNKNOWN */
ereport ( ERROR ,
( errcode ( ERRCODE_DATATYPE_MISMATCH ) ,
errmsg ( " could not determine polymorphic type because input has type \" unknown \" " ) ) ) ;
if ( allow_poly )
{
array_typeid = ANYARRAYOID ;
elem_typeid = ANYELEMENTOID ;
}
else
{
/* Only way to get here is if all the generic args are UNKNOWN */
ereport ( ERROR ,
( errcode ( ERRCODE_DATATYPE_MISMATCH ) ,
errmsg ( " could not determine polymorphic type because input has type \" unknown \" " ) ) ) ;
}
}
if ( have_anynonarray )
if ( have_anynonarray & & elem_typeid ! = ANYELEMENTOID )
{
/* require the element type to not be an array */
if ( type_is_array ( elem_typeid ) )
@ -1386,7 +1395,7 @@ enforce_generic_type_consistency(Oid *actual_arg_types,
format_type_be ( elem_typeid ) ) ) ) ;
}
if ( have_anyenum )
if ( have_anyenum & & elem_typeid ! = ANYELEMENTOID )
{
/* require the element type to be an enum */
if ( ! type_is_enum ( elem_typeid ) )