mirror of
https://github.com/postgres/postgres.git
synced 2025-04-24 10:47:04 +03:00
Allow LIKE/ILIKE to appear in more places in a query.
Fabien COELHO
This commit is contained in:
parent
6165bbab8c
commit
0969dc867b
@ -11,7 +11,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.449 2004/03/17 20:48:42 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.450 2004/04/05 03:07:26 momjian Exp $
|
||||||
*
|
*
|
||||||
* HISTORY
|
* HISTORY
|
||||||
* AUTHOR DATE MAJOR EVENT
|
* AUTHOR DATE MAJOR EVENT
|
||||||
@ -194,7 +194,7 @@ static void doNegateFloat(Value *v);
|
|||||||
database_name access_method_clause access_method attr_name
|
database_name access_method_clause access_method attr_name
|
||||||
index_name name function_name file_name
|
index_name name function_name file_name
|
||||||
|
|
||||||
%type <list> func_name handler_name qual_Op qual_all_Op
|
%type <list> func_name handler_name qual_Op qual_all_Op subquery_Op
|
||||||
opt_class opt_validator
|
opt_class opt_validator
|
||||||
|
|
||||||
%type <range> qualified_name OptConstrFromTable
|
%type <range> qualified_name OptConstrFromTable
|
||||||
@ -5692,7 +5692,7 @@ r_expr: row IN_P select_with_parens
|
|||||||
/* Stick a NOT on top */
|
/* Stick a NOT on top */
|
||||||
$$ = (Node *) makeA_Expr(AEXPR_NOT, NIL, NULL, (Node *) n);
|
$$ = (Node *) makeA_Expr(AEXPR_NOT, NIL, NULL, (Node *) n);
|
||||||
}
|
}
|
||||||
| row qual_all_Op sub_type select_with_parens
|
| row subquery_Op sub_type select_with_parens
|
||||||
%prec Op
|
%prec Op
|
||||||
{
|
{
|
||||||
SubLink *n = makeNode(SubLink);
|
SubLink *n = makeNode(SubLink);
|
||||||
@ -5702,7 +5702,7 @@ r_expr: row IN_P select_with_parens
|
|||||||
n->subselect = $4;
|
n->subselect = $4;
|
||||||
$$ = (Node *)n;
|
$$ = (Node *)n;
|
||||||
}
|
}
|
||||||
| row qual_all_Op select_with_parens
|
| row subquery_Op select_with_parens
|
||||||
%prec Op
|
%prec Op
|
||||||
{
|
{
|
||||||
SubLink *n = makeNode(SubLink);
|
SubLink *n = makeNode(SubLink);
|
||||||
@ -5712,7 +5712,7 @@ r_expr: row IN_P select_with_parens
|
|||||||
n->subselect = $3;
|
n->subselect = $3;
|
||||||
$$ = (Node *)n;
|
$$ = (Node *)n;
|
||||||
}
|
}
|
||||||
| row qual_all_Op row
|
| row subquery_Op row
|
||||||
%prec Op
|
%prec Op
|
||||||
{
|
{
|
||||||
$$ = makeRowExpr($2, $1, $3);
|
$$ = makeRowExpr($2, $1, $3);
|
||||||
@ -5807,6 +5807,23 @@ qual_all_Op:
|
|||||||
| OPERATOR '(' any_operator ')' { $$ = $3; }
|
| OPERATOR '(' any_operator ')' { $$ = $3; }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
subquery_Op:
|
||||||
|
all_Op { $$ = makeList1(makeString($1)); }
|
||||||
|
| OPERATOR '(' any_operator ')' { $$ = $3; }
|
||||||
|
| LIKE { $$ = makeList1(makeString("~~")); }
|
||||||
|
| NOT LIKE { $$ = makeList1(makeString("!~~")); }
|
||||||
|
| ILIKE { $$ = makeList1(makeString("~~*")); }
|
||||||
|
| NOT ILIKE { $$ = makeList1(makeString("!~~*")); }
|
||||||
|
/* cannot put SIMILAR TO here, because SIMILAR TO is a hack.
|
||||||
|
* the regular expression is preprocessed by a function (similar_escape),
|
||||||
|
* and the ~ operator for posix regular expressions is used.
|
||||||
|
* x SIMILAR TO y -> x ~ similar_escape(y)
|
||||||
|
* this transformation is made on the fly by the parser upwards.
|
||||||
|
* however the SubLink structure which handles any/some/all stuff
|
||||||
|
* is not ready for such a thing.
|
||||||
|
*/
|
||||||
|
;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* General expressions
|
* General expressions
|
||||||
* This is the heart of the expression syntax.
|
* This is the heart of the expression syntax.
|
||||||
@ -6132,7 +6149,7 @@ a_expr: c_expr { $$ = $1; }
|
|||||||
$$ = n;
|
$$ = n;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
| a_expr qual_all_Op sub_type select_with_parens %prec Op
|
| a_expr subquery_Op sub_type select_with_parens %prec Op
|
||||||
{
|
{
|
||||||
SubLink *n = makeNode(SubLink);
|
SubLink *n = makeNode(SubLink);
|
||||||
n->subLinkType = $3;
|
n->subLinkType = $3;
|
||||||
@ -6141,7 +6158,7 @@ a_expr: c_expr { $$ = $1; }
|
|||||||
n->subselect = $4;
|
n->subselect = $4;
|
||||||
$$ = (Node *)n;
|
$$ = (Node *)n;
|
||||||
}
|
}
|
||||||
| a_expr qual_all_Op sub_type '(' a_expr ')' %prec Op
|
| a_expr subquery_Op sub_type '(' a_expr ')' %prec Op
|
||||||
{
|
{
|
||||||
if ($3 == ANY_SUBLINK)
|
if ($3 == ANY_SUBLINK)
|
||||||
$$ = (Node *) makeA_Expr(AEXPR_OP_ANY, $2, $1, $5);
|
$$ = (Node *) makeA_Expr(AEXPR_OP_ANY, $2, $1, $5);
|
||||||
|
@ -377,3 +377,52 @@ select * from arr_tbl where f1 > '{1,2,3}' and f1 <= '{1,5,3}';
|
|||||||
|
|
||||||
-- note: if above select doesn't produce the expected tuple order,
|
-- note: if above select doesn't produce the expected tuple order,
|
||||||
-- then you didn't get an indexscan plan, and something is busted.
|
-- then you didn't get an indexscan plan, and something is busted.
|
||||||
|
-- test [not] (like|ilike) (any|all) (...)
|
||||||
|
select 'foo' like any (array['%a', '%o']); -- t
|
||||||
|
?column?
|
||||||
|
----------
|
||||||
|
t
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
select 'foo' like any (array['%a', '%b']); -- f
|
||||||
|
?column?
|
||||||
|
----------
|
||||||
|
f
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
select 'foo' like all (array['f%', '%o']); -- t
|
||||||
|
?column?
|
||||||
|
----------
|
||||||
|
t
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
select 'foo' like all (array['f%', '%b']); -- f
|
||||||
|
?column?
|
||||||
|
----------
|
||||||
|
f
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
select 'foo' not like any (array['%a', '%b']); -- t
|
||||||
|
?column?
|
||||||
|
----------
|
||||||
|
t
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
select 'foo' not like all (array['%a', '%o']); -- f
|
||||||
|
?column?
|
||||||
|
----------
|
||||||
|
f
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
select 'foo' ilike any (array['%A', '%O']); -- t
|
||||||
|
?column?
|
||||||
|
----------
|
||||||
|
t
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
select 'foo' ilike all (array['F%', '%O']); -- t
|
||||||
|
?column?
|
||||||
|
----------
|
||||||
|
t
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
@ -183,3 +183,13 @@ set enable_seqscan to off;
|
|||||||
select * from arr_tbl where f1 > '{1,2,3}' and f1 <= '{1,5,3}';
|
select * from arr_tbl where f1 > '{1,2,3}' and f1 <= '{1,5,3}';
|
||||||
-- note: if above select doesn't produce the expected tuple order,
|
-- note: if above select doesn't produce the expected tuple order,
|
||||||
-- then you didn't get an indexscan plan, and something is busted.
|
-- then you didn't get an indexscan plan, and something is busted.
|
||||||
|
|
||||||
|
-- test [not] (like|ilike) (any|all) (...)
|
||||||
|
select 'foo' like any (array['%a', '%o']); -- t
|
||||||
|
select 'foo' like any (array['%a', '%b']); -- f
|
||||||
|
select 'foo' like all (array['f%', '%o']); -- t
|
||||||
|
select 'foo' like all (array['f%', '%b']); -- f
|
||||||
|
select 'foo' not like any (array['%a', '%b']); -- t
|
||||||
|
select 'foo' not like all (array['%a', '%o']); -- f
|
||||||
|
select 'foo' ilike any (array['%A', '%O']); -- t
|
||||||
|
select 'foo' ilike all (array['F%', '%O']); -- t
|
||||||
|
Loading…
x
Reference in New Issue
Block a user