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

Commit56be925

Browse files
committed
Further tweaking of raw grammar output to distinguish different inputs.
Use a different A_Expr_Kind for LIKE/ILIKE/SIMILAR TO constructs, so thatthey can be distinguished from direct invocation of the underlyingoperators. Also, postpone selection of the operator name when transforming"x IN (select)" to "x = ANY (select)", so that those syntaxes can be toldapart at parse analysis time.I had originally thought I'd also have to do something special for thesyntaxes IS NOT DISTINCT FROM, IS NOT DOCUMENT, and x NOT IN (SELECT...),which the grammar translates as though they were NOT (construct).On reflection though, we can distinguish those cases reliably by notingwhether the parse location shown for the NOT is the same as for its childnode. This only requires tweaking the parse locations for NOT IN, whichI've done here.These changes should have no effect outside the parser; they're just insupport of being able to give accurate warnings for planned operatorprecedence changes.
1 parent296f3a6 commit56be925

File tree

5 files changed

+63
-17
lines changed

5 files changed

+63
-17
lines changed

‎src/backend/nodes/outfuncs.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2516,6 +2516,18 @@ _outAExpr(StringInfo str, const A_Expr *node)
25162516
appendStringInfoString(str," IN ");
25172517
WRITE_NODE_FIELD(name);
25182518
break;
2519+
caseAEXPR_LIKE:
2520+
appendStringInfoString(str," LIKE ");
2521+
WRITE_NODE_FIELD(name);
2522+
break;
2523+
caseAEXPR_ILIKE:
2524+
appendStringInfoString(str," ILIKE ");
2525+
WRITE_NODE_FIELD(name);
2526+
break;
2527+
caseAEXPR_SIMILAR:
2528+
appendStringInfoString(str," SIMILAR ");
2529+
WRITE_NODE_FIELD(name);
2530+
break;
25192531
caseAEXPR_BETWEEN:
25202532
appendStringInfoString(str," BETWEEN ");
25212533
WRITE_NODE_FIELD(name);

‎src/backend/parser/gram.y

Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11220,69 +11220,89 @@ a_expr:c_expr{ $$ = $1; }
1122011220
{$$ = makeNotExpr($2,@1); }
1122111221

