8
8
*
9
9
*
10
10
* 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 $
12
12
*
13
13
*-------------------------------------------------------------------------
14
14
*/
@@ -1255,22 +1255,27 @@ check_generic_type_consistency(Oid *actual_arg_types,
1255
1255
* we add the extra condition that the ANYELEMENT type must not be an array.
1256
1256
* (This is a no-op if used in combination with ANYARRAY or ANYENUM, but
1257
1257
* 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.)
1258
1265
*/
1259
1266
Oid
1260
1267
enforce_generic_type_consistency (Oid * actual_arg_types ,
1261
1268
Oid * declared_arg_types ,
1262
1269
int nargs ,
1263
- Oid rettype )
1270
+ Oid rettype ,
1271
+ bool allow_poly )
1264
1272
{
1265
1273
int j ;
1266
1274
bool have_generics = false;
1267
1275
bool have_unknowns = false;
1268
1276
Oid elem_typeid = InvalidOid ;
1269
1277
Oid array_typeid = InvalidOid ;
1270
1278
Oid array_typelem ;
1271
- bool have_anyelement = (rettype == ANYELEMENTOID ||
1272
- rettype == ANYNONARRAYOID ||
1273
- rettype == ANYENUMOID );
1274
1279
bool have_anynonarray = (rettype == ANYNONARRAYOID );
1275
1280
bool have_anyenum = (rettype == ANYENUMOID );
1276
1281
@@ -1287,7 +1292,7 @@ enforce_generic_type_consistency(Oid *actual_arg_types,
1287
1292
decl_type == ANYNONARRAYOID ||
1288
1293
decl_type == ANYENUMOID )
1289
1294
{
1290
- have_generics = have_anyelement = true;
1295
+ have_generics = true;
1291
1296
if (decl_type == ANYNONARRAYOID )
1292
1297
have_anynonarray = true;
1293
1298
else if (decl_type == ANYENUMOID )
@@ -1297,6 +1302,8 @@ enforce_generic_type_consistency(Oid *actual_arg_types,
1297
1302
have_unknowns = true;
1298
1303
continue ;
1299
1304
}
1305
+ if (allow_poly && decl_type == actual_type )
1306
+ continue ; /* no new information here */
1300
1307
if (OidIsValid (elem_typeid ) && actual_type != elem_typeid )
1301
1308
ereport (ERROR ,
1302
1309
(errcode (ERRCODE_DATATYPE_MISMATCH ),
@@ -1314,6 +1321,8 @@ enforce_generic_type_consistency(Oid *actual_arg_types,
1314
1321
have_unknowns = true;
1315
1322
continue ;
1316
1323
}
1324
+ if (allow_poly && decl_type == actual_type )
1325
+ continue ; /* no new information here */
1317
1326
if (OidIsValid (array_typeid ) && actual_type != array_typeid )
1318
1327
ereport (ERROR ,
1319
1328
(errcode (ERRCODE_DATATYPE_MISMATCH ),
@@ -1335,20 +1344,12 @@ enforce_generic_type_consistency(Oid *actual_arg_types,
1335
1344
/* Get the element type based on the array type, if we have one */
1336
1345
if (OidIsValid (array_typeid ))
1337
1346
{
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 ))));
1352
1353
1353
1354
if (!OidIsValid (elem_typeid ))
1354
1355
{
@@ -1370,13 +1371,21 @@ enforce_generic_type_consistency(Oid *actual_arg_types,
1370
1371
}
1371
1372
else if (!OidIsValid (elem_typeid ))
1372
1373
{
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
+ }
1377
1386
}
1378
1387
1379
- if (have_anynonarray )
1388
+ if (have_anynonarray && elem_typeid != ANYELEMENTOID )
1380
1389
{
1381
1390
/* require the element type to not be an array */
1382
1391
if (type_is_array (elem_typeid ))
@@ -1386,7 +1395,7 @@ enforce_generic_type_consistency(Oid *actual_arg_types,
1386
1395
format_type_be (elem_typeid ))));
1387
1396
}
1388
1397
1389
- if (have_anyenum )
1398
+ if (have_anyenum && elem_typeid != ANYELEMENTOID )
1390
1399
{
1391
1400
/* require the element type to be an enum */
1392
1401
if (!type_is_enum (elem_typeid ))
0 commit comments