diff --git a/src/backend/catalog/pg_aggregate.c b/src/backend/catalog/pg_aggregate.c
index 0b7face..7d887ea 100644
--- a/src/backend/catalog/pg_aggregate.c
+++ b/src/backend/catalog/pg_aggregate.c
@@ -93,8 +93,6 @@ AggregateCreate(const char *aggName,
 	Oid			mfinalfn = InvalidOid;	/* can be omitted */
 	Oid			sortop = InvalidOid;	/* can be omitted */
 	Oid		   *aggArgTypes = parameterTypes->values;
-	bool		hasPolyArg;
-	bool		hasInternalArg;
 	bool		mtransIsStrict = false;
 	Oid			rettype;
 	Oid			finaltype;
@@ -103,6 +101,7 @@ AggregateCreate(const char *aggName,
 	int			nargs_finalfn;
 	Oid			procOid;
 	TupleDesc	tupDesc;
+	char	   *detailmsg;
 	int			i;
 	ObjectAddress myself,
 				referenced;
@@ -131,36 +130,33 @@ AggregateCreate(const char *aggName,
 							   FUNC_MAX_ARGS - 1,
 							   FUNC_MAX_ARGS - 1)));
 
-	/* check for polymorphic and INTERNAL arguments */
-	hasPolyArg = false;
-	hasInternalArg = false;
-	for (i = 0; i < numArgs; i++)
-	{
-		if (IsPolymorphicType(aggArgTypes[i]))
-			hasPolyArg = true;
-		else if (aggArgTypes[i] == INTERNALOID)
-			hasInternalArg = true;
-	}
-
 	/*
 	 * If transtype is polymorphic, must have polymorphic argument also; else
 	 * we will have no way to deduce the actual transtype.
 	 */
-	if (IsPolymorphicType(aggTransType) && !hasPolyArg)
+	detailmsg = check_valid_polymorphic_signature(aggTransType,
+												  aggArgTypes,
+												  numArgs);
+	if (detailmsg)
 		ereport(ERROR,
 				(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
 				 errmsg("cannot determine transition data type"),
-				 errdetail("An aggregate using a polymorphic transition type must have at least one polymorphic argument.")));
+				 errdetail_internal("%s", detailmsg)));
 
 	/*
 	 * Likewise for moving-aggregate transtype, if any
 	 */
-	if (OidIsValid(aggmTransType) &&
-		IsPolymorphicType(aggmTransType) && !hasPolyArg)
-		ereport(ERROR,
-				(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
-				 errmsg("cannot determine transition data type"),
-				 errdetail("An aggregate using a polymorphic transition type must have at least one polymorphic argument.")));
+	if (OidIsValid(aggmTransType))
+	{
+		detailmsg = check_valid_polymorphic_signature(aggmTransType,
+													  aggArgTypes,
+													  numArgs);
+		if (detailmsg)
+			ereport(ERROR,
+					(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
+					 errmsg("cannot determine transition data type"),
+					 errdetail_internal("%s", detailmsg)));
+	}
 
 	/*
 	 * An ordered-set aggregate that is VARIADIC must be VARIADIC ANY.  In
@@ -492,12 +488,14 @@ AggregateCreate(const char *aggName,
 	 * that itself violates the rule against polymorphic result with no
 	 * polymorphic input.)
 	 */
-	if (IsPolymorphicType(finaltype) && !hasPolyArg)
+	detailmsg = check_valid_polymorphic_signature(finaltype,
+												  aggArgTypes,
+												  numArgs);
+	if (detailmsg)
 		ereport(ERROR,
 				(errcode(ERRCODE_DATATYPE_MISMATCH),
 				 errmsg("cannot determine result data type"),
-				 errdetail("An aggregate returning a polymorphic type "
-						   "must have at least one polymorphic argument.")));
+				 errdetail_internal("%s", detailmsg)));
 
 	/*
 	 * Also, the return type can't be INTERNAL unless there's at least one
@@ -505,11 +503,14 @@ AggregateCreate(const char *aggName,
 	 * for regular functions, but at the level of aggregates.  We must test
 	 * this explicitly because we allow INTERNAL as the transtype.
 	 */
