diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c
index fa84164b068f9ede9edc42806e024fb083ff18d8..ccf913b35cf34c7f0b516af90efbe86c3be4d1d4 100644
--- a/src/backend/optimizer/util/clauses.c
+++ b/src/backend/optimizer/util/clauses.c
@@ -2583,7 +2583,18 @@ eval_const_expressions_mutator(Node *node,
 		 * placeholder nodes, so that we have the opportunity to reduce
 		 * constant test conditions.  For example this allows
 		 *		CASE 0 WHEN 0 THEN 1 ELSE 1/0 END
-		 * to reduce to 1 rather than drawing a divide-by-0 error.
+		 * to reduce to 1 rather than drawing a divide-by-0 error.  Note
+		 * that when the test expression is constant, we don't have to
+		 * include it in the resulting CASE; for example
+		 *		CASE 0 WHEN x THEN y ELSE z END
+		 * is transformed by the parser to
+		 *		CASE 0 WHEN CaseTestExpr = x THEN y ELSE z END
+		 * which we can simplify to
+		 *		CASE WHEN 0 = x THEN y ELSE z END
+		 * It is not necessary for the executor to evaluate the "arg"
+		 * expression when executing the CASE, since any contained
+		 * CaseTestExprs that might have referred to it will have been
+		 * replaced by the constant.
 		 *----------
 		 */
 		CaseExpr   *caseexpr = (CaseExpr *) node;
@@ -2602,7 +2613,10 @@ eval_const_expressions_mutator(Node *node,
 		/* Set up for contained CaseTestExpr nodes */
 		save_case_val = context->case_val;
 		if (newarg && IsA(newarg, Const))
+		{
 			context->case_val = newarg;
+			newarg = NULL;		/* not needed anymore, see comment above */
+		}
 		else
 			context->case_val = NULL;
 
diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c
index dc17685563bad4f1141b44becbf05f7b204c4b34..21aa6718c8439ede2741b264f726613e2ccf61d0 100644
--- a/src/backend/utils/adt/ruleutils.c
+++ b/src/backend/utils/adt/ruleutils.c
@@ -5146,23 +5146,19 @@ get_rule_expr(Node *node, deparse_context *context,
 						 * boolexpr WHEN TRUE THEN ...", then the optimizer's
 						 * simplify_boolean_equality() may have reduced this
 						 * to just "CaseTestExpr" or "NOT CaseTestExpr", for
-						 * which we have to show "TRUE" or "FALSE".  Also,
-						 * depending on context the original CaseTestExpr
-						 * might have been reduced to a Const (but we won't
-						 * see "WHEN Const").  We have also to consider the
-						 * possibility that an implicit coercion was inserted
-						 * between the CaseTestExpr and the operator.
+						 * which we have to show "TRUE" or "FALSE".  We have
+						 * also to consider the possibility that an implicit
+						 * coercion was inserted between the CaseTestExpr and
+						 * the operator.
 						 */
 						if (IsA(w, OpExpr))
 						{
 							List	   *args = ((OpExpr *) w)->args;
-							Node	   *lhs;
 							Node	   *rhs;
 
 							Assert(list_length(args) == 2);
-							lhs = strip_implicit_coercions(linitial(args));
-							Assert(IsA(lhs, CaseTestExpr) ||
-								   IsA(lhs, Const));
+							Assert(IsA(strip_implicit_coercions(linitial(args)),
+									   CaseTestExpr));
 							rhs = (Node *) lsecond(args);
 							get_rule_expr(rhs, context, false);
 						}