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