diff --git a/datafusion/sql/src/unparser/expr.rs b/datafusion/sql/src/unparser/expr.rs index 416ab03d1fa9..a50bb7a69823 100644 --- a/datafusion/sql/src/unparser/expr.rs +++ b/datafusion/sql/src/unparser/expr.rs @@ -394,8 +394,22 @@ impl Unparser<'_> { expr: Box::new(sql_parser_expr), }) } - Expr::ScalarVariable(_, _) => { - not_impl_err!("Unsupported Expr conversion: {expr:?}") + Expr::ScalarVariable(_, ids) => { + if ids.is_empty() { + return internal_err!("Not a valid ScalarVariable"); + } + + Ok(if ids.len() == 1 { + ast::Expr::Identifier( + self.new_ident_without_quote_style(ids[0].to_string()), + ) + } else { + ast::Expr::CompoundIdentifier( + ids.iter() + .map(|i| self.new_ident_without_quote_style(i.to_string())) + .collect(), + ) + }) } Expr::GetIndexedField(_) => { not_impl_err!("Unsupported Expr conversion: {expr:?}") @@ -497,6 +511,13 @@ impl Unparser<'_> { } } + pub(super) fn new_ident_without_quote_style(&self, str: String) -> ast::Ident { + ast::Ident { + value: str, + quote_style: None, + } + } + pub(super) fn binary_op_to_sql( &self, lhs: ast::Expr, @@ -868,6 +889,7 @@ mod tests { use std::{any::Any, sync::Arc, vec}; use arrow::datatypes::{Field, Schema}; + use arrow_schema::DataType::Int8; use datafusion_common::TableReference; use datafusion_expr::{ case, col, exists, @@ -1158,6 +1180,17 @@ mod tests { try_cast(col("a"), DataType::UInt32), r#"TRY_CAST("a" AS INTEGER UNSIGNED)"#, ), + ( + Expr::ScalarVariable(Int8, vec![String::from("@a")]), + r#"@a"#, + ), + ( + Expr::ScalarVariable( + Int8, + vec![String::from("@root"), String::from("foo")], + ), + r#"@root.foo"#, + ), (col("x").eq(placeholder("$1")), r#"("x" = $1)"#), ( out_ref_col(DataType::Int32, "t.a").gt(lit(1)),