Skip to content

Commit 0842efe

Browse files
jakeswensonlustefaniak
authored andcommitted
feat(apache#757): Add Location/Spans in to the AST/parse layer
1 parent 097b677 commit 0842efe

15 files changed

+838
-471
lines changed

src/ast/ddl.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ use serde::{Deserialize, Serialize};
2222

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

2627
use crate::ast::value::escape_single_quote_string;
2728
use crate::ast::{
@@ -741,7 +742,7 @@ impl fmt::Display for UserDefinedTypeRepresentation {
741742
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
742743
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
743744
pub struct UserDefinedTypeCompositeAttributeDef {
744-
pub name: Ident,
745+
pub name: WithSpan<Ident>,
745746
pub data_type: DataType,
746747
pub collation: Option<ObjectName>,
747748
}

src/ast/mod.rs

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

2225
#[cfg(feature = "serde")]
2326
use serde::{Deserialize, Serialize};
@@ -45,9 +48,11 @@ pub use self::value::{
4548
escape_quoted_string, DateTimeField, DollarQuotedString, TrimWhereField, Value,
4649
};
4750

51+
4852
use crate::ast::helpers::stmt_data_loading::{
4953
DataLoadingOptions, StageLoadSelectItem, StageParamsObject,
5054
};
55+
use crate::tokenizer::Span;
5156
#[cfg(feature = "visitor")]
5257
pub use visitor::*;
5358

@@ -319,6 +324,78 @@ impl fmt::Display for JsonOperator {
319324
}
320325
}
321326

327+
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
328+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
329+
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
330+
pub struct WithSpan<T>
331+
where
332+
T: Clone + Eq + Ord + std::hash::Hash + PartialOrd + PartialEq,
333+
{
334+
inner: T,
335+
span: Span,
336+
}
337+
338+
impl<T> WithSpan<T>
339+
where
340+
T: Clone + Eq + Ord + std::hash::Hash + PartialOrd + PartialEq,
341+
{
342+
pub fn new(inner: T, span: Span) -> Self {
343+
Self { inner, span }
344+
}
345+
346+
pub fn unwrap(self) -> T {
347+
self.inner
348+
}
349+
}
350+
351+
pub trait SpanWrapped: Clone + Eq + Ord + std::hash::Hash + PartialOrd + PartialEq {
352+
fn spanning<U: Into<Span>>(self, span: U) -> WithSpan<Self> {
353+
WithSpan::new(self, span.into())
354+
}
355+
356+
fn empty_span(self) -> WithSpan<Self> {
357+
self.spanning(Span::default())
358+
}
359+
}
360+
361+
impl<T> SpanWrapped for T
362+
where
363+
T: Clone + Eq + Ord + std::hash::Hash + PartialOrd + PartialEq,
364+
{
365+
fn spanning<U: Into<Span>>(self, span: U) -> WithSpan<Self> {
366+
WithSpan::new(self, span.into())
367+
}
368+
}
369+
370+
impl<T> Deref for WithSpan<T>
371+
where
372+
T: Clone + Eq + Ord + std::hash::Hash + PartialOrd + PartialEq,
373+
{
374+
type Target = T;
375+
376+
fn deref(&self) -> &Self::Target {
377+
&self.inner
378+
}
379+
}
380+
381+
impl<T> Borrow<T> for WithSpan<T>
382+
where
383+
T: Clone + Eq + Ord + std::hash::Hash + PartialOrd + PartialEq,
384+
{
385+
fn borrow(&self) -> &T {
386+
&self.inner
387+
}
388+
}
389+
390+
impl<T: fmt::Display> fmt::Display for WithSpan<T>
391+
where
392+
T: Clone + Eq + Ord + std::hash::Hash + PartialOrd + PartialEq,
393+
{
394+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
395+
write!(f, "{}", self.inner)
396+
}
397+
}
398+
322399
/// An SQL expression of any type.
323400
///
324401
/// The parser does not distinguish between expressions of different types
@@ -333,7 +410,7 @@ impl fmt::Display for JsonOperator {
333410
)]
334411
pub enum Expr {
335412
/// Identifier e.g. table name or column name
336-
Identifier(Ident),
413+
Identifier(WithSpan<Ident>),
337414
/// Multi-part identifier, e.g. `table_alias.column` or `schema.table.col`
338415
CompoundIdentifier(Vec<Ident>),
339416
/// JSON access (postgres) eg: data->'tags'
@@ -936,7 +1013,7 @@ impl fmt::Display for Expr {
9361013
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9371014
pub enum WindowType {
9381015
WindowSpec(WindowSpec),
939-
NamedWindow(Ident),
1016+
NamedWindow(WithSpan<Ident>),
9401017
}
9411018

9421019
impl Display for WindowType {
@@ -4415,6 +4492,10 @@ impl fmt::Display for SearchModifier {
44154492
mod tests {
44164493
use super::*;
44174494

4495+
fn ident<T: Into<String>>(value: T) -> WithSpan<Ident> {
4496+
SpanWrapped::empty_span(Ident::new(value))
4497+
}
4498+
44184499
#[test]
44194500
fn test_window_frame_default() {
44204501
let window_frame = WindowFrame::default();
@@ -4425,84 +4506,72 @@ mod tests {
44254506
fn test_grouping_sets_display() {
44264507
// a and b in different group
44274508
let grouping_sets = Expr::GroupingSets(vec![
4428-
vec![Expr::Identifier(Ident::new("a"))],
4429-
vec![Expr::Identifier(Ident::new("b"))],
4509+
vec![Expr::Identifier(ident("a"))],
4510+
vec![Expr::Identifier(ident("b"))],
44304511
]);
44314512
assert_eq!("GROUPING SETS ((a), (b))", format!("{grouping_sets}"));
44324513

44334514
// a and b in the same group
44344515
let grouping_sets = Expr::GroupingSets(vec![vec![
4435-
Expr::Identifier(Ident::new("a")),
4436-
Expr::Identifier(Ident::new("b")),
4516+
Expr::Identifier(ident("a")),
4517+
Expr::Identifier(ident("b")),
44374518
]]);
44384519
assert_eq!("GROUPING SETS ((a, b))", format!("{grouping_sets}"));
44394520

44404521
// (a, b) and (c, d) in different group
44414522
let grouping_sets = Expr::GroupingSets(vec![
4442-
vec![
4443-
Expr::Identifier(Ident::new("a")),
4444-
Expr::Identifier(Ident::new("b")),
4445-
],
4446-
vec![
4447-
Expr::Identifier(Ident::new("c")),
4448-
Expr::Identifier(Ident::new("d")),
4449-
],
4523+
vec![Expr::Identifier(ident("a")), Expr::Identifier(ident("b"))],
4524+
vec![Expr::Identifier(ident("c")), Expr::Identifier(ident("d"))],
44504525
]);
44514526
assert_eq!("GROUPING SETS ((a, b), (c, d))", format!("{grouping_sets}"));
44524527
}
44534528

44544529
#[test]
44554530
fn test_rollup_display() {
4456-
let rollup = Expr::Rollup(vec![vec![Expr::Identifier(Ident::new("a"))]]);
4531+
let rollup = Expr::Rollup(vec![vec![Expr::Identifier(ident("a"))]]);
44574532
assert_eq!("ROLLUP (a)", format!("{rollup}"));
44584533

44594534
let rollup = Expr::Rollup(vec![vec![
4460-
Expr::Identifier(Ident::new("a")),
4461-
Expr::Identifier(Ident::new("b")),
4535+
Expr::Identifier(ident("a")),
4536+
Expr::Identifier(ident("b")),
44624537
]]);
44634538
assert_eq!("ROLLUP ((a, b))", format!("{rollup}"));
44644539

44654540
let rollup = Expr::Rollup(vec![
4466-
vec![Expr::Identifier(Ident::new("a"))],
4467-
vec![Expr::Identifier(Ident::new("b"))],
4541+
vec![Expr::Identifier(ident("a"))],
4542+
vec![Expr::Identifier(ident("b"))],
44684543
]);
44694544
assert_eq!("ROLLUP (a, b)", format!("{rollup}"));
44704545

44714546
let rollup = Expr::Rollup(vec![
4472-
vec![Expr::Identifier(Ident::new("a"))],
4473-
vec![
4474-
Expr::Identifier(Ident::new("b")),
4475-
Expr::Identifier(Ident::new("c")),
4476-
],
4477-
vec![Expr::Identifier(Ident::new("d"))],
4547+
vec![Expr::Identifier(ident("a"))],
4548+
vec![Expr::Identifier(ident("b")), Expr::Identifier(ident("c"))],
4549+
vec![Expr::Identifier(ident("d"))],
44784550
]);
44794551
assert_eq!("ROLLUP (a, (b, c), d)", format!("{rollup}"));
44804552
}
44814553

44824554
#[test]
44834555
fn test_cube_display() {
4484-
let cube = Expr::Cube(vec![vec![Expr::Identifier(Ident::new("a"))]]);
4556+
let cube = Expr::Cube(vec![vec![Expr::Identifier(ident("a"))]]);
44854557
assert_eq!("CUBE (a)", format!("{cube}"));
44864558

44874559
let cube = Expr::Cube(vec![vec![
4488-
Expr::Identifier(Ident::new("a")),
4489-
Expr::Identifier(Ident::new("b")),
4560+
Expr::Identifier(ident("a")),
4561+
Expr::Identifier(ident("b")),
44904562
]]);
44914563
assert_eq!("CUBE ((a, b))", format!("{cube}"));
44924564

44934565
let cube = Expr::Cube(vec![
4494-
vec![Expr::Identifier(Ident::new("a"))],
4495-
vec![Expr::Identifier(Ident::new("b"))],
4566+
vec![Expr::Identifier(ident("a"))],
4567+
vec![Expr::Identifier(ident("b"))],
44964568
]);
44974569
assert_eq!("CUBE (a, b)", format!("{cube}"));
44984570

44994571
let cube = Expr::Cube(vec![
4500-
vec![Expr::Identifier(Ident::new("a"))],
4501-
vec![
4502-
Expr::Identifier(Ident::new("b")),
4503-
Expr::Identifier(Ident::new("c")),
4504-
],
4505-
vec![Expr::Identifier(Ident::new("d"))],
4572+
vec![Expr::Identifier(ident("a"))],
4573+
vec![Expr::Identifier(ident("b")), Expr::Identifier(ident("c"))],
4574+
vec![Expr::Identifier(ident("d"))],
45064575
]);
45074576
assert_eq!("CUBE (a, (b, c), d)", format!("{cube}"));
45084577
}

src/ast/query.rs

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

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

0 commit comments

Comments
 (0)