mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-09-22 13:42:31 +00:00
Fix for Postgres regex and like binary operators (#1928)
This commit is contained in:
parent
650681422a
commit
4d9338638f
2 changed files with 55 additions and 15 deletions
|
@ -3486,10 +3486,18 @@ impl<'a> Parser<'a> {
|
||||||
| BinaryOperator::LtEq
|
| BinaryOperator::LtEq
|
||||||
| BinaryOperator::Eq
|
| BinaryOperator::Eq
|
||||||
| BinaryOperator::NotEq
|
| BinaryOperator::NotEq
|
||||||
|
| BinaryOperator::PGRegexMatch
|
||||||
|
| BinaryOperator::PGRegexIMatch
|
||||||
|
| BinaryOperator::PGRegexNotMatch
|
||||||
|
| BinaryOperator::PGRegexNotIMatch
|
||||||
|
| BinaryOperator::PGLikeMatch
|
||||||
|
| BinaryOperator::PGILikeMatch
|
||||||
|
| BinaryOperator::PGNotLikeMatch
|
||||||
|
| BinaryOperator::PGNotILikeMatch
|
||||||
) {
|
) {
|
||||||
return parser_err!(
|
return parser_err!(
|
||||||
format!(
|
format!(
|
||||||
"Expected one of [=, >, <, =>, =<, !=] as comparison operator, found: {op}"
|
"Expected one of [=, >, <, =>, =<, !=, ~, ~*, !~, !~*, ~~, ~~*, !~~, !~~*] as comparison operator, found: {op}"
|
||||||
),
|
),
|
||||||
span.start
|
span.start
|
||||||
);
|
);
|
||||||
|
|
|
@ -2187,21 +2187,39 @@ fn parse_pg_regex_match_ops() {
|
||||||
("!~*", BinaryOperator::PGRegexNotIMatch),
|
("!~*", BinaryOperator::PGRegexNotIMatch),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// Match against a single value
|
||||||
for (str_op, op) in 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));
|
let select = pg().verified_only_select(&format!("SELECT 'abc' {str_op} '^a'"));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
SelectItem::UnnamedExpr(Expr::BinaryOp {
|
SelectItem::UnnamedExpr(Expr::BinaryOp {
|
||||||
left: Box::new(Expr::Value(
|
left: Box::new(Expr::Value(single_quoted_string("abc").with_empty_span(),)),
|
||||||
(Value::SingleQuotedString("abc".into())).with_empty_span()
|
|
||||||
)),
|
|
||||||
op: op.clone(),
|
op: op.clone(),
|
||||||
right: Box::new(Expr::Value(
|
right: Box::new(Expr::Value(single_quoted_string("^a").with_empty_span(),)),
|
||||||
(Value::SingleQuotedString("^a".into())).with_empty_span()
|
|
||||||
)),
|
|
||||||
}),
|
}),
|
||||||
select.projection[0]
|
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]
|
#[test]
|
||||||
|
@ -2213,21 +2231,35 @@ fn parse_pg_like_match_ops() {
|
||||||
("!~~*", BinaryOperator::PGNotILikeMatch),
|
("!~~*", BinaryOperator::PGNotILikeMatch),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// Match against a single value
|
||||||
for (str_op, op) in 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));
|
let select = pg().verified_only_select(&format!("SELECT 'abc' {str_op} 'a_c%'"));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
SelectItem::UnnamedExpr(Expr::BinaryOp {
|
SelectItem::UnnamedExpr(Expr::BinaryOp {
|
||||||
left: Box::new(Expr::Value(
|
left: Box::new(Expr::Value(single_quoted_string("abc").with_empty_span(),)),
|
||||||
(Value::SingleQuotedString("abc".into())).with_empty_span()
|
|
||||||
)),
|
|
||||||
op: op.clone(),
|
op: op.clone(),
|
||||||
right: Box::new(Expr::Value(
|
right: Box::new(Expr::Value(single_quoted_string("a_c%").with_empty_span(),)),
|
||||||
(Value::SingleQuotedString("a_c%".into())).with_empty_span()
|
|
||||||
)),
|
|
||||||
}),
|
}),
|
||||||
select.projection[0]
|
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]
|
#[test]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue