1use std::fmt;
19
20#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Hash)]
22pub enum Operator {
23 Eq,
25 NotEq,
27 Lt,
29 LtEq,
31 Gt,
33 GtEq,
35 Plus,
37 Minus,
39 Multiply,
41 Divide,
43 Modulo,
45 And,
47 Or,
49 IsDistinctFrom,
53 IsNotDistinctFrom,
57 RegexMatch,
59 RegexIMatch,
61 RegexNotMatch,
63 RegexNotIMatch,
65 LikeMatch,
67 ILikeMatch,
69 NotLikeMatch,
71 NotILikeMatch,
73 BitwiseAnd,
75 BitwiseOr,
77 BitwiseXor,
79 BitwiseShiftRight,
81 BitwiseShiftLeft,
83 StringConcat,
85 AtArrow,
92 ArrowAt,
99 Arrow,
103 LongArrow,
107 HashArrow,
111 HashLongArrow,
115 AtAt,
119 IntegerDivide,
123 HashMinus,
127 AtQuestion,
131 Question,
135 QuestionAnd,
139 QuestionPipe,
143}
144
145impl Operator {
146 pub fn negate(&self) -> Option<Operator> {
149 match self {
150 Operator::Eq => Some(Operator::NotEq),
151 Operator::NotEq => Some(Operator::Eq),
152 Operator::Lt => Some(Operator::GtEq),
153 Operator::LtEq => Some(Operator::Gt),
154 Operator::Gt => Some(Operator::LtEq),
155 Operator::GtEq => Some(Operator::Lt),
156 Operator::IsDistinctFrom => Some(Operator::IsNotDistinctFrom),
157 Operator::IsNotDistinctFrom => Some(Operator::IsDistinctFrom),
158 Operator::LikeMatch => Some(Operator::NotLikeMatch),
159 Operator::ILikeMatch => Some(Operator::NotILikeMatch),
160 Operator::NotLikeMatch => Some(Operator::LikeMatch),
161 Operator::NotILikeMatch => Some(Operator::ILikeMatch),
162 Operator::Plus
163 | Operator::Minus
164 | Operator::Multiply
165 | Operator::Divide
166 | Operator::Modulo
167 | Operator::And
168 | Operator::Or
169 | Operator::RegexMatch
170 | Operator::RegexIMatch
171 | Operator::RegexNotMatch
172 | Operator::RegexNotIMatch
173 | Operator::BitwiseAnd
174 | Operator::BitwiseOr
175 | Operator::BitwiseXor
176 | Operator::BitwiseShiftRight
177 | Operator::BitwiseShiftLeft
178 | Operator::StringConcat
179 | Operator::AtArrow
180 | Operator::ArrowAt
181 | Operator::Arrow
182 | Operator::LongArrow
183 | Operator::HashArrow
184 | Operator::HashLongArrow
185 | Operator::AtAt
186 | Operator::IntegerDivide
187 | Operator::HashMinus
188 | Operator::AtQuestion
189 | Operator::Question
190 | Operator::QuestionAnd
191 | Operator::QuestionPipe => None,
192 }
193 }
194
195 pub fn is_numerical_operators(&self) -> bool {
200 matches!(
201 self,
202 Operator::Plus
203 | Operator::Minus
204 | Operator::Multiply
205 | Operator::Divide
206 | Operator::Modulo
207 )
208 }
209
210 pub fn supports_propagation(&self) -> bool {
215 matches!(
216 self,
217 Operator::Eq
218 | Operator::NotEq
219 | Operator::Lt
220 | Operator::LtEq
221 | Operator::Gt
222 | Operator::GtEq
223 | Operator::IsDistinctFrom
224 | Operator::IsNotDistinctFrom
225 | Operator::RegexMatch
226 | Operator::RegexIMatch
227 | Operator::RegexNotMatch
228 | Operator::RegexNotIMatch
229 )
230 }
231
232 pub fn is_logic_operator(&self) -> bool {
237 matches!(self, Operator::And | Operator::Or)
238 }
239
240 pub fn swap(&self) -> Option<Operator> {
244 match self {
245 Operator::Eq => Some(Operator::Eq),
246 Operator::NotEq => Some(Operator::NotEq),
247 Operator::Lt => Some(Operator::Gt),
248 Operator::LtEq => Some(Operator::GtEq),
249 Operator::Gt => Some(Operator::Lt),
250 Operator::GtEq => Some(Operator::LtEq),
251 Operator::AtArrow => Some(Operator::ArrowAt),
252 Operator::ArrowAt => Some(Operator::AtArrow),
253 Operator::IsDistinctFrom
254 | Operator::IsNotDistinctFrom
255 | Operator::Plus
256 | Operator::Minus
257 | Operator::Multiply
258 | Operator::Divide
259 | Operator::Modulo
260 | Operator::And
261 | Operator::Or
262 | Operator::RegexMatch
263 | Operator::RegexIMatch
264 | Operator::RegexNotMatch
265 | Operator::RegexNotIMatch
266 | Operator::LikeMatch
267 | Operator::ILikeMatch
268 | Operator::NotLikeMatch
269 | Operator::NotILikeMatch
270 | Operator::BitwiseAnd
271 | Operator::BitwiseOr
272 | Operator::BitwiseXor
273 | Operator::BitwiseShiftRight
274 | Operator::BitwiseShiftLeft
275 | Operator::StringConcat
276 | Operator::Arrow
277 | Operator::LongArrow
278 | Operator::HashArrow
279 | Operator::HashLongArrow
280 | Operator::AtAt
281 | Operator::IntegerDivide
282 | Operator::HashMinus
283 | Operator::AtQuestion
284 | Operator::Question
285 | Operator::QuestionAnd
286 | Operator::QuestionPipe => None,
287 }
288 }
289
290 pub fn precedence(&self) -> u8 {
293 match self {
294 Operator::Or => 5,
295 Operator::And => 10,
296 Operator::Eq | Operator::NotEq | Operator::LtEq | Operator::GtEq => 15,
297 Operator::Lt | Operator::Gt => 20,
298 Operator::LikeMatch
299 | Operator::NotLikeMatch
300 | Operator::ILikeMatch
301 | Operator::NotILikeMatch => 25,
302 Operator::IsDistinctFrom
303 | Operator::IsNotDistinctFrom
304 | Operator::RegexMatch
305 | Operator::RegexNotMatch
306 | Operator::RegexIMatch
307 | Operator::RegexNotIMatch
308 | Operator::BitwiseAnd
309 | Operator::BitwiseOr
310 | Operator::BitwiseShiftLeft
311 | Operator::BitwiseShiftRight
312 | Operator::BitwiseXor
313 | Operator::StringConcat
314 | Operator::AtArrow
315 | Operator::ArrowAt
316 | Operator::Arrow
317 | Operator::LongArrow
318 | Operator::HashArrow
319 | Operator::HashLongArrow
320 | Operator::AtAt
321 | Operator::IntegerDivide
322 | Operator::HashMinus
323 | Operator::AtQuestion
324 | Operator::Question
325 | Operator::QuestionAnd
326 | Operator::QuestionPipe => 30,
327 Operator::Plus | Operator::Minus => 40,
328 Operator::Multiply | Operator::Divide | Operator::Modulo => 45,
329 }
330 }
331
332 pub fn returns_null_on_null(&self) -> bool {
335 match self {
336 Operator::Eq
337 | Operator::NotEq
338 | Operator::Lt
339 | Operator::LtEq
340 | Operator::Gt
341 | Operator::GtEq
342 | Operator::Plus
343 | Operator::Minus
344 | Operator::Multiply
345 | Operator::Divide
346 | Operator::Modulo
347 | Operator::RegexMatch
348 | Operator::RegexIMatch
349 | Operator::RegexNotMatch
350 | Operator::RegexNotIMatch
351 | Operator::LikeMatch
352 | Operator::ILikeMatch
353 | Operator::NotLikeMatch
354 | Operator::NotILikeMatch
355 | Operator::BitwiseAnd
356 | Operator::BitwiseOr
357 | Operator::BitwiseXor
358 | Operator::BitwiseShiftRight
359 | Operator::BitwiseShiftLeft
360 | Operator::AtArrow
361 | Operator::ArrowAt
362 | Operator::Arrow
363 | Operator::LongArrow
364 | Operator::HashArrow
365 | Operator::HashLongArrow
366 | Operator::AtAt
367 | Operator::IntegerDivide
368 | Operator::HashMinus
369 | Operator::AtQuestion
370 | Operator::Question
371 | Operator::QuestionAnd
372 | Operator::QuestionPipe => true,
373
374 Operator::Or
376 | Operator::And
378 | Operator::IsDistinctFrom
380 | Operator::IsNotDistinctFrom
381 | Operator::StringConcat => false,
383 }
384 }
385}
386
387impl fmt::Display for Operator {
388 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
389 let display = match &self {
390 Operator::Eq => "=",
391 Operator::NotEq => "!=",
392 Operator::Lt => "<",
393 Operator::LtEq => "<=",
394 Operator::Gt => ">",
395 Operator::GtEq => ">=",
396 Operator::Plus => "+",
397 Operator::Minus => "-",
398 Operator::Multiply => "*",
399 Operator::Divide => "/",
400 Operator::Modulo => "%",
401 Operator::And => "AND",
402 Operator::Or => "OR",
403 Operator::RegexMatch => "~",
404 Operator::RegexIMatch => "~*",
405 Operator::RegexNotMatch => "!~",
406 Operator::RegexNotIMatch => "!~*",
407 Operator::LikeMatch => "~~",
408 Operator::ILikeMatch => "~~*",
409 Operator::NotLikeMatch => "!~~",
410 Operator::NotILikeMatch => "!~~*",
411 Operator::IsDistinctFrom => "IS DISTINCT FROM",
412 Operator::IsNotDistinctFrom => "IS NOT DISTINCT FROM",
413 Operator::BitwiseAnd => "&",
414 Operator::BitwiseOr => "|",
415 Operator::BitwiseXor => "BIT_XOR",
416 Operator::BitwiseShiftRight => ">>",
417 Operator::BitwiseShiftLeft => "<<",
418 Operator::StringConcat => "||",
419 Operator::AtArrow => "@>",
420 Operator::ArrowAt => "<@",
421 Operator::Arrow => "->",
422 Operator::LongArrow => "->>",
423 Operator::HashArrow => "#>",
424 Operator::HashLongArrow => "#>>",
425 Operator::AtAt => "@@",
426 Operator::IntegerDivide => "DIV",
427 Operator::HashMinus => "#-",
428 Operator::AtQuestion => "@?",
429 Operator::Question => "?",
430 Operator::QuestionAnd => "?&",
431 Operator::QuestionPipe => "?|",
432 };
433 write!(f, "{display}")
434 }
435}