Skip to content

Commit 4e4507a

Browse files
committed
Split operators by arity
It is useful downstream to have two separate enums, one for unary operators and one for binary operators, so that the compiler can check exhaustiveness. Otherwise downstream consumers need to manually encode which operators are unary and which operators are binary when matching on an Operator enum.
1 parent cc0f643 commit 4e4507a

File tree

4 files changed

+92
-75
lines changed

4 files changed

+92
-75
lines changed

src/ast/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ pub use self::query::{
3030
pub use self::sqltype::SqlType;
3131
pub use self::value::Value;
3232

33-
pub use self::operator::Operator;
33+
pub use self::operator::{BinaryOperator, UnaryOperator};
3434

3535
/// Like `vec.join(", ")`, but for any types implementing ToString.
3636
fn comma_separated_string<I>(iter: I) -> String
@@ -92,7 +92,7 @@ pub enum Expr {
9292
/// Binary operation e.g. `1 + 1` or `foo > bar`
9393
BinaryOp {
9494
left: Box<Expr>,
95-
op: Operator,
95+
op: BinaryOperator,
9696
right: Box<Expr>,
9797
},
9898
/// CAST an expression to a different data type e.g. `CAST(foo AS VARCHAR(123))`
@@ -110,7 +110,7 @@ pub enum Expr {
110110
Nested(Box<Expr>),
111111
/// Unary operation, like `NOT false`
112112
UnaryOp {
113-
op: Operator,
113+
op: UnaryOperator,
114114
expr: Box<Expr>,
115115
},
116116
/// SQLValue

src/ast/operator.rs

Lines changed: 37 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,25 @@
1-
/// SQL Operator
1+
/// Unary operators
22
#[derive(Debug, Clone, PartialEq, Hash)]
3-
pub enum Operator {
3+
pub enum UnaryOperator {
4+
Plus,
5+
Minus,
6+
Not,
7+
}
8+
9+
impl ToString for UnaryOperator {
10+
fn to_string(&self) -> String {
11+
match self {
12+
UnaryOperator::Plus => "+".to_string(),
13+
UnaryOperator::Minus => "-".to_string(),
14+
UnaryOperator::Not => "NOT".to_string(),
15+
}
16+
}
17+
}
18+
19+
20+
/// Binary operators
21+
#[derive(Debug, Clone, PartialEq, Hash)]
22+
pub enum BinaryOperator {
423
Plus,
524
Minus,
625
Multiply,
@@ -14,30 +33,28 @@ pub enum Operator {
1433
NotEq,
1534
And,
1635
Or,
17-
Not,
1836
Like,
1937
NotLike,
2038
}
2139

22-
impl ToString for Operator {
40+
impl ToString for BinaryOperator {
2341
fn to_string(&self) -> String {
2442
match self {
25-
Operator::Plus => "+".to_string(),
26-
Operator::Minus => "-".to_string(),
27-
Operator::Multiply => "*".to_string(),
28-
Operator::Divide => "/".to_string(),
29-
Operator::Modulus => "%".to_string(),
30-
Operator::Gt => ">".to_string(),
31-
Operator::Lt => "<".to_string(),
32-
Operator::GtEq => ">=".to_string(),
33-
Operator::LtEq => "<=".to_string(),
34-
Operator::Eq => "=".to_string(),
35-
Operator::NotEq => "<>".to_string(),
36-
Operator::And => "AND".to_string(),
37-
Operator::Or => "OR".to_string(),
38-
Operator::Not => "NOT".to_string(),
39-
Operator::Like => "LIKE".to_string(),
40-
Operator::NotLike => "NOT LIKE".to_string(),
43+
BinaryOperator::Plus => "+".to_string(),
44+
BinaryOperator::Minus => "-".to_string(),
45+
BinaryOperator::Multiply => "*".to_string(),
46+
BinaryOperator::Divide => "/".to_string(),
47+
BinaryOperator::Modulus => "%".to_string(),
48+
BinaryOperator::Gt => ">".to_string(),
49+
BinaryOperator::Lt => "<".to_string(),
50+
BinaryOperator::GtEq => ">=".to_string(),
51+
BinaryOperator::LtEq => "<=".to_string(),
52+
BinaryOperator::Eq => "=".to_string(),
53+
BinaryOperator::NotEq => "<>".to_string(),
54+
BinaryOperator::And => "AND".to_string(),
55+
BinaryOperator::Or => "OR".to_string(),
56+
BinaryOperator::Like => "LIKE".to_string(),
57+
BinaryOperator::NotLike => "NOT LIKE".to_string(),
4158
}
4259
}
4360
}

src/parser.rs

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ impl Parser {
196196
"EXISTS" => self.parse_exists_expression(),
197197
"EXTRACT" => self.parse_extract_expression(),
198198
"NOT" => Ok(Expr::UnaryOp {
199-
op: Operator::Not,
199+
op: UnaryOperator::Not,
200200
expr: Box::new(self.parse_subexpr(Self::UNARY_NOT_PREC)?),
201201
}),
202202
"TIME" => Ok(Expr::Value(Value::Time(self.parse_literal_string()?))),
@@ -237,9 +237,9 @@ impl Parser {
237237
Token::Mult => Ok(Expr::Wildcard),
238238
tok @ Token::Minus | tok @ Token::Plus => {
239239
let operator = if tok == Token::Plus {
240-
Operator::Plus
240+
UnaryOperator::Plus
241241
} else {
242-
Operator::Minus
242+
UnaryOperator::Minus
243243
};
244244
Ok(Expr::UnaryOp {
245245
op: operator,
@@ -454,24 +454,24 @@ impl Parser {
454454
let tok = self.next_token().unwrap(); // safe as EOF's precedence is the lowest
455455

456456
let regular_binary_operator = match tok {
457-
Token::Eq => Some(Operator::Eq),
458-
Token::Neq => Some(Operator::NotEq),
459-
Token::Gt => Some(Operator::Gt),
460-
Token::GtEq => Some(Operator::GtEq),
461-
Token::Lt => Some(Operator::Lt),
462-
Token::LtEq => Some(Operator::LtEq),
463-
Token::Plus => Some(Operator::Plus),
464-
Token::Minus => Some(Operator::Minus),
465-
Token::Mult => Some(Operator::Multiply),
466-
Token::Mod => Some(Operator::Modulus),
467-
Token::Div => Some(Operator::Divide),
457+
Token::Eq => Some(BinaryOperator::Eq),
458+
Token::Neq => Some(BinaryOperator::NotEq),
459+
Token::Gt => Some(BinaryOperator::Gt),
460+
Token::GtEq => Some(BinaryOperator::GtEq),
461+
Token::Lt => Some(BinaryOperator::Lt),
462+
Token::LtEq => Some(BinaryOperator::LtEq),
463+
Token::Plus => Some(BinaryOperator::Plus),
464+
Token::Minus => Some(BinaryOperator::Minus),
465+
Token::Mult => Some(BinaryOperator::Multiply),
466+
Token::Mod => Some(BinaryOperator::Modulus),
467+
Token::Div => Some(BinaryOperator::Divide),
468468
Token::Word(ref k) => match k.keyword.as_ref() {
469-
"AND" => Some(Operator::And),
470-
"OR" => Some(Operator::Or),
471-
"LIKE" => Some(Operator::Like),
469+
"AND" => Some(BinaryOperator::And),
470+
"OR" => Some(BinaryOperator::Or),
471+
"LIKE" => Some(BinaryOperator::Like),
472472
"NOT" => {
473473
if self.parse_keyword("LIKE") {
474-
Some(Operator::NotLike)
474+
Some(BinaryOperator::NotLike)
475475
} else {
476476
None
477477
}

0 commit comments

Comments
 (0)