diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index d540026ff8..5569e338bb 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -3721,50 +3721,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); } @@ -3780,6 +3766,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;