aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2008-12-14 19:45:52 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2008-12-14 19:45:52 +0000
commita9d5f30be328fb83f0667b8a60df00a30d934fb2 (patch)
treed552f96a1f72d1821d222b3653a457e8e7e9f294 /src
parentb8753e5955db8735107eb769fa0004b9f28a0c4e (diff)
downloadpostgresql-a9d5f30be328fb83f0667b8a60df00a30d934fb2.tar.gz
postgresql-a9d5f30be328fb83f0667b8a60df00a30d934fb2.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/backend/parser/parse_coerce.c36
-rw-r--r--src/test/regress/expected/polymorphism.out11
-rw-r--r--src/test/regress/sql/polymorphism.sql7
3 files changed, 46 insertions, 8 deletions
diff --git a/src/backend/parser/parse_coerce.c b/src/backend/parser/parse_coerce.c
index 112a07beb58..1bac7ca2fce 100644
--- a/src/backend/parser/parse_coerce.c
+++ b/src/backend/parser/parse_coerce.c
@@ -8,7 +8,7 @@
*
*
* 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,
* 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.)
+ *
+ * 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
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 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);
@@ -1454,7 +1466,7 @@ enforce_generic_type_consistency(Oid *actual_arg_types,
decl_type == ANYNONARRAYOID ||
decl_type == ANYENUMOID)
{
- have_generics = true;
+ have_generics = have_anyelement = true;
if (decl_type == ANYNONARRAYOID)
have_anynonarray = true;
else if (decl_type == ANYENUMOID)
@@ -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 */
if (OidIsValid(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 (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))));
+ }
if (!OidIsValid(elem_typeid))
{
diff --git a/src/test/regress/expected/polymorphism.out b/src/test/regress/expected/polymorphism.out
index 340b7c0f973..69e0ea47463 100644
--- a/src/test/regress/expected/polymorphism.out
+++ b/src/test/regress/expected/polymorphism.out
@@ -613,6 +613,17 @@ create aggregate build_group(int8, integer) (
SFUNC = add_group,
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
create function myleast(variadic anyarray) returns anyelement as $$
select min($1[i]) from generate_subscripts($1,1) g(i)
diff --git a/src/test/regress/sql/polymorphism.sql b/src/test/regress/sql/polymorphism.sql
index 56f90c597a8..6c7b1813f94 100644
--- a/src/test/regress/sql/polymorphism.sql
+++ b/src/test/regress/sql/polymorphism.sql
@@ -427,6 +427,13 @@ create aggregate build_group(int8, integer) (
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
create function myleast(variadic anyarray) returns anyelement as $$