From 64eccdbba2fbc69fdb76ee451a1c43e30e7bfe3c Mon Sep 17 00:00:00 2001 From: Andrew Lamb Date: Mon, 27 Nov 2023 12:29:59 -0500 Subject: [PATCH] Document round trip ability (#1052) --- README.md | 22 ++++++++++++++++++++++ src/lib.rs | 20 +++++++++++++++++++- src/test_utils.rs | 5 +++++ 3 files changed, 46 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 19efc4368..6a551d0fb 100644 --- a/README.md +++ b/README.md @@ -59,6 +59,28 @@ This crate avoids semantic analysis because it varies drastically between dialects and implementations. If you want to do semantic analysis, feel free to use this project as a base. +## Preserves Syntax Round Trip + +This crate allows users to recover the original SQL text (with normalized +whitespace and keyword capitalization), which is useful for tools that +analyze and manipulate SQL. + +This means that other than whitespace and the capitalization of keywords, the +following should hold true for all SQL: + +```rust +// Parse SQL +let ast = Parser::parse_sql(&GenericDialect, sql).unwrap(); + +// The original SQL text can be generated from the AST +assert_eq!(ast[0].to_string(), sql); +``` + +There are still some cases in this crate where different SQL with seemingly +similar semantics are represented with the same AST. We welcome PRs to fix such +issues and distinguish different syntaxes in the AST. + + ## SQL compliance SQL was first standardized in 1987, and revisions of the standard have been diff --git a/src/lib.rs b/src/lib.rs index 5bcd32949..5afdfbc08 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -21,7 +21,7 @@ //! 2. [`ast`] for the AST structure //! 3. [`Dialect`] for supported SQL dialects //! -//! # Example +//! # Example parsing SQL text //! //! ``` //! use sqlparser::dialect::GenericDialect; @@ -39,6 +39,24 @@ //! println!("AST: {:?}", ast); //! ``` //! +//! # Creating SQL text from AST +//! +//! This crate allows users to recover the original SQL text (with normalized +//! whitespace and identifier capitalization), which is useful for tools that +//! analyze and manipulate SQL. +//! +//! ``` +//! # use sqlparser::dialect::GenericDialect; +//! # use sqlparser::parser::Parser; +//! let sql = "SELECT a FROM table_1"; +//! +//! // parse to a Vec +//! let ast = Parser::parse_sql(&GenericDialect, sql).unwrap(); +//! +//! // The original SQL text can be generated from the AST +//! assert_eq!(ast[0].to_string(), sql); +//! ``` +//! //! [sqlparser crates.io page]: https://crates.io/crates/sqlparser //! [`Parser::parse_sql`]: crate::parser::Parser::parse_sql //! [`Parser::new`]: crate::parser::Parser::new diff --git a/src/test_utils.rs b/src/test_utils.rs index 76a3e073b..26cfec463 100644 --- a/src/test_utils.rs +++ b/src/test_utils.rs @@ -102,6 +102,11 @@ impl TestedDialects { /// Ensures that `sql` parses as a single [Statement] for all tested /// dialects. /// + /// In general, the canonical SQL should be the same (see crate + /// documentation for rationale) and you should prefer the `verified_` + /// variants in testing, such as [`verified_statement`] or + /// [`verified_query`]. + /// /// If `canonical` is non empty,this function additionally asserts /// that: ///