Skip to main content

databend_common_ast/ast/
expr.rs

1// Copyright 2021 Datafuse Labs
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use 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    /// Column reference, with indirection like `table.column`
48    ColumnRef {
49        span: Span,
50        column: ColumnRef,
51    },
52    /// `IS [ NOT ] NULL` expression
53    IsNull {
54        span: Span,
55        expr: Box<Expr>,
56        not: bool,
57    },
58    /// `IS [NOT] DISTINCT` expression
59    IsDistinctFrom {
60        span: Span,
61        left: Box<Expr>,
62        right: Box<Expr>,
63        not: bool,
64    },
65    /// `[ NOT ] IN (expr, ...)`
66    InList {
67        span: Span,
68        expr: Box<Expr>,
69        list: Vec<Expr>,
70        not: bool,
71    },
72    /// `[ NOT ] IN (SELECT ...)`
73    InSubquery {
74        span: Span,
75        expr: Box<Expr>,
76        subquery: Box<Query>,
77        not: bool,
78    },
79    /// `LIKE (SELECT ...) [ESCAPE '<escape>']`
80    LikeSubquery {
81        span: Span,
82        expr: Box<Expr>,
83        subquery: Box<Query>,
84        modifier: SubqueryModifier,
85        escape: Option<String>,
86    },
87    /// `<left> LIKE ANY <right> ESCAPE '<escape>'`
88    LikeAnyWithEscape {
89        span: Span,
90        left: Box<Expr>,
91        right: Box<Expr>,
92        escape: String,
93    },
94    /// `<left> [NOT] LIKE <right> ESCAPE '<escape>'`
95    LikeWithEscape {
96        span: Span,
97        left: Box<Expr>,
98        right: Box<Expr>,
99        is_not: bool,
100        escape: String,
101    },
102    /// `BETWEEN ... AND ...`
103    Between {
104        span: Span,
105        expr: Box<Expr>,
106        low: Box<Expr>,
107        high: Box<Expr>,
108        not: bool,
109    },
110    /// Binary operation
111    BinaryOp {
112        span: Span,
113        op: BinaryOperator,
114        left: Box<Expr>,
115        right: Box<Expr>,
116    },
117    /// JSON operation
118    JsonOp {
119        span: Span,
120        op: JsonOperator,
121        left: Box<Expr>,
122        right: Box<Expr>,
123    },
124    /// Unary operation
125    UnaryOp {
126        span: Span,
127        op: UnaryOperator,
128        expr: Box<Expr>,
129    },
130    /// `CAST` expression, like `CAST(expr AS target_type)`
131    Cast {
132        span: Span,
133        expr: Box<Expr>,
134        target_type: TypeName,
135        pg_style: bool,
136    },
137    /// `TRY_CAST` expression`
138    TryCast {
139        span: Span,
140        expr: Box<Expr>,
141        target_type: TypeName,
142    },
143    /// EXTRACT(IntervalKind FROM <expr>)
144    Extract {
145        span: Span,
146        kind: IntervalKind,
147        expr: Box<Expr>,
148    },
149    /// DATE_PART(IntervalKind, <expr>)
150    DatePart {
151        span: Span,
152        kind: IntervalKind,
153        expr: Box<Expr>,
154    },
155    /// POSITION(<expr> IN <expr>)
156    Position {
157        span: Span,
158        substr_expr: Box<Expr>,
159        str_expr: Box<Expr>,
160    },
161    /// SUBSTRING(<expr> [FROM <expr>] [FOR <expr>])
162    Substring {
163        span: Span,
164        expr: Box<Expr>,
165        substring_from: Box<Expr>,
166        substring_for: Option<Box<Expr>>,
167    },
168    /// TRIM([[BOTH | LEADING | TRAILING] <expr> FROM] <expr>)
169    /// Or
170    /// TRIM(<expr>)
171    Trim {
172        span: Span,
173        expr: Box<Expr>,
174        // ([BOTH | LEADING | TRAILING], <expr>)
175        trim_where: Option<(TrimWhere, Box<Expr>)>,
176    },
177    /// A literal value, such as string, number, date or NULL
178    Literal {
179        span: Span,
180        value: Literal,
181    },
182    /// `COUNT(*)` expression
183    CountAll {
184        span: Span,
185        qualified: Vec<Indirection>,
186        window: Option<Window>,
187    },
188    /// `(foo, bar)`
189    Tuple {
190        span: Span,
191        exprs: Vec<Expr>,
192    },
193    /// Scalar/Agg/Window function call
194    FunctionCall {
195        span: Span,
196        func: FunctionCall,
197    },
198    /// `CASE ... WHEN ... ELSE ...` expression
199    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` expression
207    Exists {
208        span: Span,
209        /// Indicate if this is a `NOT EXISTS`
210        not: bool,
211        subquery: Box<Query>,
212    },
213    /// Scalar/ANY/ALL/SOME subquery
214    Subquery {
215        span: Span,
216        modifier: Option<SubqueryModifier>,
217        subquery: Box<Query>,
218    },
219    /// Access elements of `Array`, `Map` and `Variant` by index or key, like `arr[0]`, or `obj:k1`
220    MapAccess {
221        span: Span,
222        expr: Box<Expr>,
223        accessor: MapAccessor,
224    },
225    /// The `Array` expr
226    Array {
227        span: Span,
228        exprs: Vec<Expr>,
229    },
230    /// The `Map` expr
231    Map {
232        span: Span,
233        kvs: Vec<(Literal, Expr)>,
234    },
235    /// The `Interval 1 DAY` expr
236    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                        // TODO (xieqijun) Maybe special attribute are provided to check whether the symbol is before or after.
690                        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    // Quoted string literal value
1031    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    /// Set to true if the function is aggregate function with `DISTINCT`, like `COUNT(DISTINCT a)`
1097    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/// The display style for a map access expression
1167#[derive(Debug, Clone, PartialEq, Drive, DriveMut)]
1168pub enum MapAccessor {
1169    /// `[0][1]`
1170    Bracket { key: Box<Expr> },
1171    /// `.1`
1172    DotNumber { key: u64 },
1173    /// `:a:b`
1174    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/// `RANGE UNBOUNDED PRECEDING` or `ROWS BETWEEN 5 PRECEDING AND CURRENT ROW`.
1493#[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/// Specifies [WindowFrame]'s `start_bound` and `end_bound`
1507#[derive(Debug, Clone, PartialEq, Drive, DriveMut)]
1508pub enum WindowFrameBound {
1509    /// `CURRENT ROW`
1510    CurrentRow,
1511    /// `<N> PRECEDING` or `UNBOUNDED PRECEDING`
1512    Preceding(Option<Box<Expr>>),
1513    /// `<N> FOLLOWING` or `UNBOUNDED FOLLOWING`.
1514    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    // `>` operator
1549    Gt,
1550    // `<` operator
1551    Lt,
1552    // `>=` operator
1553    Gte,
1554    // `<=` operator
1555    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    /// -> keeps the value as json
1730    Arrow,
1731    /// ->> keeps the value as text or int.
1732    LongArrow,
1733    /// #> Extracts JSON sub-object at the specified path
1734    HashArrow,
1735    /// #>> Extracts JSON sub-object at the specified path as text
1736    HashLongArrow,
1737    /// ? Checks whether text key exist as top-level key or array element.
1738    Question,
1739    /// ?| Checks whether any of the text keys exist as top-level keys or array elements.
1740    QuestionOr,
1741    /// ?& Checks whether all of the text keys exist as top-level keys or array elements.
1742    QuestionAnd,
1743    /// @> Checks whether left json contains the right json
1744    AtArrow,
1745    /// <@ Checks whether right json contains the left json
1746    ArrowAt,
1747    /// @? Checks whether JSON path return any item for the specified JSON value
1748    AtQuestion,
1749    /// @@ Returns the result of a JSON path predicate check for the specified JSON value.
1750    AtAt,
1751    /// #- Deletes the field or array element at the specified keypath.
1752    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}