Skip to content

Commit 4955863

Browse files
authored
fix: handle bigquery offset in map key (#797)
* fix: handle bigquery offset in map key * chore: add in more comments and tests * chore: fix all linting and compilation warnings
1 parent ca93941 commit 4955863

File tree

2 files changed

+42
-3
lines changed

2 files changed

+42
-3
lines changed

src/parser.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4183,7 +4183,13 @@ impl<'a> Parser<'a> {
41834183
pub fn parse_map_key(&mut self) -> Result<Expr, ParserError> {
41844184
let next_token = self.next_token();
41854185
match next_token.token {
4186-
Token::Word(Word { value, keyword, .. }) if keyword == Keyword::NoKeyword => {
4186+
// handle bigquery offset subscript operator which overlaps with OFFSET operator
4187+
Token::Word(Word { value, keyword, .. })
4188+
if (dialect_of!(self is BigQueryDialect) && keyword == Keyword::OFFSET) =>
4189+
{
4190+
self.parse_function(ObjectName(vec![Ident::new(value)]))
4191+
}
4192+
Token::Word(Word { value, keyword, .. }) if (keyword == Keyword::NoKeyword) => {
41874193
if self.peek_token() == Token::LParen {
41884194
return self.parse_function(ObjectName(vec![Ident::new(value)]));
41894195
}

tests/sqlparser_bigquery.rs

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,9 @@
1313
#[macro_use]
1414
mod test_utils;
1515

16-
use test_utils::*;
17-
1816
use sqlparser::ast::*;
1917
use sqlparser::dialect::{BigQueryDialect, GenericDialect};
18+
use test_utils::*;
2019

2120
#[test]
2221
fn parse_literal_string() {
@@ -306,3 +305,37 @@ fn bigquery_and_generic() -> TestedDialects {
306305
dialects: vec![Box::new(BigQueryDialect {}), Box::new(GenericDialect {})],
307306
}
308307
}
308+
309+
#[test]
310+
fn parse_map_access_offset() {
311+
let sql = "SELECT d[offset(0)]";
312+
let _select = bigquery().verified_only_select(sql);
313+
#[cfg(not(feature = "bigdecimal"))]
314+
assert_eq!(
315+
_select.projection[0],
316+
SelectItem::UnnamedExpr(Expr::MapAccess {
317+
column: Box::new(Expr::Identifier(Ident {
318+
value: "d".to_string(),
319+
quote_style: None,
320+
})),
321+
keys: vec![Expr::Function(Function {
322+
name: ObjectName(vec!["offset".into()]),
323+
args: vec![FunctionArg::Unnamed(FunctionArgExpr::Expr(Expr::Value(
324+
Value::Number("0".into(), false)
325+
))),],
326+
over: None,
327+
distinct: false,
328+
special: false,
329+
})],
330+
})
331+
);
332+
333+
// test other operators
334+
for sql in [
335+
"SELECT d[SAFE_OFFSET(0)]",
336+
"SELECT d[ORDINAL(0)]",
337+
"SELECT d[SAFE_ORDINAL(0)]",
338+
] {
339+
bigquery().verified_only_select(sql);
340+
}
341+
}

0 commit comments

Comments
 (0)