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