Repository: DerekStride/tree-sitter-sql (language: python)

Issue:
select statements enclosed in parentheses next to 'union' aren't parsed proplerly
Hi, the following query isn't parsed correctly, please have a look.
```
-- CREATE TABLE tb AS
(
  SELECT 1 as col
)
UNION ALL
(
  SELECT 2 as col
);
```


Add support for parenthesized expressions & EXISTS subquery
## What

There's three changes being made in this PR, each are contained to individual commits.
1. Support for parenthesized expression. e.g. wrapping expressions in `(` & `)` to group them.
2. Support for the [`EXISTS`](https://dev.mysql.com/doc/refman/8.0/en/exists-and-not-exists-subqueries.html) expression.
    - Includes subquery support for `IN`
    - Excludes `NOT IN`, there was conflicts with precedence that I want to sort out separately.
3. Support for [`ANY`, `SOME`, & `ALL`](https://www.postgresql.org/docs/current/functions-subquery.html)


Discussion / hints:

FYI I've enabled branch protection to require at least 1 approval & all the test suites passing before merging a PR
I've update the PR (& the PR description) to include the suggested changes.

The one exception was `NOT IN` ended up causing precedence issues. I can open a separate issue to explore that in the future.
LGTM

Fix patch:
diff --git a/grammar.js b/grammar.js
index bc08e82e..02384b8c 100644
--- a/grammar.js
+++ b/grammar.js
@@ -694,19 +694,41 @@ module.exports = grammar({
             repeat($._table_settings),
             seq(
               $.keyword_as,
-              choice(
-                $._select_statement,
-                seq(
-                  $._cte,
-                  $._select_statement,
-                ),
-              ),
+              $.create_query,
             ),
           ),
         ),
       ),
     ),
 
+    create_query: $ => choice(
+      $._select_statement,
+      seq(
+        $._cte,
+        $._select_statement,
+      ),
+      seq(
+        $._inner_create_query,
+        repeat(
+          seq(
+            $.keyword_union,
+            optional($.keyword_all),
+            $._inner_create_query,
+          ),
+        )
+      ),
+    ),
+
+    _inner_create_query: $ => choice(
+      seq( '(', $._select_statement, ')'),
+      seq(
+        '(',
+        $._cte,
+        $._select_statement,
+        ')',
+      ),
+    ),
+
     create_view: $ => prec.right(
       seq(
         $.keyword_create,
@@ -718,18 +740,7 @@ module.exports = grammar({
         $.table_reference,
         optional(paren_list($.identifier)),
         $.keyword_as,
-        choice(
-          $._select_statement,
-          seq(
-            $._cte,
-            $._select_statement,
-          ),
-          seq(
-            '(',
-            $._select_statement,
-            ')',
-          ),
-        ),
+        $.create_query,
         optional(
           seq(
             $.keyword_with,
@@ -754,13 +765,7 @@ module.exports = grammar({
         optional($._if_not_exists),
         $.table_reference,
         $.keyword_as,
-        choice(
-          $._select_statement,
-          seq(
-              $._cte,
-              $._select_statement,
-          ),
-        ),
+        $.create_query,
         optional(
           choice(
             seq(


Test patch:
diff --git a/test/corpus/create.txt b/test/corpus/create.txt
index 50c85625..2d4a7f66 100644
--- a/test/corpus/create.txt
+++ b/test/corpus/create.txt
@@ -520,17 +520,17 @@ CREATE TABLE my_table (
             (keyword_null))
           (direction
             (keyword_asc))))
-        (table_option
-          name: (keyword_engine)
-          value: (identifier))
-        (table_option
-          name: (keyword_default))
-        (table_option
-          name: (identifier)
-          value: (identifier))
-        (table_option
-          name: (identifier)
-          value: (identifier)))))
+      (table_option
+        name: (keyword_engine)
+        value: (identifier))
+      (table_option
+        name: (keyword_default))
+      (table_option
+        name: (identifier)
+        value: (identifier))
+      (table_option
+        name: (identifier)
+        value: (identifier)))))
 
 ================================================================================
 Create view
@@ -549,15 +549,16 @@ SELECT * FROM my_table;
       (table_reference
         name: (identifier))
       (keyword_as)
-      (select
-        (keyword_select)
-        (select_expression
-          (all_fields)))
-      (from
-        (keyword_from)
-        (relation
-          (table_reference
-            name: (identifier)))))))
+      (create_query
+        (select
+          (keyword_select)
+          (select_expression
+            (all_fields)))
+        (from
+          (keyword_from)
+          (relation
+            (table_reference
+              name: (identifier))))))))
 
 ================================================================================
 Create or replace view
@@ -578,15 +579,16 @@ SELECT * FROM my_table;
       (table_reference
         name: (identifier))
       (keyword_as)
