From 29ea21047ae96f9e940109b2db12e7f6c71b1fd3 Mon Sep 17 00:00:00 2001 From: Sergey Olontsev Date: Sun, 6 Jul 2025 09:25:57 +0100 Subject: [PATCH 1/3] Fix for Postgres regex and like binary operators --- src/parser/mod.rs | 10 ++++++- tests/sqlparser_postgres.rs | 60 +++++++++++++++++++++++++++---------- 2 files changed, 53 insertions(+), 17 deletions(-) diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 32f8a97e4..31b06dbf3 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..e7fa1a5d7 100644 --- a/tests/sqlparser_postgres.rs +++ b/tests/sqlparser_postgres.rs @@ -2181,19 +2181,35 @@ fn parse_pg_regex_match_ops() { ]; for (str_op, op) in pg_regex_match_ops { - let select = pg().verified_only_select(&format!("SELECT 'abc' {} '^a'", &str_op)); + // Basic binary operation usage + 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] + select.projection[0], ); + + // Binary operator with ANY operator + 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], + ) } } @@ -2207,19 +2223,31 @@ fn parse_pg_like_match_ops() { ]; for (str_op, op) in pg_like_match_ops { - let select = pg().verified_only_select(&format!("SELECT 'abc' {} 'a_c%'", &str_op)); + // Basic binary operation usage + 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] + select.projection[0], ); + + // Binary operator with ALL operator + 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], + ) } } From 9b1612fe5b16267c5531d4eb4202aba8feea7484 Mon Sep 17 00:00:00 2001 From: Sergey Olontsev Date: Sun, 6 Jul 2025 09:28:04 +0100 Subject: [PATCH 2/3] code cleanup --- tests/sqlparser_postgres.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/sqlparser_postgres.rs b/tests/sqlparser_postgres.rs index e7fa1a5d7..b21051c1d 100644 --- a/tests/sqlparser_postgres.rs +++ b/tests/sqlparser_postgres.rs @@ -2189,7 +2189,7 @@ fn parse_pg_regex_match_ops() { op: op.clone(), right: Box::new(Expr::Value(single_quoted_string("^a").with_empty_span(),)), }), - select.projection[0], + select.projection[0] ); // Binary operator with ANY operator @@ -2208,7 +2208,7 @@ fn parse_pg_regex_match_ops() { })), is_some: false, }), - select.projection[0], + select.projection[0] ) } } @@ -2231,7 +2231,7 @@ fn parse_pg_like_match_ops() { op: op.clone(), right: Box::new(Expr::Value(single_quoted_string("a_c%").with_empty_span(),)), }), - select.projection[0], + select.projection[0] ); // Binary operator with ALL operator @@ -2246,7 +2246,7 @@ fn parse_pg_like_match_ops() { named: true, })), }), - select.projection[0], + select.projection[0] ) } } From 60acdc5bb67383ba0e4b3a6291ca6701ab2ec752 Mon Sep 17 00:00:00 2001 From: Sergey Olontsev Date: Sun, 6 Jul 2025 09:28:37 +0100 Subject: [PATCH 3/3] code cleanup --- tests/sqlparser_postgres.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/sqlparser_postgres.rs b/tests/sqlparser_postgres.rs index b21051c1d..5b8407500 100644 --- a/tests/sqlparser_postgres.rs +++ b/tests/sqlparser_postgres.rs @@ -2181,7 +2181,7 @@ fn parse_pg_regex_match_ops() { ]; for (str_op, op) in pg_regex_match_ops { - // Basic binary operation usage + // Basic binary operator usage let select = pg().verified_only_select(&format!("SELECT 'abc' {str_op} '^a'")); assert_eq!( SelectItem::UnnamedExpr(Expr::BinaryOp { @@ -2223,7 +2223,7 @@ fn parse_pg_like_match_ops() { ]; for (str_op, op) in pg_like_match_ops { - // Basic binary operation usage + // Basic binary operator usage let select = pg().verified_only_select(&format!("SELECT 'abc' {str_op} 'a_c%'")); assert_eq!( SelectItem::UnnamedExpr(Expr::BinaryOp {