diff --git a/src/dialect/duckdb.rs b/src/dialect/duckdb.rs index f08d827b9..ea0990131 100644 --- a/src/dialect/duckdb.rs +++ b/src/dialect/duckdb.rs @@ -43,6 +43,10 @@ impl Dialect for DuckDbDialect { true } + fn supports_bitwise_shift_operators(&self) -> bool { + true + } + fn supports_named_fn_args_with_eq_operator(&self) -> bool { true } diff --git a/src/dialect/generic.rs b/src/dialect/generic.rs index bbedbc059..f3a0903a4 100644 --- a/src/dialect/generic.rs +++ b/src/dialect/generic.rs @@ -132,6 +132,10 @@ impl Dialect for GenericDialect { true } + fn supports_bitwise_shift_operators(&self) -> bool { + true + } + fn supports_comment_on(&self) -> bool { true } diff --git a/src/dialect/mod.rs b/src/dialect/mod.rs index 1a416e4df..0b6212974 100644 --- a/src/dialect/mod.rs +++ b/src/dialect/mod.rs @@ -894,6 +894,11 @@ pub trait Dialect: Debug + Any { false } + /// Returns true if the dialect supports `<<` and `>>` shift operators. + fn supports_bitwise_shift_operators(&self) -> bool { + false + } + /// Returns true if the dialect supports nested comments /// e.g. `/* /* nested */ */` fn supports_nested_comments(&self) -> bool { diff --git a/src/dialect/mysql.rs b/src/dialect/mysql.rs index 8d2a5ad4b..53a30f184 100644 --- a/src/dialect/mysql.rs +++ b/src/dialect/mysql.rs @@ -84,6 +84,10 @@ impl Dialect for MySqlDialect { true } + fn supports_bitwise_shift_operators(&self) -> bool { + true + } + fn parse_infix( &self, parser: &mut crate::parser::Parser, diff --git a/src/dialect/postgresql.rs b/src/dialect/postgresql.rs index e861cc515..02bab0e06 100644 --- a/src/dialect/postgresql.rs +++ b/src/dialect/postgresql.rs @@ -199,6 +199,10 @@ impl Dialect for PostgreSqlDialect { true } + fn supports_bitwise_shift_operators(&self) -> bool { + true + } + /// see fn supports_comment_on(&self) -> bool { true diff --git a/src/dialect/redshift.rs b/src/dialect/redshift.rs index 1cd6098a6..43c0646ce 100644 --- a/src/dialect/redshift.rs +++ b/src/dialect/redshift.rs @@ -120,6 +120,10 @@ impl Dialect for RedshiftSqlDialect { true } + fn supports_bitwise_shift_operators(&self) -> bool { + true + } + fn supports_array_typedef_with_brackets(&self) -> bool { true } diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 373076f12..fa049739c 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -3485,10 +3485,10 @@ impl<'a> Parser<'a> { Token::DuckIntDiv if dialect_is!(dialect is DuckDbDialect | GenericDialect) => { Some(BinaryOperator::DuckIntegerDivide) } - Token::ShiftLeft if dialect_is!(dialect is PostgreSqlDialect | DuckDbDialect | GenericDialect | RedshiftSqlDialect) => { + Token::ShiftLeft if dialect.supports_bitwise_shift_operators() => { Some(BinaryOperator::PGBitwiseShiftLeft) } - Token::ShiftRight if dialect_is!(dialect is PostgreSqlDialect | DuckDbDialect | GenericDialect | RedshiftSqlDialect) => { + Token::ShiftRight if dialect.supports_bitwise_shift_operators() => { Some(BinaryOperator::PGBitwiseShiftRight) } Token::Sharp if dialect_is!(dialect is PostgreSqlDialect | RedshiftSqlDialect) => { diff --git a/tests/sqlparser_common.rs b/tests/sqlparser_common.rs index 9f549e4d0..365bddb0f 100644 --- a/tests/sqlparser_common.rs +++ b/tests/sqlparser_common.rs @@ -2369,6 +2369,29 @@ fn parse_bitwise_ops() { } } +#[test] +fn parse_bitwise_shift_ops() { + let dialects = all_dialects_where(|d| d.supports_bitwise_shift_operators()); + let sql = "SELECT 1 << 2, 3 >> 4"; + let select = dialects.verified_only_select(sql); + assert_eq!( + SelectItem::UnnamedExpr(Expr::BinaryOp { + left: Box::new(Expr::Value((number("1")).with_empty_span())), + op: BinaryOperator::PGBitwiseShiftLeft, + right: Box::new(Expr::Value((number("2")).with_empty_span())), + }), + select.projection[0] + ); + assert_eq!( + SelectItem::UnnamedExpr(Expr::BinaryOp { + left: Box::new(Expr::Value((number("3")).with_empty_span())), + op: BinaryOperator::PGBitwiseShiftRight, + right: Box::new(Expr::Value((number("4")).with_empty_span())), + }), + select.projection[1] + ); +} + #[test] fn parse_binary_any() { let select = verified_only_select("SELECT a = ANY(b)");