Skip to main content

nodedb_sql/parser/
statement.rs

1// SPDX-License-Identifier: Apache-2.0
2
3//! SQL parsing via sqlparser-rs.
4
5use sqlparser::ast::Statement;
6use sqlparser::dialect::PostgreSqlDialect;
7use sqlparser::parser::Parser;
8
9use crate::error::{Result, SqlError};
10
11/// Parse a SQL string into one or more statements.
12pub fn parse_sql(sql: &str) -> Result<Vec<Statement>> {
13    let dialect = PostgreSqlDialect {};
14    let statements = Parser::parse_sql(&dialect, sql)?;
15    if statements.is_empty() {
16        return Err(SqlError::Parse {
17            detail: "empty SQL statement".into(),
18        });
19    }
20    Ok(statements)
21}
22
23/// Classify a parsed statement for routing.
24#[derive(Debug)]
25pub enum StatementKind<'a> {
26    Select(&'a sqlparser::ast::Query),
27    Insert(&'a sqlparser::ast::Insert),
28    Update(&'a sqlparser::ast::Statement),
29    Delete(&'a sqlparser::ast::Statement),
30    Truncate(&'a sqlparser::ast::Statement),
31    Merge(&'a sqlparser::ast::Statement),
32    CreateIndex(&'a sqlparser::ast::CreateIndex),
33    DropIndex(&'a sqlparser::ast::Statement),
34    Other,
35}
36
37/// Classify a parsed statement.
38pub fn classify(stmt: &Statement) -> StatementKind<'_> {
39    match stmt {
40        Statement::Query(q) => StatementKind::Select(q),
41        Statement::Insert(ins) => StatementKind::Insert(ins),
42        Statement::Update(_) => StatementKind::Update(stmt),
43        Statement::Delete(_) => StatementKind::Delete(stmt),
44        Statement::Truncate(_) => StatementKind::Truncate(stmt),
45        Statement::Merge(_) => StatementKind::Merge(stmt),
46        Statement::CreateIndex(ci) => StatementKind::CreateIndex(ci),
47        Statement::Drop {
48            object_type: sqlparser::ast::ObjectType::Index,
49            ..
50        } => StatementKind::DropIndex(stmt),
51        _ => StatementKind::Other,
52    }
53}