diff options
| -rw-r--r-- | src/backend/optimizer/util/clauses.c | 16 | ||||
| -rw-r--r-- | src/backend/utils/adt/ruleutils.c | 16 | 
2 files changed, 21 insertions, 11 deletions
| diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c index c270b735fec..8902b5b8e6a 100644 --- a/src/backend/optimizer/util/clauses.c +++ b/src/backend/optimizer/util/clauses.c @@ -2595,7 +2595,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; @@ -2614,7 +2625,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 5d4c0462d5a..72316425d22 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -4906,23 +4906,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);  						} | 
