diff --git a/src/backend/optimizer/prep/preptlist.c b/src/backend/optimizer/prep/preptlist.c
index afc733f..277ca8b 100644
*** a/src/backend/optimizer/prep/preptlist.c
--- b/src/backend/optimizer/prep/preptlist.c
*************** expand_targetlist(List *tlist, int comma
*** 306,314 ****
  						new_expr = coerce_to_domain(new_expr,
  													InvalidOid, -1,
  													atttype,
  													COERCE_IMPLICIT_CAST,
  													-1,
- 													false,
  													false);
  					}
  					else
--- 306,314 ----
  						new_expr = coerce_to_domain(new_expr,
  													InvalidOid, -1,
  													atttype,
+ 													COERCION_IMPLICIT,
  													COERCE_IMPLICIT_CAST,
  													-1,
  													false);
  					}
  					else
diff --git a/src/backend/parser/parse_coerce.c b/src/backend/parser/parse_coerce.c
index 0bc7dba..c406cea 100644
*** a/src/backend/parser/parse_coerce.c
--- b/src/backend/parser/parse_coerce.c
***************
*** 34,48 ****
  
  static Node *coerce_type_typmod(Node *node,
  				   Oid targetTypeId, int32 targetTypMod,
! 				   CoercionForm cformat, int location,
! 				   bool isExplicit, bool hideInputCoercion);
  static void hide_coercion_node(Node *node);
  static Node *build_coercion_expression(Node *node,
  						  CoercionPathType pathtype,
  						  Oid funcId,
  						  Oid targetTypeId, int32 targetTypMod,
! 						  CoercionForm cformat, int location,
! 						  bool isExplicit);
  static Node *coerce_record_to_complex(ParseState *pstate, Node *node,
  						 Oid targetTypeId,
  						 CoercionContext ccontext,
--- 34,49 ----
  
  static Node *coerce_type_typmod(Node *node,
  				   Oid targetTypeId, int32 targetTypMod,
! 				   CoercionContext ccontext, CoercionForm cformat,
! 				   int location,
! 				   bool hideInputCoercion);
  static void hide_coercion_node(Node *node);
  static Node *build_coercion_expression(Node *node,
  						  CoercionPathType pathtype,
  						  Oid funcId,
  						  Oid targetTypeId, int32 targetTypMod,
! 						  CoercionContext ccontext, CoercionForm cformat,
! 						  int location);
  static Node *coerce_record_to_complex(ParseState *pstate, Node *node,
  						 Oid targetTypeId,
  						 CoercionContext ccontext,
*************** coerce_to_target_type(ParseState *pstate
*** 110,117 ****
  	 */
  	result = coerce_type_typmod(result,
  								targettype, targettypmod,
! 								cformat, location,
! 								(cformat != COERCE_IMPLICIT_CAST),
  								(result != expr && !IsA(result, Const)));
  
  	if (expr != origexpr)
--- 111,117 ----
  	 */
  	result = coerce_type_typmod(result,
  								targettype, targettypmod,
! 								ccontext, cformat, location,
  								(result != expr && !IsA(result, Const)));
  
  	if (expr != origexpr)
*************** coerce_type(ParseState *pstate, Node *no
*** 355,361 ****
  			result = coerce_to_domain(result,
  									  baseTypeId, baseTypeMod,
  									  targetTypeId,
! 									  cformat, location, false, false);
  
  		ReleaseSysCache(baseType);
  
--- 355,362 ----
  			result = coerce_to_domain(result,
  									  baseTypeId, baseTypeMod,
  									  targetTypeId,
! 									  ccontext, cformat, location,
! 									  false);
  
  		ReleaseSysCache(baseType);
  
*************** coerce_type(ParseState *pstate, Node *no
*** 417,436 ****
  
  			result = build_coercion_expression(node, pathtype, funcId,
  											   baseTypeId, baseTypeMod,
! 											   cformat, location,
! 											   (cformat != COERCE_IMPLICIT_CAST));
  
  			/*
  			 * If domain, coerce to the domain type and relabel with domain
! 			 * type ID.  We can skip the internal length-coercion step if the
! 			 * selected coercion function was a type-and-length coercion.
  			 */
  			if (targetTypeId != baseTypeId)
  				result = coerce_to_domain(result, baseTypeId, baseTypeMod,
  										  targetTypeId,
! 										  cformat, location, true,
! 										  exprIsLengthCoercion(result,
! 															   NULL));
  		}
  		else
  		{
--- 418,434 ----
  
  			result = build_coercion_expression(node, pathtype, funcId,
  											   baseTypeId, baseTypeMod,
! 											   ccontext, cformat, location);
  
  			/*
  			 * If domain, coerce to the domain type and relabel with domain
! 			 * type ID, hiding the previous coercion node.
  			 */
  			if (targetTypeId != baseTypeId)
  				result = coerce_to_domain(result, baseTypeId, baseTypeMod,
  										  targetTypeId,
! 										  ccontext, cformat, location,
! 										  true);
  		}
  		else
  		{
*************** coerce_type(ParseState *pstate, Node *no
*** 444,450 ****
  			 * then we won't need a RelabelType node.
  			 */
  			result = coerce_to_domain(node, InvalidOid, -1, targetTypeId,
! 									  cformat, location, false, false);
  			if (result == node)
  			{
  				/*
--- 442,449 ----
  			 * then we won't need a RelabelType node.
  			 */
  			result = coerce_to_domain(node, InvalidOid, -1, targetTypeId,
! 									  ccontext, cformat, location,
! 									  false);
  			if (result == node)
  			{
  				/*
*************** can_coerce_type(int nargs, Oid *input_ty
*** 636,654 ****
   * 'baseTypeMod': base type typmod of domain, if known (pass -1 if caller
   *		has not bothered to look this up)
   * 'typeId': target type to coerce to
!  * 'cformat': coercion format
   * 'location': coercion request location
   * 'hideInputCoercion': if true, hide the input coercion under this one.
-  * 'lengthCoercionDone': if true, caller already accounted for length,
-  *		ie the input is already of baseTypMod as well as baseTypeId.
   *
   * If the target type isn't a domain, the given 'arg' is returned as-is.
   */
  Node *
  coerce_to_domain(Node *arg, Oid baseTypeId, int32 baseTypeMod, Oid typeId,
! 				 CoercionForm cformat, int location,
! 				 bool hideInputCoercion,
! 				 bool lengthCoercionDone)
  {
  	CoerceToDomain *result;
  
--- 635,651 ----
   * 'baseTypeMod': base type typmod of domain, if known (pass -1 if caller
   *		has not bothered to look this up)
   * 'typeId': target type to coerce to
!  * 'ccontext': context indicator to control coercions
!  * 'cformat': coercion display format
   * 'location': coercion request location
   * 'hideInputCoercion': if true, hide the input coercion under this one.
   *
   * If the target type isn't a domain, the given 'arg' is returned as-is.
   */
  Node *
  coerce_to_domain(Node *arg, Oid baseTypeId, int32 baseTypeMod, Oid typeId,
! 				 CoercionContext ccontext, CoercionForm cformat, int location,
! 				 bool hideInputCoercion)
  {
  	CoerceToDomain *result;
  
*************** coerce_to_domain(Node *arg, Oid baseType
*** 677,690 ****
  	 * would be safe to do anyway, without lots of knowledge about what the
  	 * base type thinks the typmod means.
  	 */
! 	if (!lengthCoercionDone)
! 	{
! 		if (baseTypeMod >= 0)
! 			arg = coerce_type_typmod(arg, baseTypeId, baseTypeMod,
! 									 COERCE_IMPLICIT_CAST, location,
! 									 (cformat != COERCE_IMPLICIT_CAST),
! 									 false);
! 	}
  
  	/*
  	 * Now build the domain coercion node.  This represents run-time checking
--- 674,682 ----
  	 * would be safe to do anyway, without lots of knowledge about what the
  	 * base type thinks the typmod means.
  	 */
! 	arg = coerce_type_typmod(arg, baseTypeId, baseTypeMod,
! 							 ccontext, COERCE_IMPLICIT_CAST, location,
! 							 false);
  
  	/*
  	 * Now build the domain coercion node.  This represents run-time checking
*************** coerce_to_domain(Node *arg, Oid baseType
*** 714,724 ****
   * The caller must have already ensured that the value is of the correct
   * type, typically by applying coerce_type.
   *
!  * cformat determines the display properties of the generated node (if any),
!  * while isExplicit may affect semantics.  If hideInputCoercion is true
!  * *and* we generate a node, the input node is forced to IMPLICIT display
!  * form, so that only the typmod coercion node will be visible when
!  * displaying the expression.
   *
   * NOTE: this does not need to work on domain types, because any typmod
   * coercion for a domain is considered to be part of the type coercion
--- 706,719 ----
   * The caller must have already ensured that the value is of the correct
   * type, typically by applying coerce_type.
   *
!  * ccontext may affect semantics, depending on whether the length coercion
!  * function pays attention to the isExplicit flag it's passed.
!  *
!  * cformat determines the display properties of the generated node (if any).
!  *
!  * If hideInputCoercion is true *and* we generate a node, the input node is
!  * forced to IMPLICIT display form, so that only the typmod coercion node will
!  * be visible when displaying the expression.
   *
   * NOTE: this does not need to work on domain types, because any typmod
   * coercion for a domain is considered to be part of the type coercion
*************** coerce_to_domain(Node *arg, Oid baseType
*** 726,733 ****
   */
  static Node *
  coerce_type_typmod(Node *node, Oid targetTypeId, int32 targetTypMod,
! 				   CoercionForm cformat, int location,
! 				   bool isExplicit, bool hideInputCoercion)
  {
  	CoercionPathType pathtype;
  	Oid			funcId;
--- 721,729 ----
   */
  static Node *
  coerce_type_typmod(Node *node, Oid targetTypeId, int32 targetTypMod,
! 				   CoercionContext ccontext, CoercionForm cformat,
! 				   int location,
! 				   bool hideInputCoercion)
  {
  	CoercionPathType pathtype;
  	Oid			funcId;
*************** coerce_type_typmod(Node *node, Oid targe
*** 749,756 ****
  
  		node = build_coercion_expression(node, pathtype, funcId,
  										 targetTypeId, targetTypMod,
! 										 cformat, location,
! 										 isExplicit);
  	}
  
  	return node;
--- 745,751 ----
  
  		node = build_coercion_expression(node, pathtype, funcId,
  										 targetTypeId, targetTypMod,
! 										 ccontext, cformat, location);
  	}
  
  	return node;
*************** build_coercion_expression(Node *node,
*** 799,806 ****
  						  CoercionPathType pathtype,
  						  Oid funcId,
  						  Oid targetTypeId, int32 targetTypMod,
! 						  CoercionForm cformat, int location,
! 						  bool isExplicit)
  {
  	int			nargs = 0;
  
--- 794,801 ----
  						  CoercionPathType pathtype,
  						  Oid funcId,
  						  Oid targetTypeId, int32 targetTypMod,
! 						  CoercionContext ccontext, CoercionForm cformat,
! 						  int location)
  {
  	int			nargs = 0;
  
*************** build_coercion_expression(Node *node,
*** 865,871 ****
  							 -1,
  							 InvalidOid,
  							 sizeof(bool),
! 							 BoolGetDatum(isExplicit),
  							 false,
  							 true);
  
--- 860,866 ----
  							 -1,
  							 InvalidOid,
  							 sizeof(bool),
! 							 BoolGetDatum(ccontext == COERCION_EXPLICIT),
  							 false,
  							 true);
  
*************** build_coercion_expression(Node *node,
*** 893,899 ****
  		 */
  		acoerce->resulttypmod = (nargs >= 2) ? targetTypMod : -1;
  		/* resultcollid will be set by parse_collate.c */
! 		acoerce->isExplicit = isExplicit;
  		acoerce->coerceformat = cformat;
  		acoerce->location = location;
  
--- 888,894 ----
  		 */
  		acoerce->resulttypmod = (nargs >= 2) ? targetTypMod : -1;
  		/* resultcollid will be set by parse_collate.c */
! 		acoerce->isExplicit = (ccontext == COERCION_EXPLICIT);
  		acoerce->coerceformat = cformat;
  		acoerce->location = location;
  
diff --git a/src/backend/rewrite/rewriteHandler.c b/src/backend/rewrite/rewriteHandler.c
index 6b79c69..a2841d2 100644
*** a/src/backend/rewrite/rewriteHandler.c
--- b/src/backend/rewrite/rewriteHandler.c
*************** rewriteTargetListIU(List *targetList,
*** 875,883 ****
  					new_expr = coerce_to_domain(new_expr,
  												InvalidOid, -1,
  												att_tup->atttypid,
  												COERCE_IMPLICIT_CAST,
  												-1,
- 												false,
  												false);
  				}
  			}
--- 875,883 ----
  					new_expr = coerce_to_domain(new_expr,
  												InvalidOid, -1,
  												att_tup->atttypid,
+ 												COERCION_IMPLICIT,
  												COERCE_IMPLICIT_CAST,
  												-1,
  												false);
  				}
  			}
*************** rewriteValuesRTE(RangeTblEntry *rte, Rel
*** 1271,1279 ****
  					new_expr = coerce_to_domain(new_expr,
  												InvalidOid, -1,
  												att_tup->atttypid,
  												COERCE_IMPLICIT_CAST,
  												-1,
- 												false,
  												false);
  				}
  				newList = lappend(newList, new_expr);
--- 1271,1279 ----
  					new_expr = coerce_to_domain(new_expr,
  												InvalidOid, -1,
  												att_tup->atttypid,
+ 												COERCION_IMPLICIT,
  												COERCE_IMPLICIT_CAST,
  												-1,
  												false);
  				}
  				newList = lappend(newList, new_expr);
diff --git a/src/backend/rewrite/rewriteManip.c b/src/backend/rewrite/rewriteManip.c
index ba706b2..d962ae3 100644
*** a/src/backend/rewrite/rewriteManip.c
--- b/src/backend/rewrite/rewriteManip.c
*************** ReplaceVarsFromTargetList_callback(Var *
*** 1429,1437 ****
  															   var->varcollid),
  										InvalidOid, -1,
  										var->vartype,
  										COERCE_IMPLICIT_CAST,
  										-1,
- 										false,
  										false);
  		}
  		elog(ERROR, "could not find replacement targetlist entry for attno %d",
--- 1429,1437 ----
  															   var->varcollid),
  										InvalidOid, -1,
  										var->vartype,
+ 										COERCION_IMPLICIT,
  										COERCE_IMPLICIT_CAST,
  										-1,
  										false);
  		}
  		elog(ERROR, "could not find replacement targetlist entry for attno %d",
diff --git a/src/include/parser/parse_coerce.h b/src/include/parser/parse_coerce.h
index 06f6529..e560f0c 100644
*** a/src/include/parser/parse_coerce.h
--- b/src/include/parser/parse_coerce.h
*************** extern Node *coerce_type(ParseState *pst
*** 48,56 ****
  			CoercionContext ccontext, CoercionForm cformat, int location);
  extern Node *coerce_to_domain(Node *arg, Oid baseTypeId, int32 baseTypeMod,
  				 Oid typeId,
! 				 CoercionForm cformat, int location,
! 				 bool hideInputCoercion,
! 				 bool lengthCoercionDone);
  
  extern Node *coerce_to_boolean(ParseState *pstate, Node *node,
  				  const char *constructName);
--- 48,55 ----
  			CoercionContext ccontext, CoercionForm cformat, int location);
  extern Node *coerce_to_domain(Node *arg, Oid baseTypeId, int32 baseTypeMod,
  				 Oid typeId,
! 				 CoercionContext ccontext, CoercionForm cformat, int location,
! 				 bool hideInputCoercion);
  
  extern Node *coerce_to_boolean(ParseState *pstate, Node *node,
  				  const char *constructName);
