Skip to content

Commit f1edf26

Browse files
committed
Provide Parens<T> and track Value's (expressions) span
1 parent 913cf0e commit f1edf26

9 files changed

Lines changed: 110 additions & 73 deletions

File tree

src/ast/mod.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ use core::{
3535
fmt::{self, Display},
3636
hash,
3737
};
38+
use std::ops::DerefMut;
3839

3940
#[cfg(feature = "serde")]
4041
use serde::{Deserialize, Serialize};
@@ -199,6 +200,46 @@ fn format_statement_list(f: &mut fmt::Formatter, statements: &[Statement]) -> fm
199200
write!(f, ";")
200201
}
201202

203+
/// A item `T` enclosed in a pair of parentheses
204+
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
205+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
206+
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
207+
pub struct Parens<T> {
208+
/// the opening parenthesis token, i.e. `(`
209+
pub opening_token: AttachedToken,
210+
/// content enclosed in parentheses
211+
pub content: T,
212+
/// the closing parenthesis token, i.e. `)`
213+
pub closing_token: AttachedToken,
214+
}
215+
216+
impl<T> Parens<T> {
217+
/// Constructor wrapping `content` into `Parens` with an empty span;
218+
/// useful for testing purposes.
219+
#[inline]
220+
pub fn with_empty_span(content: T) -> Self {
221+
Self {
222+
opening_token: AttachedToken::empty(),
223+
content,
224+
closing_token: AttachedToken::empty(),
225+
}
226+
}
227+
}
228+
229+
impl<T> Deref for Parens<T> {
230+
type Target = T;
231+
232+
fn deref(&self) -> &Self::Target {
233+
&self.content
234+
}
235+
}
236+
237+
impl <T> DerefMut for Parens<T> {
238+
fn deref_mut(&mut self) -> &mut Self::Target {
239+
&mut self.content
240+
}
241+
}
242+
202243
/// An identifier, decomposed into its value or character data and the quote style.
203244
#[derive(Debug, Clone)]
204245
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]

src/ast/query.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3613,7 +3613,7 @@ pub struct Values {
36133613
/// <https://dev.mysql.com/doc/refman/9.2/en/insert.html>
36143614
pub value_keyword: bool,
36153615
/// The list of rows, each row is a list of expressions.
3616-
pub rows: Vec<Vec<Expr>>,
3616+
pub rows: Vec<Parens<Vec<Expr>>>,
36173617
}
36183618

