-
Notifications
You must be signed in to change notification settings - Fork 597
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Update comments / docs for Spanned
#1549
Changes from all commits
ec24d26
018afff
19a9278
dd9cfee
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,21 +21,51 @@ use super::{ | |
|
||
/// Given an iterator of spans, return the [Span::union] of all spans. | ||
fn union_spans<I: Iterator<Item = Span>>(iter: I) -> Span { | ||
iter.reduce(|acc, item| acc.union(&item)) | ||
.unwrap_or(Span::empty()) | ||
Span::union_iter(iter) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this was useful enough I felt making it a method in |
||
} | ||
|
||
/// A trait for AST nodes that have a source span for use in diagnostics. | ||
/// Trait for AST nodes that have a source location information. | ||
/// | ||
/// Source spans are not guaranteed to be entirely accurate. They may | ||
/// be missing keywords or other tokens. Some nodes may not have a computable | ||
/// span at all, in which case they return [`Span::empty()`]. | ||
/// # Notes: | ||
/// | ||
/// Source [`Span`] are not yet complete. They may be missing: | ||
/// | ||
/// 1. keywords or other tokens | ||
/// 2. span information entirely, in which case they return [`Span::empty()`]. | ||
/// | ||
/// Note Some impl blocks (rendered below) are annotated with which nodes are | ||
/// missing spans. See [this ticket] for additional information and status. | ||
/// | ||
/// [this ticket]: https://github.com/apache/datafusion-sqlparser-rs/issues/1548 | ||
/// | ||
/// # Example | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I felt an example will help people understand how to use the Spans |
||
/// ``` | ||
/// # use sqlparser::parser::{Parser, ParserError}; | ||
/// # use sqlparser::ast::Spanned; | ||
/// # use sqlparser::dialect::GenericDialect; | ||
/// # use sqlparser::tokenizer::Location; | ||
/// # fn main() -> Result<(), ParserError> { | ||
/// let dialect = GenericDialect {}; | ||
/// let sql = r#"SELECT * | ||
/// FROM table_1"#; | ||
/// let statements = Parser::new(&dialect) | ||
/// .try_with_sql(sql)? | ||
/// .parse_statements()?; | ||
/// // Get the span of the first statement (SELECT) | ||
/// let span = statements[0].span(); | ||
/// // statement starts at line 1, column 1 (1 based, not 0 based) | ||
/// assert_eq!(span.start, Location::new(1, 1)); | ||
/// // statement ends on line 2, column 15 | ||
/// assert_eq!(span.end, Location::new(2, 15)); | ||
/// # Ok(()) | ||
/// # } | ||
/// ``` | ||
/// | ||
/// Some impl blocks may contain doc comments with information | ||
/// on which nodes are missing spans. | ||
pub trait Spanned { | ||
/// Compute the source span for this AST node, by recursively | ||
/// combining the spans of its children. | ||
/// Return the [`Span`] (the minimum and maximum [`Location`]) for this AST | ||
/// node, by recursively combining the spans of its children. | ||
/// | ||
/// [`Location`]: crate::tokenizer::Location | ||
fn span(&self) -> Span; | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -25,6 +25,9 @@ | |
//! 1. [`Parser::parse_sql`] and [`Parser::new`] for the Parsing API | ||
//! 2. [`ast`] for the AST structure | ||
//! 3. [`Dialect`] for supported SQL dialects | ||
//! 4. [`Spanned`] for source text locations (see "Source Spans" below for details) | ||
//! | ||
//! [`Spanned`]: ast::Spanned | ||
//! | ||
//! # Example parsing SQL text | ||
//! | ||
|
@@ -61,13 +64,67 @@ | |
//! // 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 | ||
//! [`AST`]: crate::ast | ||
//! [`ast`]: crate::ast | ||
//! [`Dialect`]: crate::dialect::Dialect | ||
//! | ||
//! # Source Spans | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This content is largely migrated from |
||
//! | ||
//! Starting with version `0.53.0` sqlparser introduced source spans to the | ||
//! AST. This feature provides source information for syntax errors, enabling | ||
//! better error messages. See [issue #1548] for more information and the | ||
//! [`Spanned`] trait to access the spans. | ||
//! | ||
//! [issue #1548]: https://github.com/apache/datafusion-sqlparser-rs/issues/1548 | ||
//! [`Spanned`]: ast::Spanned | ||
//! | ||
//! ## Migration Guide | ||
//! | ||
//! For the next few releases, we will be incrementally adding source spans to the | ||
//! AST nodes, trying to minimize the impact on existing users. Some breaking | ||
//! changes are inevitable, and the following is a summary of the changes: | ||
//! | ||
//! #### New fields for spans (must be added to any existing pattern matches) | ||
//! | ||
//! The primary change is that new fields will be added to AST nodes to store the source `Span` or `TokenWithLocation`. | ||
//! | ||
//! This will require | ||
//! 1. Adding new fields to existing pattern matches. | ||
//! 2. Filling in the proper span information when constructing AST nodes. | ||
//! | ||
//! For example, since `Ident` now stores a `Span`, to construct an `Ident` you | ||
//! must provide now provide one: | ||
//! | ||
//! Previously: | ||
//! ```text | ||
//! # use sqlparser::ast::Ident; | ||
//! Ident { | ||
//! value: "name".into(), | ||
//! quote_style: None, | ||
//! } | ||
//! ``` | ||
//! Now | ||
//! ```rust | ||
//! # use sqlparser::ast::Ident; | ||
//! # use sqlparser::tokenizer::Span; | ||
//! Ident { | ||
//! value: "name".into(), | ||
//! quote_style: None, | ||
//! span: Span::empty(), | ||
//! }; | ||
//! ``` | ||
//! | ||
//! Similarly, when pattern matching on `Ident`, you must now account for the | ||
//! `span` field. | ||
//! | ||
//! #### Misc. | ||
//! - [`TokenWithLocation`] stores a full `Span`, rather than just a source location. | ||
//! Users relying on `token.location` should use `token.location.start` instead. | ||
//! | ||
//![`TokenWithLocation`]: tokenizer::TokenWithLocation | ||
|
||
#![cfg_attr(not(feature = "std"), no_std)] | ||
#![allow(clippy::upper_case_acronyms)] | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
drive by clarification