Skip to content

Commit

Permalink
Fix(bigquery): STRING_AGG parsing bug (#1846)
Browse files Browse the repository at this point in the history
* Fix(bigquery): STRING_AGG parsing bug

* Refactor
  • Loading branch information
georgesittas authored Jun 28, 2023
1 parent 7cb01a0 commit abdf34b
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 8 deletions.
19 changes: 11 additions & 8 deletions sqlglot/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -3732,20 +3732,23 @@ def _parse_concat(self) -> t.Optional[exp.Expression]:
)

def _parse_string_agg(self) -> exp.Expression:
expression: t.Optional[exp.Expression]

if self._match(TokenType.DISTINCT):
args = self._parse_csv(self._parse_conjunction)
expression = self.expression(exp.Distinct, expressions=[seq_get(args, 0)])
args: t.List[t.Optional[exp.Expression]] = [
self.expression(exp.Distinct, expressions=[self._parse_conjunction()])
]
if self._match(TokenType.COMMA):
args.extend(self._parse_csv(self._parse_conjunction))
else:
args = self._parse_csv(self._parse_conjunction)
expression = seq_get(args, 0)

index = self._index
if not self._match(TokenType.R_PAREN):
# postgres: STRING_AGG([DISTINCT] expression, separator [ORDER BY expression1 {ASC | DESC} [, ...]])
order = self._parse_order(this=expression)
return self.expression(exp.GroupConcat, this=order, separator=seq_get(args, 1))
return self.expression(
exp.GroupConcat,
this=seq_get(args, 0),
separator=self._parse_order(this=seq_get(args, 1)),
)

# Checks if we can parse an order clause: WITHIN GROUP (ORDER BY <order_by_expression_list> [ASC | DESC]).
# This is done "manually", instead of letting _parse_window parse it into an exp.WithinGroup node, so that
Expand All @@ -3755,7 +3758,7 @@ def _parse_string_agg(self) -> exp.Expression:
return self.validate_expression(exp.GroupConcat.from_arg_list(args), args)

self._match_l_paren() # The corresponding match_r_paren will be called in parse_function (caller)
order = self._parse_order(this=expression)
order = self._parse_order(this=seq_get(args, 0))
return self.expression(exp.GroupConcat, this=order, separator=seq_get(args, 1))

def _parse_convert(self, strict: bool) -> t.Optional[exp.Expression]:
Expand Down
4 changes: 4 additions & 0 deletions tests/dialects/test_bigquery.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ def test_bigquery(self):
with self.assertRaises(ParseError):
transpile("SELECT * FROM UNNEST(x) AS x(y)", read="bigquery")

self.validate_identity("STRING_AGG(a)")
self.validate_identity("STRING_AGG(a, ' & ')")
self.validate_identity("STRING_AGG(DISTINCT a, ' & ')")
self.validate_identity("STRING_AGG(a, ' & ' ORDER BY LENGTH(a))")
self.validate_identity("DATE(2016, 12, 25)")
self.validate_identity("DATE(CAST('2016-12-25 23:59:59' AS DATETIME))")
self.validate_identity("SELECT foo IN UNNEST(bar) AS bla")
Expand Down

0 comments on commit abdf34b

Please sign in to comment.