Commit a9d5f30b authored by Tom Lane's avatar Tom Lane

Restore enforce_generic_type_consistency's pre-8.3 behavior of allowing an

actual argument type of ANYARRAY to match an argument declared ANYARRAY,
so long as ANYELEMENT etc aren't used.  I had overlooked the fact that this
is a possible case while fixing bug #3852; but it is possible because
pg_statistic contains columns declared ANYARRAY.  Per gripe from Corey Horton.
parent b8753e59
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/parser/parse_coerce.c,v 2.171 2008/10/31 08:39:21 heikki Exp $ * $PostgreSQL: pgsql/src/backend/parser/parse_coerce.c,v 2.172 2008/12/14 19:45:52 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -1424,6 +1424,15 @@ check_generic_type_consistency(Oid *actual_arg_types, ...@@ -1424,6 +1424,15 @@ check_generic_type_consistency(Oid *actual_arg_types,
* arg types, and we can return ANYARRAY or ANYELEMENT as the result. (This * 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 * case is currently used only to check compatibility of an aggregate's
* declaration with the underlying transfn.) * declaration with the underlying transfn.)
*
* A special case is that we could see ANYARRAY as an actual_arg_type even
* when allow_poly is false (this is possible only because pg_statistic has
* columns shown as anyarray in the catalogs). We allow this to match a
* declared ANYARRAY argument, but only if there is no ANYELEMENT argument
* or result (since we can't determine a specific element type to match to
* ANYELEMENT). Note this means that functions taking ANYARRAY had better
* behave sanely if applied to the pg_statistic columns; they can't just
* assume that successive inputs are of the same actual element type.
*/ */
Oid Oid
enforce_generic_type_consistency(Oid *actual_arg_types, enforce_generic_type_consistency(Oid *actual_arg_types,
...@@ -1438,6 +1447,9 @@ enforce_generic_type_consistency(Oid *actual_arg_types, ...@@ -1438,6 +1447,9 @@ enforce_generic_type_consistency(Oid *actual_arg_types,
Oid elem_typeid = InvalidOid; Oid elem_typeid = InvalidOid;
Oid array_typeid = InvalidOid; Oid array_typeid = InvalidOid;
Oid array_typelem; Oid array_typelem;
bool have_anyelement = (rettype == ANYELEMENTOID ||
rettype == ANYNONARRAYOID ||
rettype == ANYENUMOID);
bool have_anynonarray = (rettype == ANYNONARRAYOID); bool have_anynonarray = (rettype == ANYNONARRAYOID);
bool have_anyenum = (rettype == ANYENUMOID); bool have_anyenum = (rettype == ANYENUMOID);
...@@ -1454,7 +1466,7 @@ enforce_generic_type_consistency(Oid *actual_arg_types, ...@@ -1454,7 +1466,7 @@ enforce_generic_type_consistency(Oid *actual_arg_types,
decl_type == ANYNONARRAYOID || decl_type == ANYNONARRAYOID ||
decl_type == ANYENUMOID) decl_type == ANYENUMOID)
{ {
have_generics = true; have_generics = have_anyelement = true;
if (decl_type == ANYNONARRAYOID) if (decl_type == ANYNONARRAYOID)
have_anynonarray = true; have_anynonarray = true;
else if (decl_type == ANYENUMOID) else if (decl_type == ANYENUMOID)
...@@ -1506,12 +1518,20 @@ enforce_generic_type_consistency(Oid *actual_arg_types, ...@@ -1506,12 +1518,20 @@ enforce_generic_type_consistency(Oid *actual_arg_types,
/* Get the element type based on the array type, if we have one */ /* Get the element type based on the array type, if we have one */
if (OidIsValid(array_typeid)) if (OidIsValid(array_typeid))
{ {
array_typelem = get_element_type(array_typeid); if (array_typeid == ANYARRAYOID && !have_anyelement)
if (!OidIsValid(array_typelem)) {
ereport(ERROR, /* Special case for ANYARRAY input: okay iff no ANYELEMENT */
(errcode(ERRCODE_DATATYPE_MISMATCH), array_typelem = InvalidOid;
errmsg("argument declared \"anyarray\" is not an array but type %s", }
format_type_be(array_typeid)))); 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))));
}
if (!OidIsValid(elem_typeid)) if (!OidIsValid(elem_typeid))
{ {
......
...@@ -613,6 +613,17 @@ create aggregate build_group(int8, integer) ( ...@@ -613,6 +613,17 @@ create aggregate build_group(int8, integer) (
SFUNC = add_group, SFUNC = add_group,
STYPE = int8[] STYPE = int8[]
); );
-- check that we can apply functions taking ANYARRAY to pg_stats
select distinct array_ndims(histogram_bounds) from pg_stats
where histogram_bounds is not null;
array_ndims
-------------
1
(1 row)
-- such functions must protect themselves if varying element type isn't OK
select max(histogram_bounds) from pg_stats;
ERROR: cannot compare arrays of different element types
-- test variadic polymorphic functions -- test variadic polymorphic functions
create function myleast(variadic anyarray) returns anyelement as $$ create function myleast(variadic anyarray) returns anyelement as $$
select min($1[i]) from generate_subscripts($1,1) g(i) select min($1[i]) from generate_subscripts($1,1) g(i)
......
...@@ -427,6 +427,13 @@ create aggregate build_group(int8, integer) ( ...@@ -427,6 +427,13 @@ create aggregate build_group(int8, integer) (
STYPE = int8[] STYPE = int8[]
); );
-- check that we can apply functions taking ANYARRAY to pg_stats
select distinct array_ndims(histogram_bounds) from pg_stats
where histogram_bounds is not null;
-- such functions must protect themselves if varying element type isn't OK
select max(histogram_bounds) from pg_stats;
-- test variadic polymorphic functions -- test variadic polymorphic functions
create function myleast(variadic anyarray) returns anyelement as $$ create function myleast(variadic anyarray) returns anyelement as $$
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment