diff --git a/src/backend/parser/parse_func.c b/src/backend/parser/parse_func.c
index 2f2f2c7..050779b 100644
*** a/src/backend/parser/parse_func.c
--- b/src/backend/parser/parse_func.c
*************** func_get_detail(List *funcname,
*** 1357,1362 ****
--- 1357,1367 ----
  		 * never supported that historically, so we can insist that people
  		 * write it as a normal cast instead.
  		 *
+ 		 * We also reject the specific case of casting a composite type to
+ 		 * itself (with RELABELTYPE).  That's not really a useful thing to do,
+ 		 * and it would likely produce user complaints about "why does my
+ 		 * table seem to have a column named after itself?"
+ 		 *
  		 * We also reject the specific case of COERCEVIAIO for a composite
  		 * source type and a string-category target type.  This is a case that
  		 * find_coercion_pathway() allows by default, but experience has shown
*************** func_get_detail(List *funcname,
*** 1395,1401 ****
  					switch (cpathtype)
  					{
  						case COERCION_PATH_RELABELTYPE:
! 							iscoercion = true;
  							break;
  						case COERCION_PATH_COERCEVIAIO:
  							if ((sourceType == RECORDOID ||
--- 1400,1411 ----
  					switch (cpathtype)
  					{
  						case COERCION_PATH_RELABELTYPE:
! 							if (sourceType == targetType &&
! 								(sourceType == RECORDOID ||
! 								 ISCOMPLEX(sourceType)))
! 								iscoercion = false;
! 							else
! 								iscoercion = true;
  							break;
  						case COERCION_PATH_COERCEVIAIO:
  							if ((sourceType == RECORDOID ||
*************** make_fn_arguments(ParseState *pstate,
*** 1761,1767 ****
   *	  convenience routine to see if a function name matches a type name
   *
   * Returns the OID of the matching type, or InvalidOid if none.  We ignore
!  * shell types and complex types.
   */
  static Oid
  FuncNameAsType(List *funcname)
--- 1771,1777 ----
   *	  convenience routine to see if a function name matches a type name
   *
   * Returns the OID of the matching type, or InvalidOid if none.  We ignore
!  * shell types, since casting to a shell type would be useless.
   */
  static Oid
  FuncNameAsType(List *funcname)
*************** FuncNameAsType(List *funcname)
*** 1773,1780 ****
  	if (typtup == NULL)
  		return InvalidOid;
  
! 	if (((Form_pg_type) GETSTRUCT(typtup))->typisdefined &&
! 		!OidIsValid(typeTypeRelid(typtup)))
  		result = typeTypeId(typtup);
  	else
  		result = InvalidOid;
--- 1783,1789 ----
  	if (typtup == NULL)
  		return InvalidOid;
  
! 	if (((Form_pg_type) GETSTRUCT(typtup))->typisdefined)
  		result = typeTypeId(typtup);
  	else
  		result = InvalidOid;
