Skip to content

Commit 4e66a81

Browse files
committed
feat(apache#757): Add Location/Spans in to the AST/parse layer
1 parent a8a8e65 commit 4e66a81

14 files changed

+816
-456
lines changed

src/ast/mod.rs

+102-35
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@ use alloc::{
1717
string::{String, ToString},
1818
vec::Vec,
1919
};
20+
use core::borrow::Borrow;
2021
use core::fmt;
22+
use std::ops::Deref;
2123

2224
#[cfg(feature = "serde")]
2325
use serde::{Deserialize, Serialize};
@@ -44,6 +46,7 @@ pub use self::value::{
4446
escape_quoted_string, DateTimeField, DollarQuotedString, TrimWhereField, Value,
4547
};
4648

49+
use crate::tokenizer::Span;
4750
#[cfg(feature = "visitor")]
4851
pub use visitor::*;
4952

@@ -251,6 +254,76 @@ impl fmt::Display for JsonOperator {
251254
}
252255
}
253256

257+
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
258+
pub struct WithSpan<T>
259+
where
260+
T: Clone + Eq + Ord + std::hash::Hash + PartialOrd + PartialEq,
261+
{
262+
inner: T,
263+
span: Span,
264+
}
265+
266+
impl<T> WithSpan<T>
267+
where
268+
T: Clone + Eq + Ord + std::hash::Hash + PartialOrd + PartialEq,
269+
{
270+
pub fn new(inner: T, span: Span) -> Self {
271+
Self { inner, span }
272+
}
273+
274+
pub fn unwrap(self) -> T {
275+
self.inner
276+
}
277+
}
278+
279+
pub trait SpanWrapped: Clone + Eq + Ord + std::hash::Hash + PartialOrd + PartialEq {
280+
fn spanning<U: Into<Span>>(self, span: U) -> WithSpan<Self> {
281+
WithSpan::new(self, span.into())
282+
}
283+
284+
fn empty_span(self) -> WithSpan<Self> {
285+
self.spanning(Span::default())
286+
}
287+
}
288+
289+
impl<T> SpanWrapped for T
290+
where
291+
T: Clone + Eq + Ord + std::hash::Hash + PartialOrd + PartialEq,
292+
{
293+
fn spanning<U: Into<Span>>(self, span: U) -> WithSpan<Self> {
294+
WithSpan::new(self, span.into())
295+
}
296+
}
297+
298+
impl<T> Deref for WithSpan<T>
299+
where
300+
T: Clone + Eq + Ord + std::hash::Hash + PartialOrd + PartialEq,
301+
{
302+
type Target = T;
303+
304+
fn deref(&self) -> &Self::Target {
305+
&self.inner
306+
}
307+
}
308+
309+
impl<T> Borrow<T> for WithSpan<T>
310+
where
311+
T: Clone + Eq + Ord + std::hash::Hash + PartialOrd + PartialEq,
312+
{
313+
fn borrow(&self) -> &T {
314+
&self.inner
315+
}
316+
}
317+
318+
impl<T: fmt::Display> fmt::Display for WithSpan<T>
319+
where
320+
T: Clone + Eq + Ord + std::hash::Hash + PartialOrd + PartialEq,
321+
{
322+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
323+
write!(f, "{}", self.inner)
324+
}
325+
}
326+
254327
/// An SQL expression of any type.
255328
///
256329
/// The parser does not distinguish between expressions of different types
@@ -265,7 +338,7 @@ impl fmt::Display for JsonOperator {
265338
)]
266339
pub enum Expr {
267340
/// Identifier e.g. table name or column name
268-
Identifier(Ident),
341+
Identifier(WithSpan<Ident>),
269342
/// Multi-part identifier, e.g. `table_alias.column` or `schema.table.col`
270343
CompoundIdentifier(Vec<Ident>),
271344
/// JSON access (postgres) eg: data->'tags'
@@ -4162,6 +4235,12 @@ impl fmt::Display for SearchModifier {
41624235
mod tests {
41634236
use super::*;
41644237

4238+
fn ident<T: Into<String>>(value: T) -> WithSpan<Ident> {
4239+
use crate::ast::SpanWrapped;
4240+
4241+
SpanWrapped::empty_span(Ident::new(value))
4242+
}
4243+
41654244
#[test]
41664245
fn test_window_frame_default() {
41674246
let window_frame = WindowFrame::default();
@@ -4172,84 +4251,72 @@ mod tests {
41724251
fn test_grouping_sets_display() {
41734252
// a and b in different group
41744253
let grouping_sets = Expr::GroupingSets(vec![
4175-
vec![Expr::Identifier(Ident::new("a"))],
4176-
vec![Expr::Identifier(Ident::new("b"))],
4254+
vec![Expr::Identifier(ident("a"))],
4255+
vec![Expr::Identifier(ident("b"))],
41774256
]);
41784257
assert_eq!("GROUPING SETS ((a), (b))", format!("{grouping_sets}"));
41794258

41804259
// a and b in the same group
41814260
let grouping_sets = Expr::GroupingSets(vec![vec![
4182-
Expr::Identifier(Ident::new("a")),
4183-
Expr::Identifier(Ident::new("b")),
4261+
Expr::Identifier(ident("a")),
4262+
Expr::Identifier(ident("b")),
41844263
]]);
41854264
assert_eq!("GROUPING SETS ((a, b))", format!("{grouping_sets}"));
41864265

41874266
// (a, b) and (c, d) in different group
41884267
let grouping_sets = Expr::GroupingSets(vec![
4189-
vec![
4190-
Expr::Identifier(Ident::new("a")),
4191-
Expr::Identifier(Ident::new("b")),
4192-
],
4193-
vec![
4194-
Expr::Identifier(Ident::new("c")),
4195-
Expr::Identifier(Ident::new("d")),
4196-
],
4268+
vec![Expr::Identifier(ident("a")), Expr::Identifier(ident("b"))],
4269+
vec![Expr::Identifier(ident("c")), Expr::Identifier(ident("d"))],
41974270
]);
41984271
assert_eq!("GROUPING SETS ((a, b), (c, d))", format!("{grouping_sets}"));
41994272
}
42004273

42014274
#[test]
42024275
fn test_rollup_display() {
4203-
let rollup = Expr::Rollup(vec![vec![Expr::Identifier(Ident::new("a"))]]);
4276+
let rollup = Expr::Rollup(vec![vec![Expr::Identifier(ident("a"))]]);
42044277
assert_eq!("ROLLUP (a)", format!("{rollup}"));
42054278

42064279
let rollup = Expr::Rollup(vec![vec![
4207-
Expr::Identifier(Ident::new("a")),
4208-
Expr::Identifier(Ident::new("b")),
4280+
Expr::Identifier(ident("a")),
4281+
Expr::Identifier(ident("b")),
42094282
]]);
42104283
assert_eq!("ROLLUP ((a, b))", format!("{rollup}"));
42114284

42124285
let rollup = Expr::Rollup(vec![
4213-
vec![Expr::Identifier(Ident::new("a"))],
4214-
vec![Expr::Identifier(Ident::new("b"))],
4286+
vec![Expr::Identifier(ident("a"))],
4287+
vec![Expr::Identifier(ident("b"))],
42154288
]);
42164289
assert_eq!("ROLLUP (a, b)", format!("{rollup}"));
42174290

42184291
let rollup = Expr::Rollup(vec![
4219-
vec![Expr::Identifier(Ident::new("a"))],
4220-
vec![
4221-
Expr::Identifier(Ident::new("b")),
4222-
Expr::Identifier(Ident::new("c")),
4223-
],
4224-
vec![Expr::Identifier(Ident::new("d"))],
4292+
vec![Expr::Identifier(ident("a"))],
4293+
vec![Expr::Identifier(ident("b")), Expr::Identifier(ident("c"))],
4294+
vec![Expr::Identifier(ident("d"))],
42254295
]);
42264296
assert_eq!("ROLLUP (a, (b, c), d)", format!("{rollup}"));
42274297
}
42284298

42294299
#[test]
42304300
fn test_cube_display() {
4231-
let cube = Expr::Cube(vec![vec![Expr::Identifier(Ident::new("a"))]]);
4301+
let cube = Expr::Cube(vec![vec![Expr::Identifier(ident("a"))]]);
42324302
assert_eq!("CUBE (a)", format!("{cube}"));
42334303

42344304
let cube = Expr::Cube(vec![vec![
4235-
Expr::Identifier(Ident::new("a")),
4236-
Expr::Identifier(Ident::new("b")),
4305+
Expr::Identifier(ident("a")),
4306+
Expr::Identifier(ident("b")),
42374307
]]);
42384308
assert_eq!("CUBE ((a, b))", format!("{cube}"));
42394309

42404310
let cube = Expr::Cube(vec![
4241-
vec![Expr::Identifier(Ident::new("a"))],
4242-
vec![Expr::Identifier(Ident::new("b"))],
4311+
vec![Expr::Identifier(ident("a"))],
4312+
vec![Expr::Identifier(ident("b"))],
42434313
]);
42444314
assert_eq!("CUBE (a, b)", format!("{cube}"));
42454315

42464316
let cube = Expr::Cube(vec![
4247-
vec![Expr::Identifier(Ident::new("a"))],
4248-
vec![
4249-
Expr::Identifier(Ident::new("b")),
4250-
Expr::Identifier(Ident::new("c")),
4251-
],
4252-
vec![Expr::Identifier(Ident::new("d"))],
4317+
vec![Expr::Identifier(ident("a"))],
4318+
vec![Expr::Identifier(ident("b")), Expr::Identifier(ident("c"))],
4319+
vec![Expr::Identifier(ident("d"))],
42534320
]);
42544321
assert_eq!("CUBE (a, (b, c), d)", format!("{cube}"));
42554322
}

src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ extern crate alloc;
5151
#[macro_use]
5252
#[cfg(test)]
5353
extern crate pretty_assertions;
54+
extern crate core;
5455

5556
pub mod ast;
5657
#[macro_use]

0 commit comments

Comments
 (0)