diff options
Diffstat (limited to 'src/backend')
-rw-r--r-- | src/backend/nodes/outfuncs.c | 12 | ||||
-rw-r--r-- | src/backend/parser/gram.y | 52 | ||||
-rw-r--r-- | src/backend/parser/parse_expr.c | 12 |
3 files changed, 60 insertions, 16 deletions
diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c index 98aa5f03102..2f417fee20a 100644 --- a/src/backend/nodes/outfuncs.c +++ b/src/backend/nodes/outfuncs.c @@ -2516,6 +2516,18 @@ _outAExpr(StringInfo str, const A_Expr *node) appendStringInfoString(str, " IN "); WRITE_NODE_FIELD(name); break; + case AEXPR_LIKE: + appendStringInfoString(str, " LIKE "); + WRITE_NODE_FIELD(name); + break; + case AEXPR_ILIKE: + appendStringInfoString(str, " ILIKE "); + WRITE_NODE_FIELD(name); + break; + case AEXPR_SIMILAR: + appendStringInfoString(str, " SIMILAR "); + WRITE_NODE_FIELD(name); + break; case AEXPR_BETWEEN: appendStringInfoString(str, " BETWEEN "); WRITE_NODE_FIELD(name); diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 76b0affff06..6c210028753 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -11220,40 +11220,56 @@ a_expr: c_expr { $$ = $1; } { $$ = makeNotExpr($2, @1); } | a_expr LIKE a_expr - { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "~~", $1, $3, @2); } + { + $$ = (Node *) makeSimpleA_Expr(AEXPR_LIKE, "~~", + $1, $3, @2); + } | a_expr LIKE a_expr ESCAPE a_expr { FuncCall *n = makeFuncCall(SystemFuncName("like_escape"), list_make2($3, $5), @2); - $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "~~", $1, (Node *) n, @2); + $$ = (Node *) makeSimpleA_Expr(AEXPR_LIKE, "~~", + $1, (Node *) n, @2); } | a_expr NOT LIKE a_expr - { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "!~~", $1, $4, @2); } + { + $$ = (Node *) makeSimpleA_Expr(AEXPR_LIKE, "!~~", + $1, $4, @2); + } | a_expr NOT LIKE a_expr ESCAPE a_expr { FuncCall *n = makeFuncCall(SystemFuncName("like_escape"), list_make2($4, $6), @2); - $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "!~~", $1, (Node *) n, @2); + $$ = (Node *) makeSimpleA_Expr(AEXPR_LIKE, "!~~", + $1, (Node *) n, @2); } | a_expr ILIKE a_expr - { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "~~*", $1, $3, @2); } + { + $$ = (Node *) makeSimpleA_Expr(AEXPR_ILIKE, "~~*", + $1, $3, @2); + } | a_expr ILIKE a_expr ESCAPE a_expr { FuncCall *n = makeFuncCall(SystemFuncName("like_escape"), list_make2($3, $5), @2); - $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "~~*", $1, (Node *) n, @2); + $$ = (Node *) makeSimpleA_Expr(AEXPR_ILIKE, "~~*", + $1, (Node *) n, @2); } | a_expr NOT ILIKE a_expr - { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "!~~*", $1, $4, @2); } + { + $$ = (Node *) makeSimpleA_Expr(AEXPR_ILIKE, "!~~*", + $1, $4, @2); + } | a_expr NOT ILIKE a_expr ESCAPE a_expr { FuncCall *n = makeFuncCall(SystemFuncName("like_escape"), list_make2($4, $6), @2); - $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "!~~*", $1, (Node *) n, @2); + $$ = (Node *) makeSimpleA_Expr(AEXPR_ILIKE, "!~~*", + $1, (Node *) n, @2); } | a_expr SIMILAR TO a_expr %prec SIMILAR @@ -11261,28 +11277,32 @@ a_expr: c_expr { $$ = $1; } FuncCall *n = makeFuncCall(SystemFuncName("similar_escape"), list_make2($4, makeNullAConst(-1)), @2); - $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "~", $1, (Node *) n, @2); + $$ = (Node *) makeSimpleA_Expr(AEXPR_SIMILAR, "~", + $1, (Node *) n, @2); } | a_expr SIMILAR TO a_expr ESCAPE a_expr { FuncCall *n = makeFuncCall(SystemFuncName("similar_escape"), list_make2($4, $6), @2); - $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "~", $1, (Node *) n, @2); + $$ = (Node *) makeSimpleA_Expr(AEXPR_SIMILAR, "~", + $1, (Node *) n, @2); } | a_expr NOT SIMILAR TO a_expr %prec SIMILAR { FuncCall *n = makeFuncCall(SystemFuncName("similar_escape"), list_make2($5, makeNullAConst(-1)), @2); - $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "!~", $1, (Node *) n, @2); + $$ = (Node *) makeSimpleA_Expr(AEXPR_SIMILAR, "!~", + $1, (Node *) n, @2); } | a_expr NOT SIMILAR TO a_expr ESCAPE a_expr { FuncCall *n = makeFuncCall(SystemFuncName("similar_escape"), list_make2($5, $7), @2); - $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "!~", $1, (Node *) n, @2); + $$ = (Node *) makeSimpleA_Expr(AEXPR_SIMILAR, "!~", + $1, (Node *) n, @2); } /* NullTest clause @@ -11450,7 +11470,7 @@ a_expr: c_expr { $$ = $1; } n->subLinkType = ANY_SUBLINK; n->subLinkId = 0; n->testexpr = $1; - n->operName = list_make1(makeString("=")); + n->operName = NIL; /* show it's IN not = ANY */ n->location = @2; $$ = (Node *)n; } @@ -11471,9 +11491,9 @@ a_expr: c_expr { $$ = $1; } n->subLinkType = ANY_SUBLINK; n->subLinkId = 0; n->testexpr = $1; - n->operName = list_make1(makeString("=")); - n->location = @3; - /* Stick a NOT on top */ + n->operName = NIL; /* show it's IN not = ANY */ + n->location = @2; + /* Stick a NOT on top; must have same parse location */ $$ = makeNotExpr((Node *) n, @2); } else diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c index f314745818b..7829bcbac16 100644 --- a/src/backend/parser/parse_expr.c +++ b/src/backend/parser/parse_expr.c @@ -182,6 +182,12 @@ transformExprRecurse(ParseState *pstate, Node *expr) case AEXPR_IN: result = transformAExprIn(pstate, a); break; + case AEXPR_LIKE: + case AEXPR_ILIKE: + case AEXPR_SIMILAR: + /* we can transform these just like AEXPR_OP */ + result = transformAExprOp(pstate, a); + break; case AEXPR_BETWEEN: case AEXPR_NOT_BETWEEN: case AEXPR_BETWEEN_SYM: @@ -1649,6 +1655,12 @@ transformSubLink(ParseState *pstate, SubLink *sublink) ListCell *l; /* + * If the source was "x IN (select)", convert to "x = ANY (select)". + */ + if (sublink->operName == NIL) + sublink->operName = list_make1(makeString("=")); + + /* * Transform lefthand expression, and convert to a list */ lefthand = transformExprRecurse(pstate, sublink->testexpr); |