@@ -60,7 +60,7 @@ use datafusion::{
6060 prelude:: { Column , SessionContext } ,
6161 scalar:: ScalarValue ,
6262} ;
63- use std:: collections:: HashMap ;
63+ use std:: collections:: { HashMap , HashSet } ;
6464use std:: str:: FromStr ;
6565use std:: sync:: Arc ;
6666use substrait:: proto:: exchange_rel:: ExchangeKind ;
@@ -404,22 +404,33 @@ pub async fn from_substrait_rel(
404404 let mut input = LogicalPlanBuilder :: from (
405405 from_substrait_rel ( ctx, input, extensions) . await ?,
406406 ) ;
407+ let mut names: HashSet < String > = HashSet :: new ( ) ;
407408 let mut exprs: Vec < Expr > = vec ! [ ] ;
408409 for e in & p. expressions {
409410 let x =
410411 from_substrait_rex ( ctx, e, input. clone ( ) . schema ( ) , extensions)
411412 . await ?;
412413 // if the expression is WindowFunction, wrap in a Window relation
413- // before returning and do not add to list of this Projection's expression list
414- // otherwise, add expression to the Projection's expression list
415- match & * x {
416- Expr :: WindowFunction ( _) => {
417- input = input. window ( vec ! [ x. as_ref( ) . clone( ) ] ) ?;
418- exprs. push ( x. as_ref ( ) . clone ( ) ) ;
419- }
420- _ => {
421- exprs. push ( x. as_ref ( ) . clone ( ) ) ;
422- }
414+ if let Expr :: WindowFunction ( _) = x. as_ref ( ) {
415+ // Adding the same expression here and in the project below
416+ // works because the project's builder uses columnize_expr(..)
417+ // to transform it into a column reference
418+ input = input. window ( vec ! [ x. as_ref( ) . clone( ) ] ) ?
419+ }
420+ // Ensure the expression has a unique display name, so that project's
421+ // validate_unique_names doesn't fail
422+ let name = x. display_name ( ) ?;
423+ let mut new_name = name. clone ( ) ;
424+ let mut i = 0 ;
425+ while names. contains ( & new_name) {
426+ new_name = format ! ( "{}__temp__{}" , name, i) ;
427+ i += 1 ;
428+ }
429+ names. insert ( new_name. clone ( ) ) ;
430+ if new_name != name {
431+ exprs. push ( x. as_ref ( ) . clone ( ) . alias ( new_name. clone ( ) ) ) ;
432+ } else {
433+ exprs. push ( x. as_ref ( ) . clone ( ) ) ;
423434 }
424435 }
425436 input. project ( exprs) ?. build ( )
0 commit comments