From eea49769d415b00ea36e2ee64774cb4d1313d991 Mon Sep 17 00:00:00 2001 From: Tom Lane <tgl@sss.pgh.pa.us> Date: Wed, 25 Feb 2009 18:00:01 +0000 Subject: [PATCH] Fix an old problem in decompilation of CASE constructs: the ruleutils.c code looks for a CaseTestExpr to figure out what the parser did, but it failed to consider the possibility that an implicit coercion might be inserted above the CaseTestExpr. This could result in an Assert failure in some cases (but correct results if Asserts weren't enabled), or an "unexpected CASE WHEN clause" error in other cases. Per report from Alan Li. Back-patch to 8.1; problem doesn't exist before that because CASE was implemented differently. --- src/backend/utils/adt/ruleutils.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 845b1bf96a2..f05e6a2cb93 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.295 2009/01/07 13:44:36 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.296 2009/02/25 18:00:01 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -4575,24 +4575,29 @@ get_rule_expr(Node *node, deparse_context *context, * 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"). + * see "WHEN Const"). 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(IsA(linitial(((OpExpr *) w)->args), - CaseTestExpr) || - IsA(linitial(((OpExpr *) w)->args), - Const)); - rhs = (Node *) lsecond(((OpExpr *) w)->args); + Assert(list_length(args) == 2); + lhs = strip_implicit_coercions(linitial(args)); + Assert(IsA(lhs, CaseTestExpr) || + IsA(lhs, Const)); + rhs = (Node *) lsecond(args); get_rule_expr(rhs, context, false); } - else if (IsA(w, CaseTestExpr)) + else if (IsA(strip_implicit_coercions(w), + CaseTestExpr)) appendStringInfo(buf, "TRUE"); else if (not_clause(w)) { - Assert(IsA(get_notclausearg((Expr *) w), + Assert(IsA(strip_implicit_coercions((Node *) get_notclausearg((Expr *) w)), CaseTestExpr)); appendStringInfo(buf, "FALSE"); } -- GitLab