1122211222
|a_exprLIKEa_expr
11223-
{$$ = (Node *) makeSimpleA_Expr(AEXPR_OP,"~~",$1,$3,@2); }
11223+
{
11224+
$$ = (Node *) makeSimpleA_Expr(AEXPR_LIKE,"~~",
11225+
$1,$3,@2);
11226+
}
1122411227
|a_exprLIKEa_exprESCAPEa_expr
1122511228
{
1122611229
FuncCall *n = makeFuncCall(SystemFuncName("like_escape"),
1122711230
list_make2($3, $5),
1122811231
@2);
11229-
$$ = (Node *) makeSimpleA_Expr(AEXPR_OP,"~~",$1, (Node *) n,@2);
11232+
$$ = (Node *) makeSimpleA_Expr(AEXPR_LIKE,"~~",
11233+
$1, (Node *) n,@2);
1123011234
}
1123111235
|a_exprNOTLIKEa_expr
11232-
{$$ = (Node *) makeSimpleA_Expr(AEXPR_OP,"!~~",$1,$4,@2); }
11236+
{
11237+
$$ = (Node *) makeSimpleA_Expr(AEXPR_LIKE,"!~~",
11238+
$1,$4,@2);
11239+
}
1123311240
|a_exprNOTLIKEa_exprESCAPEa_expr
1123411241
{
1123511242
FuncCall *n = makeFuncCall(SystemFuncName("like_escape"),
1123611243
list_make2($4, $6),
1123711244
@2);
11238-
$$ = (Node *) makeSimpleA_Expr(AEXPR_OP,"!~~",$1, (Node *) n,@2);
11245+
$$ = (Node *) makeSimpleA_Expr(AEXPR_LIKE,"!~~",
11246+
$1, (Node *) n,@2);
1123911247
}
1124011248
|a_exprILIKEa_expr
11241-
{$$ = (Node *) makeSimpleA_Expr(AEXPR_OP,"~~*",$1,$3,@2); }
11249+
{
11250+
$$ = (Node *) makeSimpleA_Expr(AEXPR_ILIKE,"~~*",
11251+
$1,$3,@2);
11252+
}
1124211253
|a_exprILIKEa_exprESCAPEa_expr
1124311254
{
1124411255
FuncCall *n = makeFuncCall(SystemFuncName("like_escape"),
1124511256
list_make2($3, $5),
1124611257
@2);
11247-
$$ = (Node *) makeSimpleA_Expr(AEXPR_OP,"~~*",$1, (Node *) n,@2);
11258+
$$ = (Node *) makeSimpleA_Expr(AEXPR_ILIKE,"~~*",
11259+
$1, (Node *) n,@2);
1124811260
}
1124911261
|a_exprNOTILIKEa_expr
11250-
{$$ = (Node *) makeSimpleA_Expr(AEXPR_OP,"!~~*",$1,$4,@2); }
11262+
{
11263+
$$ = (Node *) makeSimpleA_Expr(AEXPR_ILIKE,"!~~*",
11264+
$1,$4,@2);
11265+
}
1125111266
|a_exprNOTILIKEa_exprESCAPEa_expr
1125211267
{
1125311268
FuncCall *n = makeFuncCall(SystemFuncName("like_escape"),
1125411269
list_make2($4, $6),
1125511270
@2);
11256-
$$ = (Node *) makeSimpleA_Expr(AEXPR_OP,"!~~*",$1, (Node *) n,@2);
11271+
$$ = (Node *) makeSimpleA_Expr(AEXPR_ILIKE,"!~~*",
11272+
$1, (Node *) n,@2);
1125711273
}
1125811274

1125911275
|a_exprSIMILARTOa_expr%precSIMILAR
1126011276
{
1126111277
FuncCall *n = makeFuncCall(SystemFuncName("similar_escape"),
1126211278
list_make2($4, makeNullAConst(-1)),
1126311279
@2);
11264-
$$ = (Node *) makeSimpleA_Expr(AEXPR_OP,"~",$1, (Node *) n,@2);
11280+
$$ = (Node *) makeSimpleA_Expr(AEXPR_SIMILAR,"~",
11281+
$1, (Node *) n,@2);
1126511282
}
1126611283
|a_exprSIMILARTOa_exprESCAPEa_expr
1126711284
{
1126811285
FuncCall *n = makeFuncCall(SystemFuncName("similar_escape"),
1126911286
list_make2($4, $6),
1127011287
@2);
11271-
$$ = (Node *) makeSimpleA_Expr(AEXPR_OP,"~",$1, (Node *) n,@2);
11288+
$$ = (Node *) makeSimpleA_Expr(AEXPR_SIMILAR,"~",
11289+
$1, (Node *) n,@2);
1127211290
}
1127311291
|a_exprNOTSIMILARTOa_expr%precSIMILAR
1127411292
{
1127511293
FuncCall *n = makeFuncCall(SystemFuncName("similar_escape"),
1127611294
list_make2($5, makeNullAConst(-1)),
1127711295
@2);
11278-
$$ = (Node *) makeSimpleA_Expr(AEXPR_OP,"!~",$1, (Node *) n,@2);
11296+
$$ = (Node *) makeSimpleA_Expr(AEXPR_SIMILAR,"!~",
11297+
$1, (Node *) n,@2);
1127911298
}
1128011299
|a_exprNOTSIMILARTOa_exprESCAPEa_expr
1128111300
{
1128211301
FuncCall *n = makeFuncCall(SystemFuncName("similar_escape"),
1128311302
list_make2($5, $7),
1128411303
@2);
11285-
$$ = (Node *) makeSimpleA_Expr(AEXPR_OP,"!~",$1, (Node *) n,@2);
11304+
$$ = (Node *) makeSimpleA_Expr(AEXPR_SIMILAR,"!~",
11305+
$1, (Node *) n,@2);
1128611306
}
1128711307

