1use sqlparser::ast::Statement;
7use sqlparser::dialect::GenericDialect;
8use sqlparser::parser::Parser;
9use thiserror::Error;
10
11#[derive(Error, Debug)]
13#[error("{0}")]
14pub struct ParseError(String);
15
16pub fn parse_sql(query: &str) -> Result<Statement, ParseError> {
21 let dialect = GenericDialect {};
22 let stmts = Parser::parse_sql(&dialect, query).map_err(|e| {
23 ParseError(format!(
24 "SQL parse error: {}. Hint: only SELECT and CREATE SCHEMA/DATABASE/DROP TABLE/VIEW/SCHEMA are supported.",
25 e
26 ))
27 })?;
28 if stmts.len() != 1 {
29 return Err(ParseError(format!(
30 "SQL: expected exactly one statement, got {}. Hint: run one statement at a time.",
31 stmts.len()
32 )));
33 }
34 let stmt = stmts.into_iter().next().unwrap();
35 match &stmt {
36 Statement::Query(_) => {}
37 Statement::CreateSchema { .. } | Statement::CreateDatabase { .. } => {}
38 Statement::Drop {
39 object_type:
40 sqlparser::ast::ObjectType::Table
41 | sqlparser::ast::ObjectType::View
42 | sqlparser::ast::ObjectType::Schema,
43 ..
44 } => {}
45 _ => {
46 return Err(ParseError(format!(
47 "SQL: only SELECT, CREATE SCHEMA/DATABASE, and DROP TABLE/VIEW/SCHEMA are supported, got {:?}.",
48 stmt
49 )));
50 }
51 }
52 Ok(stmt)
53}