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
This commit is contained in:
Ziinc 2023-01-22 01:05:59 +08:00 committed by GitHub
parent ca939413f2
commit 4955863bdf
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 42 additions and 3 deletions

View file

@ -4183,7 +4183,13 @@ impl<'a> Parser<'a> {
pub fn parse_map_key(&mut self) -> Result<Expr, ParserError> {
let next_token = self.next_token();
match next_token.token {
Token::Word(Word { value, keyword, .. }) if keyword == Keyword::NoKeyword => {
// handle bigquery offset subscript operator which overlaps with OFFSET operator
Token::Word(Word { value, keyword, .. })
if (dialect_of!(self is BigQueryDialect) && keyword == Keyword::OFFSET) =>
{
self.parse_function(ObjectName(vec![Ident::new(value)]))
}
Token::Word(Word { value, keyword, .. }) if (keyword == Keyword::NoKeyword) => {
if self.peek_token() == Token::LParen {
return self.parse_function(ObjectName(vec![Ident::new(value)]));
}

View file

@ -13,10 +13,9 @@
#[macro_use]
mod test_utils;
use test_utils::*;
use sqlparser::ast::*;
use sqlparser::dialect::{BigQueryDialect, GenericDialect};
use test_utils::*;
#[test]
fn parse_literal_string() {
@ -306,3 +305,37 @@ fn bigquery_and_generic() -> TestedDialects {
dialects: vec![Box::new(BigQueryDialect {}), Box::new(GenericDialect {})],
}
}
#[test]
fn parse_map_access_offset() {
let sql = "SELECT d[offset(0)]";
let _select = bigquery().verified_only_select(sql);
#[cfg(not(feature = "bigdecimal"))]
assert_eq!(
_select.projection[0],
SelectItem::UnnamedExpr(Expr::MapAccess {
column: Box::new(Expr::Identifier(Ident {
value: "d".to_string(),
quote_style: None,
})),
keys: vec![Expr::Function(Function {
name: ObjectName(vec!["offset".into()]),
args: vec![FunctionArg::Unnamed(FunctionArgExpr::Expr(Expr::Value(
Value::Number("0".into(), false)
))),],
over: None,
distinct: false,
special: false,
})],
})
);
// test other operators
for sql in [
"SELECT d[SAFE_OFFSET(0)]",
"SELECT d[ORDINAL(0)]",
"SELECT d[SAFE_ORDINAL(0)]",
] {
bigquery().verified_only_select(sql);
}
}