mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-08-25 08:24:05 +00:00
feat: Support MySQL's DIV
operator (#876)
* feat: MySQL's DIV operator * fix: do not use `_` prefix for used variable --------- Co-authored-by: Andrew Lamb <andrew@nerdnetworks.org>
This commit is contained in:
parent
feaa13c9a9
commit
097e7ad56e
5 changed files with 38 additions and 1 deletions
|
@ -85,6 +85,8 @@ pub enum BinaryOperator {
|
|||
BitwiseOr,
|
||||
BitwiseAnd,
|
||||
BitwiseXor,
|
||||
/// MySQL [`DIV`](https://dev.mysql.com/doc/refman/8.0/en/arithmetic-functions.html) integer division
|
||||
MyIntegerDivide,
|
||||
/// Support for custom operators (built by parsers outside this crate)
|
||||
Custom(String),
|
||||
PGBitwiseXor,
|
||||
|
@ -124,6 +126,7 @@ impl fmt::Display for BinaryOperator {
|
|||
BinaryOperator::BitwiseOr => f.write_str("|"),
|
||||
BinaryOperator::BitwiseAnd => f.write_str("&"),
|
||||
BinaryOperator::BitwiseXor => f.write_str("^"),
|
||||
BinaryOperator::MyIntegerDivide => f.write_str("DIV"),
|
||||
BinaryOperator::Custom(s) => f.write_str(s),
|
||||
BinaryOperator::PGBitwiseXor => f.write_str("#"),
|
||||
BinaryOperator::PGBitwiseShiftLeft => f.write_str("<<"),
|
||||
|
|
|
@ -10,7 +10,14 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use crate::dialect::Dialect;
|
||||
#[cfg(not(feature = "std"))]
|
||||
use alloc::boxed::Box;
|
||||
|
||||
use crate::{
|
||||
ast::{BinaryOperator, Expr},
|
||||
dialect::Dialect,
|
||||
keywords::Keyword,
|
||||
};
|
||||
|
||||
/// [MySQL](https://www.mysql.com/)
|
||||
#[derive(Debug)]
|
||||
|
@ -35,4 +42,22 @@ impl Dialect for MySqlDialect {
|
|||
fn is_delimited_identifier_start(&self, ch: char) -> bool {
|
||||
ch == '`'
|
||||
}
|
||||
|
||||
fn parse_infix(
|
||||
&self,
|
||||
parser: &mut crate::parser::Parser,
|
||||
expr: &crate::ast::Expr,
|
||||
_precedence: u8,
|
||||
) -> Option<Result<crate::ast::Expr, crate::parser::ParserError>> {
|
||||
// Parse DIV as an operator
|
||||
if parser.parse_keyword(Keyword::DIV) {
|
||||
Some(Ok(Expr::BinaryOp {
|
||||
left: Box::new(expr.clone()),
|
||||
op: BinaryOperator::MyIntegerDivide,
|
||||
right: Box::new(parser.parse_expr().unwrap()),
|
||||
}))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -211,6 +211,7 @@ define_keywords!(
|
|||
DISCONNECT,
|
||||
DISTINCT,
|
||||
DISTRIBUTE,
|
||||
DIV,
|
||||
DO,
|
||||
DOUBLE,
|
||||
DOW,
|
||||
|
|
|
@ -1982,6 +1982,8 @@ impl<'a> Parser<'a> {
|
|||
const AND_PREC: u8 = 10;
|
||||
const OR_PREC: u8 = 5;
|
||||
|
||||
const DIV_OP_PREC: u8 = 40;
|
||||
|
||||
/// Get the precedence of the next token
|
||||
pub fn get_next_precedence(&self) -> Result<u8, ParserError> {
|
||||
// allow the dialect to override precedence logic
|
||||
|
@ -2031,6 +2033,7 @@ impl<'a> Parser<'a> {
|
|||
Token::Word(w) if w.keyword == Keyword::ILIKE => Ok(Self::LIKE_PREC),
|
||||
Token::Word(w) if w.keyword == Keyword::SIMILAR => Ok(Self::LIKE_PREC),
|
||||
Token::Word(w) if w.keyword == Keyword::OPERATOR => Ok(Self::BETWEEN_PREC),
|
||||
Token::Word(w) if w.keyword == Keyword::DIV => Ok(Self::DIV_OP_PREC),
|
||||
Token::Eq
|
||||
| Token::Lt
|
||||
| Token::LtEq
|
||||
|
|
|
@ -1407,3 +1407,8 @@ fn parse_string_introducers() {
|
|||
mysql().one_statement_parses_to("SELECT _utf8mb4'abc'", "SELECT _utf8mb4 'abc'");
|
||||
mysql().verified_stmt("SELECT _binary 'abc', _utf8mb4 'abc'");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_div_infix() {
|
||||
mysql().verified_stmt(r#"SELECT 5 DIV 2"#);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue