]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Fix an old problem in decompilation of CASE constructs: the ruleutils.c code
authorTom Lane <tgl@sss.pgh.pa.us>
Wed, 25 Feb 2009 18:00:14 +0000 (18:00 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Wed, 25 Feb 2009 18:00:14 +0000 (18:00 +0000)
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

index ff8b73bade38e0b37f6ff755b45c62033be84bbe..16a0ae54875f2d9e348f2f592dd13730f81ae212 100644 (file)
@@ -2,7 +2,7 @@
  * ruleutils.c - Functions to convert stored expressions/querytrees
  *                             back to source text
  *
- *       $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.235.2.6 2008/06/06 17:59:45 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.235.2.7 2009/02/25 18:00:14 tgl Exp $
  **********************************************************************/
 
 #include "postgres.h"
@@ -3693,24 +3693,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");
                                                }