goldmedal commented on code in PR #13493:
URL: https://github.com/apache/datafusion/pull/13493#discussion_r1851732566


##########
datafusion/sql/src/unparser/expr.rs:
##########
@@ -514,6 +516,57 @@ impl Unparser<'_> {
         })
     }
 
+    fn named_struct_to_sql(&self, args: &[Expr]) -> Result<ast::Expr> {
+        if args.len() % 2 != 0 {
+            return internal_err!("named_struct must have an even number of 
arguments");
+        }
+
+        let args = args
+            .chunks_exact(2)
+            .map(|chunk| {
+                let key = match &chunk[0] {
+                    Expr::Literal(lit) => 
self.new_ident_quoted_if_needs(lit.to_string()),

Review Comment:
   ```suggestion
                       Expr::Literal(ScalarValue::Utf8(Some(s))) => 
self.new_ident_quoted_if_needs(s.to_string()),
   ```
   Refer to the implementation of `named_struct`, we can match the string 
literal only.
   
https://github.com/apache/datafusion/blob/9fb7aee95c5fcf177609963cedadf443ba6fe1b7/datafusion/functions/src/core/named_struct.rs#L49-L52



##########
datafusion/sql/src/unparser/expr.rs:
##########
@@ -514,6 +516,57 @@ impl Unparser<'_> {
         })
     }
 
+    fn named_struct_to_sql(&self, args: &[Expr]) -> Result<ast::Expr> {
+        if args.len() % 2 != 0 {
+            return internal_err!("named_struct must have an even number of 
arguments");
+        }
+
+        let args = args
+            .chunks_exact(2)
+            .map(|chunk| {
+                let key = match &chunk[0] {
+                    Expr::Literal(lit) => 
self.new_ident_quoted_if_needs(lit.to_string()),
+                    _ => return internal_err!("named_struct expects even 
arguments to be strings, but received: {:?}", &chunk[0])
+                };
+
+                Ok(ast::DictionaryField {
+                    key,
+                    value: Box::new(self.expr_to_sql(&chunk[1])?),
+                })
+            })
+            .collect::<Result<Vec<_>>>()?;
+
+        Ok(ast::Expr::Dictionary(args))
+    }
+
+    fn get_field_to_sql(&self, args: &[Expr]) -> Result<ast::Expr> {
+        if args.len() != 2 {
+            return internal_err!("get_field must have exactly 2 arguments");
+        }
+
+        let mut id = match &args[0] {
+            Expr::Column(col) => match self.col_to_sql(col)? {
+                ast::Expr::Identifier(ident) => vec![ident],
+                ast::Expr::CompoundIdentifier(idents) => idents,
+                other => return internal_err!("expected col_to_sql to return 
an Identifier or CompoundIdentifier, but received: {:?}", other),
+            },
+            _ => return internal_err!("get_field expects first argument to be 
column, but received: {:?}", &args[0]),
+        };

Review Comment:
   We should consider the more complex cases, a struct contains a struct field. 
Consider the following SQL that uses another way to access the struct:
   ```
   > explain SELECT s.a['a1'] FROM (SELECT {a:{a1:c1}, b:{a1:c1}} AS s from t1);
   
+---------------+-------------------------------------------------------------------------------------------------------------------------------------------+
   | plan_type     | plan                                                       
                                                                               |
   
+---------------+-------------------------------------------------------------------------------------------------------------------------------------------+
   | logical_plan  | Projection: get_field(get_field(named_struct(Utf8("a"), 
__common_expr_1, Utf8("b"), __common_expr_1), Utf8("a")), Utf8("a1")) AS 
s[a][a1] |
   |               |   Projection: named_struct(Utf8("a1"), t1.c1) AS 
__common_expr_1                                                                 
         |
   |               |     TableScan: t1 projection=[c1]   
   ```
   You can see the `get_field` accepts another `get_field` function. However, I 
think we can't do a roundtrip test for this kind of case currently because SQL 
like `select s.a.a1` isn't supported 
(https://github.com/apache/datafusion-sqlparser-rs/pull/1541 will address it).
   
   By the way, I think we can file a follow-up issue for the nested case. We 
don't need to support it in this PR.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscr...@datafusion.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: github-unsubscr...@datafusion.apache.org
For additional commands, e-mail: github-h...@datafusion.apache.org

Reply via email to