Repository: tobymao/sqlglot

Issue:
Optimizer is incorrect when superfluous parens wrap subqueries
```
from sqlglot import parse_one
from sqlglot.optimizer import optimize
from sqlglot.dialects import Snowflake

sql = """
SELECT 
  ("SUBQUERY_0"."KEY") AS "SUBQUERY_1_COL_0"
FROM 
  (
    SELECT 
      * 
    FROM 
      ((( -- <-------------- ***note multiple parens****
          select 
            * 
          from 
            (
              select 
                event_name as key, 
                insert_ts 
              from 
                (
                  select 
                    insert_ts, 
                    event_name 
                  from 
                    sales
                  where 
                    insert_ts > '2023-08-07 21:03:35.590 -0700'
                )
        )
      ))) AS "SF_CONNECTOR_QUERY_ALIAS"
  ) AS "SUBQUERY_0"

"""

print("========= with parens ==========")
optimized = optimize(parse_one(sql, dialect=Snowflake), dialect=Snowflake)
print(optimized.sql(pretty=True))

print("========= without parens ==========")
without_double_parens = sql.replace("((", "").replace("))","")
optimized = optimize(parse_one(without_double_parens, dialect=Snowflake), dialect=Snowflake)
print(optimized.sql(pretty=True))
```
returns

```
========= with parens ==========
SELECT
  "SF_CONNECTOR_QUERY_ALIAS"."KEY" AS "SUBQUERY_1_COL_0"
FROM (
  (
    "cte" AS "cte"
  )
) AS "SF_CONNECTOR_QUERY_ALIAS"
========= without parens ==========
SELECT
  "SALES"."EVENT_NAME" AS "SUBQUERY_1_COL_0"
FROM "SALES" AS "SALES"
WHERE
  "SALES"."INSERT_TS" > '2023-08-07 21:03:35.590 -0700'
```

I've run into a case where the optimizer is sensitive to the number of [superfluous] parentheses wrapping a subquery, and further returns incorrect logic in the "with parens" case. Note entirely missing `where` clause in the `with parens` case.

The parsed ASTs seem to be the same, so I'm assuming this is in the optimizer somewhere. 


Discussion:

Resolving patch:
diff --git a/sqlglot/expressions.py b/sqlglot/expressions.py
--- a/sqlglot/expressions.py
+++ b/sqlglot/expressions.py
@@ -3263,6 +3263,23 @@ def unnest(self):
             expression = expression.this
         return expression
 
+    def unwrap(self) -> Subquery:
+        expression = self
+        while expression.same_parent and expression.is_wrapper:
+            expression = t.cast(Subquery, expression.parent)
+        return expression
+
+    @property
+    def is_wrapper(self) -> bool:
+        """
+        Whether this Subquery acts as a simple wrapper around another expression.
+
+        SELECT * FROM (((SELECT * FROM t)))
+                      ^
+                      This corresponds to a "wrapper" Subquery node
+        """
+        return all(v is None for k, v in self.args.items() if k != "this")
+
     @property
     def is_star(self) -> bool:
         return self.this.is_star
diff --git a/sqlglot/optimizer/eliminate_subqueries.py b/sqlglot/optimizer/eliminate_subqueries.py
--- a/sqlglot/optimizer/eliminate_subqueries.py
+++ b/sqlglot/optimizer/eliminate_subqueries.py
@@ -142,13 +142,14 @@ def _eliminate_derived_table(scope, existing_ctes, taken):
     if scope.parent.pivots or isinstance(scope.parent.expression, exp.Lateral):
         return None
 
-    parent = scope.expression.parent
+    # Get rid of redundant exp.Subquery expressions, i.e. those that are just used as wrappers
+    to_replace = scope.expression.parent.unwrap()
     name, cte = _new_cte(scope, existing_ctes, taken)
