diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c
index 8df3693..34c8f68 100644
*** a/src/backend/optimizer/util/clauses.c
--- b/src/backend/optimizer/util/clauses.c
*************** eval_const_expressions_mutator(Node *nod
*** 3699,3704 ****
--- 3699,3761 ----
  				newbtest->location = btest->location;
  				return (Node *) newbtest;
  			}
+ 		case T_CoerceToDomain:
+ 			{
+ 				/*
+ 				 * If the domain currently has no constraints, we replace the
+ 				 * CoerceToDomain node with a simple RelabelType, which is
+ 				 * both far faster to execute and more amenable to later
+ 				 * optimization.  (XXX this would need to be backed up with
+ 				 * some plan invalidation support, but leave that for later.)
+ 				 *
+ 				 * Also, in estimation mode, just drop the CoerceToDomain
+ 				 * node, effectively assuming that the coercion will succeed.
+ 				 */
+ 				CoerceToDomain *cdomain = (CoerceToDomain *) node;
+ 				CoerceToDomain *newcdomain;
+ 				Node	   *arg;
+ 
+ 				arg = eval_const_expressions_mutator((Node *) cdomain->arg,
+ 													 context);
+ 				if (context->estimate ||
+ 					!DomainHasConstraints(cdomain->resulttype))
+ 				{
+ 					/* This bit should match the RelabelType logic above */
+ 					while (arg && IsA(arg, RelabelType))
+ 						arg = (Node *) ((RelabelType *) arg)->arg;
+ 
+ 					if (arg && IsA(arg, Const))
+ 					{
+ 						Const	   *con = (Const *) arg;
+ 
+ 						con->consttype = cdomain->resulttype;
+ 						con->consttypmod = cdomain->resulttypmod;
+ 						con->constcollid = cdomain->resultcollid;
+ 						return (Node *) con;
+ 					}
+ 					else
+ 					{
+ 						RelabelType *newrelabel = makeNode(RelabelType);
+ 
+ 						newrelabel->arg = (Expr *) arg;
+ 						newrelabel->resulttype = cdomain->resulttype;
+ 						newrelabel->resulttypmod = cdomain->resulttypmod;
+ 						newrelabel->resultcollid = cdomain->resultcollid;
+ 						newrelabel->relabelformat = cdomain->coercionformat;
+ 						newrelabel->location = cdomain->location;
+ 						return (Node *) newrelabel;
+ 					}
+ 				}
+ 
+ 				newcdomain = makeNode(CoerceToDomain);
+ 				newcdomain->arg = (Expr *) arg;
+ 				newcdomain->resulttype = cdomain->resulttype;
+ 				newcdomain->resulttypmod = cdomain->resulttypmod;
+ 				newcdomain->resultcollid = cdomain->resultcollid;
+ 				newcdomain->coercionformat = cdomain->coercionformat;
+ 				newcdomain->location = cdomain->location;
+ 				return (Node *) newcdomain;
+ 			}
  		case T_PlaceHolderVar:
  
  			/*
*************** eval_const_expressions_mutator(Node *nod
*** 3770,3776 ****
  	 * For any node type not handled above, copy the node unchanged but
  	 * const-simplify its subexpressions.  This is the correct thing for node
  	 * types whose behavior might change between planning and execution, such
! 	 * as CoerceToDomain.  It's also a safe default for new node types not
  	 * known to this routine.
  	 */
  	return ece_generic_processing(node);
--- 3827,3833 ----
  	 * For any node type not handled above, copy the node unchanged but
  	 * const-simplify its subexpressions.  This is the correct thing for node
  	 * types whose behavior might change between planning and execution, such
! 	 * as CurrentOfExpr.  It's also a safe default for new node types not
  	 * known to this routine.
  	 */
  	return ece_generic_processing(node);
