@@ -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-
188150def _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