mvzink commented on code in PR #1757:
URL: 
https://github.com/apache/datafusion-sqlparser-rs/pull/1757#discussion_r1986222154


##########
src/ast/mod.rs:
##########
@@ -2947,6 +2947,17 @@ pub enum Statement {
         variables: OneOrManyWithParens<ObjectName>,
         value: Vec<Expr>,
     },
+
+    /// ```sql
+    /// SET <variable> = expression [, <variable> = expression]*;
+    /// ```
+    ///
+    /// Note: this is a MySQL-specific statement.
+    /// Refer to [`Dialect.supports_comma_separated_set_assignments`]
+    SetVariables {
+        variables: Vec<ObjectName>,
+        values: Vec<Expr>,
+    },

Review Comment:
   It seems @MohamedAbdeen21 was right that this aspect should be a different 
PR to have a more comprehensive discussion. I suggested this new variant in 
[another 
comment](https://github.com/apache/datafusion-sqlparser-rs/pull/1757#discussion_r1984144488)
 because I think that this is a different enough syntactic construct from the 
other two existing styles (single-variable assignment a la Postgres and 
parenthesized multiple-variable assignment a la Snowflake) that adding another 
flag to differentiate them would be unclear and cumbersome. Already, the use of 
`OneOrManyWithParens` to differentiate the Postgres and Snowflake styles is, in 
my opinion, inferior to a higher level enum variant differeniating the two 
styles. Furthermore, especially in the case of the new MySQL-style 
multiple-assignments-of-single-variables, I don't think that there enough in 
common or a way in which dialects would need elements from both, that warrants 
having them in the same variant.
   
   However, I think my opinion would be clearer with two changes. First, when I 
initially suggested adding a new variant, I was imagining something more 
similar to `Case` with its `Vec<CaseWhen>`: i.e. having a 
`Vec<VariableAssignment>` or `Vec<(ObjectName, Expr)>` instead of two vecs 
which you later have to `zip` together to do anything with (i.e. in the 
`Display` implementation). This loses the structure that was parsed and only 
makes sense for the Snowflake style. Again, having that syle also be used for 
the Postgres single-assignment style is cumbersome and unclear, and this is 
similar. I actually didn't notice this difference from my original suggestion 
when re-reviewing this PR or I would have raised it.
   
   The second change that might make my thinking clearer is the other one I 
suggested in that comment, which is to unify some or all `SET` statements in 
another struct/enum. I originally suggested `Statement::Set(SetStatement)` to 
include `SetNames` etc., but I actually think 
`Statement::SetVariable(SetVariable)` only covering these 3 cases would be 
better. Then any common handling between different types of variable 
assignments could still be handled centrally, but the 3 distinct styles could 
be represented more concretely, similar to this:
   
   ```rust
   enum SetVariable {
       /// SQL Standard-style
       /// SET a = 1;
       SingleAssignment {
           local: bool,
           hivevar: bool,
           variable: ObjectName,
           value: Expr,
       }
       /// Snowflake-style
       /// SET (a, b) = (1, 2);
       ParenthesizedAssignments {
           variables: Vec<ObjectName>,
           values: Vec<Expr>,
       }
       /// MySQL-style
       /// SET a = 1, b = 2;
       MultipleAssignments {
           assignments: Vec<(ObjectName, Expr)>
       }
   }
   ```
   
   Shoe-horning all 3 of these into one struct/variant via a combination of 
`OneOrManyWithParens` and a new boolean flag differentiating Snowflake-style 
from MySQL-style that only applies when `variables` matches 
`OneOrManyWithParens::Many(_))` seems really annoying without, as far as I can 
tell, buying us anything.
   
   If y'all think it would be clear enough to do it that way, I won't stand in 
the way, but I really think some kind of new variant/structure (if not 
precisely this one) would be a huge improvement.



-- 
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