1pub mod engine_rules;
12pub mod error;
13pub mod functions;
14pub mod optimizer;
15pub mod params;
16pub mod parser;
17pub mod planner;
18pub mod resolver;
19pub mod types;
20
21pub use error::{Result, SqlError};
22pub use params::ParamValue;
23pub use types::*;
24
25use functions::registry::FunctionRegistry;
26use parser::preprocess;
27use parser::statement::{StatementKind, classify, parse_sql};
28
29pub fn plan_sql(sql: &str, catalog: &dyn SqlCatalog) -> Result<Vec<SqlPlan>> {
34 let preprocessed = preprocess::preprocess(sql);
35 let effective_sql = preprocessed.as_ref().map_or(sql, |p| p.sql.as_str());
36 let is_upsert = preprocessed.as_ref().is_some_and(|p| p.is_upsert);
37
38 let statements = parse_sql(effective_sql)?;
39 plan_statements(&statements, is_upsert, catalog)
40}
41
42pub fn plan_sql_with_params(
49 sql: &str,
50 params: &[ParamValue],
51 catalog: &dyn SqlCatalog,
52) -> Result<Vec<SqlPlan>> {
53 let preprocessed = preprocess::preprocess(sql);
54 let effective_sql = preprocessed.as_ref().map_or(sql, |p| p.sql.as_str());
55 let is_upsert = preprocessed.as_ref().is_some_and(|p| p.is_upsert);
56
57 let mut statements = parse_sql(effective_sql)?;
58 for stmt in &mut statements {
59 params::bind_params(stmt, params);
60 }
61 plan_statements(&statements, is_upsert, catalog)
62}
63
64fn plan_statements(
66 statements: &[sqlparser::ast::Statement],
67 is_upsert: bool,
68 catalog: &dyn SqlCatalog,
69) -> Result<Vec<SqlPlan>> {
70 let functions = FunctionRegistry::new();
71 let mut plans = Vec::new();
72
73 for stmt in statements {
74 match classify(stmt) {
75 StatementKind::Select(query) => {
76 let plan = planner::select::plan_query(query, catalog, &functions)?;
77 let plan = optimizer::optimize(plan);
78 plans.push(plan);
79 }
80 StatementKind::Insert(ins) => {
81 let mut dml_plans = if is_upsert {
82 planner::dml::plan_upsert(ins, catalog)?
83 } else {
84 planner::dml::plan_insert(ins, catalog)?
85 };
86 plans.append(&mut dml_plans);
87 }
88 StatementKind::Update(stmt) => {
89 let mut update_plans = planner::dml::plan_update(stmt, catalog)?;
90 plans.append(&mut update_plans);
91 }
92 StatementKind::Delete(stmt) => {
93 let mut delete_plans = planner::dml::plan_delete(stmt, catalog)?;
94 plans.append(&mut delete_plans);
95 }
96 StatementKind::Truncate(stmt) => {
97 let mut trunc_plans = planner::dml::plan_truncate_stmt(stmt)?;
98 plans.append(&mut trunc_plans);
99 }
100 StatementKind::Other => {
101 return Err(SqlError::Unsupported {
102 detail: format!("statement type: {stmt}"),
103 });
104 }
105 }
106 }
107
108 Ok(plans)
109}