aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2009-02-25 18:00:14 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2009-02-25 18:00:14 +0000
commitd3247aefea14e1924710e6a1410dd14faffcbf9f (patch)
treea1cd41253a573bdfc3be2ae68aa277d306df2fb5 /src
parentb8fcef692da8742104181e79db0be1155a781ad2 (diff)
downloadpostgresql-d3247aefea14e1924710e6a1410dd14faffcbf9f.tar.gz
postgresql-d3247aefea14e1924710e6a1410dd14faffcbf9f.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/backend/utils/adt/ruleutils.c23
1 files changed, 14 insertions, 9 deletions
diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c
index ff8b73bade3..16a0ae54875 100644
--- a/src/backend/utils/adt/ruleutils.c
+++ b/src/backend/utils/adt/ruleutils.c
@@ -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");
}