sqlparser_mysql/
parser.rs

1use std::fmt;
2use std::io::BufRead;
3use std::str;
4
5use das::SetStatement;
6use dds::{
7    AlterDatabaseStatement, AlterTableStatement, CreateIndexStatement, CreateTableStatement,
8    DropDatabaseStatement, DropEventStatement, DropFunctionStatement, DropIndexStatement,
9    DropLogfileGroupStatement, DropProcedureStatement, DropServerStatement,
10    DropSpatialReferenceSystemStatement, DropTableStatement, DropTablespaceStatement,
11    DropTriggerStatement, DropViewStatement, RenameTableStatement, TruncateTableStatement,
12};
13use dms::{
14    CompoundSelectStatement, DeleteStatement, InsertStatement, SelectStatement, UpdateStatement,
15};
16use nom::branch::alt;
17use nom::combinator::map;
18use nom::Offset;
19
20pub struct Parser;
21
22impl Parser {
23    pub fn parse(config: &ParseConfig, input: &str) -> Result<Statement, String> {
24        let input = input.trim();
25
26        let dds_parser = alt((
27            map(AlterDatabaseStatement::parse, Statement::AlterDatabase),
28            map(AlterTableStatement::parse, Statement::AlterTable),
29            map(CreateIndexStatement::parse, Statement::CreateIndex),
30            map(CreateTableStatement::parse, Statement::CreateTable),
31            map(DropDatabaseStatement::parse, Statement::DropDatabase),
32            map(DropEventStatement::parse, Statement::DropEvent),
33            map(DropFunctionStatement::parse, Statement::DropFunction),
34            map(DropIndexStatement::parse, Statement::DropIndex),
35            map(
36                DropLogfileGroupStatement::parse,
37                Statement::DropLogfileGroup,
38            ),
39            map(DropProcedureStatement::parse, Statement::DropProcedure),
40            map(DropServerStatement::parse, Statement::DropServer),
41            map(
42                DropSpatialReferenceSystemStatement::parse,
43                Statement::DropSpatialReferenceSystem,
44            ),
45            map(DropTableStatement::parse, Statement::DropTable),
46            map(DropTablespaceStatement::parse, Statement::DropTableSpace),
47            map(DropTriggerStatement::parse, Statement::DropTrigger),
48            map(DropViewStatement::parse, Statement::DropView),
49            map(RenameTableStatement::parse, Statement::RenameTable),
50            map(TruncateTableStatement::parse, Statement::TruncateTable),
51        ));
52
53        let das_parser = alt((map(SetStatement::parse, Statement::Set),));
54
55        let dms_parser = alt((
56            map(SelectStatement::parse, Statement::Select),
57            map(CompoundSelectStatement::parse, Statement::CompoundSelect),
58            map(InsertStatement::parse, Statement::Insert),
59            map(DeleteStatement::parse, Statement::Delete),
60            map(UpdateStatement::parse, Statement::Update),
61        ));
62
63        let mut parser = alt((dds_parser, dms_parser, das_parser));
64
65        match parser(input) {
66            Ok(result) => Ok(result.1),
67            Err(nom::Err::Error(err)) => {
68                if config.log_with_backtrace {
69                    println!(">>>>>>>>>>>>>>>>>>>>");
70                    for error in &err.errors {
71                        println!("{:?} :: {:?}", error.0, error.1)
72                    }
73                    println!("<<<<<<<<<<<<<<<<<<<<");
74                }
75
76                let msg = err.errors[0].0;
77                let err_msg = format!("failed to parse sql, error near `{}`", msg);
78                Err(err_msg)
79            }
80            _ => Err(String::from("failed to parse sql: other error")),
81        }
82    }
83}
84
85#[derive(Default)]
86pub struct ParseConfig {
87    pub log_with_backtrace: bool,
88}
89
90#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
91pub enum Statement {
92    // DDS
93    AlterDatabase(AlterDatabaseStatement),
94    AlterTable(AlterTableStatement),
95    CreateIndex(CreateIndexStatement),
96    CreateTable(CreateTableStatement),
97    DropDatabase(DropDatabaseStatement),
98    DropEvent(DropEventStatement),
99    DropFunction(DropFunctionStatement),
100    DropIndex(DropIndexStatement),
101    DropLogfileGroup(DropLogfileGroupStatement),
102    DropProcedure(DropProcedureStatement),
103    DropServer(DropServerStatement),
104    DropSpatialReferenceSystem(DropSpatialReferenceSystemStatement),
105    DropTable(DropTableStatement),
106    DropTableSpace(DropTablespaceStatement),
107    DropTrigger(DropTriggerStatement),
108    DropView(DropViewStatement),
109    RenameTable(RenameTableStatement),
110    TruncateTable(TruncateTableStatement),
111    // DAS
112    Set(SetStatement),
113    // HISTORY
114    Insert(InsertStatement),
115    CompoundSelect(CompoundSelectStatement),
116    Select(SelectStatement),
117    Delete(DeleteStatement),
118    Update(UpdateStatement),
119}
120
121impl fmt::Display for Statement {
122    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
123        match *self {
124            // FIXME add all
125            Statement::Select(ref select) => write!(f, "{}", select),
126            Statement::Insert(ref insert) => write!(f, "{}", insert),
127            Statement::CreateTable(ref create) => write!(f, "{}", create),
128            Statement::Delete(ref delete) => write!(f, "{}", delete),
129            Statement::DropTable(ref drop) => write!(f, "{}", drop),
130            Statement::DropDatabase(ref drop) => write!(f, "{}", drop),
131            Statement::TruncateTable(ref drop) => write!(f, "{}", drop),
132            Statement::Update(ref update) => write!(f, "{}", update),
133            Statement::Set(ref set) => write!(f, "{}", set),
134            _ => unimplemented!(),
135        }
136    }
137}