Repository: tobymao/sqlglot
Pull request: Fix: allow '[]' when parsing a nested type
Fixes #1377

cc: @cpcloud

Problem statement:
Casting to array of struct with duckdb fails to parse
```
In [17]: import sqlglot as sg

In [18]: sg.__version__
Out[18]: '11.4.5'

In [19]: sg.parse_one("select cast([struct_pack(a := 1)] as struct(a bigint)[])", read="duckdb")
...
ParseError: Expected TYPE after CAST. Line 1, Col: 38.
  select cast([struct_pack(a := 1)] as struct(a bigint)[])
```

Hints from issue discussion:
thanks, I'll take a look soon

Commit message: Add a test for array of arrays

Patch to review:
diff --git a/sqlglot/parser.py b/sqlglot/parser.py
index 20c63dcaf2..6df4145eca 100644
--- a/sqlglot/parser.py
+++ b/sqlglot/parser.py
@@ -2636,7 +2636,7 @@ def _parse_types(self, check_func: bool = False) -> t.Optional[exp.Expression]:
             self._match_r_paren()
             maybe_func = True
 
-        if not nested and self._match_pair(TokenType.L_BRACKET, TokenType.R_BRACKET):
+        if self._match_pair(TokenType.L_BRACKET, TokenType.R_BRACKET):
             this = exp.DataType(
                 this=exp.DataType.Type.ARRAY,
                 expressions=[exp.DataType.build(type_token.value, expressions=expressions)],
diff --git a/tests/dialects/test_duckdb.py b/tests/dialects/test_duckdb.py
index 3da52df128..cb7eeb7db0 100644
--- a/tests/dialects/test_duckdb.py
+++ b/tests/dialects/test_duckdb.py
@@ -432,6 +432,18 @@ def test_cast(self):
                 "snowflake": "CAST(COL AS ARRAY)",
             },
         )
+        self.validate_all(
+            "CAST([STRUCT_PACK(a := 1)] AS STRUCT(a BIGINT)[])",
+            write={
+                "duckdb": "CAST(LIST_VALUE({'a': 1}) AS STRUCT(a BIGINT)[])",
+            },
+        )
+        self.validate_all(
+            "CAST([STRUCT_PACK(a := 1)] AS STRUCT(a BIGINT)[][])",
+            write={
+                "duckdb": "CAST(LIST_VALUE({'a': 1}) AS STRUCT(a BIGINT)[][])",
+            },
+        )
 
     def test_bool_or(self):
         self.validate_all(


Code review comments:
diff_hunk: @@ -432,6 +432,18 @@ def test_cast(self):
                 "snowflake": "CAST(COL AS ARRAY)",
             },
         )
+        self.validate_all(
+            "CAST([STRUCT_PACK(a := 1)] AS STRUCT(a BIGINT)[])",
+            write={
+                "duckdb": "CAST(LIST_VALUE({'a': 1}) AS STRUCT(a BIGINT)[])",
+            },
+        )
+        self.validate_all(
+            "CAST([STRUCT_PACK(a := 1)] AS STRUCT(a BIGINT)[][])",
path: tests/dialects/test_duckdb.py
text: @user1:
This isn't valid according to duckdb, because you can't cast `array<T>` to `array<array<T>>`.

What I meant was to test the valid case of:

```
CAST([[STRUCT_PACK(a := 1)]] AS STRUCT(a BIGINT)[][])
```

@author:
Ah, thanks. I assume this can be transpiled to `CAST(LIST_VALUE(LIST_VALUE({'a': 1})) AS STRUCT(a BIGINT)[][])`, correct?

EDIT: checked it, seems to have the same behavior.