36193619
impl fmt::Display for Values {

src/ast/spans.rs

Lines changed: 12 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -28,26 +28,7 @@ use core::iter;
2828
use crate::tokenizer::Span;
2929

3030
use super::{
31-
comments, dcl::SecondaryRoles, value::ValueWithSpan, AccessExpr, AlterColumnOperation,
32-
AlterIndexOperation, AlterTableOperation, Analyze, Array, Assignment, AssignmentTarget,
33-
AttachedToken, BeginEndStatements, CaseStatement, CloseCursor, ClusteredIndex, ColumnDef,
34-
ColumnOption, ColumnOptionDef, ConditionalStatementBlock, ConditionalStatements,
35-
ConflictTarget, ConnectByKind, ConstraintCharacteristics, CopySource, CreateIndex, CreateTable,
36-
CreateTableOptions, Cte, Delete, DoUpdate, ExceptSelectItem, ExcludeSelectItem, Expr,
37-
ExprWithAlias, Fetch, ForValues, FromTable, Function, FunctionArg, FunctionArgExpr,
38-
FunctionArgumentClause, FunctionArgumentList, FunctionArguments, GroupByExpr, HavingBound,
39-
IfStatement, IlikeSelectItem, IndexColumn, Insert, Interpolate, InterpolateExpr, Join,
40-
JoinConstraint, JoinOperator, JsonPath, JsonPathElem, LateralView, LimitClause,
41-
MatchRecognizePattern, Measure, Merge, MergeAction, MergeClause, MergeInsertExpr,
42-
MergeInsertKind, MergeUpdateExpr, NamedParenthesizedList, NamedWindowDefinition, ObjectName,
43-
ObjectNamePart, Offset, OnConflict, OnConflictAction, OnInsert, OpenStatement, OrderBy,
44-
OrderByExpr, OrderByKind, OutputClause, Partition, PartitionBoundValue, PivotValueSource,
45-
ProjectionSelect, Query, RaiseStatement, RaiseStatementValue, ReferentialAction,
46-
RenameSelectItem, ReplaceSelectElement, ReplaceSelectItem, Select, SelectInto, SelectItem,
47-
SetExpr, SqlOption, Statement, Subscript, SymbolDefinition, TableAlias, TableAliasColumnDef,
48-
TableConstraint, TableFactor, TableObject, TableOptionsClustered, TableWithJoins, Update,
49-
UpdateTableFromKind, Use, Values, ViewColumnDef, WhileStatement, WildcardAdditionalOptions,
50-
With, WithFill,
31+
AccessExpr, AlterColumnOperation, AlterIndexOperation, AlterTableOperation, Analyze, Array, Assignment, AssignmentTarget, AttachedToken, BeginEndStatements, CaseStatement, CloseCursor, ClusteredIndex, ColumnDef, ColumnOption, ColumnOptionDef, ConditionalStatementBlock, ConditionalStatements, ConflictTarget, ConnectByKind, ConstraintCharacteristics, CopySource, CreateIndex, CreateTable, CreateTableOptions, Cte, Delete, DoUpdate, ExceptSelectItem, ExcludeSelectItem, Expr, ExprWithAlias, Fetch, ForValues, FromTable, Function, FunctionArg, FunctionArgExpr, FunctionArgumentClause, FunctionArgumentList, FunctionArguments, GroupByExpr, HavingBound, IfStatement, IlikeSelectItem, IndexColumn, Insert, Interpolate, InterpolateExpr, Join, JoinConstraint, JoinOperator, JsonPath, JsonPathElem, LateralView, LimitClause, MatchRecognizePattern, Measure, Merge, MergeAction, MergeClause, MergeInsertExpr, MergeInsertKind, MergeUpdateExpr, NamedParenthesizedList, NamedWindowDefinition, ObjectName, ObjectNamePart, Offset, OnConflict, OnConflictAction, OnInsert, OpenStatement, OrderBy, OrderByExpr, OrderByKind, OutputClause, Parens, Partition, PartitionBoundValue, PivotValueSource, ProjectionSelect, Query, RaiseStatement, RaiseStatementValue, ReferentialAction, RenameSelectItem, ReplaceSelectElement, ReplaceSelectItem, Select, SelectInto, SelectItem, SetExpr, SqlOption, Statement, Subscript, SymbolDefinition, TableAlias, TableAliasColumnDef, TableConstraint, TableFactor, TableObject, TableOptionsClustered, TableWithJoins, Update, UpdateTableFromKind, Use, Values, ViewColumnDef, WhileStatement, WildcardAdditionalOptions, With, WithFill, comments, dcl::SecondaryRoles, value::ValueWithSpan
5132
};
5233

5334
/// Given an iterator of spans, return the [Span::union] of all spans.
@@ -106,6 +87,12 @@ impl Spanned for TokenWithSpan {
10687
}
10788
}
10889

90+
impl<T> Spanned for Parens<T> {
91+
fn span(&self) -> Span {
92+
union_spans([self.opening_token.0.span, self.closing_token.0.span].into_iter())
93+
}
94+
}
95+
10996
impl Spanned for Query {
11097
fn span(&self) -> Span {
11198
let Query {
@@ -239,10 +226,11 @@ impl Spanned for Values {
239226
rows,
240227
} = self;
241228

242-
union_spans(
243-
rows.iter()
244-
.map(|row| union_spans(row.iter().map(|expr| expr.span()))),
245-
)
229+
match &rows[..] {
230+
[] => Span::empty(),
231+
[f] => f.span(),
232+
[f, .., l] => union_spans([f.span(), l.span()].into_iter()),
233+
}
246234
}
247235
}
248236

src/parser/mod.rs

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18591,14 +18591,22 @@ impl<'a> Parser<'a> {
1859118591
explicit_row = true;
1859218592
}
1859318593

18594-
parser.expect_token(&Token::LParen)?;
18594+
let opening_paren = parser.expect_token(&Token::LParen)?;
1859518595
if allow_empty && parser.peek_token().token == Token::RParen {
18596-
parser.next_token();
18597-
Ok(vec![])
18596+
let closing_paren = parser.next_token();
18597+
Ok(Parens {
18598+
opening_token: opening_paren.into(),
18599+
content: vec![],
18600+
closing_token: closing_paren.into()
18601+
})
1859818602
} else {
1859918603
let exprs = parser.parse_comma_separated(Parser::parse_expr)?;
18600-
parser.expect_token(&Token::RParen)?;
18601-
Ok(exprs)
18604+
let closing_paren = parser.expect_token(&Token::RParen)?;
18605+
Ok(Parens {
18606+
opening_token: opening_paren.into(),
18607+
content: exprs,
18608+
closing_token: closing_paren.into(),
18609+
})
1860218610
}
1860318611
})?;
1860418612
Ok(Values {

tests/sqlparser_bigquery.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1821,7 +1821,7 @@ fn parse_merge() {
18211821
kind: MergeInsertKind::Values(Values {
18221822
value_keyword: false,
18231823
explicit_row: false,
1824-
rows: vec![vec![Expr::value(number("1")), Expr::value(number("2"))]],
1824+
rows: vec![Parens::with_empty_span(vec![Expr::value(number("1")), Expr::value(number("2"))])],
18251825
}),
18261826
insert_predicate: None,
18271827
});
@@ -2003,10 +2003,10 @@ fn parse_merge() {
20032003
kind: MergeInsertKind::Values(Values {
20042004
value_keyword: false,
20052005
explicit_row: false,
2006-
rows: vec![vec![
2006+
rows: vec![Parens::with_empty_span(vec![
20072007
Expr::value(number("1")),
20082008
Expr::Identifier(Ident::new("DEFAULT")),
2009-
]]
2009+
])]
20102010
}),
20112011
insert_predicate: None,
20122012
})
@@ -2022,10 +2022,10 @@ fn parse_merge() {
20222022
kind: MergeInsertKind::Values(Values {
20232023
value_keyword: false,
20242024
explicit_row: false,
2025-
rows: vec![vec![
2025+
rows: vec![Parens::with_empty_span(vec![
20262026
Expr::value(number("1")),
20272027
Expr::Identifier(Ident::new("DEFAULT")),
2028-
]]
2028+
])]
20292029
}),
20302030
insert_predicate: None,
20312031
})

