1pub mod aggregate_walk;
14pub mod catalog;
15pub mod coerce;
16pub mod ddl_ast;
17pub mod dsl_bind;
18pub mod engine_rules;
19pub mod error;
20pub mod fts_types;
21pub mod functions;
22pub mod optimizer;
23pub mod params;
24pub mod parser;
25pub mod planner;
26pub mod reserved;
27pub mod resolver;
28pub mod temporal;
29pub mod types;
30pub mod types_array;
31pub mod types_expr;
32
33pub use temporal::{TemporalScope, ValidTime};
34
35pub use catalog::{SqlCatalog, SqlCatalogError};
36pub use error::{Result, SqlError};
37pub use params::ParamValue;
38pub use types::*;
39
40pub fn parse_expr_string(expr_text: &str) -> Result<SqlExpr> {
45 use sqlparser::dialect::GenericDialect;
46 use sqlparser::parser::Parser;
47
48 let dialect = GenericDialect {};
49 let ast_expr = Parser::new(&dialect)
50 .try_with_sql(expr_text)
51 .map_err(|e| SqlError::Parse {
52 detail: e.to_string(),
53 })?
54 .parse_expr()
55 .map_err(|e| SqlError::Parse {
56 detail: e.to_string(),
57 })?;
58
59 resolver::expr::convert_expr(&ast_expr)
60}
61
62use functions::registry::FunctionRegistry;
63use parser::array_stmt::{ArrayStatement, try_parse_array_statement};
64use parser::preprocess;
65use parser::statement::{StatementKind, classify, parse_sql};
66
67pub fn plan_sql(sql: &str, catalog: &dyn SqlCatalog) -> Result<Vec<SqlPlan>> {
72 if let Some(stmt) = try_parse_array_statement(sql)? {
75 return plan_array_statement(stmt, catalog);
76 }
77 let preprocessed = preprocess::preprocess(sql)?;
78 let effective_sql = preprocessed.as_ref().map_or(sql, |p| p.sql.as_str());
79 let is_upsert = preprocessed.as_ref().is_some_and(|p| p.is_upsert);
80 let temporal = preprocessed
81 .as_ref()
82 .map(|p| p.temporal)
83 .unwrap_or_default();
84
85 let statements = parse_sql(effective_sql)?;
86 plan_statements(&statements, is_upsert, temporal, catalog)
87}
88
89pub fn plan_sql_with_params(
96 sql: &str,
97 params: &[ParamValue],
98 catalog: &dyn SqlCatalog,
99) -> Result<Vec<SqlPlan>> {
100 if let Some(stmt) = try_parse_array_statement(sql)? {
104 let _ = params; return plan_array_statement(stmt, catalog);
106 }
107 let preprocessed = preprocess::preprocess(sql)?;
108 let effective_sql = preprocessed.as_ref().map_or(sql, |p| p.sql.as_str());
109 let is_upsert = preprocessed.as_ref().is_some_and(|p| p.is_upsert);
110 let temporal = preprocessed
111 .as_ref()
112 .map(|p| p.temporal)
113 .unwrap_or_default();
114
115 let mut statements = parse_sql(effective_sql)?;
116 for stmt in &mut statements {
117 params::bind_params(stmt, params);
118 }
119 plan_statements(&statements, is_upsert, temporal, catalog)
120}
121
122fn plan_statements(
124 statements: &[sqlparser::ast::Statement],
125 is_upsert: bool,
126 temporal: TemporalScope,
127 catalog: &dyn SqlCatalog,
128) -> Result<Vec<SqlPlan>> {
129 let functions = FunctionRegistry::new();
130 let mut plans = Vec::new();
131
132 for stmt in statements {
133 match classify(stmt) {
134 StatementKind::Select(query) => {
135 let plan = planner::select::plan_query(query, catalog, &functions, temporal)?;
136 let plan = optimizer::optimize(plan);
137 plans.push(plan);
138 }
139 StatementKind::Insert(ins) => {
140 let mut dml_plans = if is_upsert {
141 planner::dml::plan_upsert(ins, catalog)?
142 } else {
143 planner::dml::plan_insert(ins, catalog)?
144 };
145 plans.append(&mut dml_plans);
146 }
147 StatementKind::Update(stmt) => {
148 let mut update_plans = planner::dml::plan_update(stmt, catalog)?;
149 plans.append(&mut update_plans);
150 }
151 StatementKind::Delete(stmt) => {
152 let mut delete_plans = planner::dml::plan_delete(stmt, catalog)?;
153 plans.append(&mut delete_plans);
154 }
155 StatementKind::Truncate(stmt) => {
156 let mut trunc_plans = planner::dml::plan_truncate_stmt(stmt)?;
157 plans.append(&mut trunc_plans);
158 }
159 StatementKind::Merge(stmt) => {
160 let mut merge_plans = planner::merge::plan_merge(stmt, catalog)?;
161 plans.append(&mut merge_plans);
162 }
163 StatementKind::Other => {
164 return Err(SqlError::Unsupported {
165 detail: format!("statement type: {stmt}"),
166 });
167 }
168 }
169 }
170
171 Ok(plans)
172}
173
174fn plan_array_statement(stmt: ArrayStatement, catalog: &dyn SqlCatalog) -> Result<Vec<SqlPlan>> {
176 match stmt {
177 ArrayStatement::Create(c) => Ok(vec![planner::array_ddl::plan_create_array(&c)?]),
178 ArrayStatement::Drop(d) => Ok(vec![planner::array_ddl::plan_drop_array(&d)?]),
179 ArrayStatement::Insert(i) => planner::array_dml::plan_insert_array(&i, catalog),
180 ArrayStatement::Delete(d) => planner::array_dml::plan_delete_array(&d, catalog),
181 ArrayStatement::Alter(a) => Ok(vec![planner::array_ddl::plan_alter_array(&a)?]),
182 }
183}