aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2008-12-14 19:46:02 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2008-12-14 19:46:02 +0000
commit4d2fa58aeab8866f983bbf5bee92df6656213029 (patch)
treeb6930ba7f056006d7d25f7a4200eab4a685942eb
parent8d1d6019d4d85c51a4c414bb95a71f8897956218 (diff)
downloadpostgresql-4d2fa58aeab8866f983bbf5bee92df6656213029.tar.gz
postgresql-4d2fa58aeab8866f983bbf5bee92df6656213029.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.
-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 7933283cabc..a2633f5785c 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.161.2.1 2008/10/25 17:19:17 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/parse_coerce.c,v 2.161.2.2 2008/12/14 19:46:02 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1265,6 +1265,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,
@@ -1279,6 +1288,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);
@@ -1295,7 +1307,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)
@@ -1347,12 +1359,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 a208203c6d3..5741b075be9 100644
--- a/src/test/regress/expected/polymorphism.out
+++ b/src/test/regress/expected/polymorphism.out
@@ -613,3 +613,14 @@ 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_eq(histogram_bounds,histogram_bounds) from pg_stats
+where histogram_bounds is not null;
+ array_eq
+----------
+ t
+(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
diff --git a/src/test/regress/sql/polymorphism.sql b/src/test/regress/sql/polymorphism.sql
index 2df963952f4..015443ce22c 100644
--- a/src/test/regress/sql/polymorphism.sql
+++ b/src/test/regress/sql/polymorphism.sql
@@ -426,3 +426,10 @@ 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_eq(histogram_bounds,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;