summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjhspetersson <jhspetersson@gmail.com>2023-11-30 23:34:19 +0100
committerjhspetersson <jhspetersson@gmail.com>2023-11-30 23:34:19 +0100
commit346114554e44b3482730834399ad7188cb840739 (patch)
treecae7a68bb34f2e9591dbb5221c07d2902553f7e2
parentadc37d08a590eef908416de6591bdc7b8ab8453a (diff)
support BETWEEN operator #139
-rw-r--r--src/lexer.rs19
-rw-r--r--src/operators.rs5
-rw-r--r--src/parser.rs28
3 files changed, 51 insertions, 1 deletions
diff --git a/src/lexer.rs b/src/lexer.rs
index cecca2f..2f47b92 100644
--- a/src/lexer.rs
+++ b/src/lexer.rs
@@ -151,7 +151,8 @@ impl<'a> Lexer<'a> {
"limit" => Some(Lexem::Limit),
"into" => Some(Lexem::Into),
"eq" | "ne" | "gt" | "lt" | "ge" | "le" | "gte" | "lte" |
- "regexp" | "rx" | "like" => Some(Lexem::Operator(s)),
+ "regexp" | "rx" | "like" |
+ "between" => Some(Lexem::Operator(s)),
"mul" | "div" | "mod" | "plus" | "minus" => Some(Lexem::ArithmeticOperator(s)),
_ => Some(Lexem::RawString(s)),
}
@@ -581,4 +582,20 @@ mod tests {
assert_eq!(lexer.next_lexem(), Some(Lexem::By));
assert_eq!(lexer.next_lexem(), Some(Lexem::RawString(String::from("mime"))));
}
+
+ #[test]
+ fn between_op() {
+ let mut lexer = Lexer::new("select name from /home/user where size between 1000000 and 2000000");
+
+ assert_eq!(lexer.next_lexem(), Some(Lexem::RawString(String::from("select"))));
+ assert_eq!(lexer.next_lexem(), Some(Lexem::RawString(String::from("name"))));
+ assert_eq!(lexer.next_lexem(), Some(Lexem::From));
+ assert_eq!(lexer.next_lexem(), Some(Lexem::RawString(String::from("/home/user"))));
+ assert_eq!(lexer.next_lexem(), Some(Lexem::Where));
+ assert_eq!(lexer.next_lexem(), Some(Lexem::RawString(String::from("size"))));
+ assert_eq!(lexer.next_lexem(), Some(Lexem::Operator(String::from("between"))));
+ assert_eq!(lexer.next_lexem(), Some(Lexem::RawString(String::from("1000000"))));
+ assert_eq!(lexer.next_lexem(), Some(Lexem::And));
+ assert_eq!(lexer.next_lexem(), Some(Lexem::RawString(String::from("2000000"))));
+ }
}
diff --git a/src/operators.rs b/src/operators.rs
index 1df9fb5..759dfe6 100644
--- a/src/operators.rs
+++ b/src/operators.rs
@@ -20,6 +20,8 @@ pub enum Op {
NotRx,
Like,
NotLike,
+ Between,
+ NotBetween,
}
impl Op {
@@ -37,6 +39,7 @@ impl Op {
"!=~" | "!~=" | "notrx" => Some(Op::NotRx),
"like" => Some(Op::Like),
"notlike" => Some(Op::NotLike),
+ "between" => Some(Op::Between),
_ => None
}
}
@@ -65,6 +68,8 @@ impl Op {
Op::NotRx => Op::Rx,
Op::Like => Op::NotLike,
Op::NotLike => Op::Like,
+ Op::Between => Op::NotBetween,
+ Op::NotBetween => Op::Between,
}
}
}
diff --git a/src/parser.rs b/src/parser.rs
index 3b3eb18..7f0aaca 100644
--- a/src/parser.rs
+++ b/src/parser.rs
@@ -481,6 +481,21 @@ impl Parser {
let lexem = self.next_lexem();
let mut result = match lexem {
+ Some(Lexem::Operator(s)) if s.as_str() == "between" => {
+ let left_between = self.parse_add_sub()?;
+
+ let and_lexem = self.next_lexem();
+ if and_lexem.is_none() || and_lexem.unwrap() != Lexem::And {
+ return Err(String::from("Error parsing BETWEEN operator"))
+ }
+
+ let right_between = self.parse_add_sub()?;
+
+ let left_expr = Expr::op(left.clone().unwrap(), match not { false => Op::Gte, true => Op::Lte }, left_between.unwrap());
+ let right_expr = Expr::op(left.unwrap(), match not { false => Op::Lte, true => Op::Gte }, right_between.unwrap());
+
+ Ok(Some(Expr::logical_op(left_expr, match not { false => LogicalOp::And, true => LogicalOp::Or }, right_expr)))
+ },
Some(Lexem::Operator(s)) => {
let right = self.parse_add_sub()?;
let op = Op::from_with_not(s, not);
@@ -1146,4 +1161,17 @@ mod tests {
assert_eq!(query.grouping_fields, Rc::new(vec![Expr::field(Field::Mime)]));
}
+
+ #[test]
+ fn query_with_between() {
+ let query = "select name, size from /test where size between 5mb and 6mb";
+ let mut p = Parser::new();
+ let query = p.parse(&query, false).unwrap();
+
+ let query2 = "select name, size from /test where size gte 5mb and size lte 6mb";
+ let mut p2 = Parser::new();
+ let query2 = p2.parse(&query2, false).unwrap();
+
+ assert_eq!(query.expr, query2.expr);
+ }
}