aboutsummaryrefslogtreecommitdiff
path: root/src/backend
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend')
-rw-r--r--src/backend/nodes/outfuncs.c12
-rw-r--r--src/backend/parser/gram.y52
-rw-r--r--src/backend/parser/parse_expr.c12
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);