sqltk_parser/lib.rs
1// Licensed to the Apache Software Foundation (ASF) under one
2// or more contributor license agreements. See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership. The ASF licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License. You may obtain a copy of the License at
8//
9// http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied. See the License for the
15// specific language governing permissions and limitations
16// under the License.
17
18//! # SQL Parser for Rust
19//!
20//! This crate provides an ANSI:SQL 2011 lexer and parser that can parse SQL
21//! into an Abstract Syntax Tree ([`AST`]). See the [sqltk_parser crates.io page]
22//! for more information.
23//!
24//! For more information:
25//! 1. [`Parser::parse_sql`] and [`Parser::new`] for the Parsing API
26//! 2. [`ast`] for the AST structure
27//! 3. [`Dialect`] for supported SQL dialects
28//! 4. [`Spanned`] for source text locations (see "Source Spans" below for details)
29//!
30//! [`Spanned`]: ast::Spanned
31//!
32//! # Example parsing SQL text
33//!
34//! ```
35//! use sqltk_parser::dialect::GenericDialect;
36//! use sqltk_parser::parser::Parser;
37//!
38//! let dialect = GenericDialect {}; // or AnsiDialect
39//!
40//! let sql = "SELECT a, b, 123, myfunc(b) \
41//! FROM table_1 \
42//! WHERE a > b AND b < 100 \
43//! ORDER BY a DESC, b";
44//!
45//! let ast = Parser::parse_sql(&dialect, sql).unwrap();
46//!
47//! println!("AST: {:?}", ast);
48//! ```
49//!
50//! # Creating SQL text from AST
51//!
52//! This crate allows users to recover the original SQL text (with comments
53//! removed, normalized whitespace and identifier capitalization), which is
54//! useful for tools that analyze and manipulate SQL.
55//!
56//! ```
57//! # use sqltk_parser::dialect::GenericDialect;
58//! # use sqltk_parser::parser::Parser;
59//! let sql = "SELECT a FROM table_1";
60//!
61//! // parse to a Vec<Statement>
62//! let ast = Parser::parse_sql(&GenericDialect, sql).unwrap();
63//!
64//! // The original SQL text can be generated from the AST
65//! assert_eq!(ast[0].to_string(), sql);
66//! ```
67//! [sqltk_parser crates.io page]: https://crates.io/crates/sqltk_parser
68//! [`Parser::parse_sql`]: crate::parser::Parser::parse_sql
69//! [`Parser::new`]: crate::parser::Parser::new
70//! [`AST`]: crate::ast
71//! [`ast`]: crate::ast
72//! [`Dialect`]: crate::dialect::Dialect
73//!
74//! # Source Spans
75//!
76//! Starting with version `0.53.0` sqltk_parser introduced source spans to the
77//! AST. This feature provides source information for syntax errors, enabling
78//! better error messages. See [issue #1548] for more information and the
79//! [`Spanned`] trait to access the spans.
80//!
81//! [issue #1548]: https://github.com/apache/datafusion-sqlparser-rs/issues/1548
82//! [`Spanned`]: ast::Spanned
83//!
84//! ## Migration Guide
85//!
86//! For the next few releases, we will be incrementally adding source spans to the
87//! AST nodes, trying to minimize the impact on existing users. Some breaking
88//! changes are inevitable, and the following is a summary of the changes:
89//!
90//! #### New fields for spans (must be added to any existing pattern matches)
91//!
92//! The primary change is that new fields will be added to AST nodes to store the source `Span` or `TokenWithLocation`.
93//!
94//! This will require
95//! 1. Adding new fields to existing pattern matches.
96//! 2. Filling in the proper span information when constructing AST nodes.
97//!
98//! For example, since `Ident` now stores a `Span`, to construct an `Ident` you
99//! must provide now provide one:
100//!
101//! Previously:
102//! ```text
103//! # use sqltk_parser::ast::Ident;
104//! Ident {
105//! value: "name".into(),
106//! quote_style: None,
107//! }
108//! ```
109//! Now
110//! ```rust
111//! # use sqltk_parser::ast::Ident;
112//! # use sqltk_parser::tokenizer::Span;
113//! Ident {
114//! value: "name".into(),
115//! quote_style: None,
116//! span: Span::empty(),
117//! };
118//! ```
119//!
120//! Similarly, when pattern matching on `Ident`, you must now account for the
121//! `span` field.
122//!
123//! #### Misc.
124//! - [`TokenWithLocation`] stores a full `Span`, rather than just a source location.
125//! Users relying on `token.location` should use `token.location.start` instead.
126//!
127//![`TokenWithLocation`]: tokenizer::TokenWithLocation
128
129#![cfg_attr(not(feature = "std"), no_std)]
130#![allow(clippy::upper_case_acronyms)]
131
132// Allow proc-macros to find this crate
133extern crate self as sqltk_parser;
134
135#[cfg(not(feature = "std"))]
136extern crate alloc;
137
138#[macro_use]
139#[cfg(test)]
140extern crate pretty_assertions;
141
142pub mod ast;
143#[macro_use]
144pub mod dialect;
145pub mod keywords;
146pub mod parser;
147pub mod tokenizer;
148
149#[doc(hidden)]
150// This is required to make utilities accessible by both the crate-internal
151// unit-tests and by the integration tests <https://stackoverflow.com/a/44541071/1026>
152// External users are not supposed to rely on this module.
153pub mod test_utils;