Skip to content

Commit

Permalink
Fix: allow type column ops for bigquery
Browse files Browse the repository at this point in the history
  • Loading branch information
tobymao committed May 30, 2023
1 parent 2792eaa commit 6045b74
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 3 deletions.
3 changes: 2 additions & 1 deletion sqlglot/generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -802,7 +802,8 @@ def datatype_sql(self, expression: exp.DataType) -> str:
nested = f"{self.STRUCT_DELIMITER[0]}{interior}{self.STRUCT_DELIMITER[1]}"
if expression.args.get("values") is not None:
delimiters = ("[", "]") if type_value == exp.DataType.Type.ARRAY else ("(", ")")
values = f"{delimiters[0]}{self.expressions(expression, key='values')}{delimiters[1]}"
values = self.expressions(expression, key="values", flat=True)
values = f"{delimiters[0]}{values}{delimiters[1]}"
else:
nested = f"({interior})"

Expand Down
22 changes: 20 additions & 2 deletions sqlglot/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -2842,7 +2842,7 @@ def _parse_type(self) -> t.Optional[exp.Expression]:
if not data_type.expressions:
self._retreat(index)
return self._parse_column()
return data_type
return self._parse_column_ops(data_type)

return this

Expand Down Expand Up @@ -2985,6 +2985,9 @@ def _parse_column(self) -> t.Optional[exp.Expression]:
this = self.expression(exp.Column, this=this)
elif not this:
return self._parse_bracket(this)
return self._parse_column_ops(this)

def _parse_column_ops(self, this: exp.Expression) -> exp.Expression:
this = self._parse_bracket(this)

while self._match_set(self.COLUMN_OPERATORS):
Expand Down Expand Up @@ -3029,7 +3032,6 @@ def _parse_column(self) -> t.Optional[exp.Expression]:
else:
this = self.expression(exp.Dot, this=this, expression=field)
this = self._parse_bracket(this)

return this

def _parse_primary(self) -> t.Optional[exp.Expression]:
Expand Down Expand Up @@ -3462,7 +3464,15 @@ def _parse_primary_key(self) -> exp.Expression:
options = self._parse_key_constraint_options()
return self.expression(exp.PrimaryKey, expressions=expressions, options=options)

@t.overload
def _parse_bracket(self, this: exp.Expression) -> exp.Expression:
...

@t.overload
def _parse_bracket(self, this: t.Optional[exp.Expression]) -> t.Optional[exp.Expression]:
...

def _parse_bracket(self, this):
if not self._match_set((TokenType.L_BRACKET, TokenType.L_BRACE)):
return this

Expand Down Expand Up @@ -4516,9 +4526,17 @@ def _match_text_seq(self, *texts, advance=True):

return True

@t.overload
def _replace_columns_with_dots(self, this: exp.Expression) -> exp.Expression:
...

@t.overload
def _replace_columns_with_dots(
self, this: t.Optional[exp.Expression]
) -> t.Optional[exp.Expression]:
...

def _replace_columns_with_dots(self, this):
if isinstance(this, exp.Dot):
exp.replace_children(this, self._replace_columns_with_dots)
elif isinstance(this, exp.Column):
Expand Down
1 change: 1 addition & 0 deletions tests/dialects/test_bigquery.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ def test_bigquery(self):
self.validate_identity("SELECT DISTINCT AS STRUCT 1 AS a, 2 AS b")
self.validate_identity("SELECT AS VALUE STRUCT(1 AS a, 2 AS b)")
self.validate_identity("SELECT STRUCT<ARRAY<STRING>>(['2023-01-17'])")
self.validate_identity("SELECT STRUCT<STRING>((SELECT a FROM b.c LIMIT 1)).*")
self.validate_identity("SELECT * FROM q UNPIVOT(values FOR quarter IN (b, c))")
self.validate_identity("""CREATE TABLE x (a STRUCT<values ARRAY<INT64>>)""")
self.validate_identity("""CREATE TABLE x (a STRUCT<b STRING OPTIONS (description='b')>)""")
Expand Down

0 comments on commit 6045b74

Please sign in to comment.