]> granicus.if.org Git - postgresql/commitdiff
Allow LIKE/ILIKE to appear in more places in a query.
authorBruce Momjian <bruce@momjian.us>
Mon, 5 Apr 2004 03:07:26 +0000 (03:07 +0000)
committerBruce Momjian <bruce@momjian.us>
Mon, 5 Apr 2004 03:07:26 +0000 (03:07 +0000)
Fabien COELHO

src/backend/parser/gram.y
src/test/regress/expected/arrays.out
src/test/regress/sql/arrays.sql

index e8abfe039f091ce53a3cd9e1759d86efd2d0d8a6..84efc2875eee44c7dd043fb06a6285839dcdb425 100644 (file)
@@ -11,7 +11,7 @@
  *
  *
  * 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
  *       AUTHOR                        DATE                    MAJOR EVENT
@@ -194,7 +194,7 @@ static void doNegateFloat(Value *v);
                                database_name access_method_clause access_method attr_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
 
 %type <range>  qualified_name OptConstrFromTable
@@ -5692,7 +5692,7 @@ r_expr:  row IN_P select_with_parens
                                        /* Stick a NOT on top */
                                        $$ = (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
                                {
                                        SubLink *n = makeNode(SubLink);
@@ -5702,7 +5702,7 @@ r_expr:  row IN_P select_with_parens
                                        n->subselect = $4;
                                        $$ = (Node *)n;
                                }
-                       | row qual_all_Op select_with_parens
+                       | row subquery_Op select_with_parens
                        %prec Op
                                {
                                        SubLink *n = makeNode(SubLink);
@@ -5712,7 +5712,7 @@ r_expr:  row IN_P select_with_parens
                                        n->subselect = $3;
                                        $$ = (Node *)n;
                                }
-                       | row qual_all_Op row
+                       | row subquery_Op row
                        %prec Op
                                {
                                        $$ = makeRowExpr($2, $1, $3);
@@ -5807,6 +5807,23 @@ qual_all_Op:
                        | 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
  * This is the heart of the expression syntax.
@@ -6132,7 +6149,7 @@ a_expr:           c_expr                                                                  { $$ = $1; }
                                                $$ = 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);
                                        n->subLinkType = $3;
@@ -6141,7 +6158,7 @@ a_expr:           c_expr                                                                  { $$ = $1; }
                                        n->subselect = $4;
                                        $$ = (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)
                                                $$ = (Node *) makeA_Expr(AEXPR_OP_ANY, $2, $1, $5);
index 6f3c07cfb3fbf46c39247a1980ede0cde6417d84..6e82a7d0a6c70d876712a6f9c979da00a81a21e0 100644 (file)
@@ -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,
 -- 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)
+
index 3bc800cef21c99b3a8cff41578202522d4630c46..629ca15fb1c45221f7e5f05f4c5ecdd3743febed 100644 (file)
@@ -183,3 +183,13 @@ set enable_seqscan to off;
 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,
 -- 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