quill_sql/sql/parser/
mod.rs

1use crate::error::QuillSQLResult;
2use sqlparser::{ast::Statement, dialect::PostgreSqlDialect, parser::Parser};
3
4pub fn parse_sql(sql: &str) -> QuillSQLResult<Vec<Statement>> {
5    // Lightweight rewrite for unsupported SHOW syntax under Postgres dialect
6    // Maps to information_schema queries to keep planner/executor simple.
7    let normalized = sql.trim().trim_end_matches(';').trim();
8    let lower = normalized.to_ascii_lowercase();
9
10    let rewritten = if lower == "show databases" || lower == "show database" {
11        // List schemas (databases) from information_schema.schemas
12        Some("select schema from information_schema.schemas".to_string())
13    } else if lower == "show tables" {
14        // List all tables
15        Some("select table_name from information_schema.tables".to_string())
16    } else if lower.starts_with("set transaction") {
17        let rest = normalized["set transaction".len()..].trim_start();
18        Some(format!("SET TRANSACTION {}", rest))
19    } else if lower.starts_with("set session transaction") {
20        let rest = normalized["set session transaction".len()..].trim_start();
21        Some(format!(
22            "SET SESSION CHARACTERISTICS AS TRANSACTION {}",
23            rest
24        ))
25    } else {
26        None
27    };
28
29    let sql_to_parse = rewritten.as_deref().unwrap_or(normalized);
30    let stmts = Parser::parse_sql(&PostgreSqlDialect {}, sql_to_parse)?;
31    for stmt in &stmts {
32        match stmt {
33            Statement::StartTransaction { .. }
34            | Statement::Commit { .. }
35            | Statement::Rollback { .. }
36            | Statement::SetTransaction { .. } => {}
37            _ => {}
38        }
39    }
40    Ok(stmts)
41}
42
43#[cfg(test)]
44mod tests {
45
46    #[test]
47    pub fn test_parser() {
48        let sql = "select * from (select * from t1)";
49        let stmts = super::parse_sql(sql).unwrap();
50        println!("{:#?}", stmts[0]);
51    }
52}