Skip to content

Commit 14fd2c8

Browse files
jakeswensonlustefaniak
authored andcommitted
feat(apache#757): Add Location/Spans in to the AST/parse layer
1 parent 8481452 commit 14fd2c8

17 files changed

+946
-544
lines changed

src/ast/ddl.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use core::fmt;
2020
#[cfg(feature = "serde")]
2121
use serde::{Deserialize, Serialize};
2222

23+
use sqlparser::ast::WithSpan;
2324
#[cfg(feature = "visitor")]
2425
use sqlparser_derive::{Visit, VisitMut};
2526

@@ -754,7 +755,7 @@ impl fmt::Display for UserDefinedTypeRepresentation {
754755
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
755756
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
756757
pub struct UserDefinedTypeCompositeAttributeDef {
757-
pub name: Ident,
758+
pub name: WithSpan<Ident>,
758759
pub data_type: DataType,
759760
pub collation: Option<ObjectName>,
760761
}

src/ast/mod.rs

+104-36
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,10 @@ use alloc::{
1717
string::{String, ToString},
1818
vec::Vec,
1919
};
20+
21+
use core::borrow::Borrow;
2022
use core::fmt::{self, Display};
23+
use std::ops::Deref;
2124

2225
#[cfg(feature = "serde")]
2326
use serde::{Deserialize, Serialize};
@@ -50,6 +53,7 @@ pub use self::value::{
5053
use crate::ast::helpers::stmt_data_loading::{
5154
DataLoadingOptions, StageLoadSelectItem, StageParamsObject,
5255
};
56+
use crate::tokenizer::Span;
5357
#[cfg(feature = "visitor")]
5458
pub use visitor::*;
5559

@@ -340,6 +344,78 @@ impl fmt::Display for JsonOperator {
340344
}
341345
}
342346

347+
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
348+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
349+
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
350+
pub struct WithSpan<T>
351+
where
352+
T: Clone + Eq + Ord + std::hash::Hash + PartialOrd + PartialEq,
353+
{
354+
inner: T,
355+
span: Span,
356+
}
357+
358+
impl<T> WithSpan<T>
359+
where
360+
T: Clone + Eq + Ord + std::hash::Hash + PartialOrd + PartialEq,
361+
{
362+
pub fn new(inner: T, span: Span) -> Self {
363+
Self { inner, span }
364+
}
365+
366+
pub fn unwrap(self) -> T {
367+
self.inner
368+
}
369+
}
370+
371+
pub trait SpanWrapped: Clone + Eq + Ord + std::hash::Hash + PartialOrd + PartialEq {
372+
fn spanning<U: Into<Span>>(self, span: U) -> WithSpan<Self> {
373+
WithSpan::new(self, span.into())
374+
}
375+
376+
fn empty_span(self) -> WithSpan<Self> {
377+
self.spanning(Span::default())
378+
}
379+
}
380+
381+
impl<T> SpanWrapped for T
382+
where
383+
T: Clone + Eq + Ord + std::hash::Hash + PartialOrd + PartialEq,
384+
{
385+
fn spanning<U: Into<Span>>(self, span: U) -> WithSpan<Self> {
386+
WithSpan::new(self, span.into())
387+
}
388+
}
389+
390+
impl<T> Deref for WithSpan<T>
391+
where
392+
T: Clone + Eq + Ord + std::hash::Hash + PartialOrd + PartialEq,
393+
{
394+
type Target = T;
395+
396+
fn deref(&self) -> &Self::Target {
397+
&self.inner
398+
}
399+
}
400+
401+
impl<T> Borrow<T> for WithSpan<T>
402+
where
403+
T: Clone + Eq + Ord + std::hash::Hash + PartialOrd + PartialEq,
404+
{
405+
fn borrow(&self) -> &T {
406+
&self.inner
407+
}
408+
}
409+
410+
impl<T: fmt::Display> fmt::Display for WithSpan<T>
411+
where
412+
T: Clone + Eq + Ord + std::hash::Hash + PartialOrd + PartialEq,
413+
{
414+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
415+
write!(f, "{}", self.inner)
416+
}
417+
}
418+
343419
/// An SQL expression of any type.
344420
///
345421
/// The parser does not distinguish between expressions of different types
@@ -354,7 +430,7 @@ impl fmt::Display for JsonOperator {
354430
)]
355431
pub enum Expr {
356432
/// Identifier e.g. table name or column name
357-
Identifier(Ident),
433+
Identifier(WithSpan<Ident>),
358434
/// Multi-part identifier, e.g. `table_alias.column` or `schema.table.col`
359435
CompoundIdentifier(Vec<Ident>),
360436
/// JSON access (postgres) eg: data->'tags'
@@ -1025,7 +1101,7 @@ impl fmt::Display for Expr {
10251101
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10261102
pub enum WindowType {
10271103
WindowSpec(WindowSpec),
1028-
NamedWindow(Ident),
1104+
NamedWindow(WithSpan<Ident>),
10291105
}
10301106

10311107
impl Display for WindowType {
@@ -4732,6 +4808,10 @@ impl fmt::Display for SearchModifier {
47324808
mod tests {
47334809
use super::*;
47344810

4811+
fn ident<T: Into<String>>(value: T) -> WithSpan<Ident> {
4812+
SpanWrapped::empty_span(Ident::new(value))
4813+
}
4814+
47354815
#[test]
47364816
fn test_window_frame_default() {
47374817
let window_frame = WindowFrame::default();
@@ -4742,84 +4822,72 @@ mod tests {
47424822
fn test_grouping_sets_display() {
47434823
// a and b in different group
47444824
let grouping_sets = Expr::GroupingSets(vec![
4745-
vec![Expr::Identifier(Ident::new("a"))],
4746-
vec![Expr::Identifier(Ident::new("b"))],
4825+
vec![Expr::Identifier(ident("a"))],
4826+
vec![Expr::Identifier(ident("b"))],
47474827
]);
47484828
assert_eq!("GROUPING SETS ((a), (b))", format!("{grouping_sets}"));
47494829

47504830
// a and b in the same group
47514831
let grouping_sets = Expr::GroupingSets(vec![vec![
4752-
Expr::Identifier(Ident::new("a")),
4753-
Expr::Identifier(Ident::new("b")),
4832+
Expr::Identifier(ident("a")),
4833+
Expr::Identifier(ident("b")),
47544834
]]);
47554835
assert_eq!("GROUPING SETS ((a, b))", format!("{grouping_sets}"));
47564836

47574837
// (a, b) and (c, d) in different group
47584838
let grouping_sets = Expr::GroupingSets(vec![
4759-
vec![
4760-
Expr::Identifier(Ident::new("a")),
4761-
Expr::Identifier(Ident::new("b")),
4762-
],
4763-
vec![
4764-
Expr::Identifier(Ident::new("c")),
4765-
Expr::Identifier(Ident::new("d")),
4766-
],
4839+
vec![Expr::Identifier(ident("a")), Expr::Identifier(ident("b"))],
4840+
vec![Expr::Identifier(ident("c")), Expr::Identifier(ident("d"))],
47674841
]);
47684842
assert_eq!("GROUPING SETS ((a, b), (c, d))", format!("{grouping_sets}"));
47694843
}
47704844

47714845
#[test]
47724846
fn test_rollup_display() {
4773-
let rollup = Expr::Rollup(vec![vec![Expr::Identifier(Ident::new("a"))]]);
4847+
let rollup = Expr::Rollup(vec![vec![Expr::Identifier(ident("a"))]]);
47744848
assert_eq!("ROLLUP (a)", format!("{rollup}"));
47754849

47764850
let rollup = Expr::Rollup(vec![vec![
4777-
Expr::Identifier(Ident::new("a")),
4778-
Expr::Identifier(Ident::new("b")),
4851+
Expr::Identifier(ident("a")),
4852+
Expr::Identifier(ident("b")),
47794853
]]);
47804854
assert_eq!("ROLLUP ((a, b))", format!("{rollup}"));
47814855

47824856
let rollup = Expr::Rollup(vec![
4783-
vec![Expr::Identifier(Ident::new("a"))],
4784-
vec![Expr::Identifier(Ident::new("b"))],
4857+
vec![Expr::Identifier(ident("a"))],
4858+
vec![Expr::Identifier(ident("b"))],
47854859
]);
47864860
assert_eq!("ROLLUP (a, b)", format!("{rollup}"));
47874861

47884862
let rollup = Expr::Rollup(vec![
4789-
vec![Expr::Identifier(Ident::new("a"))],
4790-
vec![
4791-
Expr::Identifier(Ident::new("b")),
4792-
Expr::Identifier(Ident::new("c")),
4793-
],
4794-
vec![Expr::Identifier(Ident::new("d"))],
4863+
vec![Expr::Identifier(ident("a"))],
4864+
vec![Expr::Identifier(ident("b")), Expr::Identifier(ident("c"))],
4865+
vec![Expr::Identifier(ident("d"))],
47954866
]);
47964867
assert_eq!("ROLLUP (a, (b, c), d)", format!("{rollup}"));
47974868
}
47984869

47994870
#[test]
48004871
fn test_cube_display() {
4801-
let cube = Expr::Cube(vec![vec![Expr::Identifier(Ident::new("a"))]]);
4872+
let cube = Expr::Cube(vec![vec![Expr::Identifier(ident("a"))]]);
48024873
assert_eq!("CUBE (a)", format!("{cube}"));
48034874

48044875
let cube = Expr::Cube(vec![vec![
4805-
Expr::Identifier(Ident::new("a")),
4806-
Expr::Identifier(Ident::new("b")),
4876+
Expr::Identifier(ident("a")),
4877+
Expr::Identifier(ident("b")),
48074878
]]);
48084879
assert_eq!("CUBE ((a, b))", format!("{cube}"));
48094880

48104881
let cube = Expr::Cube(vec![
4811-
vec![Expr::Identifier(Ident::new("a"))],
4812-
vec![Expr::Identifier(Ident::new("b"))],
4882+
vec![Expr::Identifier(ident("a"))],
4883+
vec![Expr::Identifier(ident("b"))],
48134884
]);
48144885
assert_eq!("CUBE (a, b)", format!("{cube}"));
48154886

48164887
let cube = Expr::Cube(vec![
4817-
vec![Expr::Identifier(Ident::new("a"))],
4818-
vec![
4819-
Expr::Identifier(Ident::new("b")),
4820-
Expr::Identifier(Ident::new("c")),
4821-
],
4822-
vec![Expr::Identifier(Ident::new("d"))],
4888+
vec![Expr::Identifier(ident("a"))],
4889+
vec![Expr::Identifier(ident("b")), Expr::Identifier(ident("c"))],
4890+
vec![Expr::Identifier(ident("d"))],
48234891
]);
48244892
assert_eq!("CUBE (a, (b, c), d)", format!("{cube}"));
48254893
}

src/ast/query.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,7 @@ impl fmt::Display for LateralView {
338338
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
339339
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
340340
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
341-
pub struct NamedWindowDefinition(pub Ident, pub WindowSpec);
341+
pub struct NamedWindowDefinition(pub WithSpan<Ident>, pub WindowSpec);
342342

343343
impl fmt::Display for NamedWindowDefinition {
344344
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {

src/parser/alter.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -37,17 +37,17 @@ impl<'a> Parser<'a> {
3737
}
3838

3939
fn parse_mssql_alter_role(&mut self) -> Result<Statement, ParserError> {
40-
let role_name = self.parse_identifier()?;
40+
let role_name = self.parse_identifier()?.unwrap();
4141

4242
let operation = if self.parse_keywords(&[Keyword::ADD, Keyword::MEMBER]) {
43-
let member_name = self.parse_identifier()?;
43+
let member_name = self.parse_identifier()?.unwrap();
4444
AlterRoleOperation::AddMember { member_name }
4545
} else if self.parse_keywords(&[Keyword::DROP, Keyword::MEMBER]) {
46-
let member_name = self.parse_identifier()?;
46+
let member_name = self.parse_identifier()?.unwrap();
4747
AlterRoleOperation::DropMember { member_name }
4848
} else if self.parse_keywords(&[Keyword::WITH, Keyword::NAME]) {
4949
if self.consume_token(&Token::Eq) {
50-
let role_name = self.parse_identifier()?;
50+
let role_name = self.parse_identifier()?.unwrap();
5151
AlterRoleOperation::RenameRole { role_name }
5252
} else {
5353
return self.expected("= after WITH NAME ", self.peek_token());
@@ -63,7 +63,7 @@ impl<'a> Parser<'a> {
6363
}
6464

6565
fn parse_pg_alter_role(&mut self) -> Result<Statement, ParserError> {
66-
let role_name = self.parse_identifier()?;
66+
let role_name = self.parse_identifier()?.unwrap();
6767

6868
// [ IN DATABASE _`database_name`_ ]
6969
let in_database = if self.parse_keywords(&[Keyword::IN, Keyword::DATABASE]) {
@@ -74,7 +74,7 @@ impl<'a> Parser<'a> {
7474

7575
let operation = if self.parse_keyword(Keyword::RENAME) {
7676
if self.parse_keyword(Keyword::TO) {
77-
let role_name = self.parse_identifier()?;
77+
let role_name = self.parse_identifier()?.unwrap();
7878
AlterRoleOperation::RenameRole { role_name }
7979
} else {
8080
return self.expected("TO after RENAME", self.peek_token());

0 commit comments

Comments
 (0)