@@ -36,6 +36,7 @@ use crate::{
36
36
37
37
const CASE_EXPR_MARKER : & str = "__DATAFUSION_CASE_EXPR__" ;
38
38
const CASE_ELSE_MARKER : & str = "__DATAFUSION_CASE_ELSE__" ;
39
+ const WINDOW_PARTITION_MARKER : & str = "__DATAFUSION_WINDOW_PARTITION__" ;
39
40
const WINDOW_SORT_MARKER : & str = "__DATAFUSION_WINDOW_SORT__" ;
40
41
41
42
/// Recursively walk a list of expression trees, collecting the unique set of column
@@ -258,9 +259,16 @@ pub fn expr_sub_expressions(expr: &Expr) -> Result<Vec<Expr>> {
258
259
Expr :: IsNotNull ( e) => Ok ( vec ! [ e. as_ref( ) . to_owned( ) ] ) ,
259
260
Expr :: ScalarFunction { args, .. } => Ok ( args. clone ( ) ) ,
260
261
Expr :: ScalarUDF { args, .. } => Ok ( args. clone ( ) ) ,
261
- Expr :: WindowFunction { args, order_by, .. } => {
262
+ Expr :: WindowFunction {
263
+ args,
264
+ partition_by,
265
+ order_by,
266
+ ..
267
+ } => {
262
268
let mut expr_list: Vec < Expr > = vec ! [ ] ;
263
269
expr_list. extend ( args. clone ( ) ) ;
270
+ expr_list. push ( lit ( WINDOW_PARTITION_MARKER ) ) ;
271
+ expr_list. extend ( partition_by. clone ( ) ) ;
264
272
expr_list. push ( lit ( WINDOW_SORT_MARKER ) ) ;
265
273
expr_list. extend ( order_by. clone ( ) ) ;
266
274
Ok ( expr_list)
@@ -340,7 +348,19 @@ pub fn rewrite_expression(expr: &Expr, expressions: &[Expr]) -> Result<Expr> {
340
348
Expr :: WindowFunction {
341
349
fun, window_frame, ..
342
350
} => {
343
- let index = expressions
351
+ let partition_index = expressions
352
+ . iter ( )
353
+ . position ( |expr| {
354
+ matches ! ( expr, Expr :: Literal ( ScalarValue :: Utf8 ( Some ( str ) ) )
355
+ if str == WINDOW_PARTITION_MARKER )
356
+ } )
357
+ . ok_or_else ( || {
358
+ DataFusionError :: Internal (
359
+ "Ill-formed window function expressions: unexpected marker" . to_owned ( ) ,
360
+ )
361
+ } ) ?;
362
+
363
+ let sort_index = expressions
344
364
. iter ( )
345
365
. position ( |expr| {
346
366
matches ! ( expr, Expr :: Literal ( ScalarValue :: Utf8 ( Some ( str ) ) )
@@ -351,12 +371,20 @@ pub fn rewrite_expression(expr: &Expr, expressions: &[Expr]) -> Result<Expr> {
351
371
"Ill-formed window function expressions" . to_owned ( ) ,
352
372
)
353
373
} ) ?;
354
- Ok ( Expr :: WindowFunction {
355
- fun : fun. clone ( ) ,
356
- args : expressions[ ..index] . to_vec ( ) ,
357
- order_by : expressions[ index + 1 ..] . to_vec ( ) ,
358
- window_frame : * window_frame,
359
- } )
374
+
375
+ if partition_index >= sort_index {
376
+ Err ( DataFusionError :: Internal (
377
+ "Ill-formed window function expressions: partition index too large" . to_owned ( ) ,
378
+ ) )
379
+ } else {
380
+ Ok ( Expr :: WindowFunction {
381
+ fun : fun. clone ( ) ,
382
+ args : expressions[ ..partition_index] . to_vec ( ) ,
383
+ partition_by : expressions[ partition_index + 1 ..sort_index] . to_vec ( ) ,
384
+ order_by : expressions[ sort_index + 1 ..] . to_vec ( ) ,
385
+ window_frame : * window_frame,
386
+ } )
387
+ }
360
388
}
361
389
Expr :: AggregateFunction { fun, distinct, .. } => Ok ( Expr :: AggregateFunction {
362
390
fun : fun. clone ( ) ,
0 commit comments