diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 61944b8f7..a1be226ea 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -3478,10 +3478,18 @@ impl<'a> Parser<'a> { | BinaryOperator::LtEq | BinaryOperator::Eq | BinaryOperator::NotEq + | BinaryOperator::PGRegexMatch + | BinaryOperator::PGRegexIMatch + | BinaryOperator::PGRegexNotMatch + | BinaryOperator::PGRegexNotIMatch + | BinaryOperator::PGLikeMatch + | BinaryOperator::PGILikeMatch + | BinaryOperator::PGNotLikeMatch + | BinaryOperator::PGNotILikeMatch ) { return parser_err!( format!( - "Expected one of [=, >, <, =>, =<, !=] as comparison operator, found: {op}" + "Expected one of [=, >, <, =>, =<, !=, ~, ~*, !~, !~*, ~~, ~~*, !~~, !~~*] as comparison operator, found: {op}" ), span.start ); diff --git a/tests/sqlparser_postgres.rs b/tests/sqlparser_postgres.rs index 48792025a..38879f6ea 100644 --- a/tests/sqlparser_postgres.rs +++ b/tests/sqlparser_postgres.rs @@ -2180,21 +2180,39 @@ fn parse_pg_regex_match_ops() { ("!~*", BinaryOperator::PGRegexNotIMatch), ]; + // Match against a single value for (str_op, op) in pg_regex_match_ops { - let select = pg().verified_only_select(&format!("SELECT 'abc' {} '^a'", &str_op)); + let select = pg().verified_only_select(&format!("SELECT 'abc' {str_op} '^a'")); assert_eq!( SelectItem::UnnamedExpr(Expr::BinaryOp { - left: Box::new(Expr::Value( - (Value::SingleQuotedString("abc".into())).with_empty_span() - )), + left: Box::new(Expr::Value(single_quoted_string("abc").with_empty_span(),)), op: op.clone(), - right: Box::new(Expr::Value( - (Value::SingleQuotedString("^a".into())).with_empty_span() - )), + right: Box::new(Expr::Value(single_quoted_string("^a").with_empty_span(),)), }), select.projection[0] ); } + + // Match against any value from an array + for (str_op, op) in pg_regex_match_ops { + let select = + pg().verified_only_select(&format!("SELECT 'abc' {str_op} ANY(ARRAY['^a', 'x'])")); + assert_eq!( + SelectItem::UnnamedExpr(Expr::AnyOp { + left: Box::new(Expr::Value(single_quoted_string("abc").with_empty_span(),)), + compare_op: op.clone(), + right: Box::new(Expr::Array(Array { + elem: vec![ + Expr::Value(single_quoted_string("^a").with_empty_span()), + Expr::Value(single_quoted_string("x").with_empty_span()), + ], + named: true, + })), + is_some: false, + }), + select.projection[0] + ) + } } #[test] @@ -2206,21 +2224,35 @@ fn parse_pg_like_match_ops() { ("!~~*", BinaryOperator::PGNotILikeMatch), ]; + // Match against a single value for (str_op, op) in pg_like_match_ops { - let select = pg().verified_only_select(&format!("SELECT 'abc' {} 'a_c%'", &str_op)); + let select = pg().verified_only_select(&format!("SELECT 'abc' {str_op} 'a_c%'")); assert_eq!( SelectItem::UnnamedExpr(Expr::BinaryOp { - left: Box::new(Expr::Value( - (Value::SingleQuotedString("abc".into())).with_empty_span() - )), + left: Box::new(Expr::Value(single_quoted_string("abc").with_empty_span(),)), op: op.clone(), - right: Box::new(Expr::Value( - (Value::SingleQuotedString("a_c%".into())).with_empty_span() - )), + right: Box::new(Expr::Value(single_quoted_string("a_c%").with_empty_span(),)), }), select.projection[0] ); } + + // Match against all values from an array + for (str_op, op) in pg_like_match_ops { + let select = + pg().verified_only_select(&format!("SELECT 'abc' {str_op} ALL(ARRAY['a_c%'])")); + assert_eq!( + SelectItem::UnnamedExpr(Expr::AllOp { + left: Box::new(Expr::Value(single_quoted_string("abc").with_empty_span(),)), + compare_op: op.clone(), + right: Box::new(Expr::Array(Array { + elem: vec![Expr::Value(single_quoted_string("a_c%").with_empty_span())], + named: true, + })), + }), + select.projection[0] + ) + } } #[test]