sqlglot_rust/lib.rs
1//! # sqlglot-rust
2//!
3//! A SQL parser, optimizer, and transpiler library written in Rust,
4//! inspired by Python's [sqlglot](https://github.com/tobymao/sqlglot).
5//!
6//! ## Features
7//!
8//! - Parse SQL strings into a structured AST
9//! - Generate SQL from AST nodes
10//! - Transpile between SQL dialects (30 dialects including MySQL, PostgreSQL, BigQuery, Snowflake, DuckDB, Hive, Spark, Presto, Trino, T-SQL, Oracle, ClickHouse, Redshift, and more)
11//! - Optimize SQL queries
12//! - CTEs, subqueries, UNION/INTERSECT/EXCEPT
13//! - Window functions, CAST, EXTRACT, EXISTS
14//! - Pretty-print SQL output
15//! - AST traversal (walk, find, transform)
16//!
17//! ## Quick Start
18//!
19//! ```rust
20//! use sqlglot_rust::{parse, generate, transpile, Dialect};
21//!
22//! // Parse a SQL query
23//! let ast = parse("SELECT a, b FROM t WHERE a > 1", Dialect::Ansi).unwrap();
24//!
25//! // Generate SQL for a specific dialect
26//! let sql = generate(&ast, Dialect::Postgres);
27//! assert_eq!(sql, "SELECT a, b FROM t WHERE a > 1");
28//!
29//! // One-step transpile between dialects
30//! let result = transpile("SELECT a, b FROM t", Dialect::Ansi, Dialect::Postgres).unwrap();
31//! ```
32
33pub mod ast;
34pub mod dialects;
35pub mod errors;
36pub mod generator;
37pub mod optimizer;
38pub mod parser;
39pub mod schema;
40pub mod tokens;
41
42pub use ast::{Expr, QuoteStyle, Statement};
43pub use dialects::Dialect;
44pub use errors::SqlglotError;
45pub use generator::{generate, generate_pretty};
46pub use optimizer::scope_analysis::{Scope, ScopeType, build_scope, find_all_in_scope};
47pub use parser::parse;
48
49/// Transpile a SQL string from one dialect to another.
50///
51/// This is the primary high-level API, corresponding to Python sqlglot's
52/// `sqlglot.transpile()`.
53///
54/// # Example
55///
56/// ```rust
57/// use sqlglot_rust::{transpile, Dialect};
58///
59/// let result = transpile(
60/// "SELECT CAST(x AS INT) FROM t",
61/// Dialect::Ansi,
62/// Dialect::Postgres,
63/// ).unwrap();
64/// ```
65///
66/// # Errors
67///
68/// Returns a [`SqlglotError`] if parsing fails.
69pub fn transpile(
70 sql: &str,
71 read_dialect: Dialect,
72 write_dialect: Dialect,
73) -> errors::Result<String> {
74 let ast = parse(sql, read_dialect)?;
75 let transformed = dialects::transform(&ast, read_dialect, write_dialect);
76 Ok(generate(&transformed, write_dialect))
77}
78
79/// Transpile a SQL string, returning multiple statements if the input
80/// contains semicolons.
81///
82/// # Errors
83///
84/// Returns a [`SqlglotError`] if parsing fails.
85pub fn transpile_statements(
86 sql: &str,
87 read_dialect: Dialect,
88 write_dialect: Dialect,
89) -> errors::Result<Vec<String>> {
90 let stmts = parser::parse_statements(sql, read_dialect)?;
91 let mut results = Vec::with_capacity(stmts.len());
92 for stmt in &stmts {
93 let transformed = dialects::transform(stmt, read_dialect, write_dialect);
94 results.push(generate(&transformed, write_dialect));
95 }
96 Ok(results)
97}