mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-08-30 10:47:22 +00:00
feat: Support PostgreSQL exponentiation. (#813)
* Add Postgres exponent operator * Parse caret as BinaryOperator::PGExp in PostgreSQL * Update sqlparser_postgres.rs * update tests to support PGExp * cargo fmt * improve extensibility * cargo fmt * redundant code and documentation lionks
This commit is contained in:
parent
fbbf1a4e84
commit
1cf913e717
4 changed files with 32 additions and 10 deletions
|
@ -88,6 +88,7 @@ pub enum BinaryOperator {
|
||||||
PGBitwiseXor,
|
PGBitwiseXor,
|
||||||
PGBitwiseShiftLeft,
|
PGBitwiseShiftLeft,
|
||||||
PGBitwiseShiftRight,
|
PGBitwiseShiftRight,
|
||||||
|
PGExp,
|
||||||
PGRegexMatch,
|
PGRegexMatch,
|
||||||
PGRegexIMatch,
|
PGRegexIMatch,
|
||||||
PGRegexNotMatch,
|
PGRegexNotMatch,
|
||||||
|
@ -124,6 +125,7 @@ impl fmt::Display for BinaryOperator {
|
||||||
BinaryOperator::PGBitwiseXor => f.write_str("#"),
|
BinaryOperator::PGBitwiseXor => f.write_str("#"),
|
||||||
BinaryOperator::PGBitwiseShiftLeft => f.write_str("<<"),
|
BinaryOperator::PGBitwiseShiftLeft => f.write_str("<<"),
|
||||||
BinaryOperator::PGBitwiseShiftRight => f.write_str(">>"),
|
BinaryOperator::PGBitwiseShiftRight => f.write_str(">>"),
|
||||||
|
BinaryOperator::PGExp => f.write_str("^"),
|
||||||
BinaryOperator::PGRegexMatch => f.write_str("~"),
|
BinaryOperator::PGRegexMatch => f.write_str("~"),
|
||||||
BinaryOperator::PGRegexIMatch => f.write_str("~*"),
|
BinaryOperator::PGRegexIMatch => f.write_str("~*"),
|
||||||
BinaryOperator::PGRegexNotMatch => f.write_str("!~"),
|
BinaryOperator::PGRegexNotMatch => f.write_str("!~"),
|
||||||
|
|
|
@ -1648,7 +1648,15 @@ impl<'a> Parser<'a> {
|
||||||
Token::Mod => Some(BinaryOperator::Modulo),
|
Token::Mod => Some(BinaryOperator::Modulo),
|
||||||
Token::StringConcat => Some(BinaryOperator::StringConcat),
|
Token::StringConcat => Some(BinaryOperator::StringConcat),
|
||||||
Token::Pipe => Some(BinaryOperator::BitwiseOr),
|
Token::Pipe => Some(BinaryOperator::BitwiseOr),
|
||||||
Token::Caret => Some(BinaryOperator::BitwiseXor),
|
Token::Caret => {
|
||||||
|
// In PostgreSQL, ^ stands for the exponentiation operation,
|
||||||
|
// and # stands for XOR. See https://www.postgresql.org/docs/current/functions-math.html
|
||||||
|
if dialect_of!(self is PostgreSqlDialect) {
|
||||||
|
Some(BinaryOperator::PGExp)
|
||||||
|
} else {
|
||||||
|
Some(BinaryOperator::BitwiseXor)
|
||||||
|
}
|
||||||
|
}
|
||||||
Token::Ampersand => Some(BinaryOperator::BitwiseAnd),
|
Token::Ampersand => Some(BinaryOperator::BitwiseAnd),
|
||||||
Token::Div => Some(BinaryOperator::Divide),
|
Token::Div => Some(BinaryOperator::Divide),
|
||||||
Token::ShiftLeft if dialect_of!(self is PostgreSqlDialect | GenericDialect) => {
|
Token::ShiftLeft if dialect_of!(self is PostgreSqlDialect | GenericDialect) => {
|
||||||
|
|
|
@ -1228,16 +1228,27 @@ fn parse_string_agg() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// selects all dialects but PostgreSQL
|
||||||
|
pub fn all_dialects_but_pg() -> TestedDialects {
|
||||||
|
TestedDialects {
|
||||||
|
dialects: all_dialects()
|
||||||
|
.dialects
|
||||||
|
.into_iter()
|
||||||
|
.filter(|x| !x.is::<PostgreSqlDialect>())
|
||||||
|
.collect(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn parse_bitwise_ops() {
|
fn parse_bitwise_ops() {
|
||||||
let bitwise_ops = &[
|
let bitwise_ops = &[
|
||||||
("^", BinaryOperator::BitwiseXor),
|
("^", BinaryOperator::BitwiseXor, all_dialects_but_pg()),
|
||||||
("|", BinaryOperator::BitwiseOr),
|
("|", BinaryOperator::BitwiseOr, all_dialects()),
|
||||||
("&", BinaryOperator::BitwiseAnd),
|
("&", BinaryOperator::BitwiseAnd, all_dialects()),
|
||||||
];
|
];
|
||||||
|
|
||||||
for (str_op, op) in bitwise_ops {
|
for (str_op, op, dialects) in bitwise_ops {
|
||||||
let select = verified_only_select(&format!("SELECT a {} b", &str_op));
|
let select = dialects.verified_only_select(&format!("SELECT a {} b", &str_op));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
SelectItem::UnnamedExpr(Expr::BinaryOp {
|
SelectItem::UnnamedExpr(Expr::BinaryOp {
|
||||||
left: Box::new(Expr::Identifier(Ident::new("a"))),
|
left: Box::new(Expr::Identifier(Ident::new("a"))),
|
||||||
|
|
|
@ -1322,15 +1322,16 @@ fn parse_pg_returning() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn parse_pg_bitwise_binary_ops() {
|
fn parse_pg_binary_ops() {
|
||||||
let bitwise_ops = &[
|
let binary_ops = &[
|
||||||
// Sharp char cannot be used with Generic Dialect, it conflicts with identifiers
|
// Sharp char and Caret cannot be used with Generic Dialect, it conflicts with identifiers
|
||||||
("#", BinaryOperator::PGBitwiseXor, pg()),
|
("#", BinaryOperator::PGBitwiseXor, pg()),
|
||||||
|
("^", BinaryOperator::PGExp, pg()),
|
||||||
(">>", BinaryOperator::PGBitwiseShiftRight, pg_and_generic()),
|
(">>", BinaryOperator::PGBitwiseShiftRight, pg_and_generic()),
|
||||||
("<<", BinaryOperator::PGBitwiseShiftLeft, pg_and_generic()),
|
("<<", BinaryOperator::PGBitwiseShiftLeft, pg_and_generic()),
|
||||||
];
|
];
|
||||||
|
|
||||||
for (str_op, op, dialects) in bitwise_ops {
|
for (str_op, op, dialects) in binary_ops {
|
||||||
let select = dialects.verified_only_select(&format!("SELECT a {} b", &str_op));
|
let select = dialects.verified_only_select(&format!("SELECT a {} b", &str_op));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
SelectItem::UnnamedExpr(Expr::BinaryOp {
|
SelectItem::UnnamedExpr(Expr::BinaryOp {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue