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 Colon,
147}
148
149impl Operator {
150 pub fn negate(&self) -> Option<Operator> {
153 match self {
154 Operator::Eq => Some(Operator::NotEq),
155 Operator::NotEq => Some(Operator::Eq),
156 Operator::Lt => Some(Operator::GtEq),
157 Operator::LtEq => Some(Operator::Gt),
158 Operator::Gt => Some(Operator::LtEq),
159 Operator::GtEq => Some(Operator::Lt),
160 Operator::IsDistinctFrom => Some(Operator::IsNotDistinctFrom),
161 Operator::IsNotDistinctFrom => Some(Operator::IsDistinctFrom),
162 Operator::LikeMatch => Some(Operator::NotLikeMatch),
163 Operator::ILikeMatch => Some(Operator::NotILikeMatch),
164 Operator::NotLikeMatch => Some(Operator::LikeMatch),
165 Operator::NotILikeMatch => Some(Operator::ILikeMatch),
166 Operator::RegexMatch => Some(Operator::RegexNotMatch),
167 Operator::RegexIMatch => Some(Operator::RegexNotIMatch),
168 Operator::RegexNotMatch => Some(Operator::RegexMatch),
169 Operator::RegexNotIMatch => Some(Operator::RegexIMatch),
170 Operator::Plus
171 | Operator::Minus
172 | Operator::Multiply
173 | Operator::Divide
174 | Operator::Modulo
175 | Operator::And
176 | Operator::Or
177 | Operator::BitwiseAnd
178 | Operator::BitwiseOr
179 | Operator::BitwiseXor
180 | Operator::BitwiseShiftRight
181 | Operator::BitwiseShiftLeft
182 | Operator::StringConcat
183 | Operator::AtArrow
184 | Operator::ArrowAt
185 | Operator::Arrow
186 | Operator::LongArrow
187 | Operator::HashArrow
188 | Operator::HashLongArrow
189 | Operator::AtAt
190 | Operator::IntegerDivide
191 | Operator::HashMinus
192 | Operator::AtQuestion
193 | Operator::Question
194 | Operator::QuestionAnd
195 | Operator::QuestionPipe
196 | Operator::Colon => None,
197 }
198 }
199
200 pub fn is_numerical_operators(&self) -> bool {
205 matches!(
206 self,
207 Operator::Plus
208 | Operator::Minus
209 | Operator::Multiply
210 | Operator::Divide
211 | Operator::Modulo
212 )
213 }
214
215 pub fn supports_propagation(&self) -> bool {
220 matches!(
221 self,
222 Operator::Eq
223 | Operator::NotEq
224 | Operator::Lt
225 | Operator::LtEq
226 | Operator::Gt
227 | Operator::GtEq
228 | Operator::IsDistinctFrom
229 | Operator::IsNotDistinctFrom
230 | Operator::RegexMatch
231 | Operator::RegexIMatch
232 | Operator::RegexNotMatch
233 | Operator::RegexNotIMatch
234 )
235 }
236
237 pub fn is_logic_operator(&self) -> bool {
242 matches!(self, Operator::And | Operator::Or)
243 }
244
245 pub fn swap(&self) -> Option<Operator> {
249 match self {
250 Operator::Eq => Some(Operator::Eq),
251 Operator::NotEq => Some(Operator::NotEq),
252 Operator::Lt => Some(Operator::Gt),
253 Operator::LtEq => Some(Operator::GtEq),
254 Operator::Gt => Some(Operator::Lt),
255 Operator::GtEq => Some(Operator::LtEq),
256 Operator::AtArrow => Some(Operator::ArrowAt),
257 Operator::ArrowAt => Some(Operator::AtArrow),
258 Operator::IsDistinctFrom => Some(Operator::IsDistinctFrom),
259 Operator::IsNotDistinctFrom => Some(Operator::IsNotDistinctFrom),
260 Operator::Plus
261 | Operator::Minus
262 | Operator::Multiply
263 | Operator::Divide
264 | Operator::Modulo
265 | Operator::And
266 | Operator::Or
267 | Operator::RegexMatch
268 | Operator::RegexIMatch
269 | Operator::RegexNotMatch
270 | Operator::RegexNotIMatch
271 | Operator::LikeMatch
272 | Operator::ILikeMatch
273 | Operator::NotLikeMatch
274 | Operator::NotILikeMatch
275 | Operator::BitwiseAnd
276 | Operator::BitwiseOr
277 | Operator::BitwiseXor
278 | Operator::BitwiseShiftRight
279 | Operator::BitwiseShiftLeft
280 | Operator::StringConcat
281 | Operator::Arrow
282 | Operator::LongArrow
283 | Operator::HashArrow
284 | Operator::HashLongArrow
285 | Operator::AtAt
286 | Operator::IntegerDivide
287 | Operator::HashMinus
288 | Operator::AtQuestion
289 | Operator::Question
290 | Operator::QuestionAnd
291 | Operator::QuestionPipe
292 | Operator::Colon => None,
293 }
294 }
295
296 pub fn precedence(&self) -> u8 {
299 match self {
300 Operator::Or => 5,
301 Operator::And => 10,
302 Operator::Eq | Operator::NotEq | Operator::LtEq | Operator::GtEq => 15,
303 Operator::Lt | Operator::Gt => 20,
304 Operator::LikeMatch
305 | Operator::NotLikeMatch
306 | Operator::ILikeMatch
307 | Operator::NotILikeMatch => 25,
308 Operator::IsDistinctFrom
309 | Operator::IsNotDistinctFrom
310 | Operator::RegexMatch
311 | Operator::RegexNotMatch
312 | Operator::RegexIMatch
313 | Operator::RegexNotIMatch
314 | Operator::BitwiseAnd
315 | Operator::BitwiseOr
316 | Operator::BitwiseShiftLeft
317 | Operator::BitwiseShiftRight
318 | Operator::BitwiseXor
319 | Operator::StringConcat
320 | Operator::AtArrow
321 | Operator::ArrowAt
322 | Operator::Arrow
323 | Operator::LongArrow
324 | Operator::HashArrow
325 | Operator::HashLongArrow
326 | Operator::AtAt
327 | Operator::IntegerDivide
328 | Operator::HashMinus
329 | Operator::AtQuestion
330 | Operator::Question
331 | Operator::QuestionAnd
332 | Operator::QuestionPipe
333 | Operator::Colon => 30,
334 Operator::Plus | Operator::Minus => 40,
335 Operator::Multiply | Operator::Divide | Operator::Modulo => 45,
336 }
337 }
338
339 pub fn returns_null_on_null(&self) -> bool {
342 match self {
343 Operator::Eq
344 | Operator::NotEq
345 | Operator::Lt
346 | Operator::LtEq
347 | Operator::Gt
348 | Operator::GtEq
349 | Operator::Plus
350 | Operator::Minus
351 | Operator::Multiply
352 | Operator::Divide
353 | Operator::Modulo
354 | Operator::RegexMatch
355 | Operator::RegexIMatch
356 | Operator::RegexNotMatch
357 | Operator::RegexNotIMatch
358 | Operator::LikeMatch
359 | Operator::ILikeMatch
360 | Operator::NotLikeMatch
361 | Operator::NotILikeMatch
362 | Operator::BitwiseAnd
363 | Operator::BitwiseOr
364 | Operator::BitwiseXor
365 | Operator::BitwiseShiftRight
366 | Operator::BitwiseShiftLeft
367 | Operator::AtArrow
368 | Operator::ArrowAt
369 | Operator::Arrow
370 | Operator::LongArrow
371 | Operator::HashArrow
372 | Operator::HashLongArrow
373 | Operator::AtAt
374 | Operator::IntegerDivide
375 | Operator::HashMinus
376 | Operator::AtQuestion
377 | Operator::Question
378 | Operator::QuestionAnd
379 | Operator::QuestionPipe
380 | Operator::Colon
381 | Operator::StringConcat => true,
382
383 Operator::Or
385 | Operator::And
387 | Operator::IsDistinctFrom
389 | Operator::IsNotDistinctFrom => false,
390 }
391 }
392
393 pub fn from_proto_name(name: &str) -> Option<Operator> {
401 Some(match name {
402 "And" => Operator::And,
403 "Or" => Operator::Or,
404 "Eq" => Operator::Eq,
405 "NotEq" => Operator::NotEq,
406 "LtEq" => Operator::LtEq,
407 "Lt" => Operator::Lt,
408 "Gt" => Operator::Gt,
409 "GtEq" => Operator::GtEq,
410 "Plus" => Operator::Plus,
411 "Minus" => Operator::Minus,
412 "Multiply" => Operator::Multiply,
413 "Divide" => Operator::Divide,
414 "Modulo" => Operator::Modulo,
415 "IsDistinctFrom" => Operator::IsDistinctFrom,
416 "IsNotDistinctFrom" => Operator::IsNotDistinctFrom,
417 "BitwiseAnd" => Operator::BitwiseAnd,
418 "BitwiseOr" => Operator::BitwiseOr,
419 "BitwiseXor" => Operator::BitwiseXor,
420 "BitwiseShiftLeft" => Operator::BitwiseShiftLeft,
421 "BitwiseShiftRight" => Operator::BitwiseShiftRight,
422 "RegexIMatch" => Operator::RegexIMatch,
423 "RegexMatch" => Operator::RegexMatch,
424 "RegexNotIMatch" => Operator::RegexNotIMatch,
425 "RegexNotMatch" => Operator::RegexNotMatch,
426 "LikeMatch" => Operator::LikeMatch,
427 "ILikeMatch" => Operator::ILikeMatch,
428 "NotLikeMatch" => Operator::NotLikeMatch,
429 "NotILikeMatch" => Operator::NotILikeMatch,
430 "StringConcat" => Operator::StringConcat,
431 "AtArrow" => Operator::AtArrow,
432 "ArrowAt" => Operator::ArrowAt,
433 _ => return None,
434 })
435 }
436}
437
438impl fmt::Display for Operator {
439 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
440 let display = match &self {
441 Operator::Eq => "=",
442 Operator::NotEq => "!=",
443 Operator::Lt => "<",
444 Operator::LtEq => "<=",
445 Operator::Gt => ">",
446 Operator::GtEq => ">=",
447 Operator::Plus => "+",
448 Operator::Minus => "-",
449 Operator::Multiply => "*",
450 Operator::Divide => "/",
451 Operator::Modulo => "%",
452 Operator::And => "AND",
453 Operator::Or => "OR",
454 Operator::RegexMatch => "~",
455 Operator::RegexIMatch => "~*",
456 Operator::RegexNotMatch => "!~",
457 Operator::RegexNotIMatch => "!~*",
458 Operator::LikeMatch => "~~",
459 Operator::ILikeMatch => "~~*",
460 Operator::NotLikeMatch => "!~~",
461 Operator::NotILikeMatch => "!~~*",
462 Operator::IsDistinctFrom => "IS DISTINCT FROM",
463 Operator::IsNotDistinctFrom => "IS NOT DISTINCT FROM",
464 Operator::BitwiseAnd => "&",
465 Operator::BitwiseOr => "|",
466 Operator::BitwiseXor => "BIT_XOR",
467 Operator::BitwiseShiftRight => ">>",
468 Operator::BitwiseShiftLeft => "<<",
469 Operator::StringConcat => "||",
470 Operator::AtArrow => "@>",
471 Operator::ArrowAt => "<@",
472 Operator::Arrow => "->",
473 Operator::LongArrow => "->>",
474 Operator::HashArrow => "#>",
475 Operator::HashLongArrow => "#>>",
476 Operator::AtAt => "@@",
477 Operator::IntegerDivide => "DIV",
478 Operator::HashMinus => "#-",
479 Operator::AtQuestion => "@?",
480 Operator::Question => "?",
481 Operator::QuestionAnd => "?&",
482 Operator::QuestionPipe => "?|",
483 Operator::Colon => ":",
484 };
485 write!(f, "{display}")
486 }
487}