sqlparser_mysql/das/
set_statement.rs

1use std::{fmt, str};
2
3use nom::bytes::complete::tag_no_case;
4use nom::character::complete::{multispace0, multispace1};
5use nom::sequence::tuple;
6use nom::IResult;
7
8use base::error::ParseSQLError;
9use base::{CommonParser, Literal};
10
11/// parse `SET variable = expr [, variable = expr] ...`
12///
13/// `variable: {
14///     user_var_name
15///   | param_name
16///   | local_var_name
17///   | {GLOBAL | @@GLOBAL.} system_var_name
18///   | {PERSIST | @@PERSIST.} system_var_name
19///   | {PERSIST_ONLY | @@PERSIST_ONLY.} system_var_name
20///   | [SESSION | @@SESSION. | @@] system_var_name
21/// }`
22#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
23pub struct SetStatement {
24    pub variable: String,
25    pub value: Literal,
26}
27
28impl SetStatement {
29    pub fn parse(i: &str) -> IResult<&str, SetStatement, ParseSQLError<&str>> {
30        let (remaining_input, (_, _, var, _, _, _, value, _)) = tuple((
31            tag_no_case("SET"),
32            multispace1,
33            CommonParser::sql_identifier,
34            multispace0,
35            tag_no_case("="),
36            multispace0,
37            Literal::parse,
38            CommonParser::statement_terminator,
39        ))(i)?;
40        let variable = String::from(var);
41        Ok((remaining_input, SetStatement { variable, value }))
42    }
43}
44
45impl fmt::Display for SetStatement {
46    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
47        write!(f, "SET ")?;
48        write!(f, "{} = {}", self.variable, self.value)?;
49        Ok(())
50    }
51}
52
53#[cfg(test)]
54mod tests {
55    use super::*;
56
57    #[test]
58    fn simple_set() {
59        let str = "SET SQL_AUTO_IS_NULL = 0;";
60        let res = SetStatement::parse(str);
61        let exp = SetStatement {
62            variable: "SQL_AUTO_IS_NULL".to_owned(),
63            value: 0.into(),
64        };
65        assert_eq!(res.unwrap().1, exp);
66    }
67
68    #[test]
69    fn user_defined_vars() {
70        let str = "SET @var = 123;";
71        let res = SetStatement::parse(str);
72        let exp = SetStatement {
73            variable: "@var".to_owned(),
74            value: 123.into(),
75        };
76        assert_eq!(res.unwrap().1, exp);
77    }
78
79    #[test]
80    fn format_set() {
81        let str = "set autocommit=1";
82        let expected = "SET autocommit = 1";
83        let res = SetStatement::parse(str);
84        assert_eq!(format!("{}", res.unwrap().1), expected);
85    }
86}