1pub mod ast;
35pub mod builder;
36pub mod dialects;
37pub mod diff;
38pub mod errors;
39pub mod executor;
40pub mod ffi;
41pub mod generator;
42pub mod optimizer;
43pub mod parser;
44pub mod planner;
45pub mod schema;
46pub mod tokens;
47
48pub use ast::{CommentType, Expr, MergeClauseKind, QuoteStyle, Statement};
49pub use builder::{
50 ConditionBuilder,
51 SelectBuilder,
52 add,
54 alias,
55 and_all,
56 between,
57 boolean,
58 cast,
60 column,
62 condition,
64 condition_dialect,
65 div,
66 eq,
68 exists,
69 func,
70 func_distinct,
71 gt,
72 gte,
73 in_list,
74 in_subquery,
75 is_not_null,
76 is_null,
77 like,
78 literal,
79 lt,
80 lte,
81 mul,
82 neq,
83 not,
84 not_in_list,
85 null,
86 or_all,
87 parse_condition,
88 parse_condition_dialect,
89 parse_expr,
91 parse_expr_dialect,
92 qualified_star,
93 select,
94 select_all,
95 select_distinct,
96 star,
98 string_literal,
99 sub,
100 subquery,
101 table,
102 table_full,
103};
104pub use dialects::Dialect;
105pub use dialects::plugin::{
106 DialectPlugin, DialectRef, DialectRegistry, register_dialect, resolve_dialect, transpile_ext,
107 transpile_statements_ext,
108};
109pub use dialects::time::{
110 FormatConversionResult, TimeFormatStyle, TsqlStyleCode, format_time, format_time_dialect,
111 format_time_with_warnings,
112};
113pub use diff::{AstNode, ChangeAction, diff as diff_ast, diff_sql};
114pub use errors::SqlglotError;
115pub use generator::{generate, generate_pretty};
116pub use optimizer::annotate_types::{TypeAnnotations, annotate_types};
117pub use optimizer::lineage::{
118 LineageConfig, LineageError, LineageGraph, LineageNode, lineage, lineage_sql,
119};
120pub use optimizer::pushdown_predicates::pushdown_predicates;
121pub use optimizer::scope_analysis::{Scope, ScopeType, build_scope, find_all_in_scope};
122pub use parser::parse;
123pub use parser::{parse_statements_with_comments, parse_with_comments};
124pub use planner::{Plan, Projection, Step, StepId, plan};
125
126fn validate_dialect_support(stmt: &Statement, target: Dialect) -> errors::Result<()> {
128 use crate::ast::Expr;
129 use crate::dialects::Dialect::{Fabric, Tsql};
130
131 if !matches!(target, Tsql | Fabric) {
132 return Ok(());
133 }
134
135 let mut found_array = false;
137 fn check_expr(expr: &Expr, found: &mut bool) {
138 match expr {
139 Expr::ArrayLiteral(_) => {
140 *found = true;
141 }
142 _ => {
143 expr.walk(&mut |e| {
144 if matches!(e, Expr::ArrayLiteral(_)) {
145 *found = true;
146 false
147 } else {
148 true
149 }
150 });
151 }
152 }
153 }
154
155 match stmt {
156 Statement::Select(sel) => {
157 for item in &sel.columns {
158 if let ast::SelectItem::Expr { expr, .. } = item {
159 check_expr(expr, &mut found_array);
160 }
161 }
162 if let Some(wh) = &sel.where_clause {
163 check_expr(wh, &mut found_array);
164 }
165 }
166 Statement::Expression(expr) => check_expr(expr, &mut found_array),
167 _ => {}
168 }
169
170 if found_array {
171 return Err(errors::SqlglotError::UnsupportedDialectFeature(
172 "ARRAY constructor has no T-SQL equivalent".to_string(),
173 ));
174 }
175
176 Ok(())
177}
178
179pub fn transpile(
200 sql: &str,
201 read_dialect: Dialect,
202 write_dialect: Dialect,
203) -> errors::Result<String> {
204 let ast = parse(sql, read_dialect)?;
205 let transformed = dialects::transform(&ast, read_dialect, write_dialect);
206 validate_dialect_support(&transformed, write_dialect)?;
207 Ok(generate(&transformed, write_dialect))
208}
209
210pub fn transpile_statements(
217 sql: &str,
218 read_dialect: Dialect,
219 write_dialect: Dialect,
220) -> errors::Result<Vec<String>> {
221 let stmts = parser::parse_statements(sql, read_dialect)?;
222 let mut results = Vec::with_capacity(stmts.len());
223 for stmt in &stmts {
224 let transformed = dialects::transform(stmt, read_dialect, write_dialect);
225 results.push(generate(&transformed, write_dialect));
226 }
227 Ok(results)
228}
229
230pub fn transpile_with_comments(
236 sql: &str,
237 read_dialect: Dialect,
238 write_dialect: Dialect,
239) -> errors::Result<String> {
240 let ast = parse_with_comments(sql, read_dialect)?;
241 let transformed = dialects::transform(&ast, read_dialect, write_dialect);
242 Ok(generate(&transformed, write_dialect))
243}