Skip to content

Commit 69db46b

Browse files
barsela1ayman-sigma
authored andcommitted
Mysql: Add support for := operator (apache#1779)
1 parent eb545cc commit 69db46b

File tree

4 files changed

+111
-1
lines changed

4 files changed

+111
-1
lines changed

src/ast/operator.rs

+4
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,9 @@ pub enum BinaryOperator {
321321
/// `~=` Same as? (PostgreSQL/Redshift geometric operator)
322322
/// See <https://www.postgresql.org/docs/9.5/functions-geometry.html>
323323
TildeEq,
324+
/// ':=' Assignment Operator
325+
/// See <https://dev.mysql.com/doc/refman/8.4/en/assignment-operators.html#operator_assign-value>
326+
Assignment,
324327
}
325328

326329
impl fmt::Display for BinaryOperator {
@@ -394,6 +397,7 @@ impl fmt::Display for BinaryOperator {
394397
BinaryOperator::QuestionDoublePipe => f.write_str("?||"),
395398
BinaryOperator::At => f.write_str("@"),
396399
BinaryOperator::TildeEq => f.write_str("~="),
400+
BinaryOperator::Assignment => f.write_str(":="),
397401
}
398402
}
399403
}

src/dialect/mod.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -620,7 +620,8 @@ pub trait Dialect: Debug + Any {
620620
Token::Word(w) if w.keyword == Keyword::OPERATOR => Ok(p!(Between)),
621621
Token::Word(w) if w.keyword == Keyword::DIV => Ok(p!(MulDivModOp)),
622622
Token::Period => Ok(p!(Period)),
623-
Token::Eq
623+
Token::Assignment
624+
| Token::Eq
624625
| Token::Lt
625626
| Token::LtEq
626627
| Token::Neq

src/parser/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -3233,6 +3233,7 @@ impl<'a> Parser<'a> {
32333233
let regular_binary_operator = match &tok.token {
32343234
Token::Spaceship => Some(BinaryOperator::Spaceship),
32353235
Token::DoubleEq => Some(BinaryOperator::Eq),
3236+
Token::Assignment => Some(BinaryOperator::Assignment),
32363237
Token::Eq => Some(BinaryOperator::Eq),
32373238
Token::Neq => Some(BinaryOperator::NotEq),
32383239
Token::Gt => Some(BinaryOperator::Gt),

tests/sqlparser_mysql.rs

+104
Original file line numberDiff line numberDiff line change
@@ -3483,3 +3483,107 @@ fn parse_match_against_with_alias() {
34833483
_ => unreachable!(),
34843484
}
34853485
}
3486+
3487+
#[test]
3488+
fn test_variable_assignment_using_colon_equal() {
3489+
let sql_select = "SELECT @price := price, @tax := price * 0.1 FROM products WHERE id = 1";
3490+
let stmt = mysql().verified_stmt(sql_select);
3491+
match stmt {
3492+
Statement::Query(query) => {
3493+
let select = query.body.as_select().unwrap();
3494+
3495+
assert_eq!(
3496+
select.projection,
3497+
vec![
3498+
SelectItem::UnnamedExpr(Expr::BinaryOp {
3499+
left: Box::new(Expr::Identifier(Ident {
3500+
value: "@price".to_string(),
3501+
quote_style: None,
3502+
span: Span::empty(),
3503+
})),
3504+
op: BinaryOperator::Assignment,
3505+
right: Box::new(Expr::Identifier(Ident {
3506+
value: "price".to_string(),
3507+
quote_style: None,
3508+
span: Span::empty(),
3509+
})),
3510+
}),
3511+
SelectItem::UnnamedExpr(Expr::BinaryOp {
3512+
left: Box::new(Expr::Identifier(Ident {
3513+
value: "@tax".to_string(),
3514+
quote_style: None,
3515+
span: Span::empty(),
3516+
})),
3517+
op: BinaryOperator::Assignment,
3518+
right: Box::new(Expr::BinaryOp {
3519+
left: Box::new(Expr::Identifier(Ident {
3520+
value: "price".to_string(),
3521+
quote_style: None,
3522+
span: Span::empty(),
3523+
})),
3524+
op: BinaryOperator::Multiply,
3525+
right: Box::new(Expr::Value(
3526+
(test_utils::number("0.1")).with_empty_span()
3527+
)),
3528+
}),
3529+
}),
3530+
]
3531+
);
3532+
3533+
assert_eq!(
3534+
select.selection,
3535+
Some(Expr::BinaryOp {
3536+
left: Box::new(Expr::Identifier(Ident {
3537+
value: "id".to_string(),
3538+
quote_style: None,
3539+
span: Span::empty(),
3540+
})),
3541+
op: BinaryOperator::Eq,
3542+
right: Box::new(Expr::Value((test_utils::number("1")).with_empty_span())),
3543+
})
3544+
);
3545+
}
3546+
_ => panic!("Unexpected statement {stmt}"),
3547+
}
3548+
3549+
let sql_update =
3550+
"UPDATE products SET price = @new_price := price * 1.1 WHERE category = 'Books'";
3551+
let stmt = mysql().verified_stmt(sql_update);
3552+
3553+
match stmt {
3554+
Statement::Update { assignments, .. } => {
3555+
assert_eq!(
3556+
assignments,
3557+
vec![Assignment {
3558+
target: AssignmentTarget::ColumnName(ObjectName(vec![
3559+
ObjectNamePart::Identifier(Ident {
3560+
value: "price".to_string(),
3561+
quote_style: None,
3562+
span: Span::empty(),
3563+
})
3564+
])),
3565+
value: Expr::BinaryOp {
3566+
left: Box::new(Expr::Identifier(Ident {
3567+
value: "@new_price".to_string(),
3568+
quote_style: None,
3569+
span: Span::empty(),
3570+
})),
3571+
op: BinaryOperator::Assignment,
3572+
right: Box::new(Expr::BinaryOp {
3573+
left: Box::new(Expr::Identifier(Ident {
3574+
value: "price".to_string(),
3575+
quote_style: None,
3576+
span: Span::empty(),
3577+
})),
3578+
op: BinaryOperator::Multiply,
3579+
right: Box::new(Expr::Value(
3580+
(test_utils::number("1.1")).with_empty_span()
3581+
)),
3582+
}),
3583+
},
3584+
}]
3585+
)
3586+
}
3587+
_ => panic!("Unexpected statement {stmt}"),
3588+
}
3589+
}

0 commit comments

Comments
 (0)