This is an automated email from the ASF dual-hosted git repository.

iffyio pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/datafusion-sqlparser-rs.git


The following commit(s) were added to refs/heads/main by this push:
     new 62495f2f Mysql: Add support for := operator (#1779)
62495f2f is described below

commit 62495f2f0d998690495f111063a0b0a3466ffa69
Author: bar sela <[email protected]>
AuthorDate: Thu Mar 27 23:48:57 2025 +0200

    Mysql: Add support for := operator (#1779)
---
 src/ast/operator.rs      |   4 ++
 src/dialect/mod.rs       |   3 +-
 src/parser/mod.rs        |   1 +
 tests/sqlparser_mysql.rs | 104 +++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 111 insertions(+), 1 deletion(-)

diff --git a/src/ast/operator.rs b/src/ast/operator.rs
index 66a35fee..73fe9cf4 100644
--- a/src/ast/operator.rs
+++ b/src/ast/operator.rs
@@ -321,6 +321,9 @@ pub enum BinaryOperator {
     /// `~=` Same as? (PostgreSQL/Redshift geometric operator)
     /// See <https://www.postgresql.org/docs/9.5/functions-geometry.html>
     TildeEq,
+    /// ':=' Assignment Operator
+    /// See 
<https://dev.mysql.com/doc/refman/8.4/en/assignment-operators.html#operator_assign-value>
+    Assignment,
 }
 
 impl fmt::Display for BinaryOperator {
@@ -394,6 +397,7 @@ impl fmt::Display for BinaryOperator {
             BinaryOperator::QuestionDoublePipe => f.write_str("?||"),
             BinaryOperator::At => f.write_str("@"),
             BinaryOperator::TildeEq => f.write_str("~="),
+            BinaryOperator::Assignment => f.write_str(":="),
         }
     }
 }
diff --git a/src/dialect/mod.rs b/src/dialect/mod.rs
index 8d4557e2..79184dd7 100644
--- a/src/dialect/mod.rs
+++ b/src/dialect/mod.rs
@@ -620,7 +620,8 @@ pub trait Dialect: Debug + Any {
             Token::Word(w) if w.keyword == Keyword::OPERATOR => 
Ok(p!(Between)),
             Token::Word(w) if w.keyword == Keyword::DIV => Ok(p!(MulDivModOp)),
             Token::Period => Ok(p!(Period)),
-            Token::Eq
+            Token::Assignment
+            | Token::Eq
             | Token::Lt
             | Token::LtEq
             | Token::Neq
diff --git a/src/parser/mod.rs b/src/parser/mod.rs
index 65d536f7..adaae286 100644
--- a/src/parser/mod.rs
+++ b/src/parser/mod.rs
@@ -3233,6 +3233,7 @@ impl<'a> Parser<'a> {
         let regular_binary_operator = match &tok.token {
             Token::Spaceship => Some(BinaryOperator::Spaceship),
             Token::DoubleEq => Some(BinaryOperator::Eq),
+            Token::Assignment => Some(BinaryOperator::Assignment),
             Token::Eq => Some(BinaryOperator::Eq),
             Token::Neq => Some(BinaryOperator::NotEq),
             Token::Gt => Some(BinaryOperator::Gt),
diff --git a/tests/sqlparser_mysql.rs b/tests/sqlparser_mysql.rs
index 3d318f70..1d4fd6a0 100644
--- a/tests/sqlparser_mysql.rs
+++ b/tests/sqlparser_mysql.rs
@@ -3483,3 +3483,107 @@ fn parse_match_against_with_alias() {
         _ => unreachable!(),
     }
 }
+
+#[test]
+fn test_variable_assignment_using_colon_equal() {
+    let sql_select = "SELECT @price := price, @tax := price * 0.1 FROM 
products WHERE id = 1";
+    let stmt = mysql().verified_stmt(sql_select);
+    match stmt {
+        Statement::Query(query) => {
+            let select = query.body.as_select().unwrap();
+
+            assert_eq!(
+                select.projection,
+                vec![
+                    SelectItem::UnnamedExpr(Expr::BinaryOp {
+                        left: Box::new(Expr::Identifier(Ident {
+                            value: "@price".to_string(),
+                            quote_style: None,
+                            span: Span::empty(),
+                        })),
+                        op: BinaryOperator::Assignment,
+                        right: Box::new(Expr::Identifier(Ident {
+                            value: "price".to_string(),
+                            quote_style: None,
+                            span: Span::empty(),
+                        })),
+                    }),
+                    SelectItem::UnnamedExpr(Expr::BinaryOp {
+                        left: Box::new(Expr::Identifier(Ident {
+                            value: "@tax".to_string(),
+                            quote_style: None,
+                            span: Span::empty(),
+                        })),
+                        op: BinaryOperator::Assignment,
+                        right: Box::new(Expr::BinaryOp {
+                            left: Box::new(Expr::Identifier(Ident {
+                                value: "price".to_string(),
+                                quote_style: None,
+                                span: Span::empty(),
+                            })),
+                            op: BinaryOperator::Multiply,
+                            right: Box::new(Expr::Value(
+                                (test_utils::number("0.1")).with_empty_span()
+                            )),
+                        }),
+                    }),
+                ]
+            );
+
+            assert_eq!(
+                select.selection,
+                Some(Expr::BinaryOp {
+                    left: Box::new(Expr::Identifier(Ident {
+                        value: "id".to_string(),
+                        quote_style: None,
+                        span: Span::empty(),
+                    })),
+                    op: BinaryOperator::Eq,
+                    right: 
Box::new(Expr::Value((test_utils::number("1")).with_empty_span())),
+                })
+            );
+        }
+        _ => panic!("Unexpected statement {stmt}"),
+    }
+
+    let sql_update =
+        "UPDATE products SET price = @new_price := price * 1.1 WHERE category 
= 'Books'";
+    let stmt = mysql().verified_stmt(sql_update);
+
+    match stmt {
+        Statement::Update { assignments, .. } => {
+            assert_eq!(
+                assignments,
+                vec![Assignment {
+                    target: AssignmentTarget::ColumnName(ObjectName(vec![
+                        ObjectNamePart::Identifier(Ident {
+                            value: "price".to_string(),
+                            quote_style: None,
+                            span: Span::empty(),
+                        })
+                    ])),
+                    value: Expr::BinaryOp {
+                        left: Box::new(Expr::Identifier(Ident {
+                            value: "@new_price".to_string(),
+                            quote_style: None,
+                            span: Span::empty(),
+                        })),
+                        op: BinaryOperator::Assignment,
+                        right: Box::new(Expr::BinaryOp {
+                            left: Box::new(Expr::Identifier(Ident {
+                                value: "price".to_string(),
+                                quote_style: None,
+                                span: Span::empty(),
+                            })),
+                            op: BinaryOperator::Multiply,
+                            right: Box::new(Expr::Value(
+                                (test_utils::number("1.1")).with_empty_span()
+                            )),
+                        }),
+                    },
+                }]
+            )
+        }
+        _ => panic!("Unexpected statement {stmt}"),
+    }
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to