1pub mod catalog;
12pub mod ddl_ast;
13pub mod engine_rules;
14pub mod error;
15pub mod functions;
16pub mod optimizer;
17pub mod params;
18pub mod parser;
19pub mod planner;
20pub mod resolver;
21pub mod types;
22
23pub use catalog::{SqlCatalog, SqlCatalogError};
24pub use error::{Result, SqlError};
25pub use params::ParamValue;
26pub use types::*;
27
28pub fn parse_expr_string(expr_text: &str) -> Result<SqlExpr> {
33 use sqlparser::dialect::GenericDialect;
34 use sqlparser::parser::Parser;
35
36 let dialect = GenericDialect {};
37 let ast_expr = Parser::new(&dialect)
38 .try_with_sql(expr_text)
39 .map_err(|e| SqlError::Parse {
40 detail: e.to_string(),
41 })?
42 .parse_expr()
43 .map_err(|e| SqlError::Parse {
44 detail: e.to_string(),
45 })?;
46
47 resolver::expr::convert_expr(&ast_expr)
48}
49
50use functions::registry::FunctionRegistry;
51use parser::preprocess;
52use parser::statement::{StatementKind, classify, parse_sql};
53
54pub fn plan_sql(sql: &str, catalog: &dyn SqlCatalog) -> Result<Vec<SqlPlan>> {
59 let preprocessed = preprocess::preprocess(sql);
60 let effective_sql = preprocessed.as_ref().map_or(sql, |p| p.sql.as_str());
61 let is_upsert = preprocessed.as_ref().is_some_and(|p| p.is_upsert);
62
63 let statements = parse_sql(effective_sql)?;
64 plan_statements(&statements, is_upsert, catalog)
65}
66
67pub fn plan_sql_with_params(
74 sql: &str,
75 params: &[ParamValue],
76 catalog: &dyn SqlCatalog,
77) -> Result<Vec<SqlPlan>> {
78 let preprocessed = preprocess::preprocess(sql);
79 let effective_sql = preprocessed.as_ref().map_or(sql, |p| p.sql.as_str());
80 let is_upsert = preprocessed.as_ref().is_some_and(|p| p.is_upsert);
81
82 let mut statements = parse_sql(effective_sql)?;
83 for stmt in &mut statements {
84 params::bind_params(stmt, params);
85 }
86 plan_statements(&statements, is_upsert, catalog)
87}
88
89fn plan_statements(
91 statements: &[sqlparser::ast::Statement],
92 is_upsert: bool,
93 catalog: &dyn SqlCatalog,
94) -> Result<Vec<SqlPlan>> {
95 let functions = FunctionRegistry::new();
96 let mut plans = Vec::new();
97
98 for stmt in statements {
99 match classify(stmt) {
100 StatementKind::Select(query) => {
101 let plan = planner::select::plan_query(query, catalog, &functions)?;
102 let plan = optimizer::optimize(plan);
103 plans.push(plan);
104 }
105 StatementKind::Insert(ins) => {
106 let mut dml_plans = if is_upsert {
107 planner::dml::plan_upsert(ins, catalog)?
108 } else {
109 planner::dml::plan_insert(ins, catalog)?
110 };
111 plans.append(&mut dml_plans);
112 }
113 StatementKind::Update(stmt) => {
114 let mut update_plans = planner::dml::plan_update(stmt, catalog)?;
115 plans.append(&mut update_plans);
116 }
117 StatementKind::Delete(stmt) => {
118 let mut delete_plans = planner::dml::plan_delete(stmt, catalog)?;
119 plans.append(&mut delete_plans);
120 }
121 StatementKind::Truncate(stmt) => {
122 let mut trunc_plans = planner::dml::plan_truncate_stmt(stmt)?;
123 plans.append(&mut trunc_plans);
124 }
125 StatementKind::Other => {
126 return Err(SqlError::Unsupported {
127 detail: format!("statement type: {stmt}"),
128 });
129 }
130 }
131 }
132
133 Ok(plans)
134}