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::Plus
167 | Operator::Minus
168 | Operator::Multiply
169 | Operator::Divide
170 | Operator::Modulo
171 | Operator::And
172 | Operator::Or
173 | Operator::RegexMatch
174 | Operator::RegexIMatch
175 | Operator::RegexNotMatch
176 | Operator::RegexNotIMatch
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
259 | 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 => true,
381
382 Operator::Or
384 | Operator::And
386 | Operator::IsDistinctFrom
388 | Operator::IsNotDistinctFrom
389 | Operator::StringConcat => false,
391 }
392 }
393}
394
395impl fmt::Display for Operator {
396 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
397 let display = match &self {
398 Operator::Eq => "=",
399 Operator::NotEq => "!=",
400 Operator::Lt => "<",
401 Operator::LtEq => "<=",
402 Operator::Gt => ">",
403 Operator::GtEq => ">=",
404 Operator::Plus => "+",
405 Operator::Minus => "-",
406 Operator::Multiply => "*",
407 Operator::Divide => "/",
408 Operator::Modulo => "%",
409 Operator::And => "AND",
410 Operator::Or => "OR",
411 Operator::RegexMatch => "~",
412 Operator::RegexIMatch => "~*",
413 Operator::RegexNotMatch => "!~",
414 Operator::RegexNotIMatch => "!~*",
415 Operator::LikeMatch => "~~",
416 Operator::ILikeMatch => "~~*",
417 Operator::NotLikeMatch => "!~~",
418 Operator::NotILikeMatch => "!~~*",
419 Operator::IsDistinctFrom => "IS DISTINCT FROM",
420 Operator::IsNotDistinctFrom => "IS NOT DISTINCT FROM",
421 Operator::BitwiseAnd => "&",
422 Operator::BitwiseOr => "|",
423 Operator::BitwiseXor => "BIT_XOR",
424 Operator::BitwiseShiftRight => ">>",
425 Operator::BitwiseShiftLeft => "<<",
426 Operator::StringConcat => "||",
427 Operator::AtArrow => "@>",
428 Operator::ArrowAt => "<@",
429 Operator::Arrow => "->",
430 Operator::LongArrow => "->>",
431 Operator::HashArrow => "#>",
432 Operator::HashLongArrow => "#>>",
433 Operator::AtAt => "@@",
434 Operator::IntegerDivide => "DIV",
435 Operator::HashMinus => "#-",
436 Operator::AtQuestion => "@?",
437 Operator::Question => "?",
438 Operator::QuestionAnd => "?&",
439 Operator::QuestionPipe => "?|",
440 Operator::Colon => ":",
441 };
442 write!(f, "{display}")
443 }
444}