]> granicus.if.org Git - postgresql/commitdiff
Teach deparsing of CASE expressions to cope with the simplified forms
authorTom Lane <tgl@sss.pgh.pa.us>
Sat, 10 Dec 2005 19:21:03 +0000 (19:21 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Sat, 10 Dec 2005 19:21:03 +0000 (19:21 +0000)
that simplify_boolean_equality() may leave behind.  This is only relevant
if the user writes something a bit silly, like CASE x=y WHEN TRUE THEN.
Per example from Michael Fuhr; may or may not explain bug #2106.

src/backend/utils/adt/ruleutils.c

index c7b8066cbfbaeb72c7d2f096f7467fea6654e926..5a102e5fed566d55f573bf7ae13d4e6d60951643 100644 (file)
@@ -3,7 +3,7 @@
  *                             back to source text
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.209 2005/11/22 18:17:23 momjian Exp $
+ *       $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.210 2005/12/10 19:21:03 tgl Exp $
  *
  *       This software is copyrighted by Jan Wieck - Hamburg.
  *
@@ -3389,6 +3389,7 @@ get_rule_expr(Node *node, deparse_context *context,
                                foreach(temp, caseexpr->args)
                                {
                                        CaseWhen   *when = (CaseWhen *) lfirst(temp);
+                                       Node       *w = (Node *) when->expr;
 
                                        if (!PRETTY_INDENT(context))
                                                appendStringInfoChar(buf, ' ');
@@ -3396,15 +3397,39 @@ get_rule_expr(Node *node, deparse_context *context,
                                                                                 0, 0, 0);
                                        if (caseexpr->arg)
                                        {
-                                               /* Show only the RHS of "CaseTestExpr = RHS" */
-                                               Node       *rhs;
+                                               /*
+                                                * 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".
+                                                */
+                                               if (IsA(w, OpExpr))
+                                               {
+                                                       Node       *rhs;
 
-                                               Assert(IsA(when->expr, OpExpr));
-                                               rhs = (Node *) lsecond(((OpExpr *) when->expr)->args);
-                                               get_rule_expr(rhs, context, false);
+                                                       Assert(IsA(linitial(((OpExpr *) w)->args),
+                                                                          CaseTestExpr));
+                                                       rhs = (Node *) lsecond(((OpExpr *) w)->args);
+                                                       get_rule_expr(rhs, context, false);
+                                               }
+                                               else if (IsA(w, CaseTestExpr))
+                                                       appendStringInfo(buf, "TRUE");
+                                               else if (not_clause(w))
+                                               {
+                                                       Assert(IsA(get_notclausearg((Expr *) w),
+                                                                          CaseTestExpr));
+                                                       appendStringInfo(buf, "FALSE");
+                                               }
+                                               else
+                                                       elog(ERROR, "unexpected CASE WHEN clause: %d",
+                                                                (int) nodeTag(w));
                                        }
                                        else
-                                               get_rule_expr((Node *) when->expr, context, false);
+                                               get_rule_expr(w, context, false);
                                        appendStringInfo(buf, " THEN ");
                                        get_rule_expr((Node *) when->result, context, true);
                                }