-	if (finaltype == INTERNALOID && !hasInternalArg)
+	detailmsg = check_valid_internal_signature(finaltype,
+											   aggArgTypes,
+											   numArgs);
+	if (detailmsg)
 		ereport(ERROR,
 				(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
 				 errmsg("unsafe use of pseudo-type \"internal\""),
-				 errdetail("A function returning \"internal\" must have at least one \"internal\" argument.")));
+				 errdetail_internal("%s", detailmsg)));
 
 	/*
 	 * If a moving-aggregate implementation is supplied, look up its finalfn
diff --git a/src/backend/catalog/pg_proc.c b/src/backend/catalog/pg_proc.c
index 423fd79..0cac936 100644
--- a/src/backend/catalog/pg_proc.c
+++ b/src/backend/catalog/pg_proc.c
@@ -32,6 +32,7 @@
 #include "mb/pg_wchar.h"
 #include "miscadmin.h"
 #include "nodes/nodeFuncs.h"
+#include "parser/parse_coerce.h"
 #include "parser/parse_type.h"
 #include "tcop/pquery.h"
 #include "tcop/tcopprot.h"
@@ -97,12 +98,6 @@ ProcedureCreate(const char *procedureName,
 	int			allParamCount;
 	Oid		   *allParams;
 	char	   *paramModes = NULL;
-	bool		genericInParam = false;
-	bool		genericOutParam = false;
-	bool		anyrangeInParam = false;
-	bool		anyrangeOutParam = false;
-	bool		internalInParam = false;
-	bool		internalOutParam = false;
 	Oid			variadicType = InvalidOid;
 	Acl		   *proacl = NULL;
 	Relation	rel;
@@ -116,6 +111,7 @@ ProcedureCreate(const char *procedureName,
 	bool		is_update;
 	ObjectAddress myself,
 				referenced;
+	char	   *detailmsg;
 	int			i;
 	Oid			trfid;
 
@@ -178,29 +174,34 @@ ProcedureCreate(const char *procedureName,
 	}
 
 	/*
-	 * Detect whether we have polymorphic or INTERNAL arguments.  The first
-	 * loop checks input arguments, the second output arguments.
+	 * Do not allow polymorphic return type unless there is a polymorphic
+	 * input argument that we can use to deduce the actual return type.
 	 */
-	for (i = 0; i < parameterCount; i++)
-	{
-		switch (parameterTypes->values[i])
-		{
-			case ANYARRAYOID:
-			case ANYELEMENTOID:
-			case ANYNONARRAYOID:
-			case ANYENUMOID:
-				genericInParam = true;
-				break;
-			case ANYRANGEOID:
-				genericInParam = true;
-				anyrangeInParam = true;
-				break;
-			case INTERNALOID:
-				internalInParam = true;
-				break;
-		}
-	}
+	detailmsg = check_valid_polymorphic_signature(returnType,
+												  parameterTypes->values,
+												  parameterCount);
+	if (detailmsg)
+		ereport(ERROR,
+				(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
+				 errmsg("cannot determine result data type"),
+				 errdetail_internal("%s", detailmsg)));
 
