sqlparser/dialect/
mysql.rs1#[cfg(not(feature = "std"))]
14use alloc::boxed::Box;
15
16use crate::{
17 ast::{BinaryOperator, Expr, LockTable, LockTableType, Statement},
18 dialect::Dialect,
19 keywords::Keyword,
20 parser::{Parser, ParserError},
21};
22
23#[derive(Debug)]
25pub struct MySqlDialect {}
26
27impl Dialect for MySqlDialect {
28 fn is_identifier_start(&self, ch: char) -> bool {
29 ch.is_alphabetic()
33 || ch == '_'
34 || ch == '$'
35 || ch == '@'
36 || ('\u{0080}'..='\u{ffff}').contains(&ch)
37 }
38
39 fn is_identifier_part(&self, ch: char) -> bool {
40 self.is_identifier_start(ch) || ch.is_ascii_digit()
41 }
42
43 fn is_delimited_identifier_start(&self, ch: char) -> bool {
44 ch == '`'
45 }
46
47 fn parse_infix(
48 &self,
49 parser: &mut crate::parser::Parser,
50 expr: &crate::ast::Expr,
51 _precedence: u8,
52 ) -> Option<Result<crate::ast::Expr, ParserError>> {
53 if parser.parse_keyword(Keyword::DIV) {
55 Some(Ok(Expr::BinaryOp {
56 left: Box::new(expr.clone()),
57 op: BinaryOperator::MyIntegerDivide,
58 right: Box::new(parser.parse_expr().unwrap()),
59 }))
60 } else {
61 None
62 }
63 }
64
65 fn parse_statement(&self, parser: &mut Parser) -> Option<Result<Statement, ParserError>> {
66 if parser.parse_keywords(&[Keyword::LOCK, Keyword::TABLES]) {
67 Some(parse_lock_tables(parser))
68 } else if parser.parse_keywords(&[Keyword::UNLOCK, Keyword::TABLES]) {
69 Some(parse_unlock_tables(parser))
70 } else {
71 None
72 }
73 }
74}
75
76fn parse_lock_tables(parser: &mut Parser) -> Result<Statement, ParserError> {
79 let tables = parser.parse_comma_separated(parse_lock_table)?;
80 Ok(Statement::LockTables { tables })
81}
82
83fn parse_lock_table(parser: &mut Parser) -> Result<LockTable, ParserError> {
85 let table = parser.parse_identifier(false)?;
86 let alias =
87 parser.parse_optional_alias(&[Keyword::READ, Keyword::WRITE, Keyword::LOW_PRIORITY])?;
88 let lock_type = parse_lock_tables_type(parser)?;
89
90 Ok(LockTable {
91 table,
92 alias,
93 lock_type,
94 })
95}
96
97fn parse_lock_tables_type(parser: &mut Parser) -> Result<LockTableType, ParserError> {
99 if parser.parse_keyword(Keyword::READ) {
100 if parser.parse_keyword(Keyword::LOCAL) {
101 Ok(LockTableType::Read { local: true })
102 } else {
103 Ok(LockTableType::Read { local: false })
104 }
105 } else if parser.parse_keyword(Keyword::WRITE) {
106 Ok(LockTableType::Write {
107 low_priority: false,
108 })
109 } else if parser.parse_keywords(&[Keyword::LOW_PRIORITY, Keyword::WRITE]) {
110 Ok(LockTableType::Write { low_priority: true })
111 } else {
112 parser.expected("an lock type in LOCK TABLES", parser.peek_token())
113 }
114}
115
116fn parse_unlock_tables(_parser: &mut Parser) -> Result<Statement, ParserError> {
119 Ok(Statement::UnlockTables)
120}