Fixed the bug that the access parsing is wrong when multiple query conditions contain arrays or map. (#433)

This commit is contained in:
Simon Liu 2022-03-13 03:29:37 +08:00 committed by GitHub
parent 6b55e51101
commit 497a3b0e1b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 71 additions and 21 deletions

View file

@ -1285,7 +1285,7 @@ impl<'a> Parser<'a> {
Token::Mul | Token::Div | Token::Mod | Token::StringConcat => Ok(40),
Token::DoubleColon => Ok(50),
Token::ExclamationMark => Ok(50),
Token::LBracket => Ok(10),
Token::LBracket => Ok(50),
_ => Ok(0),
}
}

View file

@ -18,36 +18,86 @@ mod test_utils;
use test_utils::*;
use sqlparser::ast::Expr::{Identifier, MapAccess};
use sqlparser::ast::Expr::{BinaryOp, Identifier, MapAccess};
use sqlparser::ast::Ident;
use sqlparser::ast::SelectItem::UnnamedExpr;
use sqlparser::ast::TableFactor::Table;
use sqlparser::ast::*;
use sqlparser::dialect::ClickHouseDialect;
#[test]
fn parse_map_access_expr() {
let sql = r#"SELECT string_values[indexOf(string_names, 'endpoint')] FROM foos"#;
let sql = r#"SELECT string_values[indexOf(string_names, 'endpoint')] FROM foos WHERE id = 'test' AND string_value[indexOf(string_name, 'app')] <> 'foo'"#;
let select = clickhouse().verified_only_select(sql);
assert_eq!(
&MapAccess {
column: Box::new(Identifier(Ident {
value: "string_values".to_string(),
quote_style: None,
})),
keys: vec![Expr::Function(Function {
name: ObjectName(vec!["indexOf".into()]),
args: vec![
FunctionArg::Unnamed(FunctionArgExpr::Expr(Expr::Identifier(Ident::new(
"string_names"
)))),
FunctionArg::Unnamed(FunctionArgExpr::Expr(Expr::Value(
Value::SingleQuotedString("endpoint".to_string())
))),
],
over: None,
distinct: false,
Select {
distinct: false,
top: None,
projection: vec![UnnamedExpr(MapAccess {
column: Box::new(Identifier(Ident {
value: "string_values".to_string(),
quote_style: None,
})),
keys: vec![Expr::Function(Function {
name: ObjectName(vec!["indexOf".into()]),
args: vec![
FunctionArg::Unnamed(FunctionArgExpr::Expr(Expr::Identifier(Ident::new(
"string_names"
)))),
FunctionArg::Unnamed(FunctionArgExpr::Expr(Expr::Value(
Value::SingleQuotedString("endpoint".to_string())
))),
],
over: None,
distinct: false,
})],
})],
from: vec![TableWithJoins {
relation: Table {
name: ObjectName(vec![Ident::new("foos")]),
alias: None,
args: vec![],
with_hints: vec![],
},
joins: vec![]
}],
lateral_views: vec![],
selection: Some(BinaryOp {
left: Box::new(BinaryOp {
left: Box::new(Identifier(Ident::new("id"))),
op: BinaryOperator::Eq,
right: Box::new(Expr::Value(Value::SingleQuotedString("test".to_string())))
}),
op: BinaryOperator::And,
right: Box::new(BinaryOp {
left: Box::new(MapAccess {
column: Box::new(Identifier(Ident::new("string_value"))),
keys: vec![Expr::Function(Function {
name: ObjectName(vec![Ident::new("indexOf")]),
args: vec![
FunctionArg::Unnamed(FunctionArgExpr::Expr(Expr::Identifier(
Ident::new("string_name")
))),
FunctionArg::Unnamed(FunctionArgExpr::Expr(Expr::Value(
Value::SingleQuotedString("app".to_string())
))),
],
over: None,
distinct: false
})]
}),
op: BinaryOperator::NotEq,
right: Box::new(Expr::Value(Value::SingleQuotedString("foo".to_string())))
})
}),
group_by: vec![],
cluster_by: vec![],
distribute_by: vec![],
sort_by: vec![],
having: None
},
expr_from_projection(only(&select.projection)),
select
);
}