+    table = exp.alias_(exp.table_(name), alias=to_replace.alias or name)
+    table.set("joins", to_replace.args.get("joins"))
 
-    table = exp.alias_(exp.table_(name), alias=parent.alias or name)
-    table.set("joins", parent.args.get("joins"))
+    to_replace.replace(table)
 
-    parent.replace(table)
     return cte
 
 


Test patch:
diff --git a/tests/fixtures/optimizer/eliminate_subqueries.sql b/tests/fixtures/optimizer/eliminate_subqueries.sql
--- a/tests/fixtures/optimizer/eliminate_subqueries.sql
+++ b/tests/fixtures/optimizer/eliminate_subqueries.sql
@@ -97,3 +97,7 @@ WITH cte1 AS (SELECT a FROM x), cte2 AS (SELECT a FROM cte1 AS cte3) SELECT a FR
 -- Wrapped subquery joined with table
 SELECT * FROM ((SELECT c FROM t1) JOIN t2);
 WITH cte AS (SELECT c FROM t1) SELECT * FROM (cte AS cte, t2);
+
+-- Wrapped subquery with redundant parentheses
+SELECT * FROM (((SELECT * FROM tbl)));
+WITH cte AS (SELECT * FROM tbl) SELECT * FROM cte AS cte;
diff --git a/tests/fixtures/optimizer/optimizer.sql b/tests/fixtures/optimizer/optimizer.sql
--- a/tests/fixtures/optimizer/optimizer.sql
+++ b/tests/fixtures/optimizer/optimizer.sql
@@ -950,3 +950,40 @@ JOIN "n" AS "foo"("a")
 SELECT CONCAT('a', 'b') || CONCAT(CONCAT('c', 'd'), CONCAT('e', 'f')) + ('g' || 'h' || 'i');
 SELECT
   'abcdefghi' AS "_col_0";
+
+# title: complex query with derived tables and redundant parentheses
+# execute: false
+# dialect: snowflake
+SELECT
+  ("SUBQUERY_0"."KEY") AS "SUBQUERY_1_COL_0"
+FROM
+  (
+    SELECT
+      *
+    FROM
+      (((
+          SELECT
+            *
+          FROM
+            (
+              SELECT
+                event_name AS key,
+                insert_ts
+              FROM
+                (
+                  SELECT
+                    insert_ts,
+                    event_name
+                  FROM
+                    sales
+                  WHERE
+                    insert_ts > '2023-08-07 21:03:35.590 -0700'
+                )
+            )
+      ))) AS "SF_CONNECTOR_QUERY_ALIAS"
+  ) AS "SUBQUERY_0";
+SELECT
+  "SALES"."EVENT_NAME" AS "SUBQUERY_1_COL_0"
+FROM "SALES" AS "SALES"
+WHERE
+  "SALES"."INSERT_TS" > '2023-08-07 21:03:35.590 -0700';
diff --git a/tests/test_expressions.py b/tests/test_expressions.py
--- a/tests/test_expressions.py
+++ b/tests/test_expressions.py
@@ -884,3 +884,15 @@ def test_set_metadata(self):
 
         ast.meta["some_other_meta_key"] = "some_other_meta_value"
         self.assertEqual(ast.meta.get("some_other_meta_key"), "some_other_meta_value")
+
+    def test_unnest(self):
+        ast = parse_one("SELECT (((1)))")
+        self.assertIs(ast.selects[0].unnest(), ast.find(exp.Literal))
+
+        ast = parse_one("SELECT * FROM (((SELECT * FROM t)))")
+        self.assertIs(ast.args["from"].this.unnest(), list(ast.find_all(exp.Select))[1])
+
+        ast = parse_one("SELECT * FROM ((((SELECT * FROM t))) AS foo)")
+        second_subquery = ast.args["from"].this.this
+        innermost_subquery = list(ast.find_all(exp.Select))[1].parent
+        self.assertIs(second_subquery, innermost_subquery.unwrap())