1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
//! Set operation and relational expression parsing for the text parser.
use super::*;
impl TextParser {
pub(super) fn parse_set_operation(&mut self) -> ParseResult<Expression> {
let mut left = self.parse_relation()?;
while let Some(token) = self.peek() {
match &token.value {
Token::Union => {
self.next();
let right = self.parse_relation()?;
left = ExprKind::SetOperation {
op: SetOp::Union,
left: Box::new(left),
right: Box::new(right),
}
.into();
}
Token::Intersect => {
self.next();
let right = self.parse_relation()?;
left = ExprKind::SetOperation {
op: SetOp::Intersection,
left: Box::new(left),
right: Box::new(right),
}
.into();
}
Token::In => {
self.next();
let right = self.parse_relation()?;
left = ExprKind::SetRelationExpr {
relation: SetRelation::In,
element: Box::new(left),
set: Box::new(right),
}
.into();
}
Token::NotIn => {
self.next();
let right = self.parse_relation()?;
left = ExprKind::SetRelationExpr {
relation: SetRelation::NotIn,
element: Box::new(left),
set: Box::new(right),
}
.into();
}
_ => break,
}
}
Ok(left)
}
pub(super) fn parse_relation(&mut self) -> ParseResult<Expression> {
let left = self.parse_additive()?;
if let Some(token) = self.peek() {
let relation = match &token.value {
Token::Equals => Some(None),
Token::Less => Some(Some(InequalityOp::Lt)),
Token::Greater => Some(Some(InequalityOp::Gt)),
Token::LessEq => Some(Some(InequalityOp::Le)),
Token::GreaterEq => Some(Some(InequalityOp::Ge)),
Token::NotEquals => Some(Some(InequalityOp::Ne)),
_ => None,
};
if let Some(rel_op) = relation {
self.next();
let right = self.parse_additive()?;
if let Some(next_token) = self.peek() {
if matches!(
next_token.value,
Token::Equals
| Token::Less
| Token::Greater
| Token::LessEq
| Token::GreaterEq
| Token::NotEquals
) {
return Err(ParseError::custom(
"chained relations are not supported; use explicit grouping \
(e.g., (a < b) and (b < c))"
.to_string(),
Some(next_token.span),
));
}
}
return Ok(match rel_op {
None => ExprKind::Equation {
left: Box::new(left),
right: Box::new(right),
}
.into(),
Some(op) => ExprKind::Inequality {
op,
left: Box::new(left),
right: Box::new(right),
}
.into(),
});
}
}
Ok(left)
}
}