@@ -21,8 +21,10 @@ use std::cmp::Ordering;
2121use std:: collections:: { BTreeSet , HashSet } ;
2222use std:: sync:: Arc ;
2323
24+ use crate :: conditional_expressions:: CaseBuilder ;
2425use crate :: expr:: { Alias , Sort , WildcardOptions , WindowFunctionParams } ;
25- use crate :: expr_rewriter:: { merged_using_key_or_column, strip_outer_reference} ;
26+ use crate :: expr_rewriter:: strip_outer_reference;
27+ use crate :: logical_plan:: JoinType ;
2628use crate :: {
2729 BinaryExpr , Expr , ExprSchemable , Filter , GroupingSet , LogicalPlan , Operator , and,
2830} ;
@@ -442,6 +444,38 @@ fn exclude_using_columns(plan: &LogicalPlan) -> Result<HashSet<Column>> {
442444 Ok ( excluded)
443445}
444446
447+ fn merged_using_key_for_wildcard (
448+ col : Column ,
449+ merged_keys : & [ ( Column , Column , JoinType ) ] ,
450+ ) -> Result < Expr > {
451+ let Some ( ( l, r, join_type) ) =
452+ merged_keys. iter ( ) . find ( |( l, r, _) | l == & col || r == & col)
453+ else {
454+ return Ok ( Expr :: Column ( col) ) ;
455+ } ;
456+
457+ let ( expr, visible_col) = match join_type {
458+ JoinType :: Right | JoinType :: RightSemi | JoinType :: RightAnti => {
459+ ( Expr :: Column ( r. clone ( ) ) , r. clone ( ) )
460+ }
461+ JoinType :: Full => CaseBuilder :: new (
462+ None ,
463+ vec ! [ Expr :: Column ( l. clone( ) ) . is_not_null( ) ] ,
464+ vec ! [ Expr :: Column ( l. clone( ) ) ] ,
465+ Some ( Box :: new ( Expr :: Column ( r. clone ( ) ) ) ) ,
466+ )
467+ . end ( )
468+ . map ( |expr| ( expr, col. clone ( ) ) ) ?,
469+ _ => ( Expr :: Column ( l. clone ( ) ) , l. clone ( ) ) ,
470+ } ;
471+
472+ if expr == Expr :: Column ( visible_col. clone ( ) ) {
473+ Ok ( expr)
474+ } else {
475+ Ok ( expr. alias_qualified ( visible_col. relation , visible_col. name ) )
476+ }
477+ }
478+
445479/// Resolves an `Expr::Wildcard` to a collection of `Expr::Column`'s.
446480pub fn expand_wildcard (
447481 schema : & DFSchema ,
@@ -463,16 +497,16 @@ pub fn expand_wildcard(
463497 columns_to_skip. extend ( excluded_columns) ;
464498 let exprs = get_exprs_except_skipped ( schema, & columns_to_skip) ;
465499
466- // Resolve the surviving USING / NATURAL key column to the internally named
467- // merged key expression .
500+ // Resolve the surviving USING / NATURAL key column to the merged key value,
501+ // while preserving the wildcard-visible field qualifier .
468502 let merged_keys = plan. using_key_pairs ( ) ?;
469503 if merged_keys. is_empty ( ) {
470504 return Ok ( exprs) ;
471505 }
472506 exprs
473507 . into_iter ( )
474508 . map ( |expr| match expr {
475- Expr :: Column ( col) => merged_using_key_or_column ( col, true , & merged_keys) ,
509+ Expr :: Column ( col) => merged_using_key_for_wildcard ( col, & merged_keys) ,
476510 other => Ok ( other) ,
477511 } )
478512 . collect ( )
0 commit comments