tests/sqlparser_common.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,8 @@ fn parse_insert_values() {
100100
Expr::value(number("2")),
101101
Expr::value(number("3")),
102102
];
103-
let rows1 = vec![row.clone()];
104-
let rows2 = vec![row.clone(), row];
103+
let rows1 = vec![Parens::with_empty_span(row.clone())];
104+
let rows2 = vec![Parens::with_empty_span(row.clone()), Parens::with_empty_span(row)];
105105

106106
let sql = "INSERT customer VALUES (1, 2, 3)";
107107
check_one(sql, "customer", &[], &rows1, false);
@@ -140,7 +140,7 @@ fn parse_insert_values() {
140140
sql: &str,
141141
expected_table_name: &str,
142142
expected_columns: &[String],
143-
expected_rows: &[Vec<Expr>],
143+
expected_rows: &[Parens<Vec<Expr>>],
144144
expected_value_keyword: bool,
145145
) {
146146
match verified_stmt(sql) {
@@ -10085,7 +10085,7 @@ fn parse_merge() {
1008510085
kind: MergeInsertKind::Values(Values {
1008610086
value_keyword: false,
1008710087
explicit_row: false,
10088-
rows: vec![vec![
10088+
rows: vec![Parens::with_empty_span(vec![
1008910089
Expr::CompoundIdentifier(vec![
1009010090
Ident::new("stg"),
1009110091
Ident::new("A")
@@ -10098,7 +10098,7 @@ fn parse_merge() {
1009810098
Ident::new("stg"),
1009910099
Ident::new("C")
1010010100
]),
10101-
]]
10101+
])]
1010210102
}),
1010310103
insert_predicate: None,
1010410104
}),

tests/sqlparser_databricks.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -174,14 +174,14 @@ fn test_values_clause() {
174174
value_keyword: false,
175175
explicit_row: false,
176176
rows: vec![
177-
vec![
177+
Parens::with_empty_span(vec![
178178
Expr::Value((Value::DoubleQuotedString("one".to_owned())).with_empty_span()),
179179
Expr::value(number("1")),
180-
],
181-
vec![
180+
]),
181+
Parens::with_empty_span(vec![
182182
Expr::Value((Value::SingleQuotedString("two".to_owned())).with_empty_span()),
183183
Expr::value(number("2")),
184-
],
184+
]),
185185
],
186186
};
187187

tests/sqlparser_mysql.rs

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1928,27 +1928,27 @@ fn parse_simple_insert() {
19281928
value_keyword: false,
19291929
explicit_row: false,
19301930
rows: vec![
1931-
vec![
1931+
Parens::with_empty_span(vec![
19321932
Expr::Value(
19331933
(Value::SingleQuotedString("Test Some Inserts".to_string()))
19341934
.with_empty_span()
19351935
),
19361936
Expr::value(number("1"))
1937-
],
1938-
vec![
1937+
]),
1938+
Parens::with_empty_span(vec![
19391939
Expr::Value(
19401940
(Value::SingleQuotedString("Test Entry 2".to_string()))
19411941
.with_empty_span()
19421942
),
19431943
Expr::value(number("2"))
1944-
],
1945-
vec![
1944+
]),
1945+
Parens::with_empty_span(vec![
19461946
Expr::Value(
19471947
(Value::SingleQuotedString("Test Entry 3".to_string()))
19481948
.with_empty_span()
19491949
),
19501950
Expr::value(number("3"))
1951-
]
1951+
])
19521952
]
19531953
})),
19541954
order_by: None,
@@ -1999,13 +1999,13 @@ fn parse_ignore_insert() {
19991999
body: Box::new(SetExpr::Values(Values {
20002000
value_keyword: false,
20012001
explicit_row: false,
2002-
rows: vec![vec![
2002+
rows: vec![Parens::with_empty_span(vec![
20032003
Expr::Value(
20042004
(Value::SingleQuotedString("Test Some Inserts".to_string()))
20052005
.with_empty_span()
20062006
),
20072007
Expr::value(number("1"))
2008-
]]
2008+
])]
20092009
})),
20102010
order_by: None,
20112011
limit_clause: None,
@@ -2055,13 +2055,13 @@ fn parse_priority_insert() {
20552055
body: Box::new(SetExpr::Values(Values {
20562056
value_keyword: false,
20572057
explicit_row: false,
2058-
rows: vec![vec![
2058+
rows: vec![Parens::with_empty_span(vec![
20592059
Expr::Value(
20602060
(Value::SingleQuotedString("Test Some Inserts".to_string()))
20612061
.with_empty_span()
20622062
),
20632063
Expr::value(number("1"))
2064-
]]
2064+
])]
20652065
})),
20662066
order_by: None,
20672067
limit_clause: None,
@@ -2108,13 +2108,13 @@ fn parse_priority_insert() {
21082108
body: Box::new(SetExpr::Values(Values {
21092109
value_keyword: false,
21102110
explicit_row: false,
2111-
rows: vec![vec![
2111+
rows: vec![Parens::with_empty_span(vec![
21122112
Expr::Value(
21132113
(Value::SingleQuotedString("Test Some Inserts".to_string()))
21142114
.with_empty_span()
21152115
),
21162116
Expr::value(number("1"))
2117-
]]
2117+
])]
21182118
})),
21192119
order_by: None,
21202120
limit_clause: None,
@@ -2164,9 +2164,9 @@ fn parse_insert_as() {
21642164
body: Box::new(SetExpr::Values(Values {
21652165
value_keyword: false,
21662166
explicit_row: false,
2167-
rows: vec![vec![Expr::Value(
2167+
rows: vec![Parens::with_empty_span(vec![Expr::Value(
21682168
(Value::SingleQuotedString("2024-01-01".to_string())).with_empty_span()
2169-
)]]
2169+
)])]
21702170
})),
21712171
order_by: None,
21722172
limit_clause: None,
@@ -2227,13 +2227,13 @@ fn parse_insert_as() {
22272227
body: Box::new(SetExpr::Values(Values {
22282228
value_keyword: false,
22292229
explicit_row: false,
2230-
rows: vec![vec![
2230+
rows: vec![Parens::with_empty_span(vec![
22312231
Expr::value(number("1")),
22322232
Expr::Value(
22332233
(Value::SingleQuotedString("2024-01-01".to_string()))
22342234
.with_empty_span()
22352235
)
2236-
]]
2236+
])]
22372237
})),
22382238
order_by: None,
22392239
limit_clause: None,
@@ -2284,13 +2284,13 @@ fn parse_replace_insert() {
22842284
body: Box::new(SetExpr::Values(Values {
22852285
value_keyword: false,
22862286
explicit_row: false,
2287-
rows: vec![vec![
2287+
rows: vec![Parens::with_empty_span(vec![
22882288
Expr::Value(
22892289
(Value::SingleQuotedString("Test Some Inserts".to_string()))
22902290
.with_empty_span()
22912291
),
22922292
Expr::value(number("1"))
2293-
]]
2293+
])]
22942294
})),
22952295
order_by: None,
22962296
limit_clause: None,
@@ -2332,7 +2332,7 @@ fn parse_empty_row_insert() {
23322332
body: Box::new(SetExpr::Values(Values {
23332333
value_keyword: false,
23342334
explicit_row: false,
2335-
rows: vec![vec![], vec![]]
2335+
rows: vec![Parens::with_empty_span(vec![]), Parens::with_empty_span(vec![])]
23362336
})),
23372337
order_by: None,
23382338
limit_clause: None,
@@ -2383,7 +2383,7 @@ fn parse_insert_with_on_duplicate_update() {
23832383
body: Box::new(SetExpr::Values(Values {
23842384
value_keyword: false,
23852385
explicit_row: false,
2386-
rows: vec![vec![
2386+
rows: vec![Parens::with_empty_span(vec![
23872387
Expr::Value(
23882388
(Value::SingleQuotedString("accounting_manager".to_string()))
23892389
.with_empty_span()
@@ -2398,7 +2398,7 @@ fn parse_insert_with_on_duplicate_update() {
23982398
Expr::Value((Value::Boolean(true)).with_empty_span()),
23992399
Expr::Value((Value::Boolean(true)).with_empty_span()),
24002400
Expr::Value((Value::Boolean(true)).with_empty_span()),
2401-
]]
2401+
])]
24022402
})),
24032403
order_by: None,
24042404
limit_clause: None,

0 commit comments

Comments
 (0)