Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit6d24189

Browse files
committed
Make decompilation of optimized CASE constructs more robust.
We had some hacks in ruleutils.c to cope with various odd transformationsthat the optimizer could do on a CASE foo WHEN "CaseTestExpr = RHS" clause.However, the fundamental impossibility of covering all cases was exposedby Heikki, who pointed out that the "=" operator could get replaced by aninlined SQL function, which could contain nearly anything at all. So giveup on the hacks and just print the expression as-is if we fail to recognizeit as "CaseTestExpr = RHS". (We must cover that case so that decompiledrules print correctly; but we are not under any obligation to make EXPLAINoutput be 100% valid SQL in all cases, and already could not do so in someother cases.) This approach requires that we have some printablerepresentation of the CaseTestExpr node type; I used "CASE_TEST_EXPR".Back-patch to all supported branches, since the problem case fails in all.
1 parentea393e4 commit6d24189

File tree

1 file changed

+33
-34
lines changed

1 file changed

+33
-34
lines changed

‎src/backend/utils/adt/ruleutils.c

Lines changed: 33 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -3678,50 +3678,36 @@ get_rule_expr(Node *node, deparse_context *context,
36783678
CaseWhen*when= (CaseWhen*)lfirst(temp);
36793679
Node*w= (Node*)when->expr;
36803680

3681-
if (!PRETTY_INDENT(context))
3682-
appendStringInfoChar(buf,' ');
3683-
appendContextKeyword(context,"WHEN ",
3684-
0,0,0);
36853681
if (caseexpr->arg)
36863682
{
36873683
/*
3688-
* The parser should have produced WHEN clauses of the
3689-
* form "CaseTestExpr = RHS"; we want to show just the
3690-
*RHS. Iftheuser wrote something silly like "CASE
3691-
*boolexpr WHEN TRUE THEN ...", then the optimizer's
3692-
*simplify_boolean_equality() may have reduced this
3693-
*to just "CaseTestExpr" or "NOT CaseTestExpr", for
3694-
*which we have to show "TRUE" or "FALSE". We have
3695-
*also to consider the possibility that an implicit
3696-
*coercion was inserted between the CaseTestExpr and
3697-
* theoperator.
3684+
* The parser should have produced WHEN clauses of
3685+
*theform "CaseTestExpr = RHS", possibly with an
3686+
*implicit coercion inserted abovetheCaseTestExpr.
3687+
*For accurate decompilation of rules it's essential
3688+
*that we show just the RHS. However in an
3689+
*expression that's been through the optimizer, the
3690+
*WHEN clause could be almost anything (since the
3691+
*equality operator could have been expanded into an
3692+
*inline function). If we don't recognize the form
3693+
*oftheWHEN clause, just punt and display it as-is.
36983694
*/
36993695
if (IsA(w,OpExpr))
37003696
{
37013697
List*args= ((OpExpr*)w)->args;
3702-
Node*rhs;
37033698

3704-
Assert(list_length(args)==2);
3705-
Assert(IsA(strip_implicit_coercions(linitial(args)),
3706-
CaseTestExpr));
3707-
rhs= (Node*)lsecond(args);
3708-
get_rule_expr(rhs,context, false);
3699+
if (list_length(args)==2&&
3700+
IsA(strip_implicit_coercions(linitial(args)),
3701+
CaseTestExpr))
3702+
w= (Node*)lsecond(args);
37093703
}
3710-
elseif (IsA(strip_implicit_coercions(w),
3711-
CaseTestExpr))
3712-
appendStringInfo(buf,"TRUE");
3713-
elseif (not_clause(w))
3714-
{
3715-
Assert(IsA(strip_implicit_coercions((Node*)get_notclausearg((Expr*)w)),
3716-
CaseTestExpr));
3717-
appendStringInfo(buf,"FALSE");
3718-
}
3719-
else
3720-
elog(ERROR,"unexpected CASE WHEN clause: %d",
3721-
(int)nodeTag(w));
37223704
}
3723-
else
3724-
get_rule_expr(w,context, false);
3705+
3706+
if (!PRETTY_INDENT(context))
3707+
appendStringInfoChar(buf,' ');
3708+
appendContextKeyword(context,"WHEN ",
3709+
0,0,0);
3710+
get_rule_expr(w,context, false);
37253711
appendStringInfo(buf," THEN ");
37263712
get_rule_expr((Node*)when->result,context, true);
37273713
}
@@ -3737,6 +3723,19 @@ get_rule_expr(Node *node, deparse_context *context,
37373723
}
37383724
break;
37393725

3726+
caseT_CaseTestExpr:
3727+
{
3728+
/*
3729+
* Normally we should never get here, since for expressions
3730+
* that can contain this node type we attempt to avoid
3731+
* recursing to it. But in an optimized expression we might
3732+
* be unable to avoid that (see comments for CaseExpr). If we
3733+
* do see one, print it as CASE_TEST_EXPR.
3734+
*/
3735+
appendStringInfo(buf,"CASE_TEST_EXPR");
3736+
}
3737+
break;
3738+
37403739
caseT_ArrayExpr:
37413740
{
37423741
ArrayExpr*arrayexpr= (ArrayExpr*)node;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp