diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/backend/utils/adt/ruleutils.c | 67 | 
1 files changed, 33 insertions, 34 deletions
| diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 72316425d22..4b5f9781105 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -4893,50 +4893,36 @@ get_rule_expr(Node *node, deparse_context *context,  					CaseWhen   *when = (CaseWhen *) lfirst(temp);  					Node	   *w = (Node *) when->expr; -					if (!PRETTY_INDENT(context)) -						appendStringInfoChar(buf, ' '); -					appendContextKeyword(context, "WHEN ", -										 0, 0, 0);  					if (caseexpr->arg)  					{  						/* -						 * The parser should have produced WHEN clauses of the -						 * form "CaseTestExpr = RHS"; we want to show just the -						 * RHS.  If the user wrote something silly like "CASE -						 * 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".  We have -						 * also to consider the possibility that an implicit -						 * coercion was inserted between the CaseTestExpr and -						 * the operator. +						 * The parser should have produced WHEN clauses of +						 * the form "CaseTestExpr = RHS", possibly with an +						 * implicit coercion inserted above the CaseTestExpr. +						 * For accurate decompilation of rules it's essential +						 * that we show just the RHS.  However in an +						 * expression that's been through the optimizer, the +						 * WHEN clause could be almost anything (since the +						 * equality operator could have been expanded into an +						 * inline function).  If we don't recognize the form +						 * of the WHEN clause, just punt and display it as-is.  						 */  						if (IsA(w, OpExpr))  						{  							List	   *args = ((OpExpr *) w)->args; -							Node	   *rhs; -							Assert(list_length(args) == 2); -							Assert(IsA(strip_implicit_coercions(linitial(args)), -									   CaseTestExpr)); -							rhs = (Node *) lsecond(args); -							get_rule_expr(rhs, context, false); +							if (list_length(args) == 2 && +								IsA(strip_implicit_coercions(linitial(args)), +									CaseTestExpr)) +								w = (Node *) lsecond(args);  						} -						else if (IsA(strip_implicit_coercions(w), -									 CaseTestExpr)) -							appendStringInfo(buf, "TRUE"); -						else if (not_clause(w)) -						{ -							Assert(IsA(strip_implicit_coercions((Node *) get_notclausearg((Expr *) w)), -									   CaseTestExpr)); -							appendStringInfo(buf, "FALSE"); -						} -						else -							elog(ERROR, "unexpected CASE WHEN clause: %d", -								 (int) nodeTag(w));  					} -					else -						get_rule_expr(w, context, false); + +					if (!PRETTY_INDENT(context)) +						appendStringInfoChar(buf, ' '); +					appendContextKeyword(context, "WHEN ", +										 0, 0, 0); +					get_rule_expr(w, context, false);  					appendStringInfo(buf, " THEN ");  					get_rule_expr((Node *) when->result, context, true);  				} @@ -4952,6 +4938,19 @@ get_rule_expr(Node *node, deparse_context *context,  			}  			break; +		case T_CaseTestExpr: +			{ +				/* +				 * Normally we should never get here, since for expressions +				 * that can contain this node type we attempt to avoid +				 * recursing to it.  But in an optimized expression we might +				 * be unable to avoid that (see comments for CaseExpr).  If we +				 * do see one, print it as CASE_TEST_EXPR. +				 */ +				appendStringInfo(buf, "CASE_TEST_EXPR"); +			} +			break; +  		case T_ArrayExpr:  			{  				ArrayExpr  *arrayexpr = (ArrayExpr *) node; | 