-      (select
-        (keyword_select)
-        (select_expression
-          (all_fields)))
-      (from
-        (keyword_from)
-        (relation
-          (table_reference
-            name: (identifier)))))))
+      (create_query
+        (select
+          (keyword_select)
+          (select_expression
+            (all_fields)))
+        (from
+          (keyword_from)
+          (relation
+            (table_reference
+              name: (identifier))))))))
 
 ================================================================================
 Create temp view
@@ -606,11 +608,12 @@ CREATE TEMP VIEW foo AS SELECT 1;
       (table_reference
         (identifier))
       (keyword_as)
-      (select
-        (keyword_select)
-        (select_expression
-          (term
-            (literal))))))
+      (create_query
+        (select
+          (keyword_select)
+          (select_expression
+            (term
+              (literal)))))))
   (statement
     (create_view
       (keyword_create)
@@ -619,11 +622,12 @@ CREATE TEMP VIEW foo AS SELECT 1;
       (table_reference
         (identifier))
       (keyword_as)
-      (select
-        (keyword_select)
-        (select_expression
-          (term
-            (literal)))))))
+      (create_query
+        (select
+          (keyword_select)
+          (select_expression
+            (term
+              (literal))))))))
 
 ================================================================================
 Create view with columns
@@ -643,15 +647,16 @@ CREATE VIEW foo(a, b) AS SELECT 1 a, 2 b;
       (identifier)
       (identifier)
       (keyword_as)
-      (select
-        (keyword_select)
-        (select_expression
-          (term
-            (literal)
-            (identifier))
-          (term
-            (literal)
-            (identifier)))))))
+      (create_query
+        (select
+          (keyword_select)
+          (select_expression
+            (term
+              (literal)
+              (identifier))
+            (term
+              (literal)
+              (identifier))))))))
 
 ================================================================================
 Create view with check option
@@ -670,11 +675,12 @@ CREATE VIEW foo AS SELECT 1 WITH CASCADED CHECK OPTION;
       (table_reference
         (identifier))
       (keyword_as)
-      (select
-        (keyword_select)
-        (select_expression
-          (term
-            (literal))))
+      (create_query
+        (select
+          (keyword_select)
+          (select_expression
+            (term
+              (literal)))))
       (keyword_with)
       (keyword_check)
       (keyword_option)))
@@ -685,11 +691,12 @@ CREATE VIEW foo AS SELECT 1 WITH CASCADED CHECK OPTION;
       (table_reference
         (identifier))
       (keyword_as)
-      (select
-        (keyword_select)
-        (select_expression
-          (term
-            (literal))))
+      (create_query
+        (select
+          (keyword_select)
+          (select_expression
+            (term
+              (literal)))))
       (keyword_with)
       (keyword_local)
       (keyword_check)
@@ -701,11 +708,12 @@ CREATE VIEW foo AS SELECT 1 WITH CASCADED CHECK OPTION;
       (table_reference
         (identifier))
       (keyword_as)
-      (select
-        (keyword_select)
-        (select_expression
-          (term
-            (literal))))
+      (create_query
+        (select
+          (keyword_select)
+          (select_expression
+            (term
+              (literal)))))
       (keyword_with)
       (keyword_cascaded)
       (keyword_check)
@@ -730,15 +738,16 @@ WITH NO DATA;
       (table_reference
         name: (identifier))
       (keyword_as)
-      (select
-        (keyword_select)
-        (select_expression
-          (all_fields)))
-      (from
-        (keyword_from)
-        (relation
-          (table_reference
-            name: (identifier))))
+      (create_query
+        (select
+          (keyword_select)
+          (select_expression
+            (all_fields)))
+        (from
+          (keyword_from)
+          (relation
+            (table_reference
+              name: (identifier)))))
       (keyword_with)
       (keyword_no)
       (keyword_data))))
@@ -762,15 +771,16 @@ WITH NO DATA
       (table_reference
         name: (identifier))
       (keyword_as)
-      (select
-        (keyword_select)
-        (select_expression
-          (all_fields)))
-      (from
-        (keyword_from)
-        (relation
-          (table_reference
-            name: (identifier))))
+      (create_query
+        (select
+          (keyword_select)
+          (select_expression
+            (all_fields)))
+        (from
+          (keyword_from)
+          (relation
+            (table_reference
+              name: (identifier)))))
       (keyword_with)
       (keyword_no)
       (keyword_data))))
@@ -1106,17 +1116,17 @@ CREATE TABLE some_table(
                 name: (identifier))
               (column
                 name: (identifier))))))
-        (table_option
-          (keyword_default)
-          (keyword_character)
-          (keyword_set)
-          (identifier))
-        (table_option
-          (keyword_collate)
-          (identifier))
-        (table_option
-          name: (keyword_engine)
-          value: (identifier)))))
+      (table_option
+        (keyword_default)
+        (keyword_character)
+        (keyword_set)
+        (identifier))
+      (table_option
+        (keyword_collate)
+        (identifier))
+      (table_option
+        name: (keyword_engine)
+        value: (identifier)))))
 
 ================================================================================
 Create table as select
