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 builder;
35pub mod dialects;
36pub mod errors;
37pub mod generator;
38pub mod optimizer;
39pub mod parser;
40pub mod schema;
41pub mod tokens;
42
43pub use ast::{Expr, MergeClauseKind, QuoteStyle, Statement};
44pub use builder::{
45 // Expression factory functions
46 column, table, table_full, literal, string_literal, boolean, null,
47 // Operators and expressions
48 cast, and_all, or_all, not, func, func_distinct,
49 // Comparison helpers
50 eq, neq, lt, lte, gt, gte, is_null, is_not_null, between, in_list, not_in_list, in_subquery, like,
51 // Arithmetic helpers
52 add, sub, mul, div,
53 // Other helpers
54 star, qualified_star, subquery, exists, alias,
55 // Parse helpers
56 parse_expr, parse_expr_dialect, parse_condition, parse_condition_dialect,
57 // Builders
58 condition, condition_dialect, select, select_all, select_distinct,
59 ConditionBuilder, SelectBuilder,
60};
61pub use dialects::Dialect;
62pub use errors::SqlglotError;
63pub use generator::{generate, generate_pretty};
64pub use optimizer::annotate_types::{TypeAnnotations, annotate_types};
65pub use optimizer::lineage::{lineage, lineage_sql, LineageConfig, LineageError, LineageGraph, LineageNode};
66pub use optimizer::pushdown_predicates::pushdown_predicates;
67pub use optimizer::scope_analysis::{Scope, ScopeType, build_scope, find_all_in_scope};
68pub use parser::parse;
69
70/// Transpile a SQL string from one dialect to another.
71///
72/// This is the primary high-level API, corresponding to Python sqlglot's
73/// `sqlglot.transpile()`.
74///
75/// # Example
76///
77/// ```rust
78/// use sqlglot_rust::{transpile, Dialect};
79///
80/// let result = transpile(
81/// "SELECT CAST(x AS INT) FROM t",
82/// Dialect::Ansi,
83/// Dialect::Postgres,
84/// ).unwrap();
85/// ```
86///
87/// # Errors
88///
89/// Returns a [`SqlglotError`] if parsing fails.
90pub fn transpile(
91 sql: &str,
92 read_dialect: Dialect,
93 write_dialect: Dialect,
94) -> errors::Result<String> {
95 let ast = parse(sql, read_dialect)?;
96 let transformed = dialects::transform(&ast, read_dialect, write_dialect);
97 Ok(generate(&transformed, write_dialect))
98}
99
100/// Transpile a SQL string, returning multiple statements if the input
101/// contains semicolons.
102///
103/// # Errors
104///
105/// Returns a [`SqlglotError`] if parsing fails.
106pub fn transpile_statements(
107 sql: &str,
108 read_dialect: Dialect,
109 write_dialect: Dialect,
110) -> errors::Result<Vec<String>> {
111 let stmts = parser::parse_statements(sql, read_dialect)?;
112 let mut results = Vec::with_capacity(stmts.len());
113 for stmt in &stmts {
114 let transformed = dialects::transform(stmt, read_dialect, write_dialect);
115 results.push(generate(&transformed, write_dialect));
116 }
117 Ok(results)
118}