Skip to content

Commit 69a5fa6

Browse files
committed
remove BQ parser, handle distinct in duck generator
1 parent 6eb954c commit 69a5fa6

File tree

3 files changed

+22
-23
lines changed

3 files changed

+22
-23
lines changed

sqlglot/dialects/bigquery.py

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -625,7 +625,6 @@ class Parser(parser.Parser):
625625
exp.JSONArray, expressions=self._parse_csv(self._parse_bitwise)
626626
),
627627
"MAKE_INTERVAL": lambda self: self._parse_make_interval(),
628-
"APPROX_QUANTILES": lambda self: self._parse_approx_quantiles(),
629628
"PREDICT": lambda self: self._parse_ml(exp.Predict),
630629
"TRANSLATE": lambda self: self._parse_translate(),
631630
"FEATURES_AT_TIME": lambda self: self._parse_features_at_time(),
@@ -919,21 +918,6 @@ def _parse_make_interval(self) -> exp.MakeInterval:
919918

920919
return expr
921920

922-
def _parse_approx_quantiles(self) -> t.Optional[exp.Expression]:
923-
# APPROX_QUANTILES([DISTINCT] expression, number [{IGNORE | RESPECT} NULLS])
924-
distinct = self._match(TokenType.DISTINCT)
925-
this = self._parse_disjunction()
926-
if distinct:
927-
this = self.expression(exp.Distinct, expressions=[this])
928-
929-
self._match(TokenType.COMMA)
930-
expression = self._parse_bitwise()
931-
if not expression:
932-
self.raise_error("Expected number of quantiles argument in APPROX_QUANTILES")
933-
934-
func = self.expression(exp.ApproxQuantiles, this=this, expression=expression)
935-
return self._parse_respect_or_ignore_nulls(func)
936-
937921
def _parse_ml(self, expr_type: t.Type[E], **kwargs) -> E:
938922
self._match_text_seq("MODEL")
939923
this = self._parse_table()

sqlglot/dialects/duckdb.py

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -152,16 +152,19 @@ def _approx_quantiles_sql(self: DuckDB.Generator, expression: exp.ApproxQuantile
152152
BigQuery's APPROX_QUANTILES(expr, n) returns an array of n+1 approximate quantile values
153153
dividing the input distribution into n equal-sized buckets.
154154
155-
This is transpiled to DuckDB as an array of individual APPROX_QUANTILE calls for each
156-
quantile value (0/n, 1/n, 2/n, ..., n/n):
157-
158-
APPROX_QUANTILES(x, 2) -> [APPROX_QUANTILE(x, 0), APPROX_QUANTILE(x, 0.5), APPROX_QUANTILE(x, 1)]
159-
160155
Both BigQuery and DuckDB use approximate algorithms for quantile estimation, but BigQuery
161-
does not document the specific algorithm used so results may differ.
156+
does not document the specific algorithm used so results may differ. DuckDB does not
157+
support RESPECT NULLS.
162158
"""
163159
this = expression.this
164-
num_quantiles_expr = expression.expression
160+
if isinstance(this, exp.Distinct):
161+
# APPROX_QUANTILES requires 2 args and DISTINCT node grabs both
162+
if len(this.expressions) < 2:
163+
self.unsupported("APPROX_QUANTILES requires a bucket count argument")
164+
return self.function_fallback_sql(expression)
165+
num_quantiles_expr = this.expressions.pop(1)
166+
else:
167+
num_quantiles_expr = expression.expression
165168

166169
if isinstance(num_quantiles_expr, (exp.Cast, exp.TryCast)):
167170
num_quantiles_expr = num_quantiles_expr.this.unnest()

tests/dialects/test_bigquery.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3513,6 +3513,18 @@ def test_approx_quantiles_to_duckdb(self):
35133513
"duckdb", unsupported_level=ErrorLevel.RAISE
35143514
)
35153515

3516+
with self.subTest("missing bucket count"):
3517+
with self.assertRaises(UnsupportedError):
3518+
self.parse_one("APPROX_QUANTILES(x)").sql(
3519+
"duckdb", unsupported_level=ErrorLevel.RAISE
3520+
)
3521+
3522+
with self.subTest("missing bucket count with DISTINCT"):
3523+
with self.assertRaises(UnsupportedError):
3524+
self.parse_one("APPROX_QUANTILES(DISTINCT x)").sql(
3525+
"duckdb", unsupported_level=ErrorLevel.RAISE
3526+
)
3527+
35163528
with self.subTest("APPROX_QUANTILES IGNORE NULLS"):
35173529
# No warning: IGNORE NULLS is the default behavior in DuckDB
35183530
from sqlglot.generator import logger as generator_logger

0 commit comments

Comments
 (0)