+	/*
+	 * Also, do not allow return type INTERNAL unless at least one input
+	 * argument is INTERNAL.
+	 */
+	detailmsg = check_valid_internal_signature(returnType,
+											   parameterTypes->values,
+											   parameterCount);
+	if (detailmsg)
+		ereport(ERROR,
+				(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
+				 errmsg("unsafe use of pseudo-type \"internal\""),
+				 errdetail_internal("%s", detailmsg)));
+
+	/*
+	 * Apply the same tests to any OUT arguments.
+	 */
 	if (allParameterTypes != PointerGetDatum(NULL))
 	{
 		for (i = 0; i < allParamCount; i++)
@@ -210,52 +211,26 @@ ProcedureCreate(const char *procedureName,
 				paramModes[i] == PROARGMODE_VARIADIC)
 				continue;		/* ignore input-only params */
 
-			switch (allParams[i])
-			{
-				case ANYARRAYOID:
-				case ANYELEMENTOID:
-				case ANYNONARRAYOID:
-				case ANYENUMOID:
-					genericOutParam = true;
-					break;
-				case ANYRANGEOID:
-					genericOutParam = true;
-					anyrangeOutParam = true;
-					break;
-				case INTERNALOID:
-					internalOutParam = true;
-					break;
-			}
+			detailmsg = check_valid_polymorphic_signature(allParams[i],
+														  parameterTypes->values,
+														  parameterCount);
+			if (detailmsg)
+				ereport(ERROR,
+						(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
+						 errmsg("cannot determine result data type"),
+						 errdetail_internal("%s", detailmsg)));
+			detailmsg = check_valid_internal_signature(allParams[i],
+													   parameterTypes->values,
+													   parameterCount);
+			if (detailmsg)
+				ereport(ERROR,
+						(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
+						 errmsg("unsafe use of pseudo-type \"internal\""),
+						 errdetail_internal("%s", detailmsg)));
 		}
 	}
 
