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

Commit81deadd

Browse files
committed
Fix unexpected side-effects of operator_precedence_warning.
The implementation of that feature involves injecting nodes into theraw parsetree where explicit parentheses appear. Various places inparse_expr.c that test to see "is this child node of type Foo" need tolook through such nodes, else we'll get different behavior whenoperator_precedence_warning is on than when it is off. Note that we onlyneed to handle this when testing untransformed child nodes, since theAEXPR_PAREN nodes will be gone anyway after transformExprRecurse.Per report from Scott Ribe and additional code-reading. Back-patchto 9.5 where this feature was added.Report: <ED37E303-1B0A-4CD8-8E1E-B9C4C2DD9A17@elevated-dev.com>
1 parent94c685a commit81deadd

File tree

1 file changed

+29
-5
lines changed

1 file changed

+29
-5
lines changed

‎src/backend/parser/parse_expr.c

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -857,6 +857,14 @@ transformAExprOp(ParseState *pstate, A_Expr *a)
857857
emit_precedence_warnings(pstate,opgroup,opname,
858858
lexpr,rexpr,
859859
a->location);
860+
861+
/* Look through AEXPR_PAREN nodes so they don't affect tests below */
862+
while (lexpr&&IsA(lexpr,A_Expr)&&
863+
((A_Expr*)lexpr)->kind==AEXPR_PAREN)
864+
lexpr= ((A_Expr*)lexpr)->lexpr;
865+
while (rexpr&&IsA(rexpr,A_Expr)&&
866+
((A_Expr*)rexpr)->kind==AEXPR_PAREN)
867+
rexpr= ((A_Expr*)rexpr)->lexpr;
860868
}
861869

862870
/*
@@ -1903,6 +1911,11 @@ transformArrayExpr(ParseState *pstate, A_ArrayExpr *a,
19031911
Node*e= (Node*)lfirst(element);
19041912
Node*newe;
19051913

1914+
/* Look through AEXPR_PAREN nodes so they don't affect test below */
1915+
while (e&&IsA(e,A_Expr)&&
1916+
((A_Expr*)e)->kind==AEXPR_PAREN)
1917+
e= ((A_Expr*)e)->lexpr;
1918+
19061919
/*
19071920
* If an element is itself an A_ArrayExpr, recurse directly so that we
19081921
* can pass down any target type we were given.
@@ -2453,29 +2466,40 @@ transformWholeRowRef(ParseState *pstate, RangeTblEntry *rte, int location)
24532466
/*
24542467
* Handle an explicit CAST construct.
24552468
*
2456-
* Transform the argument,thenlook up the type name and apply any necessary
2469+
* Transform the argument, look up the type name, and apply any necessary
24572470
* coercion function(s).
24582471
*/
24592472
staticNode*
24602473
transformTypeCast(ParseState*pstate,TypeCast*tc)
24612474
{
24622475
Node*result;
2476+
Node*arg=tc->arg;
24632477
Node*expr;
24642478
OidinputType;
24652479
OidtargetType;
24662480
int32targetTypmod;
24672481
intlocation;
24682482

2483+
/* Look up the type name first */
24692484
typenameTypeIdAndMod(pstate,tc->typeName,&targetType,&targetTypmod);
24702485

2486+
/*
2487+
* Look through any AEXPR_PAREN nodes that may have been inserted thanks
2488+
* to operator_precedence_warning. Otherwise, ARRAY[]::foo[] behaves
2489+
* differently from (ARRAY[])::foo[].
2490+
*/
2491+
while (arg&&IsA(arg,A_Expr)&&
2492+
((A_Expr*)arg)->kind==AEXPR_PAREN)
2493+
arg= ((A_Expr*)arg)->lexpr;
2494+
24712495
/*
24722496
* If the subject of the typecast is an ARRAY[] construct and the target
24732497
* type is an array type, we invoke transformArrayExpr() directly so that
24742498
* we can pass down the type information. This avoids some cases where
24752499
* transformArrayExpr() might not infer the correct type. Otherwise, just
24762500
* transform the argument normally.
24772501
*/
2478-
if (IsA(tc->arg,A_ArrayExpr))
2502+
if (IsA(arg,A_ArrayExpr))
24792503
{
24802504
OidtargetBaseType;
24812505
int32targetBaseTypmod;
@@ -2493,16 +2517,16 @@ transformTypeCast(ParseState *pstate, TypeCast *tc)
24932517
if (OidIsValid(elementType))
24942518
{
24952519
expr=transformArrayExpr(pstate,
2496-
(A_ArrayExpr*)tc->arg,
2520+
(A_ArrayExpr*)arg,
24972521
targetBaseType,
24982522
elementType,
24992523
targetBaseTypmod);
25002524
}
25012525
else
2502-
expr=transformExprRecurse(pstate,tc->arg);
2526+
expr=transformExprRecurse(pstate,arg);
25032527
}
25042528
else
2505-
expr=transformExprRecurse(pstate,tc->arg);
2529+
expr=transformExprRecurse(pstate,arg);
25062530

25072531
inputType=exprType(expr);
25082532
if (inputType==InvalidOid)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp