@@ -183,7 +183,7 @@ impl fmt::Display for ParserError {
183
183
impl std:: error:: Error for ParserError { }
184
184
185
185
// By default, allow expressions up to this deep before erroring
186
- const DEFAULT_REMAINING_DEPTH : usize = 50 ;
186
+ const DEFAULT_REMAINING_DEPTH : usize = 48 ;
187
187
188
188
/// Composite types declarations using angle brackets syntax can be arbitrary
189
189
/// nested such that the following declaration is possible:
@@ -3400,7 +3400,7 @@ impl<'a> Parser<'a> {
3400
3400
}
3401
3401
3402
3402
/// Parse a comma-separated list of 1+ SelectItem
3403
- pub fn parse_projection ( & mut self ) -> Result < Vec < SelectItem > , ParserError > {
3403
+ pub fn parse_projection ( & mut self ) -> Result < Vec < WithSpan < SelectItem > > , ParserError > {
3404
3404
// BigQuery and Snowflake allow trailing commas, but only in project lists
3405
3405
// e.g. `SELECT 1, 2, FROM t`
3406
3406
// https://cloud.google.com/bigquery/docs/reference/standard-sql/lexical#trailing_commas
@@ -8287,7 +8287,7 @@ impl<'a> Parser<'a> {
8287
8287
/// use sqlparser::parser::Parser;
8288
8288
///
8289
8289
/// let dialect = GenericDialect {};
8290
- /// let expected = vec![Ident::new("one"), Ident::new("two")];
8290
+ /// let expected = vec![Ident::new("one").empty_span() , Ident::new("two").empty_span( )];
8291
8291
///
8292
8292
/// // expected usage
8293
8293
/// let sql = "one.two";
@@ -11209,15 +11209,18 @@ impl<'a> Parser<'a> {
11209
11209
}
11210
11210
11211
11211
/// Parse a comma-delimited list of projections after SELECT
11212
- pub fn parse_select_item ( & mut self ) -> Result < SelectItem , ParserError > {
11212
+ pub fn parse_select_item ( & mut self ) -> Result < WithSpan < SelectItem > , ParserError > {
11213
+ let start_span = self . index ;
11213
11214
match self . parse_wildcard_expr ( ) ? {
11214
11215
Expr :: QualifiedWildcard ( prefix) => Ok ( SelectItem :: QualifiedWildcard (
11215
11216
prefix,
11216
11217
self . parse_wildcard_additional_options ( ) ?,
11217
- ) ) ,
11218
- Expr :: Wildcard => Ok ( SelectItem :: Wildcard (
11219
- self . parse_wildcard_additional_options ( ) ?,
11220
- ) ) ,
11218
+ )
11219
+ . spanning ( self . span_from_index ( start_span) ) ) ,
11220
+ Expr :: Wildcard => Ok (
11221
+ SelectItem :: Wildcard ( self . parse_wildcard_additional_options ( ) ?)
11222
+ . spanning ( self . span_from_index ( start_span) ) ,
11223
+ ) ,
11221
11224
Expr :: Identifier ( v) if v. value . to_lowercase ( ) == "from" && v. quote_style . is_none ( ) => {
11222
11225
parser_err ! (
11223
11226
format!( "Expected an expression, found: {}" , v) ,
@@ -11240,13 +11243,17 @@ impl<'a> Parser<'a> {
11240
11243
Ok ( SelectItem :: ExprWithAlias {
11241
11244
expr : * right,
11242
11245
alias,
11243
- } )
11246
+ }
11247
+ . spanning ( self . span_from_index ( start_span) ) )
11244
11248
}
11245
11249
expr => self
11246
11250
. parse_optional_alias ( keywords:: RESERVED_FOR_COLUMN_ALIAS )
11247
11251
. map ( |alias| match alias {
11248
- Some ( alias) => SelectItem :: ExprWithAlias { expr, alias } ,
11249
- None => SelectItem :: UnnamedExpr ( expr) ,
11252
+ Some ( alias) => SelectItem :: ExprWithAlias { expr, alias }
11253
+ . spanning ( self . span_from_index ( start_span) ) ,
11254
+ None => {
11255
+ SelectItem :: UnnamedExpr ( expr) . spanning ( self . span_from_index ( start_span) )
11256
+ }
11250
11257
} ) ,
11251
11258
}
11252
11259
}
@@ -12249,6 +12256,57 @@ impl<'a> Parser<'a> {
12249
12256
self . tokens
12250
12257
}
12251
12258
12259
+ fn span_from_index ( & mut self , mut start_index : usize ) -> Span {
12260
+ let mut start_token = & self . tokens [ start_index] ;
12261
+ loop {
12262
+ match start_token {
12263
+ TokenWithLocation {
12264
+ token : Token :: Whitespace ( _) ,
12265
+ span : _,
12266
+ } => {
12267
+ start_index += 1 ;
12268
+ start_token = & self . tokens [ start_index] ;
12269
+ continue ;
12270
+ }
12271
+ _ => break ,
12272
+ }
12273
+ }
12274
+ let start_span = start_token. span ;
12275
+
12276
+ let mut idx = self . index . max ( start_index) . min ( self . tokens . len ( ) - 1 ) ;
12277
+ loop {
12278
+ if idx <= start_index || idx >= self . tokens . len ( ) {
12279
+ break ;
12280
+ }
12281
+ let curr_token = & self . tokens [ idx] ;
12282
+ match curr_token {
12283
+ TokenWithLocation {
12284
+ token : Token :: Whitespace ( _) ,
12285
+ span : _,
12286
+ } => {
12287
+ idx -= 1 ;
12288
+ continue ;
12289
+ }
12290
+ TokenWithLocation {
12291
+ token : Token :: Comma ,
12292
+ span : _,
12293
+ } => {
12294
+ idx -= 1 ;
12295
+ continue ;
12296
+ }
12297
+ TokenWithLocation {
12298
+ token : Token :: Word ( word) ,
12299
+ span : _,
12300
+ } if word. keyword != Keyword :: NoKeyword => {
12301
+ idx -= 1 ;
12302
+ continue ;
12303
+ }
12304
+ non_whitespace => return non_whitespace. span . union ( start_span) ,
12305
+ }
12306
+ }
12307
+ start_span
12308
+ }
12309
+
12252
12310
/// Returns true if the next keyword indicates a sub query, i.e. SELECT or WITH
12253
12311
fn peek_sub_query ( & mut self ) -> bool {
12254
12312
if self
0 commit comments