-	/*
-	 * Do not allow polymorphic return type unless at least one input argument
-	 * is polymorphic.  ANYRANGE return type is even stricter: must have an
-	 * ANYRANGE input (since we can't deduce the specific range type from
-	 * ANYELEMENT).  Also, do not allow return type INTERNAL unless at least
-	 * one input argument is INTERNAL.
-	 */
-	if ((IsPolymorphicType(returnType) || genericOutParam)
-		&& !genericInParam)
-		ereport(ERROR,
-				(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
-				 errmsg("cannot determine result data type"),
-				 errdetail("A function returning a polymorphic type must have at least one polymorphic argument.")));
-
-	if ((returnType == ANYRANGEOID || anyrangeOutParam) &&
-		!anyrangeInParam)
-		ereport(ERROR,
-				(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
-				 errmsg("cannot determine result data type"),
-				 errdetail("A function returning \"anyrange\" must have at least one \"anyrange\" argument.")));
-
-	if ((returnType == INTERNALOID || internalOutParam) && !internalInParam)
-		ereport(ERROR,
-				(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
-				 errmsg("unsafe use of pseudo-type \"internal\""),
-				 errdetail("A function returning \"internal\" must have at least one \"internal\" argument.")));
-
+	/* Identify variadic argument type, if any */
 	if (paramModes != NULL)
 	{
 		/*
diff --git a/src/backend/parser/parse_coerce.c b/src/backend/parser/parse_coerce.c
index 4a2b463..7a9b303 100644
--- a/src/backend/parser/parse_coerce.c
+++ b/src/backend/parser/parse_coerce.c
@@ -1966,6 +1966,77 @@ enforce_generic_type_consistency(const Oid *actual_arg_types,
 	return rettype;
 }
 
+/*
+ * check_valid_polymorphic_signature()
+ *		Is a proposed function signature valid per polymorphism rules?
+ *
+ * Returns NULL if the signature is valid (either ret_type is not polymorphic,
+ * or it can be deduced from the given declared argument types).  Otherwise,
+ * returns a palloc'd, already translated errdetail string saying why not.
+ */
+char *
+check_valid_polymorphic_signature(Oid ret_type,
+								  const Oid *declared_arg_types,
+								  int nargs)
+{
+	if (ret_type == ANYRANGEOID)
+	{
+		/*
+		 * ANYRANGE requires an ANYRANGE input, else we can't tell which of
+		 * several range types with the same element type to use.
+		 */
+		for (int i = 0; i < nargs; i++)
+		{
+			if (declared_arg_types[i] == ret_type)
+				return NULL;	/* OK */
+		}
+		return psprintf(_("A result of type %s requires at least one input of type %s."),
+						format_type_be(ret_type), format_type_be(ret_type));
+	}
+	else if (IsPolymorphicType(ret_type))
+	{
+		/* Otherwise, any polymorphic type can be deduced from any other */
+		for (int i = 0; i < nargs; i++)
+		{
+			if (IsPolymorphicType(declared_arg_types[i]))
+				return NULL;	/* OK */
+		}
+		return psprintf(_("A result of type %s requires at least one input of type anyelement, anyarray, anynonarray, anyenum, or anyrange."),
+						format_type_be(ret_type));
+	}
+	else
+		return NULL;			/* OK, ret_type is not polymorphic */
+}
+
+/*
+ * check_valid_internal_signature()
+ *		Is a proposed function signature valid per INTERNAL safety rules?
+ *
+ * Returns NULL if OK, or a suitable error message if ret_type is INTERNAL but
+ * none of the declared arg types are.  (It's unsafe to create such a function
+ * since it would allow invocation of INTERNAL-consuming functions directly
+ * from SQL.)  It's overkill to return the error detail message, since there
+ * is only one possibility, but we do it like this to keep the API similar to
+ * check_valid_polymorphic_signature().
+ */
+char *
+check_valid_internal_signature(Oid ret_type,
+							   const Oid *declared_arg_types,
+							   int nargs)
+{
+	if (ret_type == INTERNALOID)
+	{
+		for (int i = 0; i < nargs; i++)
+		{
+			if (declared_arg_types[i] == ret_type)
+				return NULL;	/* OK */
+		}
+		return pstrdup(_("A result of type internal requires at least one input of type internal."));
+	}
+	else
+		return NULL;			/* OK, ret_type is not INTERNAL */
+}
+
 
 /* TypeCategory()
  *		Assign a category to the specified type OID.
diff --git a/src/include/parser/parse_coerce.h b/src/include/parser/parse_coerce.h
index ff9219d..8686eaa 100644
--- a/src/include/parser/parse_coerce.h
+++ b/src/include/parser/parse_coerce.h
@@ -80,6 +80,13 @@ extern Oid	enforce_generic_type_consistency(const Oid *actual_arg_types,
 											 Oid rettype,
 											 bool allow_poly);
 
+extern char *check_valid_polymorphic_signature(Oid ret_type,
+											   const Oid *declared_arg_types,
+											   int nargs);
+extern char *check_valid_internal_signature(Oid ret_type,
+											const Oid *declared_arg_types,
+											int nargs);
+
 extern CoercionPathType find_coercion_pathway(Oid targetTypeId,
 											  Oid sourceTypeId,
 											  CoercionContext ccontext,
diff --git a/src/test/regress/expected/polymorphism.out b/src/test/regress/expected/polymorphism.out
index 986417a..1573753 100644
--- a/src/test/regress/expected/polymorphism.out
+++ b/src/test/regress/expected/polymorphism.out
@@ -81,7 +81,7 @@ CREATE AGGREGATE myaggp01a(*) (SFUNC = stfnp, STYPE = int4[],
 CREATE AGGREGATE myaggp02a(*) (SFUNC = stfnp, STYPE = anyarray,
   FINALFUNC = ffp, INITCOND = '{}');
 ERROR:  cannot determine transition data type
-DETAIL:  An aggregate using a polymorphic transition type must have at least one polymorphic argument.
+DETAIL:  A result of type anyarray requires at least one input of type anyelement, anyarray, anynonarray, anyenum, or anyrange.
 --     N    P
 -- should CREATE
 CREATE AGGREGATE myaggp03a(*) (SFUNC = stfp, STYPE = int4[],
@@ -93,11 +93,11 @@ CREATE AGGREGATE myaggp03b(*) (SFUNC = stfp, STYPE = int4[],
 CREATE AGGREGATE myaggp04a(*) (SFUNC = stfp, STYPE = anyarray,
   FINALFUNC = ffp, INITCOND = '{}');
 ERROR:  cannot determine transition data type
-DETAIL:  An aggregate using a polymorphic transition type must have at least one polymorphic argument.
+DETAIL:  A result of type anyarray requires at least one input of type anyelement, anyarray, anynonarray, anyenum, or anyrange.
 CREATE AGGREGATE myaggp04b(*) (SFUNC = stfp, STYPE = anyarray,
   INITCOND = '{}');
 ERROR:  cannot determine transition data type
-DETAIL:  An aggregate using a polymorphic transition type must have at least one polymorphic argument.
+DETAIL:  A result of type anyarray requires at least one input of type anyelement, anyarray, anynonarray, anyenum, or anyrange.
 --    Case2 (R = P) && ((B = P) || (B = N))
 --    -------------------------------------
 --    S    tf1      B    tf2
@@ -152,13 +152,13 @@ ERROR:  function tfp(integer[], anyelement) does not exist
 CREATE AGGREGATE myaggp13a(BASETYPE = int, SFUNC = tfnp, STYPE = anyarray,
   FINALFUNC = ffp, INITCOND = '{}');
 ERROR:  cannot determine transition data type
-DETAIL:  An aggregate using a polymorphic transition type must have at least one polymorphic argument.
+DETAIL:  A result of type anyarray requires at least one input of type anyelement, anyarray, anynonarray, anyenum, or anyrange.
 --    P    N        N    P
 -- should ERROR: tf2p(anyarray, int) not matched by tf2p(int[],anyelement)
 CREATE AGGREGATE myaggp14a(BASETYPE = int, SFUNC = tf2p, STYPE = anyarray,
   FINALFUNC = ffp, INITCOND = '{}');
 ERROR:  cannot determine transition data type
-DETAIL:  An aggregate using a polymorphic transition type must have at least one polymorphic argument.
+DETAIL:  A result of type anyarray requires at least one input of type anyelement, anyarray, anynonarray, anyenum, or anyrange.
 --    P    N        P    N
 -- should ERROR: tfnp(anyarray, anyelement) not matched by tfnp(int[],int)
 CREATE AGGREGATE myaggp15a(BASETYPE = anyelement, SFUNC = tfnp,
@@ -174,21 +174,21 @@ ERROR:  function tf2p(anyarray, anyelement) does not exist
 CREATE AGGREGATE myaggp17a(BASETYPE = int, SFUNC = tf1p, STYPE = anyarray,
   FINALFUNC = ffp, INITCOND = '{}');
 ERROR:  cannot determine transition data type
-DETAIL:  An aggregate using a polymorphic transition type must have at least one polymorphic argument.
+DETAIL:  A result of type anyarray requires at least one input of type anyelement, anyarray, anynonarray, anyenum, or anyrange.
 CREATE AGGREGATE myaggp17b(BASETYPE = int, SFUNC = tf1p, STYPE = anyarray,
   INITCOND = '{}');
 ERROR:  cannot determine transition data type
-DETAIL:  An aggregate using a polymorphic transition type must have at least one polymorphic argument.
+DETAIL:  A result of type anyarray requires at least one input of type anyelement, anyarray, anynonarray, anyenum, or anyrange.
 --    P    P        N    P
 -- should ERROR: tfp(anyarray, int) not matched by tfp(anyarray, anyelement)
 CREATE AGGREGATE myaggp18a(BASETYPE = int, SFUNC = tfp, STYPE = anyarray,
   FINALFUNC = ffp, INITCOND = '{}');
 ERROR:  cannot determine transition data type
-DETAIL:  An aggregate using a polymorphic transition type must have at least one polymorphic argument.
+DETAIL:  A result of type anyarray requires at least one input of type anyelement, anyarray, anynonarray, anyenum, or anyrange.
 CREATE AGGREGATE myaggp18b(BASETYPE = int, SFUNC = tfp, STYPE = anyarray,
   INITCOND = '{}');
 ERROR:  cannot determine transition data type
-DETAIL:  An aggregate using a polymorphic transition type must have at least one polymorphic argument.
+DETAIL:  A result of type anyarray requires at least one input of type anyelement, anyarray, anynonarray, anyenum, or anyrange.
 --    P    P        P    N
 -- should ERROR: tf1p(anyarray, anyelement) not matched by tf1p(anyarray, int)
 CREATE AGGREGATE myaggp19a(BASETYPE = anyelement, SFUNC = tf1p,
@@ -218,11 +218,11 @@ CREATE AGGREGATE myaggn01b(*) (SFUNC = stfnp, STYPE = int4[],
 CREATE AGGREGATE myaggn02a(*) (SFUNC = stfnp, STYPE = anyarray,
   FINALFUNC = ffnp, INITCOND = '{}');
 ERROR:  cannot determine transition data type
-DETAIL:  An aggregate using a polymorphic transition type must have at least one polymorphic argument.
+DETAIL:  A result of type anyarray requires at least one input of type anyelement, anyarray, anynonarray, anyenum, or anyrange.
 CREATE AGGREGATE myaggn02b(*) (SFUNC = stfnp, STYPE = anyarray,
   INITCOND = '{}');
 ERROR:  cannot determine transition data type
-DETAIL:  An aggregate using a polymorphic transition type must have at least one polymorphic argument.
+DETAIL:  A result of type anyarray requires at least one input of type anyelement, anyarray, anynonarray, anyenum, or anyrange.
 --     N    P
 -- should CREATE
 CREATE AGGREGATE myaggn03a(*) (SFUNC = stfp, STYPE = int4[],
@@ -232,7 +232,7 @@ CREATE AGGREGATE myaggn03a(*) (SFUNC = stfp, STYPE = int4[],
 CREATE AGGREGATE myaggn04a(*) (SFUNC = stfp, STYPE = anyarray,
   FINALFUNC = ffnp, INITCOND = '{}');
 ERROR:  cannot determine transition data type
-DETAIL:  An aggregate using a polymorphic transition type must have at least one polymorphic argument.
+DETAIL:  A result of type anyarray requires at least one input of type anyelement, anyarray, anynonarray, anyenum, or anyrange.
 --    Case4 (R = N) && ((B = P) || (B = N))
 --    -------------------------------------
 --    S    tf1      B    tf2
@@ -286,21 +286,21 @@ ERROR:  function tfp(integer[], anyelement) does not exist
 CREATE AGGREGATE myaggn13a(BASETYPE = int, SFUNC = tfnp, STYPE = anyarray,
   FINALFUNC = ffnp, INITCOND = '{}');
 ERROR:  cannot determine transition data type
-DETAIL:  An aggregate using a polymorphic transition type must have at least one polymorphic argument.
+DETAIL:  A result of type anyarray requires at least one input of type anyelement, anyarray, anynonarray, anyenum, or anyrange.
 CREATE AGGREGATE myaggn13b(BASETYPE = int, SFUNC = tfnp, STYPE = anyarray,
   INITCOND = '{}');
 ERROR:  cannot determine transition data type
-DETAIL:  An aggregate using a polymorphic transition type must have at least one polymorphic argument.
+DETAIL:  A result of type anyarray requires at least one input of type anyelement, anyarray, anynonarray, anyenum, or anyrange.
 --    P    N        N    P
 -- should ERROR: tf2p(anyarray, int) not matched by tf2p(int[],anyelement)
 CREATE AGGREGATE myaggn14a(BASETYPE = int, SFUNC = tf2p, STYPE = anyarray,
   FINALFUNC = ffnp, INITCOND = '{}');
 ERROR:  cannot determine transition data type
-DETAIL:  An aggregate using a polymorphic transition type must have at least one polymorphic argument.
+DETAIL:  A result of type anyarray requires at least one input of type anyelement, anyarray, anynonarray, anyenum, or anyrange.
 CREATE AGGREGATE myaggn14b(BASETYPE = int, SFUNC = tf2p, STYPE = anyarray,
   INITCOND = '{}');
 ERROR:  cannot determine transition data type
-DETAIL:  An aggregate using a polymorphic transition type must have at least one polymorphic argument.
+DETAIL:  A result of type anyarray requires at least one input of type anyelement, anyarray, anynonarray, anyenum, or anyrange.
 --    P    N        P    N
 -- should ERROR: tfnp(anyarray, anyelement) not matched by tfnp(int[],int)
 CREATE AGGREGATE myaggn15a(BASETYPE = anyelement, SFUNC = tfnp,
@@ -322,13 +322,13 @@ ERROR:  function tf2p(anyarray, anyelement) does not exist
 CREATE AGGREGATE myaggn17a(BASETYPE = int, SFUNC = tf1p, STYPE = anyarray,
   FINALFUNC = ffnp, INITCOND = '{}');
 ERROR:  cannot determine transition data type
-DETAIL:  An aggregate using a polymorphic transition type must have at least one polymorphic argument.
+DETAIL:  A result of type anyarray requires at least one input of type anyelement, anyarray, anynonarray, anyenum, or anyrange.
 --    P    P        N    P
 -- should ERROR: tfp(anyarray, int) not matched by tfp(anyarray, anyelement)
 CREATE AGGREGATE myaggn18a(BASETYPE = int, SFUNC = tfp, STYPE = anyarray,
   FINALFUNC = ffnp, INITCOND = '{}');
 ERROR:  cannot determine transition data type
-DETAIL:  An aggregate using a polymorphic transition type must have at least one polymorphic argument.
+DETAIL:  A result of type anyarray requires at least one input of type anyelement, anyarray, anynonarray, anyenum, or anyrange.
 --    P    P        P    N
 -- should ERROR: tf1p(anyarray, anyelement) not matched by tf1p(anyarray, int)
 CREATE AGGREGATE myaggn19a(BASETYPE = anyelement, SFUNC = tf1p,
diff --git a/src/test/regress/expected/rangefuncs.out b/src/test/regress/expected/rangefuncs.out
index a70060b..cdfc43e 100644
--- a/src/test/regress/expected/rangefuncs.out
+++ b/src/test/regress/expected/rangefuncs.out
@@ -1556,7 +1556,7 @@ DROP FUNCTION dup(anyelement);
 CREATE FUNCTION bad (f1 int, out f2 anyelement, out f3 anyarray)
 AS 'select $1, array[$1,$1]' LANGUAGE sql;
 ERROR:  cannot determine result data type
-DETAIL:  A function returning a polymorphic type must have at least one polymorphic argument.
+DETAIL:  A result of type anyelement requires at least one input of type anyelement, anyarray, anynonarray, anyenum, or anyrange.
 --
 -- table functions
 --
diff --git a/src/test/regress/expected/rangetypes.out b/src/test/regress/expected/rangetypes.out
index 348235a..a28741a 100644
--- a/src/test/regress/expected/rangetypes.out
+++ b/src/test/regress/expected/rangetypes.out
@@ -1371,12 +1371,12 @@ drop function anyarray_anyrange_func(anyarray, anyrange);
 create function bogus_func(anyelement)
   returns anyrange as 'select int4range(1,10)' language sql;
 ERROR:  cannot determine result data type
-DETAIL:  A function returning "anyrange" must have at least one "anyrange" argument.
+DETAIL:  A result of type anyrange requires at least one input of type anyrange.
 -- should fail
 create function bogus_func(int)
   returns anyrange as 'select int4range(1,10)' language sql;
 ERROR:  cannot determine result data type
-DETAIL:  A function returning a polymorphic type must have at least one polymorphic argument.
+DETAIL:  A result of type anyrange requires at least one input of type anyrange.
 create function range_add_bounds(anyrange)
   returns anyelement as 'select lower($1) + upper($1)' language sql;
 select range_add_bounds(int4range(1, 17));
@@ -1521,14 +1521,14 @@ select * from table_succeed(int4range(1,11));
 create function outparam_fail(i anyelement, out r anyrange, out t text)
   as $$ select '[1,10]', 'foo' $$ language sql;
 ERROR:  cannot determine result data type
-DETAIL:  A function returning "anyrange" must have at least one "anyrange" argument.
+DETAIL:  A result of type anyrange requires at least one input of type anyrange.
 --should fail
 create function inoutparam_fail(inout i anyelement, out r anyrange)
   as $$ select $1, '[1,10]' $$ language sql;
 ERROR:  cannot determine result data type
-DETAIL:  A function returning "anyrange" must have at least one "anyrange" argument.
+DETAIL:  A result of type anyrange requires at least one input of type anyrange.
 --should fail
 create function table_fail(i anyelement) returns table(i anyelement, r anyrange)
   as $$ select $1, '[1,10]' $$ language sql;
 ERROR:  cannot determine result data type
-DETAIL:  A function returning "anyrange" must have at least one "anyrange" argument.
+DETAIL:  A result of type anyrange requires at least one input of type anyrange.
