@@ -142,49 +142,6 @@ def _build_make_timestamp(args: t.List) -> exp.Expression:
142142 )
143143
144144
145- def _build_greatest (args : t .List ) -> exp .Greatest :
146- """Build GREATEST with all arguments properly distributed."""
147- return exp .Greatest (this = seq_get (args , 0 ), expressions = args [1 :])
148-
149-
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-
188145def _show_parser (* args : t .Any , ** kwargs : t .Any ) -> t .Callable [[DuckDB .Parser ], exp .Show ]:
189146 def _parse (self : DuckDB .Parser ) -> exp .Show :
190147 return self ._parse_show_duckdb (* args , ** kwargs )
@@ -867,7 +824,6 @@ class Generator(generator.Generator):
867824 ** generator .Generator .TRANSFORMS ,
868825 exp .AnyValue : _anyvalue_sql ,
869826 exp .ApproxDistinct : approx_count_distinct_sql ,
870- exp .ApproxQuantiles : _approx_quantiles_sql ,
871827 exp .Array : transforms .preprocess (
872828 [transforms .inherit_struct_field_names ],
873829 generator = inline_array_unless_query ,
@@ -1447,11 +1403,7 @@ def ignorenulls_sql(self, expression: exp.IgnoreNulls) -> str:
14471403 if isinstance (this , exp .First ):
14481404 this = exp .AnyValue (this = this .this )
14491405
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 ):
1406+ if not isinstance (this , (exp .AnyValue , exp .ApproxQuantiles )):
14551407 self .unsupported ("IGNORE NULLS is not supported for non-window functions." )
14561408
14571409 return self .sql (this )
@@ -1643,3 +1595,40 @@ def round_sql(self, expression: exp.Round) -> str:
16431595 truncate = None
16441596
16451597 return self .func (func , this , decimals , truncate )
1598+
1599+ def approxquantiles_sql (self : DuckDB .Generator , expression : exp .ApproxQuantiles ) -> str :
1600+ """
1601+ BigQuery's APPROX_QUANTILES(expr, n) returns an array of n+1 approximate quantile values
1602+ dividing the input distribution into n equal-sized buckets.
1603+
1604+ Both BigQuery and DuckDB use approximate algorithms for quantile estimation, but BigQuery
1605+ does not document the specific algorithm used so results may differ. DuckDB does not
1606+ support RESPECT NULLS.
1607+ """
1608+ this = expression .this
1609+ if isinstance (this , exp .Distinct ):
1610+ # APPROX_QUANTILES requires 2 args and DISTINCT node grabs both
1611+ if len (this .expressions ) < 2 :
1612+ self .unsupported ("APPROX_QUANTILES requires a bucket count argument" )
1613+ return self .function_fallback_sql (expression )
1614+ num_quantiles_expr = this .expressions [1 ].pop ()
1615+ else :
1616+ num_quantiles_expr = expression .expression
1617+
1618+ if not isinstance (num_quantiles_expr , exp .Literal ) or not num_quantiles_expr .is_int :
1619+ self .unsupported ("APPROX_QUANTILES bucket count must be a positive integer" )
1620+ return self .function_fallback_sql (expression )
1621+
1622+ num_quantiles = t .cast (int , num_quantiles_expr .to_py ())
1623+ if num_quantiles <= 0 :
1624+ self .unsupported ("APPROX_QUANTILES bucket count must be a positive integer" )
1625+ return self .function_fallback_sql (expression )
1626+
1627+ quantiles = [
1628+ exp .Literal .number (Decimal (i ) / Decimal (num_quantiles ))
1629+ for i in range (num_quantiles + 1 )
1630+ ]
1631+
1632+ return self .sql (
1633+ exp .ApproxQuantile (this = this , quantile = exp .Array (expressions = quantiles ))
1634+ )
0 commit comments