@@ -1134,15 +1144,16 @@ CREATE TABLE tableName AS SELECT * FROM otherTable;
       (table_reference
         name: (identifier))
       (keyword_as)
-      (select
-        (keyword_select)
-        (select_expression
-          (all_fields)))
-      (from
-        (keyword_from)
-        (relation
-          (table_reference
-            name: (identifier)))))))
+      (create_query
+        (select
+          (keyword_select)
+          (select_expression
+            (all_fields)))
+        (from
+          (keyword_from)
+          (relation
+            (table_reference
+              name: (identifier))))))))
 
 ================================================================================
 Create table as select with cte
@@ -1163,31 +1174,73 @@ SELECT * FROM _cte
       (table_reference
         (identifier))
       (keyword_as)
-      (keyword_with)
-      (cte
-        (identifier)
-        (keyword_as)
-        (statement
-          (select
-            (keyword_select)
-            (select_expression
-              (term
-                (field
-                  (identifier)))))
-          (from
-            (keyword_from)
-            (relation
-              (table_reference
-                (identifier))))))
-      (select
-        (keyword_select)
-        (select_expression
-          (all_fields)))
-      (from
-        (keyword_from)
-        (relation
-          (table_reference
-            (identifier)))))))
+      (create_query
+        (keyword_with)
+        (cte
+          (identifier)
+          (keyword_as)
+          (statement
+            (select
+              (keyword_select)
+              (select_expression
+                (term
+                  (field
+                    (identifier)))))
+            (from
+              (keyword_from)
+              (relation
+                (table_reference
+                  (identifier))))))
+        (select
+          (keyword_select)
+          (select_expression
+            (all_fields)))
+        (from
+          (keyword_from)
+          (relation
+            (table_reference
+              (identifier))))))))
+
+================================================================================
+Create table from select statement with parenthesis
+================================================================================
+
+CREATE TABLE tb AS
+(
+  SELECT 1 as col
+)
+UNION ALL
+(
+  SELECT 2 as col
+);
+
+--------------------------------------------------------------------------------
+
+(program
+  (statement
+    (create_table
+      (keyword_create)
+      (keyword_table)
+      (table_reference
+        (identifier))
+      (keyword_as)
+      (create_query
+        (select
+          (keyword_select)
+          (select_expression
+            (term
+              (literal)
+              (keyword_as)
+              (identifier))))
+        (keyword_union)
+        (keyword_all)
+        (select
+          (keyword_select)
+          (select_expression
+            (term
+              (literal)
+              (keyword_as)
+              (identifier))))))))
 
 ================================================================================
 Create view as select with cte
@@ -1208,31 +1261,32 @@ SELECT * FROM _cte
       (table_reference
         (identifier))
       (keyword_as)
-      (keyword_with)
-      (cte
-        (identifier)
-        (keyword_as)
-        (statement
-          (select
-            (keyword_select)
-            (select_expression
-              (term
-                (field
-                  (identifier)))))
-          (from
-            (keyword_from)
-            (relation
-              (table_reference
-                (identifier))))))
-      (select
-        (keyword_select)
-        (select_expression
-          (all_fields)))
-      (from
-        (keyword_from)
-        (relation
-          (table_reference
-            (identifier)))))))
+      (create_query
+        (keyword_with)
+        (cte
+          (identifier)
+          (keyword_as)
+          (statement
+            (select
+              (keyword_select)
+              (select_expression
+                (term
+                  (field
+                    (identifier)))))
+            (from
+              (keyword_from)
+              (relation
+                (table_reference
+                  (identifier))))))
+        (select
+          (keyword_select)
+          (select_expression
+            (all_fields)))
+        (from
+          (keyword_from)
+          (relation
+            (table_reference
+              (identifier))))))))
 
 ================================================================================
 Create materialized view as select with cte
@@ -1254,31 +1308,32 @@ SELECT * FROM _cte
       (table_reference
         (identifier))
       (keyword_as)
-      (keyword_with)
-      (cte
-        (identifier)
-        (keyword_as)
-        (statement
-          (select
-            (keyword_select)
-            (select_expression
-              (term
-                (field
-                  (identifier)))))
-          (from
-            (keyword_from)
-            (relation
-              (table_reference
-                (identifier))))))
-      (select
-        (keyword_select)
-        (select_expression
-          (all_fields)))
-      (from
-        (keyword_from)
-        (relation
-          (table_reference
-            (identifier)))))))
+      (create_query
+        (keyword_with)
+        (cte
+          (identifier)
+          (keyword_as)
+          (statement
+            (select
+              (keyword_select)
+              (select_expression
+                (term
+                  (field
+                    (identifier)))))
+            (from
+              (keyword_from)
+              (relation
+                (table_reference
+                  (identifier))))))
+        (select
+          (keyword_select)
+          (select_expression
+            (all_fields)))
+        (from
+          (keyword_from)
+          (relation
+            (table_reference
+              (identifier))))))))
 
 ================================================================================
 Create hive table