Skip to content

Commit a735c18

Browse files
committed
pr feedback
1 parent e87eefa commit a735c18

File tree

1 file changed

+38
-44
lines changed

1 file changed

+38
-44
lines changed

sqlglot/dialects/duckdb.py

Lines changed: 38 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -147,44 +147,6 @@ def _build_greatest(args: t.List) -> exp.Greatest:
147147
return exp.Greatest(this=seq_get(args, 0), expressions=args[1:])
148148

149149

150-
def _approx_quantiles_sql(self: DuckDB.Generator, expression: exp.ApproxQuantiles) -> str:
151-
"""
152-
BigQuery's APPROX_QUANTILES(expr, n) returns an array of n+1 approximate quantile values
153-
dividing the input distribution into n equal-sized buckets.
154-
155-
Both BigQuery and DuckDB use approximate algorithms for quantile estimation, but BigQuery
156-
does not document the specific algorithm used so results may differ. DuckDB does not
157-
support RESPECT NULLS.
158-
"""
159-
this = expression.this
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
168-
169-
if isinstance(num_quantiles_expr, (exp.Cast, exp.TryCast)):
170-
num_quantiles_expr = num_quantiles_expr.this.unnest()
171-
172-
if not isinstance(num_quantiles_expr, exp.Literal) or not num_quantiles_expr.is_number:
173-
self.unsupported("APPROX_QUANTILES bucket count must be a positive integer")
174-
return self.function_fallback_sql(expression)
175-
176-
num_quantiles = num_quantiles_expr.to_py()
177-
if not num_quantiles or not isinstance(num_quantiles, int) or num_quantiles <= 0:
178-
self.unsupported("APPROX_QUANTILES bucket count must be a positive integer")
179-
return self.function_fallback_sql(expression)
180-
181-
quantiles = [
182-
exp.Literal.number(Decimal(i) / Decimal(num_quantiles)) for i in range(num_quantiles + 1)
183-
]
184-
185-
return self.sql(exp.ApproxQuantile(this=this, quantile=exp.Array(expressions=quantiles)))
186-
187-
188150
def _show_parser(*args: t.Any, **kwargs: t.Any) -> t.Callable[[DuckDB.Parser], exp.Show]:
189151
def _parse(self: DuckDB.Parser) -> exp.Show:
190152
return self._parse_show_duckdb(*args, **kwargs)
@@ -867,7 +829,6 @@ class Generator(generator.Generator):
867829
**generator.Generator.TRANSFORMS,
868830
exp.AnyValue: _anyvalue_sql,
869831
exp.ApproxDistinct: approx_count_distinct_sql,
870-
exp.ApproxQuantiles: _approx_quantiles_sql,
871832
exp.Array: transforms.preprocess(
872833
[transforms.inherit_struct_field_names],
873834
generator=inline_array_unless_query,
@@ -1447,11 +1408,7 @@ def ignorenulls_sql(self, expression: exp.IgnoreNulls) -> str:
14471408
if isinstance(this, exp.First):
14481409
this = exp.AnyValue(this=this.this)
14491410

1450-
# IGNORE NULLS is the default behavior for APPROX_QUANTILE
1451-
if isinstance(this, exp.ApproxQuantiles):
1452-
return self.sql(this)
1453-
1454-
if not isinstance(this, exp.AnyValue):
1411+
if not isinstance(this, (exp.AnyValue, exp.ApproxQuantiles)):
14551412
self.unsupported("IGNORE NULLS is not supported for non-window functions.")
14561413

14571414
return self.sql(this)
@@ -1643,3 +1600,40 @@ def round_sql(self, expression: exp.Round) -> str:
16431600
truncate = None
16441601

16451602
return self.func(func, this, decimals, truncate)
1603+
1604+
def approxquantiles_sql(self: DuckDB.Generator, expression: exp.ApproxQuantiles) -> str:
1605+
"""
1606+
BigQuery's APPROX_QUANTILES(expr, n) returns an array of n+1 approximate quantile values
1607+
dividing the input distribution into n equal-sized buckets.
1608+
1609+
Both BigQuery and DuckDB use approximate algorithms for quantile estimation, but BigQuery
1610+
does not document the specific algorithm used so results may differ. DuckDB does not
1611+
support RESPECT NULLS.
1612+
"""
1613+
this = expression.this
1614+
if isinstance(this, exp.Distinct):
1615+
# APPROX_QUANTILES requires 2 args and DISTINCT node grabs both
1616+
if len(this.expressions) < 2:
1617+
self.unsupported("APPROX_QUANTILES requires a bucket count argument")
1618+
return self.function_fallback_sql(expression)
1619+
num_quantiles_expr = this.expressions[1].pop()
1620+
else:
1621+
num_quantiles_expr = expression.expression
1622+
1623+
if not isinstance(num_quantiles_expr, exp.Literal) or not num_quantiles_expr.is_int:
1624+
self.unsupported("APPROX_QUANTILES bucket count must be a positive integer")
1625+
return self.function_fallback_sql(expression)
1626+
1627+
num_quantiles = t.cast(int, num_quantiles_expr.to_py())
1628+
if num_quantiles <= 0:
1629+
self.unsupported("APPROX_QUANTILES bucket count must be a positive integer")
1630+
return self.function_fallback_sql(expression)
1631+
1632+
quantiles = [
1633+
exp.Literal.number(Decimal(i) / Decimal(num_quantiles))
1634+
for i in range(num_quantiles + 1)
1635+
]
1636+
1637+
return self.sql(
1638+
exp.ApproxQuantile(this=this, quantile=exp.Array(expressions=quantiles))
1639+
)

0 commit comments

Comments
 (0)