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