Skip to content

Commit dbf8259

Browse files
committed
Tweak generic_type_consistency routines to avoid loss of functionality
since 7.3: 'select array_dims(histogram_bounds) from pg_stats' used to work and still should. Problem was that code wouldn't take input of declared type anyarray as matching an anyarray argument. Allow this case as long as we don't need to determine an element type (which in practice means as long as anyelement isn't used in the function signature).
1 parent 267924e commit dbf8259

File tree

1 file changed

+34
-9
lines changed

1 file changed

+34
-9
lines changed

src/backend/parser/parse_coerce.c

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/parser/parse_coerce.c,v 2.108 2003/08/04 02:40:01 momjian Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/parser/parse_coerce.c,v 2.109 2003/09/23 17:12:53 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -762,6 +762,12 @@ coerce_to_common_type(ParseState *pstate, Node *node,
762762
* If we have UNKNOWN input (ie, an untyped literal) for any ANYELEMENT
763763
* or ANYARRAY argument, assume it is okay.
764764
*
765+
* If an input is of type ANYARRAY (ie, we know it's an array, but not
766+
* what element type), we will accept it as a match to an argument declared
767+
* ANYARRAY, so long as we don't have to determine an element type ---
768+
* that is, so long as there is no use of ANYELEMENT. This is mostly for
769+
* backwards compatibility with the pre-7.4 behavior of ANYARRAY.
770+
*
765771
* We do not ereport here, but just return FALSE if a rule is violated.
766772
*/
767773
bool
@@ -773,6 +779,7 @@ check_generic_type_consistency(Oid *actual_arg_types,
773779
Oid elem_typeid = InvalidOid;
774780
Oid array_typeid = InvalidOid;
775781
Oid array_typelem;
782+
bool have_anyelement = false;
776783

777784
/*
778785
* Loop through the arguments to see if we have any that are ANYARRAY
@@ -785,6 +792,7 @@ check_generic_type_consistency(Oid *actual_arg_types,
785792

786793
if (declared_arg_types[j] == ANYELEMENTOID)
787794
{
795+
have_anyelement = true;
788796
if (actual_type == UNKNOWNOID)
789797
continue;
790798
if (OidIsValid(elem_typeid) && actual_type != elem_typeid)
@@ -804,6 +812,14 @@ check_generic_type_consistency(Oid *actual_arg_types,
804812
/* Get the element type based on the array type, if we have one */
805813
if (OidIsValid(array_typeid))
806814
{
815+
if (array_typeid == ANYARRAYOID)
816+
{
817+
/* Special case for ANYARRAY input: okay iff no ANYELEMENT */
818+
if (have_anyelement)
819+
return false;
820+
return true;
821+
}
822+
807823
array_typelem = get_element_type(array_typeid);
808824
if (!OidIsValid(array_typelem))
809825
return false; /* should be an array, but isn't */
@@ -875,7 +891,8 @@ enforce_generic_type_consistency(Oid *actual_arg_types,
875891
bool have_unknowns = false;
876892
Oid elem_typeid = InvalidOid;
877893
Oid array_typeid = InvalidOid;
878-
Oid array_typelem = InvalidOid;
894+
Oid array_typelem;
895+
bool have_anyelement = (rettype == ANYELEMENTOID);
879896

880897
/*
881898
* Loop through the arguments to see if we have any that are ANYARRAY
@@ -888,7 +905,7 @@ enforce_generic_type_consistency(Oid *actual_arg_types,
888905

889906
if (declared_arg_types[j] == ANYELEMENTOID)
890907
{
891-
have_generics = true;
908+
have_generics = have_anyelement = true;
892909
if (actual_type == UNKNOWNOID)
893910
{
894911
have_unknowns = true;
@@ -932,12 +949,20 @@ enforce_generic_type_consistency(Oid *actual_arg_types,
932949
/* Get the element type based on the array type, if we have one */
933950
if (OidIsValid(array_typeid))
934951
{
935-
array_typelem = get_element_type(array_typeid);
936-
if (!OidIsValid(array_typelem))
937-
ereport(ERROR,
938-
(errcode(ERRCODE_DATATYPE_MISMATCH),
939-
errmsg("argument declared ANYARRAY is not an array but %s",
940-
format_type_be(array_typeid))));
952+
if (array_typeid == ANYARRAYOID && !have_anyelement)
953+
{
954+
/* Special case for ANYARRAY input: okay iff no ANYELEMENT */
955+
array_typelem = InvalidOid;
956+
}
957+
else
958+
{
959+
array_typelem = get_element_type(array_typeid);
960+
if (!OidIsValid(array_typelem))
961+
ereport(ERROR,
962+
(errcode(ERRCODE_DATATYPE_MISMATCH),
963+
errmsg("argument declared ANYARRAY is not an array but %s",
964+
format_type_be(array_typeid))));
965+
}
941966

942967
if (!OidIsValid(elem_typeid))
943968
{

0 commit comments

Comments
 (0)