diff --git a/src/parser.rs b/src/parser.rs index 6ccd4980b..178f10fa5 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -1282,7 +1282,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), } } diff --git a/tests/sqpparser_clickhouse.rs b/tests/sqpparser_clickhouse.rs index 430933963..b4db6490b 100644 --- a/tests/sqpparser_clickhouse.rs +++ b/tests/sqpparser_clickhouse.rs @@ -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 ); }