1128811308
/* NullTest clause
@@ -11450,7 +11470,7 @@ a_expr:c_expr{ $$ = $1; }
1145011470
n->subLinkType = ANY_SUBLINK;
1145111471
n->subLinkId =0;
1145211472
n->testexpr =$1;
11453-
n->operName =list_make1(makeString("="));
11473+
n->operName =NIL;/* show it's IN not = ANY*/
1145411474
n->location =@2;
1145511475
$$ = (Node *)n;
1145611476
}
@@ -11471,9 +11491,9 @@ a_expr:c_expr{ $$ = $1; }
1147111491
n->subLinkType = ANY_SUBLINK;
1147211492
n->subLinkId =0;
1147311493
n->testexpr =$1;
11474-
n->operName =list_make1(makeString("="));
11475-
n->location =@3;
11476-
/* Stick a NOT on top*/
11494+
n->operName =NIL;/* show it's IN not = ANY*/
11495+
n->location =@2;
11496+
/* Stick a NOT on top; must have same parse location*/
1147711497
$$ = makeNotExpr((Node *) n,@2);
1147811498
}
1147911499
else

‎src/backend/parser/parse_expr.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,12 @@ transformExprRecurse(ParseState *pstate, Node *expr)
182182
caseAEXPR_IN:
183183
result=transformAExprIn(pstate,a);
184184
break;
185+
caseAEXPR_LIKE:
186+
caseAEXPR_ILIKE:
187+
caseAEXPR_SIMILAR:
188+
/* we can transform these just like AEXPR_OP */
189+
result=transformAExprOp(pstate,a);
190+
break;
185191
caseAEXPR_BETWEEN:
186192
caseAEXPR_NOT_BETWEEN:
187193
caseAEXPR_BETWEEN_SYM:
@@ -1648,6 +1654,12 @@ transformSubLink(ParseState *pstate, SubLink *sublink)
16481654
List*right_list;
16491655
ListCell*l;
16501656

1657+
/*
1658+
* If the source was "x IN (select)", convert to "x = ANY (select)".
1659+
*/
1660+
if (sublink->operName==NIL)
1661+
sublink->operName=list_make1(makeString("="));
1662+
16511663
/*
16521664
* Transform lefthand expression, and convert to a list
16531665
*/

‎src/include/nodes/parsenodes.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,9 @@ typedef enum A_Expr_Kind
233233
AEXPR_NULLIF,/* NULLIF - name must be "=" */
234234
AEXPR_OF,/* IS [NOT] OF - name must be "=" or "<>" */
235235
AEXPR_IN,/* [NOT] IN - name must be "=" or "<>" */
236+
AEXPR_LIKE,/* [NOT] LIKE - name must be "~~" or "!~~" */
237+
AEXPR_ILIKE,/* [NOT] ILIKE - name must be "~~*" or "!~~*" */
238+
AEXPR_SIMILAR,/* [NOT] SIMILAR - name must be "~" or "!~" */
236239
AEXPR_BETWEEN,/* name must be "BETWEEN" */
237240
AEXPR_NOT_BETWEEN,/* name must be "NOT BETWEEN" */
238241
AEXPR_BETWEEN_SYM,/* name must be "BETWEEN SYMMETRIC" */

‎src/include/nodes/primnodes.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -994,7 +994,6 @@ typedef struct MinMaxExpr
994994
* Note: result type/typmod/collation are not stored, but can be deduced
995995
* from the XmlExprOp. The type/typmod fields are just used for display
996996
* purposes, and are NOT necessarily the true result type of the node.
997-
* (We also use type == InvalidOid to mark a not-yet-parse-analyzed XmlExpr.)
998997
*/
999998
typedefenumXmlExprOp
1000999
{

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp