@@ -56,7 +56,7 @@ use datafusion_expr::expr::GroupingSet;
5656use sqlparser:: ast:: {
5757 ArrayAgg , BinaryOperator , DataType as SQLDataType , DateTimeField , Expr as SQLExpr ,
5858 Fetch , FunctionArg , FunctionArgExpr , Ident , Join , JoinConstraint , JoinOperator ,
59- ObjectName , Offset as SQLOffset , Query , Select , SelectItem , SetExpr , SetOperator ,
59+ ObjectName , Offset as SQLOffset , PercentileCont , Query , Select , SelectItem , SetExpr , SetOperator ,
6060 ShowStatementFilter , TableFactor , TableWithJoins , TrimWhereField , UnaryOperator ,
6161 Value , Values as SQLValues ,
6262} ;
@@ -1440,22 +1440,22 @@ impl<'a, S: ContextProvider> SqlToRel<'a, S> {
14401440
14411441 let order_by_rex = order_by
14421442 . into_iter ( )
1443- . map ( |e| self . order_by_to_sort_expr ( e, plan. schema ( ) ) )
1443+ . map ( |e| self . order_by_to_sort_expr ( e, plan. schema ( ) , true ) )
14441444 . collect :: < Result < Vec < _ > > > ( ) ?;
14451445
14461446 LogicalPlanBuilder :: from ( plan) . sort ( order_by_rex) ?. build ( )
14471447 }
14481448
14491449 /// convert sql OrderByExpr to Expr::Sort
1450- fn order_by_to_sort_expr ( & self , e : OrderByExpr , schema : & DFSchema ) -> Result < Expr > {
1450+ fn order_by_to_sort_expr ( & self , e : OrderByExpr , schema : & DFSchema , parse_indexes : bool ) -> Result < Expr > {
14511451 let OrderByExpr {
14521452 asc,
14531453 expr,
14541454 nulls_first,
14551455 } = e;
14561456
14571457 let expr = match expr {
1458- SQLExpr :: Value ( Value :: Number ( v, _) ) => {
1458+ SQLExpr :: Value ( Value :: Number ( v, _) ) if parse_indexes => {
14591459 let field_index = v
14601460 . parse :: < usize > ( )
14611461 . map_err ( |err| DataFusionError :: Plan ( err. to_string ( ) ) ) ?;
@@ -2313,7 +2313,7 @@ impl<'a, S: ContextProvider> SqlToRel<'a, S> {
23132313 let order_by = window
23142314 . order_by
23152315 . into_iter ( )
2316- . map ( |e| self . order_by_to_sort_expr ( e, schema) )
2316+ . map ( |e| self . order_by_to_sort_expr ( e, schema, true ) )
23172317 . collect :: < Result < Vec < _ > > > ( ) ?;
23182318 let window_frame = window
23192319 . window_frame
@@ -2441,6 +2441,8 @@ impl<'a, S: ContextProvider> SqlToRel<'a, S> {
24412441
24422442 SQLExpr :: ArrayAgg ( array_agg) => self . parse_array_agg ( array_agg, schema) ,
24432443
2444+ SQLExpr :: PercentileCont ( percentile_cont) => self . parse_percentile_cont ( percentile_cont, schema) ,
2445+
24442446 _ => Err ( DataFusionError :: NotImplemented ( format ! (
24452447 "Unsupported ast node {:?} in sqltorel" ,
24462448 sql
@@ -2494,6 +2496,36 @@ impl<'a, S: ContextProvider> SqlToRel<'a, S> {
24942496 } )
24952497 }
24962498
2499+ fn parse_percentile_cont (
2500+ & self ,
2501+ percentile_cont : PercentileCont ,
2502+ input_schema : & DFSchema ,
2503+ ) -> Result < Expr > {
2504+ let PercentileCont {
2505+ expr,
2506+ within_group,
2507+ } = percentile_cont;
2508+
2509+ // Some dialects have special syntax for percentile_cont. DataFusion only supports it like a function.
2510+ let expr = self . sql_expr_to_logical_expr ( * expr, input_schema) ?;
2511+ let ( order_by_expr, asc, nulls_first) = match self . order_by_to_sort_expr ( * within_group, input_schema, false ) ? {
2512+ Expr :: Sort { expr, asc, nulls_first } => ( expr, asc, nulls_first) ,
2513+ _ => return Err ( DataFusionError :: Internal ( "PercentileCont expected Sort expression in ORDER BY" . to_string ( ) ) ) ,
2514+ } ;
2515+ let asc_expr = Expr :: Literal ( ScalarValue :: Boolean ( Some ( asc) ) ) ;
2516+ let nulls_first_expr = Expr :: Literal ( ScalarValue :: Boolean ( Some ( nulls_first) ) ) ;
2517+
2518+ let args = vec ! [ expr, * order_by_expr, asc_expr, nulls_first_expr] ;
2519+ // next, aggregate built-ins
2520+ let fun = aggregates:: AggregateFunction :: PercentileCont ;
2521+
2522+ Ok ( Expr :: AggregateFunction {
2523+ fun,
2524+ distinct : false ,
2525+ args,
2526+ } )
2527+ }
2528+
24972529 fn function_args_to_expr (
24982530 & self ,
24992531 args : Vec < FunctionArg > ,
@@ -4133,6 +4165,15 @@ mod tests {
41334165 quick_test ( sql, expected) ;
41344166 }
41354167
4168+ #[ test]
4169+ fn select_percentile_cont ( ) {
4170+ let sql = "SELECT percentile_cont(0.5) WITHIN GROUP (ORDER BY age) FROM person" ;
4171+ let expected = "Projection: #PERCENTILECONT(Float64(0.5),person.age,Boolean(true),Boolean(false))\
4172+ \n Aggregate: groupBy=[[]], aggr=[[PERCENTILECONT(Float64(0.5), #person.age, Boolean(true), Boolean(false))]]\
4173+ \n TableScan: person projection=None";
4174+ quick_test ( sql, expected) ;
4175+ }
4176+
41364177 #[ test]
41374178 fn select_scalar_func ( ) {
41384179 let sql = "SELECT sqrt(age) FROM person" ;
0 commit comments