1use std::fmt::Display;
16use std::fmt::Formatter;
17
18use derive_visitor::Drive;
19use derive_visitor::DriveMut;
20use educe::Educe;
21use enum_as_inner::EnumAsInner;
22use ethnum::i256;
23use pratt::Affix;
24use pratt::Associativity;
25
26use super::ColumnRef;
27use super::OrderByExpr;
28use crate::ast::display_decimal_256;
29use crate::ast::quote::QuotedString;
30use crate::ast::write_comma_separated_list;
31use crate::ast::write_dot_separated_list;
32use crate::ast::Identifier;
33use crate::ast::Indirection;
34use crate::ast::Query;
35use crate::span::merge_span;
36use crate::ParseError;
37use crate::Result;
38use crate::Span;
39
40#[derive(Educe, Drive, DriveMut)]
41#[educe(
42 PartialEq(bound = false, attrs = "#[recursive::recursive]"),
43 Clone(bound = false, attrs = "#[recursive::recursive]"),
44 Debug(bound = false, attrs = "#[recursive::recursive]")
45)]
46pub enum Expr {
47 ColumnRef {
49 span: Span,
50 column: ColumnRef,
51 },
52 IsNull {
54 span: Span,
55 expr: Box<Expr>,
56 not: bool,
57 },
58 IsDistinctFrom {
60 span: Span,
61 left: Box<Expr>,
62 right: Box<Expr>,
63 not: bool,
64 },
65 InList {
67 span: Span,
68 expr: Box<Expr>,
69 list: Vec<Expr>,
70 not: bool,
71 },
72 InSubquery {
74 span: Span,
75 expr: Box<Expr>,
76 subquery: Box<Query>,
77 not: bool,
78 },
79 LikeSubquery {
81 span: Span,
82 expr: Box<Expr>,
83 subquery: Box<Query>,
84 modifier: SubqueryModifier,
85 escape: Option<String>,
86 },
87 LikeAnyWithEscape {
89 span: Span,
90 left: Box<Expr>,
91 right: Box<Expr>,
92 escape: String,
93 },
94 LikeWithEscape {
96 span: Span,
97 left: Box<Expr>,
98 right: Box<Expr>,
99 is_not: bool,
100 escape: String,
101 },
102 Between {
104 span: Span,
105 expr: Box<Expr>,
106 low: Box<Expr>,
107 high: Box<Expr>,
108 not: bool,
109 },
110 BinaryOp {
112 span: Span,
113 op: BinaryOperator,
114 left: Box<Expr>,
115 right: Box<Expr>,
116 },
117 JsonOp {
119 span: Span,
120 op: JsonOperator,
121 left: Box<Expr>,
122 right: Box<Expr>,
123 },
124 UnaryOp {
126 span: Span,
127 op: UnaryOperator,
128 expr: Box<Expr>,
129 },
130 Cast {
132 span: Span,
133 expr: Box<Expr>,
134 target_type: TypeName,
135 pg_style: bool,
136 },
137 TryCast {
139 span: Span,
140 expr: Box<Expr>,
141 target_type: TypeName,
142 },
143 Extract {
145 span: Span,
146 kind: IntervalKind,
147 expr: Box<Expr>,
148 },
149 DatePart {
151 span: Span,
152 kind: IntervalKind,
153 expr: Box<Expr>,
154 },
155 Position {
157 span: Span,
158 substr_expr: Box<Expr>,
159 str_expr: Box<Expr>,
160 },
161 Substring {
163 span: Span,
164 expr: Box<Expr>,
165 substring_from: Box<Expr>,
166 substring_for: Option<Box<Expr>>,
167 },
168 Trim {
172 span: Span,
173 expr: Box<Expr>,
174 trim_where: Option<(TrimWhere, Box<Expr>)>,
176 },
177 Literal {
179 span: Span,
180 value: Literal,
181 },
182 CountAll {
184 span: Span,
185 qualified: Vec<Indirection>,
186 window: Option<Window>,
187 },
188 Tuple {
190 span: Span,
191 exprs: Vec<Expr>,
192 },
193 FunctionCall {
195 span: Span,
196 func: FunctionCall,
197 },
198 Case {
200 span: Span,
201 operand: Option<Box<Expr>>,
202 conditions: Vec<Expr>,
203 results: Vec<Expr>,
204 else_result: Option<Box<Expr>>,
205 },
206 Exists {
208 span: Span,
209 not: bool,
211 subquery: Box<Query>,
212 },
213 Subquery {
215 span: Span,
216 modifier: Option<SubqueryModifier>,
217 subquery: Box<Query>,
218 },
219 MapAccess {
221 span: Span,
222 expr: Box<Expr>,
223 accessor: MapAccessor,
224 },
225 Array {
227 span: Span,
228 exprs: Vec<Expr>,
229 },
230 Map {
232 span: Span,
233 kvs: Vec<(Literal, Expr)>,
234 },
235 Interval {
237 span: Span,
238 expr: Box<Expr>,
239 unit: IntervalKind,
240 },
241 DateAdd {
242 span: Span,
243 unit: IntervalKind,
244 interval: Box<Expr>,
245 date: Box<Expr>,
246 },
247 DateDiff {
248 span: Span,
249 unit: IntervalKind,
250 date_start: Box<Expr>,
251 date_end: Box<Expr>,
252 },
253 DateBetween {
254 span: Span,
255 unit: IntervalKind,
256 date_start: Box<Expr>,
257 date_end: Box<Expr>,
258 },
259 DateSub {
260 span: Span,
261 unit: IntervalKind,
262 interval: Box<Expr>,
263 date: Box<Expr>,
264 },
265 DateTrunc {
266 span: Span,
267 unit: IntervalKind,
268 date: Box<Expr>,
269 },
270 LastDay {
271 span: Span,
272 unit: IntervalKind,
273 date: Box<Expr>,
274 },
275 PreviousDay {
276 span: Span,
277 unit: Weekday,
278 date: Box<Expr>,
279 },
280 NextDay {
281 span: Span,
282 unit: Weekday,
283 date: Box<Expr>,
284 },
285 Hole {
286 span: Span,
287 name: String,
288 },
289 Placeholder {
290 span: Span,
291 },
292}
293
294impl Expr {
295 pub fn span(&self) -> Span {
296 match self {
297 Expr::ColumnRef { span, .. }
298 | Expr::IsNull { span, .. }
299 | Expr::IsDistinctFrom { span, .. }
300 | Expr::InList { span, .. }
301 | Expr::InSubquery { span, .. }
302 | Expr::LikeSubquery { span, .. }
303 | Expr::LikeAnyWithEscape { span, .. }
304 | Expr::LikeWithEscape { span, .. }
305 | Expr::Between { span, .. }
306 | Expr::BinaryOp { span, .. }
307 | Expr::JsonOp { span, .. }
308 | Expr::UnaryOp { span, .. }
309 | Expr::Cast { span, .. }
310 | Expr::TryCast { span, .. }
311 | Expr::Extract { span, .. }
312 | Expr::DatePart { span, .. }
313 | Expr::Position { span, .. }
314 | Expr::Substring { span, .. }
315 | Expr::Trim { span, .. }
316 | Expr::Literal { span, .. }
317 | Expr::CountAll { span, .. }
318 | Expr::Tuple { span, .. }
319 | Expr::FunctionCall { span, .. }
320 | Expr::Case { span, .. }
321 | Expr::Exists { span, .. }
322 | Expr::Subquery { span, .. }
323 | Expr::MapAccess { span, .. }
324 | Expr::Array { span, .. }
325 | Expr::Map { span, .. }
326 | Expr::Interval { span, .. }
327 | Expr::DateAdd { span, .. }
328 | Expr::DateDiff { span, .. }
329 | Expr::DateBetween { span, .. }
330 | Expr::DateSub { span, .. }
331 | Expr::DateTrunc { span, .. }
332 | Expr::LastDay { span, .. }
333 | Expr::PreviousDay { span, .. }
334 | Expr::NextDay { span, .. }
335 | Expr::Hole { span, .. }
336 | Expr::Placeholder { span } => *span,
337 }
338 }
339
340 pub fn whole_span(&self) -> Span {
341 match self {
342 Expr::ColumnRef { span, .. } => *span,
343 Expr::IsNull { span, expr, .. } => merge_span(*span, expr.whole_span()),
344 Expr::IsDistinctFrom {
345 span, left, right, ..
346 } => merge_span(merge_span(*span, left.whole_span()), right.whole_span()),
347 Expr::InList {
348 span, expr, list, ..
349 } => {
350 let mut span = merge_span(*span, expr.whole_span());
351 for item in list {
352 span = merge_span(span, item.whole_span());
353 }
354 span
355 }
356 Expr::InSubquery {
357 span,
358 expr,
359 subquery,
360 ..
361 }
362 | Expr::LikeSubquery {
363 span,
364 expr,
365 subquery,
366 ..
367 } => merge_span(merge_span(*span, expr.whole_span()), subquery.span),
368 Expr::Between {
369 span,
370 expr,
371 low,
372 high,
373 ..
374 } => merge_span(
375 merge_span(*span, expr.whole_span()),
376 merge_span(low.whole_span(), high.whole_span()),
377 ),
378 Expr::BinaryOp {
379 span, left, right, ..
380 }
381 | Expr::LikeWithEscape {
382 span, left, right, ..
383 }
384 | Expr::LikeAnyWithEscape {
385 span, left, right, ..
386 } => merge_span(merge_span(*span, left.whole_span()), right.whole_span()),
387 Expr::JsonOp {
388 span, left, right, ..
389 } => merge_span(merge_span(*span, left.whole_span()), right.whole_span()),
390 Expr::UnaryOp { span, expr, .. } => merge_span(*span, expr.whole_span()),
391 Expr::Cast { span, expr, .. } => merge_span(*span, expr.whole_span()),
392 Expr::TryCast { span, expr, .. } => merge_span(*span, expr.whole_span()),
393 Expr::Extract { span, expr, .. } => merge_span(*span, expr.whole_span()),
394 Expr::DatePart { span, expr, .. } => merge_span(*span, expr.whole_span()),
395 Expr::Position {
396 span,
397 substr_expr,
398 str_expr,
399 ..
400 } => merge_span(
401 merge_span(*span, substr_expr.whole_span()),
402 str_expr.whole_span(),
403 ),
404 Expr::Substring {
405 span,
406 expr,
407 substring_from,
408 substring_for,
409 ..
410 } => {
411 let mut span = merge_span(
412 merge_span(*span, expr.whole_span()),
413 substring_from.whole_span(),
414 );
415 if let Some(substring_for) = substring_for {
416 span = merge_span(span, substring_for.whole_span());
417 }
418 span
419 }
420 Expr::Trim { span, expr, .. } => merge_span(*span, expr.whole_span()),
421 Expr::Literal { span, .. } => *span,
422 Expr::CountAll { span, .. } => *span,
423 Expr::Tuple { span, exprs } => {
424 let mut span = *span;
425 for expr in exprs {
426 span = merge_span(span, expr.whole_span());
427 }
428 span
429 }
430 Expr::FunctionCall { span, .. } => *span,
431 Expr::Case {
432 span,
433 operand,
434 conditions,
435 results,
436 else_result,
437 } => {
438 let mut span = *span;
439 if let Some(operand) = operand {
440 span = merge_span(span, operand.whole_span());
441 }
442 for (cond, res) in conditions.iter().zip(results) {
443 span = merge_span(merge_span(span, cond.whole_span()), res.whole_span());
444 }
445 if let Some(else_result) = else_result {
446 span = merge_span(span, else_result.whole_span());
447 }
448 span
449 }
450 Expr::Exists { span, subquery, .. } => merge_span(*span, subquery.span),
451 Expr::Subquery { span, subquery, .. } => merge_span(*span, subquery.span),
452 Expr::MapAccess { span, expr, .. } => merge_span(*span, expr.whole_span()),
453 Expr::Array { span, exprs } => {
454 let mut span = *span;
455 for expr in exprs {
456 span = merge_span(span, expr.whole_span());
457 }
458 span
459 }
460 Expr::Map { span, kvs } => {
461 let mut span = *span;
462 for (_, v) in kvs {
463 span = merge_span(span, v.whole_span());
464 }
465 span
466 }
467 Expr::Interval { span, expr, .. } => merge_span(*span, expr.whole_span()),
468 Expr::DateAdd {
469 span,
470 interval,
471 date,
472 ..
473 } => merge_span(merge_span(*span, interval.whole_span()), date.whole_span()),
474 Expr::DateDiff {
475 span,
476 date_start,
477 date_end,
478 ..
479 } => merge_span(
480 merge_span(*span, date_start.whole_span()),
481 date_end.whole_span(),
482 ),
483 Expr::DateBetween {
484 span,
485 date_start,
486 date_end,
487 ..
488 } => merge_span(
489 merge_span(*span, date_start.whole_span()),
490 date_end.whole_span(),
491 ),
492 Expr::DateSub {
493 span,
494 interval,
495 date,
496 ..
497 } => merge_span(merge_span(*span, interval.whole_span()), date.whole_span()),
498 Expr::DateTrunc { span, date, .. } => merge_span(*span, date.whole_span()),
499 Expr::LastDay { span, date, .. } => merge_span(*span, date.whole_span()),
500 Expr::PreviousDay { span, date, .. } => merge_span(*span, date.whole_span()),
501 Expr::NextDay { span, date, .. } => merge_span(*span, date.whole_span()),
502 Expr::Hole { span, .. } => *span,
503 Expr::Placeholder { span } => *span,
504 }
505 }
506
507 pub fn all_function_like_syntaxes() -> &'static [&'static str] {
508 &[
509 "CAST",
510 "TRY_CAST",
511 "EXTRACT",
512 "DATE_PART",
513 "POSITION",
514 "SUBSTRING",
515 "TRIM",
516 "DATE_ADD",
517 "DATE_DIFF",
518 "DATE_SUB",
519 "DATE_TRUNC",
520 ]
521 }
522}
523
524impl Display for Expr {
525 fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
526 fn needs_parentheses(parent: Option<Affix>, child: Affix, is_left: bool) -> bool {
527 match (parent, child) {
528 (Some(Affix::Infix(parent_prec, parent_assoc)), Affix::Infix(child_prec, _)) => {
529 if parent_prec < child_prec {
530 return false;
531 }
532 if parent_prec > child_prec {
533 return true;
534 }
535 if matches!(parent_assoc, Associativity::Left) && !is_left {
536 return true;
537 }
538 if matches!(parent_assoc, Associativity::Right) && is_left {
539 return true;
540 }
541 }
542 (
543 Some(
544 Affix::Infix(parent_prec, _)
545 | Affix::Prefix(parent_prec)
546 | Affix::Postfix(parent_prec),
547 ),
548 Affix::Infix(child_prec, _)
549 | Affix::Prefix(child_prec)
550 | Affix::Postfix(child_prec),
551 ) => {
552 return parent_prec > child_prec;
553 }
554 _ => (),
555 }
556 false
557 }
558
559 #[recursive::recursive]
560 fn write_expr(
561 expr: &Expr,
562 parent: Option<Affix>,
563 is_left: bool,
564 f: &mut Formatter,
565 ) -> std::fmt::Result {
566 let affix = expr.affix();
567 let need_paren = needs_parentheses(parent, affix, is_left);
568
569 if need_paren {
570 write!(f, "(")?;
571 }
572
573 match expr {
574 Expr::ColumnRef { column, .. } => {
575 if f.alternate() {
576 write!(f, "{column:#}")?;
577 } else {
578 write!(f, "{column}")?;
579 }
580 }
581 Expr::IsNull { expr, not, .. } => {
582 write_expr(expr, Some(affix), true, f)?;
583 write!(f, " IS")?;
584 if *not {
585 write!(f, " NOT")?;
586 }
587 write!(f, " NULL")?;
588 }
589 Expr::IsDistinctFrom {
590 left, right, not, ..
591 } => {
592 write_expr(left, Some(affix), true, f)?;
593 write!(f, " IS")?;
594 if *not {
595 write!(f, " NOT")?;
596 }
597 write!(f, " DISTINCT FROM ")?;
598 write_expr(right, Some(affix), true, f)?;
599 }
600
601 Expr::InList {
602 expr, list, not, ..
603 } => {
604 write_expr(expr, Some(affix), true, f)?;
605 if *not {
606 write!(f, " NOT")?;
607 }
608 write!(f, " IN(")?;
609 write_comma_separated_list(f, list)?;
610 write!(f, ")")?;
611 }
612 Expr::InSubquery {
613 expr,
614 subquery,
615 not,
616 ..
617 } => {
618 write_expr(expr, Some(affix), true, f)?;
619 if *not {
620 write!(f, " NOT")?;
621 }
622 write!(f, " IN({subquery})")?;
623 }
624 Expr::LikeSubquery {
625 expr,
626 subquery,
627 modifier,
628 escape,
629 ..
630 } => {
631 write_expr(expr, Some(affix), true, f)?;
632 write!(f, " LIKE {modifier} ({subquery})")?;
633 if let Some(escape) = escape {
634 write!(f, " ESCAPE '{escape}'")?;
635 }
636 }
637 Expr::LikeAnyWithEscape {
638 left,
639 right,
640 escape,
641 ..
642 } => {
643 write_expr(left, Some(affix), true, f)?;
644 write!(f, " LIKE ANY {right} ESCAPE '{escape}'")?;
645 }
646 Expr::LikeWithEscape {
647 left,
648 right,
649 is_not,
650 escape,
651 ..
652 } => {
653 write_expr(left, Some(affix), true, f)?;
654 if *is_not {
655 write!(f, " NOT")?;
656 }
657 write!(f, " LIKE {right} ESCAPE '{escape}'")?;
658 }
659 Expr::Between {
660 expr,
661 low,
662 high,
663 not,
664 ..
665 } => {
666 write_expr(expr, Some(affix), true, f)?;
667 if *not {
668 write!(f, " NOT")?;
669 }
670 write!(f, " BETWEEN {low} AND {high}")?;
671 }
672 Expr::UnaryOp { op, expr, .. } => {
673 match op {
674 UnaryOperator::Factorial => {
676 write_expr(expr, Some(affix), true, f)?;
677 write!(f, " {op}")?;
678 }
679 _ => {
680 write!(f, "{op} ")?;
681 write_expr(expr, Some(affix), true, f)?;
682 }
683 }
684 }
685 Expr::BinaryOp {
686 op, left, right, ..
687 } => {
688 write_expr(left, Some(affix), true, f)?;
689 write!(f, " {op} ")?;
690 write_expr(right, Some(affix), false, f)?;
691 }
692 Expr::JsonOp {
693 op, left, right, ..
694 } => {
695 write_expr(left, Some(affix), true, f)?;
696 write!(f, " {op} ")?;
697 write_expr(right, Some(affix), true, f)?;
698 }
699 Expr::Cast {
700 expr,
701 target_type,
702 pg_style,
703 ..
704 } => {
705 if *pg_style {
706 write_expr(expr, Some(affix), true, f)?;
707 write!(f, "::{target_type}")?;
708 } else {
709 write!(f, "CAST({expr} AS {target_type})")?;
710 }
711 }
712 Expr::TryCast {
713 expr, target_type, ..
714 } => {
715 write!(f, "TRY_CAST({expr} AS {target_type})")?;
716 }
717 Expr::Extract {
718 kind: field, expr, ..
719 } => {
720 write!(f, "EXTRACT({field} FROM {expr})")?;
721 }
722 Expr::DatePart {
723 kind: field, expr, ..
724 } => {
725 write!(f, "DATE_PART({field}, {expr})")?;
726 }
727 Expr::Position {
728 substr_expr,
729 str_expr,
730 ..
731 } => {
732 write!(f, "POSITION({substr_expr} IN {str_expr})")?;
733 }
734 Expr::Substring {
735 expr,
736 substring_from,
737 substring_for,
738 ..
739 } => {
740 write!(f, "SUBSTRING({expr} FROM {substring_from}")?;
741 if let Some(substring_for) = substring_for {
742 write!(f, " FOR {substring_for}")?;
743 }
744 write!(f, ")")?;
745 }
746 Expr::Trim {
747 expr, trim_where, ..
748 } => {
749 write!(f, "TRIM(")?;
750 if let Some((trim_where, trim_str)) = trim_where {
751 write!(f, "{trim_where} {trim_str} FROM ")?;
752 }
753 write!(f, "{expr})")?;
754 }
755 Expr::Literal { value, .. } => {
756 write!(f, "{value}")?;
757 }
758 Expr::CountAll {
759 window, qualified, ..
760 } => {
761 write!(f, "COUNT(")?;
762 write_dot_separated_list(f, qualified)?;
763 write!(f, ")")?;
764 if let Some(window) = window {
765 write!(f, " OVER {window}")?;
766 }
767 }
768 Expr::Tuple { exprs, .. } => {
769 write!(f, "(")?;
770 write_comma_separated_list(f, exprs)?;
771 if exprs.len() == 1 {
772 write!(f, ",")?;
773 }
774 write!(f, ")")?;
775 }
776 Expr::FunctionCall { func, .. } => {
777 write!(f, "{func}")?;
778 }
779 Expr::Case {
780 operand,
781 conditions,
782 results,
783 else_result,
784 ..
785 } => {
786 write!(f, "CASE")?;
787 if let Some(op) = operand {
788 write!(f, " {op} ")?;
789 }
790 for (cond, res) in conditions.iter().zip(results) {
791 write!(f, " WHEN {cond} THEN {res}")?;
792 }
793 if let Some(el) = else_result {
794 write!(f, " ELSE {el}")?;
795 }
796 write!(f, " END")?;
797 }
798 Expr::Exists { not, subquery, .. } => {
799 if *not {
800 write!(f, "NOT ")?;
801 }
802 write!(f, "EXISTS ({subquery})")?;
803 }
804 Expr::Subquery {
805 subquery, modifier, ..
806 } => {
807 if let Some(m) = modifier {
808 write!(f, "{m} ")?;
809 }
810 write!(f, "({subquery})")?;
811 }
812 Expr::MapAccess { expr, accessor, .. } => {
813 write_expr(expr, Some(affix), true, f)?;
814 match accessor {
815 MapAccessor::Bracket { key } => write!(f, "[{key}]")?,
816 MapAccessor::DotNumber { key } => write!(f, ".{key}")?,
817 MapAccessor::Colon { key } => write!(f, ":{key}")?,
818 }
819 }
820 Expr::Array { exprs, .. } => {
821 write!(f, "[")?;
822 write_comma_separated_list(f, exprs)?;
823 write!(f, "]")?;
824 }
825 Expr::Map { kvs, .. } => {
826 write!(f, "{{")?;
827 for (i, (k, v)) in kvs.iter().enumerate() {
828 if i > 0 {
829 write!(f, ",")?;
830 }
831 write!(f, "{k}:{v}")?;
832 }
833 write!(f, "}}")?;
834 }
835 Expr::Interval { expr, unit, .. } => {
836 write!(f, "INTERVAL {expr} {unit}")?;
837 }
838 Expr::DateAdd {
839 unit,
840 interval,
841 date,
842 ..
843 } => {
844 write!(f, "DATE_ADD({unit}, {interval}, {date})")?;
845 }
846 Expr::DateDiff {
847 unit,
848 date_start,
849 date_end,
850 ..
851 } => {
852 write!(f, "DATE_DIFF({unit}, {date_start}, {date_end})")?;
853 }
854 Expr::DateBetween {
855 unit,
856 date_start,
857 date_end,
858 ..
859 } => {
860 write!(f, "DATE_BETWEEN({unit}, {date_start}, {date_end})")?;
861 }
862 Expr::DateSub {
863 unit,
864 interval,
865 date,
866 ..
867 } => {
868 write!(f, "DATE_SUB({unit}, {interval}, {date})")?;
869 }
870 Expr::DateTrunc { unit, date, .. } => {
871 write!(f, "DATE_TRUNC({unit}, {date})")?;
872 }
873 Expr::LastDay { unit, date, .. } => {
874 write!(f, "LAST_DAY({date}, {unit})")?;
875 }
876 Expr::PreviousDay { unit, date, .. } => {
877 write!(f, "PREVIOUS_DAY({date}, {unit})")?;
878 }
879 Expr::NextDay { unit, date, .. } => {
880 write!(f, "NEXT_DAY({date}, {unit})")?;
881 }
882 Expr::Hole { name, .. } => {
883 write!(f, ":{name}")?;
884 }
885 Expr::Placeholder { .. } => {
886 write!(f, "?")?;
887 }
888 }
889
890 if need_paren {
891 write!(f, ")")?;
892 }
893
894 Ok(())
895 }
896
897 write_expr(self, None, true, f)
898 }
899}
900
901#[derive(Debug, Copy, Clone, PartialEq, Eq, Drive, DriveMut)]
902pub enum Weekday {
903 Sunday,
904 Monday,
905 Tuesday,
906 Wednesday,
907 Thursday,
908 Friday,
909 Saturday,
910}
911
912impl Display for Weekday {
913 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
914 f.write_str(match self {
915 Weekday::Sunday => "SUNDAY",
916 Weekday::Monday => "MONDAY",
917 Weekday::Tuesday => "TUESDAY",
918 Weekday::Wednesday => "WEDNESDAY",
919 Weekday::Thursday => "THURSDAY",
920 Weekday::Friday => "FRIDAY",
921 Weekday::Saturday => "SATURDAY",
922 })
923 }
924}
925
926#[derive(Debug, Copy, Clone, PartialEq, Eq, Drive, DriveMut)]
927pub enum IntervalKind {
928 ISOYear,
929 Year,
930 Quarter,
931 Month,
932 Day,
933 Hour,
934 Minute,
935 Second,
936 Doy,
937 Week,
938 ISOWeek,
939 Dow,
940 Epoch,
941 MicroSecond,
942 ISODow,
943 YearWeek,
944 Millennium,
945 UnknownIntervalKind,
946}
947
948impl Display for IntervalKind {
949 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
950 f.write_str(match self {
951 IntervalKind::ISOYear => "ISOYEAR",
952 IntervalKind::Year => "YEAR",
953 IntervalKind::Quarter => "QUARTER",
954 IntervalKind::Month => "MONTH",
955 IntervalKind::Day => "DAY",
956 IntervalKind::Hour => "HOUR",
957 IntervalKind::Minute => "MINUTE",
958 IntervalKind::Second => "SECOND",
959 IntervalKind::Doy => "DOY",
960 IntervalKind::Dow => "DOW",
961 IntervalKind::ISODow => "ISODOW",
962 IntervalKind::YearWeek => "YEARWEEK",
963 IntervalKind::Millennium => "MILLENNIUM",
964 IntervalKind::Week => "WEEK",
965 IntervalKind::ISOWeek => "ISOWEEK",
966 IntervalKind::Epoch => "EPOCH",
967 IntervalKind::MicroSecond => "MICROSECOND",
968 IntervalKind::UnknownIntervalKind => "UNKNOWNINTERVALKIND",
969 })
970 }
971}
972
973#[derive(Debug, Clone, PartialEq, Eq, Drive, DriveMut)]
974pub enum SubqueryModifier {
975 Any,
976 All,
977 Some,
978}
979
980impl Display for SubqueryModifier {
981 fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
982 match self {
983 SubqueryModifier::Any => write!(f, "ANY"),
984 SubqueryModifier::All => write!(f, "ALL"),
985 SubqueryModifier::Some => write!(f, "SOME"),
986 }
987 }
988}
989
990#[derive(Debug, Clone, PartialEq, Drive, DriveMut)]
991pub enum Literal {
992 UInt64(u64),
993 Float64(f64),
994 Decimal256 {
995 #[drive(skip)]
996 value: i256,
997 precision: u8,
998 scale: u8,
999 },
1000 String(String),
1002 Boolean(bool),
1003 Null,
1004}
1005
1006impl Literal {
1007 pub fn as_double(&self) -> Result<f64> {
1008 match self {
1009 Literal::UInt64(val) => Ok(*val as f64),
1010 Literal::Float64(val) => Ok(*val),
1011 Literal::Decimal256 { value, scale, .. } => {
1012 let div = 10_f64.powi(*scale as i32);
1013 Ok(value.as_f64() / div)
1014 }
1015 _ => Err(ParseError(
1016 None,
1017 format!("Cannot convert {:?} to double", self),
1018 )),
1019 }
1020 }
1021}
1022
1023impl Display for Literal {
1024 fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
1025 match self {
1026 Literal::UInt64(val) => {
1027 write!(f, "{val}")
1028 }
1029 Literal::Decimal256 { value, scale, .. } => {
1030 write!(f, "{}", display_decimal_256(*value, *scale))
1031 }
1032 Literal::Float64(val) => {
1033 if val.is_infinite() {
1034 if val.is_sign_positive() {
1035 write!(f, "'+INFINITY'::FLOAT64")
1036 } else {
1037 write!(f, "'-INFINITY'::FLOAT64")
1038 }
1039 } else if val.is_nan() {
1040 write!(f, "'NaN'::FLOAT64")
1041 } else {
1042 write!(f, "{val}")
1043 }
1044 }
1045 Literal::String(val) => {
1046 write!(f, "{}", QuotedString(val, '\''))
1047 }
1048 Literal::Boolean(val) => {
1049 if *val {
1050 write!(f, "TRUE")
1051 } else {
1052 write!(f, "FALSE")
1053 }
1054 }
1055 Literal::Null => {
1056 write!(f, "NULL")
1057 }
1058 }
1059 }
1060}
1061
1062#[derive(Debug, Clone, PartialEq, Drive, DriveMut)]
1063pub struct FunctionCall {
1064 pub distinct: bool,
1066 pub name: Identifier,
1067 pub args: Vec<Expr>,
1068 pub params: Vec<Expr>,
1069 pub order_by: Vec<OrderByExpr>,
1070 pub window: Option<WindowDesc>,
1071 pub lambda: Option<Lambda>,
1072}
1073
1074impl Default for FunctionCall {
1075 fn default() -> Self {
1076 Self {
1077 distinct: false,
1078 name: Identifier::from_name(None, ""),
1079 args: vec![],
1080 params: vec![],
1081 order_by: vec![],
1082 window: None,
1083 lambda: None,
1084 }
1085 }
1086}
1087
1088impl Display for FunctionCall {
1089 fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
1090 let FunctionCall {
1091 distinct,
1092 name,
1093 args,
1094 params,
1095 order_by,
1096 window,
1097 lambda,
1098 } = self;
1099 write!(f, "{name}")?;
1100 if !params.is_empty() {
1101 write!(f, "(")?;
1102 write_comma_separated_list(f, params)?;
1103 write!(f, ")")?;
1104 }
1105 write!(f, "(")?;
1106 if *distinct {
1107 write!(f, "DISTINCT ")?;
1108 }
1109 write_comma_separated_list(f, args)?;
1110 if let Some(lambda) = lambda {
1111 write!(f, ", {lambda}")?;
1112 }
1113 write!(f, ")")?;
1114
1115 if !order_by.is_empty() {
1116 write!(f, " WITHIN GROUP ( ORDER BY ")?;
1117 write_comma_separated_list(f, &self.order_by)?;
1118 write!(f, " )")?;
1119 }
1120 if let Some(window) = window {
1121 if let Some(ignore_null) = window.ignore_nulls {
1122 if ignore_null {
1123 write!(f, " IGNORE NULLS")?;
1124 } else {
1125 write!(f, " RESPECT NULLS")?;
1126 }
1127 }
1128 write!(f, " OVER {}", window.window)?;
1129 }
1130 Ok(())
1131 }
1132}
1133
1134#[derive(Debug, Clone, PartialEq, Drive, DriveMut)]
1136pub enum MapAccessor {
1137 Bracket { key: Box<Expr> },
1139 DotNumber { key: u64 },
1141 Colon { key: Identifier },
1143}
1144
1145#[derive(Debug, Clone, PartialEq, Drive, DriveMut)]
1146pub enum TypeName {
1147 Boolean,
1148 UInt8,
1149 UInt16,
1150 UInt32,
1151 UInt64,
1152 Int8,
1153 Int16,
1154 Int32,
1155 Int64,
1156 Float32,
1157 Float64,
1158 Decimal {
1159 precision: u8,
1160 scale: u8,
1161 },
1162 Date,
1163 Timestamp,
1164 Binary,
1165 String,
1166 Array(Box<TypeName>),
1167 Map {
1168 key_type: Box<TypeName>,
1169 val_type: Box<TypeName>,
1170 },
1171 Bitmap,
1172 Tuple {
1173 fields_name: Option<Vec<Identifier>>,
1174 fields_type: Vec<TypeName>,
1175 },
1176 Variant,
1177 Geometry,
1178 Geography,
1179 Interval,
1180 Vector(u64),
1181 Nullable(Box<TypeName>),
1182 NotNull(Box<TypeName>),
1183}
1184
1185impl TypeName {
1186 pub fn is_nullable(&self) -> bool {
1187 matches!(self, TypeName::Nullable(_))
1188 }
1189
1190 pub fn wrap_nullable(self) -> Self {
1191 if !self.is_nullable() {
1192 Self::Nullable(Box::new(self))
1193 } else {
1194 self
1195 }
1196 }
1197
1198 pub fn wrap_not_null(self) -> Self {
1199 match self {
1200 Self::NotNull(_) => self,
1201 _ => Self::NotNull(Box::new(self)),
1202 }
1203 }
1204}
1205
1206impl Display for TypeName {
1207 fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
1208 match self {
1209 TypeName::Boolean => {
1210 write!(f, "BOOLEAN")?;
1211 }
1212 TypeName::UInt8 => {
1213 write!(f, "UInt8")?;
1214 }
1215 TypeName::UInt16 => {
1216 write!(f, "UInt16")?;
1217 }
1218 TypeName::UInt32 => {
1219 write!(f, "UInt32")?;
1220 }
1221 TypeName::UInt64 => {
1222 write!(f, "UInt64")?;
1223 }
1224 TypeName::Int8 => {
1225 write!(f, "Int8")?;
1226 }
1227 TypeName::Int16 => {
1228 write!(f, "Int16")?;
1229 }
1230 TypeName::Int32 => {
1231 write!(f, "Int32")?;
1232 }
1233 TypeName::Int64 => {
1234 write!(f, "Int64")?;
1235 }
1236 TypeName::Float32 => {
1237 write!(f, "Float32")?;
1238 }
1239 TypeName::Float64 => {
1240 write!(f, "Float64")?;
1241 }
1242 TypeName::Decimal { precision, scale } => {
1243 write!(f, "Decimal({}, {})", precision, scale)?;
1244 }
1245 TypeName::Date => {
1246 write!(f, "DATE")?;
1247 }
1248 TypeName::Timestamp => {
1249 write!(f, "TIMESTAMP")?;
1250 }
1251 TypeName::Binary => {
1252 write!(f, "BINARY")?;
1253 }
1254 TypeName::String => {
1255 write!(f, "STRING")?;
1256 }
1257 TypeName::Array(ty) => {
1258 write!(f, "ARRAY({})", ty)?;
1259 }
1260 TypeName::Map { key_type, val_type } => {
1261 write!(f, "MAP({}, {})", key_type, val_type)?;
1262 }
1263 TypeName::Bitmap => {
1264 write!(f, "BITMAP")?;
1265 }
1266 TypeName::Tuple {
1267 fields_name,
1268 fields_type,
1269 } => {
1270 write!(f, "TUPLE(")?;
1271 let mut first = true;
1272 match fields_name {
1273 Some(fields_name) => {
1274 for (name, ty) in fields_name.iter().zip(fields_type.iter()) {
1275 if !first {
1276 write!(f, ", ")?;
1277 }
1278 first = false;
1279 write!(f, "{} {}", name, ty)?;
1280 }
1281 }
1282 None => {
1283 for ty in fields_type.iter() {
1284 if !first {
1285 write!(f, ", ")?;
1286 }
1287 first = false;
1288 write!(f, "{}", ty)?;
1289 }
1290 }
1291 }
1292 write!(f, ")")?;
1293 }
1294 TypeName::Variant => {
1295 write!(f, "VARIANT")?;
1296 }
1297 TypeName::Geometry => {
1298 write!(f, "GEOMETRY")?;
1299 }
1300 TypeName::Geography => {
1301 write!(f, "GEOGRAPHY")?;
1302 }
1303 TypeName::Nullable(ty) => {
1304 write!(f, "{} NULL", ty)?;
1305 }
1306 TypeName::NotNull(ty) => {
1307 write!(f, "{} NOT NULL", ty)?;
1308 }
1309 TypeName::Interval => {
1310 write!(f, "INTERVAL")?;
1311 }
1312 TypeName::Vector(dimension) => {
1313 write!(f, "VECTOR({dimension})")?;
1314 }
1315 }
1316 Ok(())
1317 }
1318}
1319
1320#[derive(Debug, Clone, PartialEq, Eq, Drive, DriveMut)]
1321pub enum TrimWhere {
1322 Both,
1323 Leading,
1324 Trailing,
1325}
1326
1327impl Display for TrimWhere {
1328 fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
1329 f.write_str(match self {
1330 TrimWhere::Both => "BOTH",
1331 TrimWhere::Leading => "LEADING",
1332 TrimWhere::Trailing => "TRAILING",
1333 })
1334 }
1335}
1336
1337#[derive(Debug, Clone, PartialEq, Drive, DriveMut)]
1338pub struct WindowDesc {
1339 pub ignore_nulls: Option<bool>,
1340 pub window: Window,
1341}
1342
1343#[derive(Debug, Clone, PartialEq, EnumAsInner, Drive, DriveMut)]
1344pub enum Window {
1345 WindowReference(WindowRef),
1346 WindowSpec(WindowSpec),
1347}
1348
1349impl Display for Window {
1350 fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
1351 match *self {
1352 Window::WindowReference(ref window_ref) => write!(f, "{}", window_ref),
1353 Window::WindowSpec(ref window_spec) => write!(f, "{}", window_spec),
1354 }
1355 }
1356}
1357
1358#[derive(Debug, Clone, PartialEq, Drive, DriveMut)]
1359pub struct WindowDefinition {
1360 pub name: Identifier,
1361 pub spec: WindowSpec,
1362}
1363
1364impl Display for WindowDefinition {
1365 fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
1366 write!(f, "{} AS {}", self.name, self.spec)
1367 }
1368}
1369
1370#[derive(Debug, Clone, PartialEq, Drive, DriveMut)]
1371pub struct WindowRef {
1372 pub window_name: Identifier,
1373}
1374
1375impl Display for WindowRef {
1376 fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
1377 write!(f, "{}", self.window_name)
1378 }
1379}
1380
1381#[derive(Debug, Clone, PartialEq, Drive, DriveMut)]
1382pub struct WindowSpec {
1383 pub existing_window_name: Option<Identifier>,
1384 pub partition_by: Vec<Expr>,
1385 pub order_by: Vec<OrderByExpr>,
1386 pub window_frame: Option<WindowFrame>,
1387}
1388
1389impl Display for WindowSpec {
1390 fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
1391 write!(f, "(")?;
1392
1393 let mut write = false;
1394
1395 if let Some(existing_window_name) = &self.existing_window_name {
1396 write!(f, "{existing_window_name}")?;
1397 write = true;
1398 }
1399
1400 if !self.partition_by.is_empty() {
1401 if write {
1402 write!(f, " ")?;
1403 }
1404 write = true;
1405 write!(f, "PARTITION BY ")?;
1406 write_comma_separated_list(f, &self.partition_by)?;
1407 }
1408
1409 if !self.order_by.is_empty() {
1410 if write {
1411 write!(f, " ")?;
1412 }
1413 write = true;
1414 write!(f, "ORDER BY ")?;
1415 write_comma_separated_list(f, &self.order_by)?;
1416 }
1417
1418 if let Some(frame) = &self.window_frame {
1419 if write {
1420 write!(f, " ")?;
1421 }
1422 match frame.units {
1423 WindowFrameUnits::Rows => {
1424 write!(f, "ROWS")?;
1425 }
1426 WindowFrameUnits::Range => {
1427 write!(f, "RANGE")?;
1428 }
1429 }
1430
1431 let format_frame = |frame: &WindowFrameBound| -> String {
1432 match frame {
1433 WindowFrameBound::CurrentRow => "CURRENT ROW".to_string(),
1434 WindowFrameBound::Preceding(None) => "UNBOUNDED PRECEDING".to_string(),
1435 WindowFrameBound::Following(None) => "UNBOUNDED FOLLOWING".to_string(),
1436 WindowFrameBound::Preceding(Some(n)) => format!("{} PRECEDING", n),
1437 WindowFrameBound::Following(Some(n)) => format!("{} FOLLOWING", n),
1438 }
1439 };
1440 write!(
1441 f,
1442 " BETWEEN {} AND {}",
1443 format_frame(&frame.start_bound),
1444 format_frame(&frame.end_bound)
1445 )?
1446 }
1447 write!(f, ")")?;
1448 Ok(())
1449 }
1450}
1451
1452#[derive(Debug, Clone, PartialEq, Drive, DriveMut)]
1454pub struct WindowFrame {
1455 pub units: WindowFrameUnits,
1456 pub start_bound: WindowFrameBound,
1457 pub end_bound: WindowFrameBound,
1458}
1459
1460#[derive(Debug, Clone, PartialEq, Eq, Hash, EnumAsInner, Drive, DriveMut)]
1461pub enum WindowFrameUnits {
1462 Rows,
1463 Range,
1464}
1465
1466#[derive(Debug, Clone, PartialEq, Drive, DriveMut)]
1468pub enum WindowFrameBound {
1469 CurrentRow,
1471 Preceding(Option<Box<Expr>>),
1473 Following(Option<Box<Expr>>),
1475}
1476
1477#[derive(Debug, Clone, PartialEq, Drive, DriveMut)]
1478pub struct Lambda {
1479 pub params: Vec<Identifier>,
1480 pub expr: Box<Expr>,
1481}
1482
1483impl Display for Lambda {
1484 fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
1485 if self.params.len() == 1 {
1486 write!(f, "{}", self.params[0])?;
1487 } else {
1488 write!(f, "(")?;
1489 write_comma_separated_list(f, self.params.clone())?;
1490 write!(f, ")")?;
1491 }
1492 write!(f, " -> {}", self.expr)?;
1493
1494 Ok(())
1495 }
1496}
1497
1498#[derive(Debug, Clone, PartialEq, Eq, Drive, DriveMut)]
1499pub enum BinaryOperator {
1500 Plus,
1501 Minus,
1502 Multiply,
1503 Div,
1504 Divide,
1505 IntDiv,
1506 Modulo,
1507 StringConcat,
1508 Gt,
1510 Lt,
1512 Gte,
1514 Lte,
1516 Eq,
1517 NotEq,
1518 Caret,
1519 And,
1520 Or,
1521 Xor,
1522 Like(Option<String>),
1523 NotLike(Option<String>),
1524 LikeAny(Option<String>),
1525 Regexp,
1526 RLike,
1527 NotRegexp,
1528 NotRLike,
1529 SoundsLike,
1530 BitwiseOr,
1531 BitwiseAnd,
1532 BitwiseXor,
1533 BitwiseShiftLeft,
1534 BitwiseShiftRight,
1535 CosineDistance,
1536 L1Distance,
1537 L2Distance,
1538}
1539
1540impl BinaryOperator {
1541 pub fn to_contrary(&self) -> Result<Self> {
1542 match &self {
1543 BinaryOperator::Gt => Ok(BinaryOperator::Lte),
1544 BinaryOperator::Lt => Ok(BinaryOperator::Gte),
1545 BinaryOperator::Gte => Ok(BinaryOperator::Lt),
1546 BinaryOperator::Lte => Ok(BinaryOperator::Gt),
1547 BinaryOperator::Eq => Ok(BinaryOperator::NotEq),
1548 BinaryOperator::NotEq => Ok(BinaryOperator::Eq),
1549 _ => Err(ParseError(
1550 None,
1551 format!("Converting {self} to its contrary is not currently supported"),
1552 )),
1553 }
1554 }
1555
1556 pub fn to_func_name(&self) -> String {
1557 match self {
1558 BinaryOperator::StringConcat => "concat".to_string(),
1559 BinaryOperator::BitwiseOr => "bit_or".to_string(),
1560 BinaryOperator::BitwiseAnd => "bit_and".to_string(),
1561 BinaryOperator::BitwiseXor => "bit_xor".to_string(),
1562 BinaryOperator::BitwiseShiftLeft => "bit_shift_left".to_string(),
1563 BinaryOperator::BitwiseShiftRight => "bit_shift_right".to_string(),
1564 BinaryOperator::Caret => "pow".to_string(),
1565 BinaryOperator::CosineDistance => "cosine_distance".to_string(),
1566 BinaryOperator::L1Distance => "l1_distance".to_string(),
1567 BinaryOperator::L2Distance => "l2_distance".to_string(),
1568 BinaryOperator::LikeAny(_) => "like_any".to_string(),
1569 BinaryOperator::Like(_) => "like".to_string(),
1570 _ => {
1571 let name = format!("{:?}", self);
1572 name.to_lowercase()
1573 }
1574 }
1575 }
1576}
1577
1578impl Display for BinaryOperator {
1579 fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
1580 match self {
1581 BinaryOperator::Plus => {
1582 write!(f, "+")
1583 }
1584 BinaryOperator::Minus => {
1585 write!(f, "-")
1586 }
1587 BinaryOperator::Multiply => {
1588 write!(f, "*")
1589 }
1590 BinaryOperator::Div => {
1591 write!(f, "DIV")
1592 }
1593 BinaryOperator::Divide => {
1594 write!(f, "/")
1595 }
1596 BinaryOperator::IntDiv => {
1597 write!(f, "//")
1598 }
1599 BinaryOperator::Modulo => {
1600 write!(f, "%")
1601 }
1602 BinaryOperator::StringConcat => {
1603 write!(f, "||")
1604 }
1605 BinaryOperator::Gt => {
1606 write!(f, ">")
1607 }
1608 BinaryOperator::Lt => {
1609 write!(f, "<")
1610 }
1611 BinaryOperator::Gte => {
1612 write!(f, ">=")
1613 }
1614 BinaryOperator::Lte => {
1615 write!(f, "<=")
1616 }
1617 BinaryOperator::Eq => {
1618 write!(f, "=")
1619 }
1620 BinaryOperator::NotEq => {
1621 write!(f, "<>")
1622 }
1623 BinaryOperator::Caret => {
1624 write!(f, "^")
1625 }
1626 BinaryOperator::And => {
1627 write!(f, "AND")
1628 }
1629 BinaryOperator::Or => {
1630 write!(f, "OR")
1631 }
1632 BinaryOperator::Xor => {
1633 write!(f, "XOR")
1634 }
1635 BinaryOperator::Like(_) => {
1636 write!(f, "LIKE")
1637 }
1638 BinaryOperator::LikeAny(_) => {
1639 write!(f, "LIKE ANY")
1640 }
1641 BinaryOperator::NotLike(_) => {
1642 write!(f, "NOT LIKE")
1643 }
1644 BinaryOperator::Regexp => {
1645 write!(f, "REGEXP")
1646 }
1647 BinaryOperator::RLike => {
1648 write!(f, "RLIKE")
1649 }
1650 BinaryOperator::NotRegexp => {
1651 write!(f, "NOT REGEXP")
1652 }
1653 BinaryOperator::NotRLike => {
1654 write!(f, "NOT RLIKE")
1655 }
1656 BinaryOperator::SoundsLike => {
1657 write!(f, "SOUNDS LIKE")
1658 }
1659 BinaryOperator::BitwiseOr => {
1660 write!(f, "|")
1661 }
1662 BinaryOperator::BitwiseAnd => {
1663 write!(f, "&")
1664 }
1665 BinaryOperator::BitwiseXor => {
1666 write!(f, "#")
1667 }
1668 BinaryOperator::BitwiseShiftLeft => {
1669 write!(f, "<<")
1670 }
1671 BinaryOperator::BitwiseShiftRight => {
1672 write!(f, ">>")
1673 }
1674 BinaryOperator::CosineDistance => {
1675 write!(f, "<=>")
1676 }
1677 BinaryOperator::L1Distance => {
1678 write!(f, "<+>")
1679 }
1680 BinaryOperator::L2Distance => {
1681 write!(f, "<->")
1682 }
1683 }
1684 }
1685}
1686
1687#[derive(Debug, Clone, PartialEq, Eq, Drive, DriveMut)]
1688pub enum JsonOperator {
1689 Arrow,
1691 LongArrow,
1693 HashArrow,
1695 HashLongArrow,
1697 Question,
1699 QuestionOr,
1701 QuestionAnd,
1703 AtArrow,
1705 ArrowAt,
1707 AtQuestion,
1709 AtAt,
1711 HashMinus,
1713}
1714
1715impl JsonOperator {
1716 pub fn to_func_name(&self) -> String {
1717 match self {
1718 JsonOperator::Arrow => "get".to_string(),
1719 JsonOperator::LongArrow => "get_string".to_string(),
1720 JsonOperator::HashArrow => "get_by_keypath".to_string(),
1721 JsonOperator::HashLongArrow => "get_by_keypath_string".to_string(),
1722 JsonOperator::Question => "json_exists_key".to_string(),
1723 JsonOperator::QuestionOr => "json_exists_any_keys".to_string(),
1724 JsonOperator::QuestionAnd => "json_exists_all_keys".to_string(),
1725 JsonOperator::AtArrow => "json_contains_in_left".to_string(),
1726 JsonOperator::ArrowAt => "json_contains_in_right".to_string(),
1727 JsonOperator::AtQuestion => "json_path_exists".to_string(),
1728 JsonOperator::AtAt => "json_path_match".to_string(),
1729 JsonOperator::HashMinus => "delete_by_keypath".to_string(),
1730 }
1731 }
1732}
1733
1734impl Display for JsonOperator {
1735 fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
1736 match self {
1737 JsonOperator::Arrow => {
1738 write!(f, "->")
1739 }
1740 JsonOperator::LongArrow => {
1741 write!(f, "->>")
1742 }
1743 JsonOperator::HashArrow => {
1744 write!(f, "#>")
1745 }
1746 JsonOperator::HashLongArrow => {
1747 write!(f, "#>>")
1748 }
1749 JsonOperator::Question => {
1750 write!(f, "?")
1751 }
1752 JsonOperator::QuestionOr => {
1753 write!(f, "?|")
1754 }
1755 JsonOperator::QuestionAnd => {
1756 write!(f, "?&")
1757 }
1758 JsonOperator::AtArrow => {
1759 write!(f, "@>")
1760 }
1761 JsonOperator::ArrowAt => {
1762 write!(f, "<@")
1763 }
1764 JsonOperator::AtQuestion => {
1765 write!(f, "@?")
1766 }
1767 JsonOperator::AtAt => {
1768 write!(f, "@@")
1769 }
1770 JsonOperator::HashMinus => {
1771 write!(f, "#-")
1772 }
1773 }
1774 }
1775}
1776
1777#[derive(Debug, Clone, PartialEq, Eq, Drive, DriveMut)]
1778pub enum UnaryOperator {
1779 Plus,
1780 Minus,
1781 Not,
1782 Factorial,
1783 SquareRoot,
1784 CubeRoot,
1785 Abs,
1786 BitwiseNot,
1787}
1788
1789impl Display for UnaryOperator {
1790 fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
1791 match self {
1792 UnaryOperator::Plus => {
1793 write!(f, "+")
1794 }
1795 UnaryOperator::Minus => {
1796 write!(f, "-")
1797 }
1798 UnaryOperator::Not => {
1799 write!(f, "NOT")
1800 }
1801 UnaryOperator::SquareRoot => {
1802 write!(f, "|/")
1803 }
1804 UnaryOperator::CubeRoot => {
1805 write!(f, "||/")
1806 }
1807 UnaryOperator::Factorial => {
1808 write!(f, "!")
1809 }
1810 UnaryOperator::Abs => {
1811 write!(f, "@")
1812 }
1813 UnaryOperator::BitwiseNot => {
1814 write!(f, "~")
1815 }
1816 }
1817 }
1818}
1819
1820impl UnaryOperator {
1821 pub fn to_func_name(&self) -> String {
1822 match self {
1823 UnaryOperator::SquareRoot => "sqrt".to_string(),
1824 UnaryOperator::CubeRoot => "cbrt".to_string(),
1825 UnaryOperator::BitwiseNot => "bit_not".to_string(),
1826 _ => {
1827 let name = format!("{:?}", self);
1828 name.to_lowercase()
1829 }
1830 }
1831 }
1832}
1833
1834pub fn split_conjunctions_expr(expr: &Expr) -> Vec<Expr> {
1835 match expr {
1836 Expr::BinaryOp {
1837 op, left, right, ..
1838 } if op == &BinaryOperator::And => {
1839 let mut result = split_conjunctions_expr(left);
1840 result.extend(split_conjunctions_expr(right));
1841 result
1842 }
1843 _ => vec![expr.clone()],
1844 }
1845}
1846
1847pub fn split_equivalent_predicate_expr(expr: &Expr) -> Option<(Expr, Expr)> {
1848 match expr {
1849 Expr::BinaryOp {
1850 op, left, right, ..
1851 } if op == &BinaryOperator::Eq => Some((*left.clone(), *right.clone())),
1852 _ => None,
1853 }
1854}