sql_parse/
expression.rs

1// Licensed under the Apache License, Version 2.0 (the "License");
2// you may not use this file except in compliance with the License.
3// You may obtain a copy of the License at
4//
5// http://www.apache.org/licenses/LICENSE-2.0
6//
7// Unless required by applicable law or agreed to in writing, software
8// distributed under the License is distributed on an "AS IS" BASIS,
9// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10// See the License for the specific language governing permissions and
11// limitations under the License.
12
13use crate::{
14    data_type::parse_data_type,
15    keywords::Keyword,
16    lexer::Token,
17    parser::{ParseError, Parser},
18    select::{parse_select, OrderFlag},
19    span::OptSpanned,
20    statement::parse_compound_query,
21    DataType, Identifier, SString, Span, Spanned, Statement,
22};
23use alloc::string::ToString;
24use alloc::vec;
25use alloc::{boxed::Box, vec::Vec};
26
27/// Function to execute
28#[derive(Debug, Clone, PartialEq, Eq)]
29pub enum Function<'a> {
30    Abs,
31    Acos,
32    AddDate,
33    AddMonths,
34    AddTime,
35    Ascii,
36    Asin,
37    Atan,
38    Atan2,
39    Bin,
40    BitLength,
41    Ceil,
42    CharacterLength,
43    Chr,
44    Concat,
45    ConcatWs,
46    Conv,
47    ConvertTz,
48    Cos,
49    Cot,
50    Crc32,
51    Crc32c,
52    CurDate,
53    CurrentTimestamp,
54    CurTime,
55    Date,
56    DateDiff,
57    DateFormat,
58    DateSub,
59    Datetime,
60    DayName,
61    DayOfMonth,
62    DayOfWeek,
63    DayOfYear,
64    Degrees,
65    Elt,
66    Exists,
67    Exp,
68    ExportSet,
69    ExtractValue,
70    Field,
71    FindInSet,
72    Floor,
73    Format,
74    FromBase64,
75    FromDays,
76    FromUnixTime,
77    Greatest,
78    Hex,
79    Hour,
80    If,
81    IfNull,
82    Insert,
83    InStr,
84    JsonArray,
85    JsonArrayAgg,
86    JsonArrayAppend,
87    JsonArrayInsert,
88    JsonArrayIntersect,
89    JsonCompact,
90    JsonContains,
91    JsonContainsPath,
92    JsonDepth,
93    JsonDetailed,
94    JsonEquals,
95    JsonExists,
96    JsonExtract,
97    JsonInsert,
98    JsonKeys,
99    JsonLength,
100    JsonLoose,
101    JsonMerge,
102    JsonMergePath,
103    JsonMergePerserve,
104    JsonNormalize,
105    JsonObject,
106    JsonObjectAgg,
107    JsonObjectFilterKeys,
108    JsonObjectToArray,
109    JsonOverlaps,
110    JsonPretty,
111    JsonQuery,
112    JsonQuote,
113    JsonRemove,
114    JsonReplace,
115    JsonSchemaValid,
116    JsonSearch,
117    JsonSet,
118    JsonTable,
119    JsonType,
120    JsonUnquote,
121    JsonValid,
122    JsonValue,
123    Lag,
124    LastDay,
125    LCase,
126    Lead,
127    Least,
128    Left,
129    Length,
130    LengthB,
131    Ln,
132    LoadFile,
133    Locate,
134    Log,
135    Log10,
136    Log2,
137    Lower,
138    LPad,
139    LTrim,
140    MakeDate,
141    MakeSet,
142    MakeTime,
143    Max,
144    MicroSecond,
145    Mid,
146    Min,
147    Minute,
148    Month,
149    MonthName,
150    NaturalSortkey,
151    Now,
152    NullIf,
153    NVL2,
154    Oct,
155    OctetLength,
156    Ord,
157    PeriodAdd,
158    PeriodDiff,
159    Pi,
160    Position,
161    Pow,
162    Quarter,
163    Quote,
164    Radians,
165    Rand,
166    Repeat,
167    Replace,
168    Reverse,
169    Right,
170    Round,
171    RPad,
172    RTrim,
173    Second,
174    SecToTime,
175    SFormat,
176    Sign,
177    Sin,
178    SoundEx,
179    Space,
180    Sqrt,
181    StartsWith,
182    StrCmp,
183    Strftime,
184    StrToDate,
185    SubStr,
186    SubStringIndex,
187    SubTime,
188    Sum,
189    SysDate,
190    Tan,
191    Time,
192    TimeDiff,
193    TimeFormat,
194    Timestamp,
195    TimeToSec,
196    ToBase64,
197    ToChar,
198    ToDays,
199    ToSeconds,
200    Truncate,
201    UCase,
202    UncompressedLength,
203    UnHex,
204    UnixTimestamp,
205    Unknown,
206    UpdateXml,
207    Upper,
208    UtcDate,
209    UtcTime,
210    UtcTimeStamp,
211    Value,
212    Week,
213    Weekday,
214    WeekOfYear,
215    Year,
216    YearWeek,
217    Other(&'a str),
218}
219
220/// Function to execute
221#[derive(Debug, Clone)]
222pub enum Variable<'a> {
223    TimeZone,
224    Other(&'a str),
225}
226
227/// Binary operator to apply
228#[derive(Debug, Clone, Copy)]
229pub enum BinaryOperator {
230    Or,
231    Xor,
232    And,
233    Eq,
234    NullSafeEq,
235    GtEq,
236    Gt,
237    LtEq,
238    Lt,
239    Neq,
240    ShiftLeft,
241    ShiftRight,
242    BitAnd,
243    BitOr,
244    BitXor,
245    Add,
246    Subtract,
247    Divide,
248    Div,
249    Mod,
250    Mult,
251    Like,
252    NotLike,
253}
254
255/// Type of is expression
256#[derive(Debug, Clone, Copy)]
257pub enum Is {
258    Null,
259    NotNull,
260    True,
261    NotTrue,
262    False,
263    NotFalse,
264    Unknown,
265    NotUnknown,
266}
267
268/// Unary operator to apply
269#[derive(Debug, Clone, Copy)]
270pub enum UnaryOperator {
271    Binary,
272    Collate,
273    LogicalNot,
274    Minus,
275    Not,
276}
277
278/// Part of a full identifier
279#[derive(Debug, Clone)]
280pub enum IdentifierPart<'a> {
281    Name(Identifier<'a>),
282    Star(Span),
283}
284
285impl<'a> Spanned for IdentifierPart<'a> {
286    fn span(&self) -> Span {
287        match &self {
288            IdentifierPart::Name(v) => v.span(),
289            IdentifierPart::Star(v) => v.span(),
290        }
291    }
292}
293
294/// When part of CASE
295#[derive(Debug, Clone)]
296pub struct When<'a> {
297    /// Span of WHEN
298    pub when_span: Span,
299    /// When to return then
300    pub when: Expression<'a>,
301    /// Span of THEN
302    pub then_span: Span,
303    /// What to return when when applyes
304    pub then: Expression<'a>,
305}
306
307impl<'a> Spanned for When<'a> {
308    fn span(&self) -> Span {
309        self.when_span
310            .join_span(&self.when)
311            .join_span(&self.then_span)
312            .join_span(&self.then)
313    }
314}
315
316/// When part of CASE
317#[derive(Debug, Clone)]
318pub struct WindowSpec<'a> {
319    /// Span of "ORDER BY" and list of order expression and directions, if specified
320    pub order_by: (Span, Vec<(Expression<'a>, OrderFlag)>),
321}
322
323impl<'a> Spanned for WindowSpec<'a> {
324    fn span(&self) -> Span {
325        self.order_by.span()
326    }
327}
328
329/// Units of time
330#[derive(Debug, Clone, PartialEq, Eq)]
331pub enum TimeUnit {
332    /// Microseconds
333    Microsecond,
334    /// Seconds
335    Second,
336    /// Minutes
337    Minute,
338    /// Hours
339    Hour,
340    /// Days
341    Day,
342    /// Weeks
343    Week,
344    /// Months
345    Month,
346    /// Quarters
347    Quarter,
348    /// Years
349    Year,
350    /// Seconds.Microseconds
351    SecondMicrosecond,
352    /// Minutes.Seconds.Microseconds
353    MinuteMicrosecond,
354    /// Minutes.Seconds
355    MinuteSecond,
356    /// Hours.Minutes.Seconds.Microseconds
357    HourMicrosecond,
358    /// Hours.Minutes.Seconds
359    HourSecond,
360    /// Hours.Minutes
361    HourMinute,
362    /// Days Hours.Minutes.Seconds.Microseconds
363    DayMicrosecond,
364    /// Days Hours.Minutes.Seconds
365    DaySecond,
366    /// Days Hours.Minutes
367    DayMinute,
368    /// Days Hours
369    DayHour,
370    /// Years-Months
371    YearMonth,
372}
373
374fn parse_time_unit(t: &Token<'_>) -> Option<TimeUnit> {
375    match t {
376        Token::Ident(_, Keyword::MICROSECOND) => Some(TimeUnit::Microsecond),
377        Token::Ident(_, Keyword::SECOND) => Some(TimeUnit::Second),
378        Token::Ident(_, Keyword::MINUTE) => Some(TimeUnit::Minute),
379        Token::Ident(_, Keyword::HOUR) => Some(TimeUnit::Hour),
380        Token::Ident(_, Keyword::DAY) => Some(TimeUnit::Day),
381        Token::Ident(_, Keyword::WEEK) => Some(TimeUnit::Week),
382        Token::Ident(_, Keyword::MONTH) => Some(TimeUnit::Month),
383        Token::Ident(_, Keyword::QUARTER) => Some(TimeUnit::Quarter),
384        Token::Ident(_, Keyword::YEAR) => Some(TimeUnit::Year),
385        Token::Ident(_, Keyword::SECOND_MICROSECOND) => Some(TimeUnit::SecondMicrosecond),
386        Token::Ident(_, Keyword::MINUTE_MICROSECOND) => Some(TimeUnit::MinuteMicrosecond),
387        Token::Ident(_, Keyword::MINUTE_SECOND) => Some(TimeUnit::MinuteSecond),
388        Token::Ident(_, Keyword::HOUR_MICROSECOND) => Some(TimeUnit::HourMicrosecond),
389        Token::Ident(_, Keyword::HOUR_SECOND) => Some(TimeUnit::HourSecond),
390        Token::Ident(_, Keyword::HOUR_MINUTE) => Some(TimeUnit::HourMinute),
391        Token::Ident(_, Keyword::DAY_MICROSECOND) => Some(TimeUnit::DayMicrosecond),
392        Token::Ident(_, Keyword::DAY_SECOND) => Some(TimeUnit::DaySecond),
393        Token::Ident(_, Keyword::DAY_MINUTE) => Some(TimeUnit::DayMinute),
394        Token::Ident(_, Keyword::DAY_HOUR) => Some(TimeUnit::DayHour),
395        Token::Ident(_, Keyword::YEAR_MONTH) => Some(TimeUnit::YearMonth),
396        _ => None,
397    }
398}
399
400/// Representation of an expression
401#[derive(Debug, Clone)]
402pub enum Expression<'a> {
403    /// Expression with binary operator
404    Binary {
405        /// The operator to apply
406        op: BinaryOperator,
407        /// The span of the operator
408        op_span: Span,
409        /// Expression on the left hand side
410        lhs: Box<Expression<'a>>,
411        /// Expression on the right hand side
412        rhs: Box<Expression<'a>>,
413    },
414    /// Expression with a unary (prefix) operator
415    Unary {
416        /// The operator to apply
417        op: UnaryOperator,
418        /// The span of the operator
419        op_span: Span,
420        /// The expression on the right hand side
421        operand: Box<Expression<'a>>,
422    },
423    /// Subquery expression
424    Subquery(Box<Statement<'a>>),
425    /// Literal NULL expression
426    Null(Span),
427    /// Literal bool expression "TRUE" or "FALSE"
428    Bool(bool, Span),
429    /// Literal string expression, the SString contains the represented string
430    /// with escaping removed
431    String(SString<'a>),
432    /// Literal integer expression
433    Integer((u64, Span)),
434    /// Literal _LIST_
435    ListHack((usize, Span)),
436    /// Literal floating point expression
437    Float((f64, Span)),
438    /// Function call expression,
439    Function(Function<'a>, Vec<Expression<'a>>, Span),
440    /// A window function call expression
441    WindowFunction {
442        function: Function<'a>,
443        args: Vec<Expression<'a>>,
444        function_span: Span,
445        over_span: Span,
446        window_spec: WindowSpec<'a>,
447    },
448    /// Identifier pointing to column
449    Identifier(Vec<IdentifierPart<'a>>),
450    /// Time Interval
451    Interval {
452        /// Span of "INTERVAL"
453        interval_span: Span,
454        /// Time internal
455        time_interval: (Vec<i64>, Span),
456        /// Unit of the time interval
457        time_unit: (TimeUnit, Span),
458    },
459    /// Input argument to query, the first argument is the occurrence number of the argumnet
460    Arg((usize, Span)),
461    /// Exists expression
462    Exists(Box<Statement<'a>>),
463    Extract {
464        /// Span of "EXTRACT"
465        extract_span: Span,
466        /// Unit of the time interval
467        time_unit: (TimeUnit, Span),
468        /// Span of "FROM"
469        from_span: Span,
470        /// Date expression
471        date: Box<Expression<'a>>,
472    },
473    /// In expression
474    In {
475        /// Left hand side expression
476        lhs: Box<Expression<'a>>,
477        /// Right hand side expression
478        rhs: Vec<Expression<'a>>,
479        /// Span of "IN" or "NOT IN"
480        in_span: Span,
481        /// True if not in
482        not_in: bool,
483    },
484    /// Is expression
485    Is(Box<Expression<'a>>, Is, Span),
486    /// Invalid expression, returned on recovery of a parse error
487    Invalid(Span),
488    /// Case expression
489    Case {
490        /// Span of "CASE"
491        case_span: Span,
492        /// Optional value to switch over
493        value: Option<Box<Expression<'a>>>,
494        /// When parts
495        whens: Vec<When<'a>>,
496        /// Span of "ELSE" and else value if specified
497        else_: Option<(Span, Box<Expression<'a>>)>,
498        /// Span of "END"
499        end_span: Span,
500    },
501    /// Cast expression
502    Cast {
503        /// Span of "CAST"
504        cast_span: Span,
505        /// Value to cast
506        expr: Box<Expression<'a>>,
507        /// Span of "AS"
508        as_span: Span,
509        /// Type to cast to
510        type_: DataType<'a>,
511    },
512    /// Count expression
513    Count {
514        /// Span of "COUNT"
515        count_span: Span,
516        /// Span of "DISTINCT" if specified
517        distinct_span: Option<Span>,
518        /// Expression to count
519        expr: Box<Expression<'a>>,
520    },
521    /// Group contat expression
522    GroupConcat {
523        /// Span of "GROUP_CONCAT"
524        group_concat_span: Span,
525        /// Span of "DISTINCT" if specified
526        distinct_span: Option<Span>,
527        /// Expression to count
528        expr: Box<Expression<'a>>,
529    },
530    /// Variable expression
531    Variable {
532        /// Span of "@@GLOBAL"
533        global: Option<Span>,
534        /// Span of "@@SESSION"
535        session: Option<Span>,
536        /// Span of '.'
537        dot: Option<Span>,
538        /// variable
539        variable: Variable<'a>,
540        // Span of variable
541        variable_span: Span,
542    },
543    /// Timestampadd call
544    TimestampAdd {
545        timestamp_add_span: Span,
546        unit: (TimeUnit, Span),
547        interval: Box<Expression<'a>>,
548        datetime: Box<Expression<'a>>,
549    },
550    /// Timestampdiff call
551    TimestampDiff {
552        timestamp_diff_span: Span,
553        unit: (TimeUnit, Span),
554        e1: Box<Expression<'a>>,
555        e2: Box<Expression<'a>>,
556    },
557}
558
559impl<'a> Spanned for Expression<'a> {
560    fn span(&self) -> Span {
561        match &self {
562            Expression::Binary {
563                op_span, lhs, rhs, ..
564            } => op_span.join_span(lhs).join_span(rhs),
565            Expression::Unary {
566                op_span, operand, ..
567            } => op_span.join_span(operand),
568            Expression::Subquery(v) => v.span(),
569            Expression::Null(v) => v.span(),
570            Expression::Bool(_, v) => v.span(),
571            Expression::String(v) => v.span(),
572            Expression::Integer(v) => v.span(),
573            Expression::Float(v) => v.span(),
574            Expression::ListHack((_, s)) => s.span(),
575            Expression::Function(_, b, c) => c.join_span(b),
576            Expression::Identifier(v) => v.opt_span().expect("Span of identifier parts"),
577            Expression::Arg(v) => v.span(),
578            Expression::Exists(v) => v.span(),
579            Expression::In {
580                lhs, rhs, in_span, ..
581            } => in_span.join_span(lhs).join_span(rhs),
582            Expression::Is(a, _, b) => b.join_span(a),
583            Expression::Invalid(s) => s.span(),
584            Expression::Case {
585                case_span,
586                value,
587                whens,
588                else_,
589                end_span,
590            } => case_span
591                .join_span(value)
592                .join_span(whens)
593                .join_span(else_)
594                .join_span(end_span),
595            Expression::Cast {
596                cast_span,
597                expr,
598                as_span,
599                type_,
600            } => cast_span
601                .join_span(expr)
602                .join_span(as_span)
603                .join_span(type_),
604            Expression::Count {
605                count_span,
606                distinct_span,
607                expr,
608            } => count_span.join_span(distinct_span).join_span(expr),
609            Expression::GroupConcat {
610                group_concat_span,
611                distinct_span,
612                expr,
613            } => group_concat_span.join_span(distinct_span).join_span(expr),
614            Expression::Variable {
615                global,
616                session,
617                dot,
618                variable_span,
619                variable: _,
620            } => variable_span
621                .join_span(global)
622                .join_span(session)
623                .join_span(dot),
624            Expression::WindowFunction {
625                function: _,
626                args,
627                function_span,
628                over_span,
629                window_spec,
630            } => function_span
631                .join_span(args)
632                .join_span(over_span)
633                .join_span(window_spec),
634            Expression::Interval {
635                interval_span,
636                time_interval,
637                time_unit,
638            } => interval_span
639                .join_span(&time_interval.1)
640                .join_span(&time_unit.1),
641            Expression::Extract {
642                extract_span,
643                time_unit,
644                from_span,
645                date,
646            } => extract_span
647                .join_span(&time_unit.1)
648                .join_span(from_span)
649                .join_span(date),
650            Expression::TimestampAdd {
651                timestamp_add_span: timespan_add_span,
652                unit,
653                interval,
654                datetime,
655            } => timespan_add_span
656                .join_span(&unit.1)
657                .join_span(interval)
658                .join_span(datetime),
659            Expression::TimestampDiff {
660                timestamp_diff_span,
661                unit,
662                e1,
663                e2,
664            } => timestamp_diff_span
665                .join_span(&unit.1)
666                .join_span(e1)
667                .join_span(e2),
668        }
669    }
670}
671
672fn parse_function<'a>(
673    parser: &mut Parser<'a, '_>,
674    t: Token<'a>,
675    span: Span,
676) -> Result<Expression<'a>, ParseError> {
677    parser.consume_token(Token::LParen)?;
678    let func = match &t {
679        // https://mariadb.com/kb/en/string-functions/
680        Token::Ident(_, Keyword::ASCII) => Function::Ascii,
681        Token::Ident(_, Keyword::BIN) => Function::Bin,
682        Token::Ident(_, Keyword::BIT_LENGTH) => Function::BitLength,
683        Token::Ident(_, Keyword::CHAR_LENGTH) => Function::CharacterLength,
684        Token::Ident(_, Keyword::CHARACTER_LENGTH) => Function::CharacterLength,
685        Token::Ident(_, Keyword::CHR) => Function::Chr,
686        Token::Ident(_, Keyword::CONCAT) => Function::Concat,
687        Token::Ident(_, Keyword::CONCAT_WS) => Function::ConcatWs,
688        Token::Ident(_, Keyword::ELT) => Function::Elt,
689        Token::Ident(_, Keyword::EXPORT_SET) => Function::ExportSet,
690        Token::Ident(_, Keyword::EXTRACTVALUE) => Function::ExtractValue,
691        Token::Ident(_, Keyword::FIELD) => Function::Field,
692        Token::Ident(_, Keyword::FIND_IN_SET) => Function::FindInSet,
693        Token::Ident(_, Keyword::FORMAT) => Function::Format,
694        Token::Ident(_, Keyword::FROM_BASE64) => Function::FromBase64,
695        Token::Ident(_, Keyword::HEX) => Function::Hex,
696        Token::Ident(_, Keyword::INSERT) => Function::Insert,
697        Token::Ident(_, Keyword::INSTR) => Function::InStr,
698        Token::Ident(_, Keyword::LCASE) => Function::LCase,
699        Token::Ident(_, Keyword::LEFT) => Function::Left,
700        Token::Ident(_, Keyword::LENGTH) => Function::Length,
701        Token::Ident(_, Keyword::LENGTHB) => Function::LengthB,
702        Token::Ident(_, Keyword::LOAD_FILE) => Function::LoadFile,
703        Token::Ident(_, Keyword::LOCATE) => Function::Locate,
704        Token::Ident(_, Keyword::LOWER) => Function::Lower,
705        Token::Ident(_, Keyword::LPAD) => Function::LPad,
706        Token::Ident(_, Keyword::LTRIM) => Function::LTrim,
707        Token::Ident(_, Keyword::MAKE_SET) => Function::MakeSet,
708        Token::Ident(_, Keyword::MID) => Function::Mid,
709        Token::Ident(_, Keyword::NATURAL_SORT_KEY) => Function::NaturalSortkey,
710        Token::Ident(_, Keyword::OCTET_LENGTH) => Function::OctetLength,
711        Token::Ident(_, Keyword::ORD) => Function::Ord,
712        Token::Ident(_, Keyword::POSITION) => Function::Position,
713        Token::Ident(_, Keyword::QUOTE) => Function::Quote,
714        Token::Ident(_, Keyword::REPEAT) => Function::Repeat,
715        Token::Ident(_, Keyword::REPLACE) => Function::Replace,
716        Token::Ident(_, Keyword::REVERSE) => Function::Reverse,
717        Token::Ident(_, Keyword::RIGHT) => Function::Right,
718        Token::Ident(_, Keyword::RPAD) => Function::RPad,
719        Token::Ident(_, Keyword::RTRIM) => Function::RTrim,
720        Token::Ident(_, Keyword::SOUNDEX) => Function::SoundEx,
721        Token::Ident(_, Keyword::SPACE) => Function::Space,
722        Token::Ident(_, Keyword::STRCMP) => Function::StrCmp,
723        Token::Ident(_, Keyword::SUBSTR) => Function::SubStr,
724        Token::Ident(_, Keyword::SUBSTRING) => Function::SubStr,
725        Token::Ident(_, Keyword::SUBSTRING_INDEX) => Function::SubStringIndex,
726        Token::Ident(_, Keyword::TO_BASE64) => Function::ToBase64,
727        Token::Ident(_, Keyword::TO_CHAR) => Function::ToChar,
728        Token::Ident(_, Keyword::UCASE) => Function::UCase,
729        Token::Ident(_, Keyword::UNCOMPRESSED_LENGTH) => Function::UncompressedLength,
730        Token::Ident(_, Keyword::UNHEX) => Function::UnHex,
731        Token::Ident(_, Keyword::UPDATEXML) => Function::UpdateXml,
732        Token::Ident(_, Keyword::UPPER) => Function::Upper,
733        Token::Ident(_, Keyword::SFORMAT) => Function::SFormat,
734
735        // TODO uncat
736        Token::Ident(_, Keyword::EXISTS) => Function::Exists,
737        Token::Ident(_, Keyword::MIN) => Function::Min,
738        Token::Ident(_, Keyword::MAX) => Function::Max,
739        Token::Ident(_, Keyword::SUM) => Function::Sum,
740        Token::Ident(_, Keyword::VALUE) => Function::Value,
741        Token::Ident(_, Keyword::VALUES) => Function::Value,
742        Token::Ident(_, Keyword::LEAD) => Function::Lead,
743        Token::Ident(_, Keyword::LAG) => Function::Lag,
744        Token::Ident(_, Keyword::STARTS_WITH) => Function::StartsWith,
745
746        //https://mariadb.com/kb/en/control-flow-functions/
747        Token::Ident(_, Keyword::IFNULL) => Function::IfNull,
748        Token::Ident(_, Keyword::NULLIF) => Function::NullIf,
749        Token::Ident(_, Keyword::NVL) => Function::IfNull,
750        Token::Ident(_, Keyword::NVL2) => Function::NVL2,
751        Token::Ident(_, Keyword::IF) => Function::If,
752
753        //https://mariadb.com/kb/en/numeric-functions/
754        Token::Ident(_, Keyword::ABS) => Function::Abs,
755        Token::Ident(_, Keyword::ACOS) => Function::Acos,
756        Token::Ident(_, Keyword::ASIN) => Function::Asin,
757        Token::Ident(_, Keyword::ATAN) => Function::Atan,
758        Token::Ident(_, Keyword::ATAN2) => Function::Atan2,
759        Token::Ident(_, Keyword::CEIL | Keyword::CEILING) => Function::Ceil,
760        Token::Ident(_, Keyword::CONV) => Function::Conv,
761        Token::Ident(_, Keyword::COS) => Function::Cos,
762        Token::Ident(_, Keyword::COT) => Function::Cot,
763        Token::Ident(_, Keyword::CRC32) => Function::Crc32,
764        Token::Ident(_, Keyword::DEGREES) => Function::Degrees,
765        Token::Ident(_, Keyword::EXP) => Function::Exp,
766        Token::Ident(_, Keyword::FLOOR) => Function::Floor,
767        Token::Ident(_, Keyword::GREATEST) => Function::Greatest,
768        Token::Ident(_, Keyword::LN) => Function::Ln,
769        Token::Ident(_, Keyword::LOG) => Function::Log,
770        Token::Ident(_, Keyword::LOG10) => Function::Log10,
771        Token::Ident(_, Keyword::LOG2) => Function::Log2,
772        Token::Ident(_, Keyword::OCT) => Function::Oct,
773        Token::Ident(_, Keyword::PI) => Function::Pi,
774        Token::Ident(_, Keyword::POW | Keyword::POWER) => Function::Pow,
775        Token::Ident(_, Keyword::RADIANS) => Function::Radians,
776        Token::Ident(_, Keyword::RAND) => Function::Rand,
777        Token::Ident(_, Keyword::ROUND) => Function::Round,
778        Token::Ident(_, Keyword::SIGN) => Function::Sign,
779        Token::Ident(_, Keyword::SIN) => Function::Sin,
780        Token::Ident(_, Keyword::SQRT) => Function::Sqrt,
781        Token::Ident(_, Keyword::TAN) => Function::Tan,
782        Token::Ident(_, Keyword::TRUNCATE) => Function::Truncate,
783        Token::Ident(_, Keyword::CRC32C) => Function::Crc32c,
784        Token::Ident(_, Keyword::LEAST) => Function::Least,
785
786        // https://mariadb.com/kb/en/date-time-functions/
787        Token::Ident(_, Keyword::ADDDATE) => Function::AddDate,
788        Token::Ident(_, Keyword::ADDTIME) => Function::AddTime,
789        Token::Ident(_, Keyword::CONVERT_TZ) => Function::ConvertTz,
790        Token::Ident(_, Keyword::CURDATE) => Function::CurDate,
791        Token::Ident(_, Keyword::CURRENT_DATE) => Function::CurDate,
792        Token::Ident(_, Keyword::CURRENT_TIME) => Function::CurTime,
793        Token::Ident(_, Keyword::CURTIME) => Function::CurTime,
794        Token::Ident(_, Keyword::DATE) => Function::Date,
795        Token::Ident(_, Keyword::HOUR) => Function::Hour,
796        Token::Ident(_, Keyword::DATEDIFF) => Function::DateDiff,
797        Token::Ident(_, Keyword::DATE_ADD) => Function::AddDate,
798        Token::Ident(_, Keyword::DATE_FORMAT) => Function::DateFormat,
799        Token::Ident(_, Keyword::DATE_SUB) => Function::DateSub,
800        Token::Ident(_, Keyword::DAY | Keyword::DAYOFMONTH) => Function::DayOfMonth,
801        Token::Ident(_, Keyword::DAYNAME) => Function::DayName,
802        Token::Ident(_, Keyword::DAYOFWEEK) => Function::DayOfWeek,
803        Token::Ident(_, Keyword::DAYOFYEAR) => Function::DayOfYear,
804        Token::Ident(_, Keyword::FROM_DAYS) => Function::FromDays,
805        Token::Ident(_, Keyword::CURRENT_TIMESTAMP) => Function::CurrentTimestamp,
806        Token::Ident(_, Keyword::LOCALTIME | Keyword::LOCALTIMESTAMP | Keyword::NOW) => {
807            Function::Now
808        }
809        Token::Ident(_, Keyword::MAKEDATE) => Function::MakeDate,
810        Token::Ident(_, Keyword::MAKETIME) => Function::MakeTime,
811        Token::Ident(_, Keyword::MICROSECOND) => Function::MicroSecond,
812        Token::Ident(_, Keyword::MINUTE) => Function::Minute,
813        Token::Ident(_, Keyword::MONTH) => Function::Month,
814        Token::Ident(_, Keyword::MONTHNAME) => Function::MonthName,
815        Token::Ident(_, Keyword::PERIOD_ADD) => Function::PeriodAdd,
816        Token::Ident(_, Keyword::PERIOD_DIFF) => Function::PeriodDiff,
817        Token::Ident(_, Keyword::QUARTER) => Function::Quarter,
818        Token::Ident(_, Keyword::SECOND) => Function::Second,
819        Token::Ident(_, Keyword::SEC_TO_TIME) => Function::SecToTime,
820        Token::Ident(_, Keyword::STR_TO_DATE) => Function::StrToDate,
821        Token::Ident(_, Keyword::SUBDATE) => Function::DateSub,
822        Token::Ident(_, Keyword::SUBTIME) => Function::SubTime,
823        Token::Ident(_, Keyword::TIME) => Function::Time,
824        Token::Ident(_, Keyword::LAST_DAY) => Function::LastDay,
825        Token::Ident(_, Keyword::TIMEDIFF) => Function::TimeDiff,
826        Token::Ident(_, Keyword::TIMESTAMP) => Function::Timestamp,
827        Token::Ident(_, Keyword::TIME_FORMAT) => Function::TimeFormat,
828        Token::Ident(_, Keyword::TIME_TO_SEC) => Function::TimeToSec,
829        Token::Ident(_, Keyword::TO_DAYS) => Function::ToDays,
830        Token::Ident(_, Keyword::TO_SECONDS) => Function::ToSeconds,
831        Token::Ident(_, Keyword::UNIX_TIMESTAMP) => Function::UnixTimestamp,
832        Token::Ident(_, Keyword::UTC_DATE) => Function::UtcDate,
833        Token::Ident(_, Keyword::UTC_TIME) => Function::UtcTime,
834        Token::Ident(_, Keyword::UTC_TIMESTAMP) => Function::UtcTimeStamp,
835        Token::Ident(_, Keyword::WEEK) => Function::Week,
836        Token::Ident(_, Keyword::WEEKDAY) => Function::Weekday,
837        Token::Ident(_, Keyword::WEEKOFYEAR) => Function::WeekOfYear,
838        Token::Ident(_, Keyword::ADD_MONTHS) => Function::AddMonths,
839        Token::Ident(_, Keyword::FROM_UNIXTIME) => Function::FromUnixTime,
840        Token::Ident(_, Keyword::YEAR) => Function::Year,
841        Token::Ident(_, Keyword::YEARWEEK) => Function::YearWeek,
842        Token::Ident(_, Keyword::SYSDATE) => Function::SysDate,
843
844        // https://mariadb.com/kb/en/json-functions/
845        Token::Ident(_, Keyword::JSON_ARRAY) => Function::JsonArray,
846        Token::Ident(_, Keyword::JSON_ARRAYAGG) => Function::JsonArrayAgg,
847        Token::Ident(_, Keyword::JSON_ARRAY_APPEND) => Function::JsonArrayAppend,
848        Token::Ident(_, Keyword::JSON_ARRAY_INSERT) => Function::JsonArrayInsert,
849        Token::Ident(_, Keyword::JSON_ARRAY_INTERSECT) => Function::JsonArrayIntersect,
850        Token::Ident(_, Keyword::JSON_COMPACT) => Function::JsonCompact,
851        Token::Ident(_, Keyword::JSON_CONTAINS) => Function::JsonContains,
852        Token::Ident(_, Keyword::JSON_CONTAINS_PATH) => Function::JsonContainsPath,
853        Token::Ident(_, Keyword::JSON_DEPTH) => Function::JsonDepth,
854        Token::Ident(_, Keyword::JSON_DETAILED) => Function::JsonDetailed,
855        Token::Ident(_, Keyword::JSON_EQUALS) => Function::JsonEquals,
856        Token::Ident(_, Keyword::JSON_EXISTS) => Function::JsonExists,
857        Token::Ident(_, Keyword::JSON_EXTRACT) => Function::JsonExtract,
858        Token::Ident(_, Keyword::JSON_INSERT) => Function::JsonInsert,
859        Token::Ident(_, Keyword::JSON_KEYS) => Function::JsonKeys,
860        Token::Ident(_, Keyword::JSON_LENGTH) => Function::JsonLength,
861        Token::Ident(_, Keyword::JSON_LOOSE) => Function::JsonLoose,
862        Token::Ident(_, Keyword::JSON_MERGE) => Function::JsonMerge,
863        Token::Ident(_, Keyword::JSON_MERGE_PATCH) => Function::JsonMergePath,
864        Token::Ident(_, Keyword::JSON_MERGE_PRESERVE) => Function::JsonMergePerserve,
865        Token::Ident(_, Keyword::JSON_NORMALIZE) => Function::JsonNormalize,
866        Token::Ident(_, Keyword::JSON_OBJECT) => Function::JsonObject,
867        Token::Ident(_, Keyword::JSON_OBJECT_FILTER_KEYS) => Function::JsonObjectFilterKeys,
868        Token::Ident(_, Keyword::JSON_OBJECT_TO_ARRAY) => Function::JsonObjectToArray,
869        Token::Ident(_, Keyword::JSON_OBJECTAGG) => Function::JsonObjectAgg,
870        Token::Ident(_, Keyword::JSON_OVERLAPS) => Function::JsonOverlaps,
871        Token::Ident(_, Keyword::JSON_PRETTY) => Function::JsonPretty,
872        Token::Ident(_, Keyword::JSON_QUERY) => Function::JsonQuery,
873        Token::Ident(_, Keyword::JSON_QUOTE) => Function::JsonQuote,
874        Token::Ident(_, Keyword::JSON_REMOVE) => Function::JsonRemove,
875        Token::Ident(_, Keyword::JSON_REPLACE) => Function::JsonReplace,
876        Token::Ident(_, Keyword::JSON_SCHEMA_VALID) => Function::JsonSchemaValid,
877        Token::Ident(_, Keyword::JSON_SEARCH) => Function::JsonSearch,
878        Token::Ident(_, Keyword::JSON_SET) => Function::JsonSet,
879        Token::Ident(_, Keyword::JSON_TABLE) => Function::JsonTable,
880        Token::Ident(_, Keyword::JSON_TYPE) => Function::JsonType,
881        Token::Ident(_, Keyword::JSON_UNQUOTE) => Function::JsonUnquote,
882        Token::Ident(_, Keyword::JSON_VALID) => Function::JsonValid,
883        Token::Ident(_, Keyword::JSON_VALUE) => Function::JsonValue,
884
885        // Sqlite
886        Token::Ident(_, Keyword::STRFTIME) => Function::Strftime,
887        Token::Ident(_, Keyword::DATETIME) => Function::Datetime,
888        Token::Ident(v, k) if !k.reserved() => Function::Other(v),
889        _ => {
890            parser.err("Unknown function", &span);
891            Function::Unknown
892        }
893    };
894
895    let mut args = Vec::new();
896    if !matches!(parser.token, Token::RParen) {
897        loop {
898            parser.recovered(
899                "')' or ','",
900                &|t| matches!(t, Token::RParen | Token::Comma),
901                |parser| {
902                    args.push(parse_expression_outer(parser)?);
903                    Ok(())
904                },
905            )?;
906            if parser.skip_token(Token::Comma).is_none() {
907                break;
908            }
909        }
910    }
911    parser.consume_token(Token::RParen)?;
912
913    if let Some(over_span) = parser.skip_keyword(Keyword::OVER) {
914        parser.consume_token(Token::LParen)?;
915        let order_span = parser.consume_keywords(&[Keyword::ORDER, Keyword::BY])?;
916        let mut order = Vec::new();
917        loop {
918            let e = parse_expression(parser, false)?;
919            let f = match &parser.token {
920                Token::Ident(_, Keyword::ASC) => OrderFlag::Asc(parser.consume()),
921                Token::Ident(_, Keyword::DESC) => OrderFlag::Desc(parser.consume()),
922                _ => OrderFlag::None,
923            };
924            order.push((e, f));
925            if parser.skip_token(Token::Comma).is_none() {
926                break;
927            }
928        }
929        parser.consume_token(Token::RParen)?;
930        Ok(Expression::WindowFunction {
931            function: func,
932            args,
933            function_span: span,
934            over_span,
935            window_spec: WindowSpec {
936                order_by: (order_span, order),
937            },
938        })
939    } else {
940        Ok(Expression::Function(func, args, span))
941    }
942}
943
944//const INTERVAL_PRIORITY: usize = 10;
945const IN_PRIORITY: usize = 110;
946
947trait Priority {
948    fn priority(&self) -> usize;
949}
950
951impl Priority for BinaryOperator {
952    fn priority(&self) -> usize {
953        match self {
954            BinaryOperator::Or => 140,
955            BinaryOperator::Xor => 150,
956            BinaryOperator::And => 160,
957            BinaryOperator::Eq => 110,
958            BinaryOperator::NullSafeEq => 110,
959            BinaryOperator::GtEq => 110,
960            BinaryOperator::Gt => 110,
961            BinaryOperator::LtEq => 110,
962            BinaryOperator::Lt => 110,
963            BinaryOperator::Neq => 110,
964            BinaryOperator::Like => 110,
965            BinaryOperator::NotLike => 110,
966            BinaryOperator::ShiftLeft => 80,
967            BinaryOperator::ShiftRight => 80,
968            BinaryOperator::BitAnd => 90,
969            BinaryOperator::BitOr => 100,
970            BinaryOperator::BitXor => 50,
971            BinaryOperator::Add => 70,
972            BinaryOperator::Subtract => 70,
973            BinaryOperator::Divide => 60,
974            BinaryOperator::Div => 60,
975            BinaryOperator::Mod => 60,
976            BinaryOperator::Mult => 60,
977        }
978    }
979}
980
981impl Priority for UnaryOperator {
982    fn priority(&self) -> usize {
983        match self {
984            UnaryOperator::Binary => 20,
985            UnaryOperator::Collate => 20,
986            UnaryOperator::LogicalNot => 30,
987            UnaryOperator::Minus => 40,
988            UnaryOperator::Not => 130,
989        }
990    }
991}
992
993#[derive(Debug)]
994enum ReduceMember<'a> {
995    Expression(Expression<'a>),
996    Binary(BinaryOperator, Span),
997    Unary(UnaryOperator, Span),
998}
999
1000struct Reducer<'a> {
1001    stack: Vec<ReduceMember<'a>>,
1002}
1003
1004impl<'a> Reducer<'a> {
1005    fn reduce(&mut self, priority: usize) -> Result<(), &'static str> {
1006        let mut e = match self.stack.pop() {
1007            Some(ReduceMember::Expression(e)) => e,
1008            _ => {
1009                return Err("Expected expression before here");
1010            }
1011        };
1012        loop {
1013            let v = self.stack.pop();
1014            match v {
1015                None => break,
1016                Some(ReduceMember::Expression(_)) => return Err("ICE Reduce stack error 1"),
1017                Some(ReduceMember::Unary(op, span)) if op.priority() > priority => {
1018                    self.stack.push(ReduceMember::Unary(op, span));
1019                    break;
1020                }
1021                Some(ReduceMember::Binary(op, span)) if op.priority() > priority => {
1022                    self.stack.push(ReduceMember::Binary(op, span));
1023                    break;
1024                }
1025                Some(ReduceMember::Unary(op, op_span)) => {
1026                    e = Expression::Unary {
1027                        op,
1028                        op_span,
1029                        operand: Box::new(e),
1030                    };
1031                }
1032                Some(ReduceMember::Binary(op, op_span)) => {
1033                    let lhs = match self.stack.pop() {
1034                        Some(ReduceMember::Expression(e)) => e,
1035                        _ => return Err("ICE Reduce stack error 2"),
1036                    };
1037                    e = Expression::Binary {
1038                        op,
1039                        op_span,
1040                        lhs: Box::new(lhs),
1041                        rhs: Box::new(e),
1042                    };
1043                }
1044            }
1045        }
1046        self.stack.push(ReduceMember::Expression(e));
1047        Ok(())
1048    }
1049
1050    fn shift_binop(&mut self, span: Span, op: BinaryOperator) -> Result<(), &'static str> {
1051        self.reduce(op.priority())?;
1052        self.stack.push(ReduceMember::Binary(op, span));
1053        Ok(())
1054    }
1055
1056    fn shift_unary(&mut self, span: Span, op: UnaryOperator) -> Result<(), &'static str> {
1057        if matches!(self.stack.last(), Some(ReduceMember::Expression(_))) {
1058            return Err("Unary operator cannot come before expression");
1059        }
1060        self.stack.push(ReduceMember::Unary(op, span));
1061        Ok(())
1062    }
1063
1064    fn shift_expr(&mut self, e: Expression<'a>) -> Result<(), &'static str> {
1065        if matches!(self.stack.last(), Some(ReduceMember::Expression(_))) {
1066            //panic!();
1067            return Err("Expression should not follow expression");
1068        }
1069        self.stack.push(ReduceMember::Expression(e));
1070        Ok(())
1071    }
1072}
1073
1074pub(crate) fn parse_expression<'a>(
1075    parser: &mut Parser<'a, '_>,
1076    inner: bool,
1077) -> Result<Expression<'a>, ParseError> {
1078    let mut r = Reducer { stack: Vec::new() };
1079    loop {
1080        let e = match parser.token.clone() {
1081            Token::Ident(_, Keyword::OR) | Token::DoublePipe if !inner => {
1082                r.shift_binop(parser.consume(), BinaryOperator::Or)
1083            }
1084            Token::Ident(_, Keyword::XOR) if !inner => {
1085                r.shift_binop(parser.consume(), BinaryOperator::Xor)
1086            }
1087            Token::Ident(_, Keyword::AND) | Token::DoubleAmpersand if !inner => {
1088                r.shift_binop(parser.consume(), BinaryOperator::And)
1089            }
1090            Token::Eq if !inner => r.shift_binop(parser.consume(), BinaryOperator::Eq),
1091            Token::Spaceship if !inner => {
1092                r.shift_binop(parser.consume(), BinaryOperator::NullSafeEq)
1093            }
1094            Token::GtEq if !inner => r.shift_binop(parser.consume(), BinaryOperator::GtEq),
1095            Token::Gt if !inner => r.shift_binop(parser.consume(), BinaryOperator::Gt),
1096            Token::LtEq if !inner => r.shift_binop(parser.consume(), BinaryOperator::LtEq),
1097            Token::Lt if !inner => r.shift_binop(parser.consume(), BinaryOperator::Lt),
1098            Token::Neq if !inner => r.shift_binop(parser.consume(), BinaryOperator::Neq),
1099            Token::ShiftLeft if !inner => {
1100                r.shift_binop(parser.consume(), BinaryOperator::ShiftLeft)
1101            }
1102            Token::ShiftRight if !inner => {
1103                r.shift_binop(parser.consume(), BinaryOperator::ShiftRight)
1104            }
1105            Token::Ampersand => r.shift_binop(parser.consume(), BinaryOperator::BitAnd),
1106            Token::Pipe if !inner => r.shift_binop(parser.consume(), BinaryOperator::BitOr),
1107            Token::Ident(_, Keyword::BINARY) if !inner => {
1108                r.shift_unary(parser.consume(), UnaryOperator::Binary)
1109            }
1110            Token::Ident(_, Keyword::COLLATE) if !inner => {
1111                r.shift_unary(parser.consume(), UnaryOperator::Collate)
1112            }
1113            Token::ExclamationMark if !inner => {
1114                r.shift_unary(parser.consume(), UnaryOperator::LogicalNot)
1115            }
1116            Token::Minus if !matches!(r.stack.last(), Some(ReduceMember::Expression(_))) => {
1117                r.shift_unary(parser.consume(), UnaryOperator::Minus)
1118            }
1119            Token::Minus
1120                if !inner && matches!(r.stack.last(), Some(ReduceMember::Expression(_))) =>
1121            {
1122                r.shift_binop(parser.consume(), BinaryOperator::Subtract)
1123            }
1124            Token::Ident(_, Keyword::IN) if !inner => {
1125                if let Err(e) = r.reduce(IN_PRIORITY) {
1126                    parser.err_here(e)?;
1127                }
1128                let lhs = match r.stack.pop() {
1129                    Some(ReduceMember::Expression(e)) => e,
1130                    _ => parser.err_here("Expected expression before here 3")?,
1131                };
1132                let op = parser.consume_keyword(Keyword::IN)?;
1133                parser.consume_token(Token::LParen)?;
1134                let mut rhs = Vec::new();
1135                loop {
1136                    parser.recovered(
1137                        "')' or ','",
1138                        &|t| matches!(t, Token::RParen | Token::Comma),
1139                        |parser| {
1140                            rhs.push(parse_expression_paren(parser)?);
1141                            Ok(())
1142                        },
1143                    )?;
1144                    if parser.skip_token(Token::Comma).is_none() {
1145                        break;
1146                    }
1147                }
1148                parser.consume_token(Token::RParen)?;
1149                r.shift_expr(Expression::In {
1150                    lhs: Box::new(lhs),
1151                    rhs,
1152                    in_span: op,
1153                    not_in: false,
1154                })
1155            }
1156            Token::Ident(_, Keyword::IS) if !inner => {
1157                if let Err(e) = r.reduce(IN_PRIORITY) {
1158                    parser.err_here(e)?;
1159                }
1160                let lhs = match r.stack.pop() {
1161                    Some(ReduceMember::Expression(e)) => e,
1162                    _ => parser.err_here("Expected expression before here 4")?,
1163                };
1164                let op = parser.consume_keyword(Keyword::IS)?;
1165                let (is, op) = match &parser.token {
1166                    Token::Ident(_, Keyword::NOT) => {
1167                        parser.consume();
1168                        match &parser.token {
1169                            Token::Ident(_, Keyword::TRUE) => {
1170                                (Is::NotTrue, parser.consume().join_span(&op))
1171                            }
1172                            Token::Ident(_, Keyword::FALSE) => {
1173                                (Is::NotFalse, parser.consume().join_span(&op))
1174                            }
1175                            Token::Ident(_, Keyword::NULL) => {
1176                                (Is::NotNull, parser.consume().join_span(&op))
1177                            }
1178                            Token::Ident(_, Keyword::UNKNOWN) => {
1179                                (Is::NotUnknown, parser.consume().join_span(&op))
1180                            }
1181                            _ => parser.expected_failure("'TRUE', 'FALSE', 'UNKNOWN' or 'NULL'")?,
1182                        }
1183                    }
1184                    Token::Ident(_, Keyword::TRUE) => (Is::True, parser.consume().join_span(&op)),
1185                    Token::Ident(_, Keyword::FALSE) => (Is::False, parser.consume().join_span(&op)),
1186                    Token::Ident(_, Keyword::NULL) => (Is::Null, parser.consume().join_span(&op)),
1187                    Token::Ident(_, Keyword::UNKNOWN) => {
1188                        (Is::Unknown, parser.consume().join_span(&op))
1189                    }
1190                    _ => parser.expected_failure("'NOT', 'TRUE', 'FALSE', 'UNKNOWN' or 'NULL'")?,
1191                };
1192                r.shift_expr(Expression::Is(Box::new(lhs), is, op))
1193            }
1194            Token::Ident(_, Keyword::NOT)
1195                if !matches!(r.stack.last(), Some(ReduceMember::Expression(_))) =>
1196            {
1197                r.shift_unary(parser.consume(), UnaryOperator::Not)
1198            }
1199            Token::Ident(_, Keyword::NOT)
1200                if !inner && matches!(r.stack.last(), Some(ReduceMember::Expression(_))) =>
1201            {
1202                if let Err(e) = r.reduce(IN_PRIORITY) {
1203                    parser.err_here(e)?;
1204                }
1205                let lhs = match r.stack.pop() {
1206                    Some(ReduceMember::Expression(e)) => e,
1207                    _ => parser.err_here("Expected expression before here 2")?,
1208                };
1209                let op = parser.consume_keyword(Keyword::NOT)?;
1210                match &parser.token {
1211                    Token::Ident(_, Keyword::IN) => {
1212                        let op = parser.consume_keyword(Keyword::IN)?.join_span(&op);
1213                        parser.consume_token(Token::LParen)?;
1214                        let mut rhs = Vec::new();
1215                        loop {
1216                            parser.recovered(
1217                                "')' or ','",
1218                                &|t| matches!(t, Token::RParen | Token::Comma),
1219                                |parser| {
1220                                    rhs.push(parse_expression_paren(parser)?);
1221                                    Ok(())
1222                                },
1223                            )?;
1224                            if parser.skip_token(Token::Comma).is_none() {
1225                                break;
1226                            }
1227                        }
1228                        parser.consume_token(Token::RParen)?;
1229                        r.shift_expr(Expression::In {
1230                            lhs: Box::new(lhs),
1231                            rhs,
1232                            in_span: op,
1233                            not_in: true,
1234                        })
1235                    }
1236                    Token::Ident(_, Keyword::LIKE) => {
1237                        r.stack.push(ReduceMember::Expression(lhs));
1238                        r.shift_binop(parser.consume().join_span(&op), BinaryOperator::NotLike)
1239                    }
1240                    _ => parser.expected_failure("'IN' or 'LIKE'")?,
1241                }
1242            }
1243            Token::Ident(_, Keyword::LIKE) if !inner => {
1244                r.shift_binop(parser.consume(), BinaryOperator::Like)
1245            }
1246            Token::Ident(_, Keyword::INTERVAL) => {
1247                let interval_span = parser.consume();
1248                let time_interval = match parser.token {
1249                    Token::SingleQuotedString(_) | Token::DoubleQuotedString(_) => {
1250                        let v = parser.consume_string()?;
1251                        let mut r = Vec::new();
1252                        for part in v.split([':', '!', ',', '.', '-', ' ']) {
1253                            let Ok(v) = part.parse() else {
1254                                parser.err("Expected . separated integers in a string", &v);
1255                                continue;
1256                            };
1257                            r.push(v);
1258                        }
1259                        (r, v.span())
1260                    }
1261                    Token::Integer(_) => {
1262                        let (v, s) = parser.consume_int()?;
1263                        (vec![v], s)
1264                    }
1265                    _ => parser.err_here("Expected integer or string")?,
1266                };
1267                let Some(u) = parse_time_unit(&parser.token) else {
1268                    parser.err_here("Expected time unit")?
1269                };
1270                let time_unit = (u, parser.consume());
1271                let e = Expression::Interval {
1272                    interval_span,
1273                    time_interval,
1274                    time_unit,
1275                };
1276                r.shift_expr(e)
1277            }
1278            Token::Ident(_, Keyword::TIMESTAMPADD) => {
1279                let timestamp_add_span = parser.consume();
1280                parser.consume_token(Token::LParen)?;
1281                let parts = parser.recovered("')'", &|t| matches!(t, Token::RParen), |parser| {
1282                    let Some(u) = parse_time_unit(&parser.token) else {
1283                        parser.err_here("Expected time unit")?
1284                    };
1285                    let unit = (u, parser.consume());
1286                    parser.consume_token(Token::Comma)?;
1287                    let interval = parse_expression_outer(parser)?;
1288                    parser.consume_token(Token::Comma)?;
1289                    let datetime = parse_expression_outer(parser)?;
1290                    Ok(Some((unit, Box::new(interval), Box::new(datetime))))
1291                })?;
1292                parser.consume_token(Token::RParen)?;
1293                if let Some((unit, interval, datetime)) = parts {
1294                    r.shift_expr(Expression::TimestampAdd {
1295                        timestamp_add_span,
1296                        unit,
1297                        interval,
1298                        datetime,
1299                    })
1300                } else {
1301                    r.shift_expr(Expression::Invalid(timestamp_add_span))
1302                }
1303            }
1304            Token::Ident(_, Keyword::TIMESTAMPDIFF) => {
1305                let timestamp_diff_span = parser.consume();
1306                parser.consume_token(Token::LParen)?;
1307                let parts = parser.recovered("')'", &|t| matches!(t, Token::RParen), |parser| {
1308                    let Some(u) = parse_time_unit(&parser.token) else {
1309                        parser.err_here("Expected time unit")?
1310                    };
1311                    let unit = (u, parser.consume());
1312                    parser.consume_token(Token::Comma)?;
1313                    let e1 = parse_expression_outer(parser)?;
1314                    parser.consume_token(Token::Comma)?;
1315                    let e2 = parse_expression_outer(parser)?;
1316                    Ok(Some((unit, Box::new(e1), Box::new(e2))))
1317                })?;
1318                parser.consume_token(Token::RParen)?;
1319                if let Some((unit, e1, e2)) = parts {
1320                    r.shift_expr(Expression::TimestampDiff {
1321                        timestamp_diff_span,
1322                        unit,
1323                        e1,
1324                        e2,
1325                    })
1326                } else {
1327                    r.shift_expr(Expression::Invalid(timestamp_diff_span))
1328                }
1329            }
1330            Token::Plus if !inner => r.shift_binop(parser.consume(), BinaryOperator::Add),
1331            Token::Div if !inner => r.shift_binop(parser.consume(), BinaryOperator::Divide),
1332            Token::Minus if !inner => r.shift_binop(parser.consume(), BinaryOperator::Subtract),
1333            Token::Ident(_, Keyword::LIKE) if !inner => {
1334                r.shift_binop(parser.consume(), BinaryOperator::Like)
1335            }
1336            Token::Mul if !matches!(r.stack.last(), Some(ReduceMember::Expression(_))) => r
1337                .shift_expr(Expression::Identifier(vec![IdentifierPart::Star(
1338                    parser.consume_token(Token::Mul)?,
1339                )])),
1340            Token::Mul if !inner && matches!(r.stack.last(), Some(ReduceMember::Expression(_))) => {
1341                r.shift_binop(parser.consume(), BinaryOperator::Mult)
1342            }
1343            Token::Ident(_, Keyword::TRUE) => r.shift_expr(Expression::Bool(
1344                true,
1345                parser.consume_keyword(Keyword::TRUE)?,
1346            )),
1347            Token::Ident(_, Keyword::FALSE) => r.shift_expr(Expression::Bool(
1348                false,
1349                parser.consume_keyword(Keyword::FALSE)?,
1350            )),
1351            Token::Ident(_, Keyword::NULL) => {
1352                r.shift_expr(Expression::Null(parser.consume_keyword(Keyword::NULL)?))
1353            }
1354            Token::Ident(_, Keyword::_LIST_) if parser.options.list_hack => {
1355                let arg = parser.arg;
1356                parser.arg += 1;
1357                r.shift_expr(Expression::ListHack((
1358                    arg,
1359                    parser.consume_keyword(Keyword::_LIST_)?,
1360                )))
1361            }
1362            Token::SingleQuotedString(_) | Token::DoubleQuotedString(_) => {
1363                r.shift_expr(Expression::String(parser.consume_string()?))
1364            }
1365            Token::Integer(_) => r.shift_expr(Expression::Integer(parser.consume_int()?)),
1366            Token::Float(_) => r.shift_expr(Expression::Float(parser.consume_float()?)),
1367
1368            Token::Ident(_, Keyword::CAST) => {
1369                let cast_span = parser.consume_keyword(Keyword::CAST)?;
1370                parser.consume_token(Token::LParen)?;
1371                let cast = parser.recovered("')'", &|t| matches!(t, Token::RParen), |parser| {
1372                    let expr = parse_expression_outer(parser)?;
1373                    let as_span = parser.consume_keyword(Keyword::AS)?;
1374                    let type_ = parse_data_type(parser, false)?;
1375                    Ok(Some((expr, as_span, type_)))
1376                })?;
1377                parser.consume_token(Token::RParen)?;
1378                if let Some((expr, as_span, type_)) = cast {
1379                    r.shift_expr(Expression::Cast {
1380                        cast_span,
1381                        expr: Box::new(expr),
1382                        as_span,
1383                        type_,
1384                    })
1385                } else {
1386                    r.shift_expr(Expression::Invalid(cast_span))
1387                }
1388            }
1389            Token::Ident(_, Keyword::COUNT) => {
1390                let count_span = parser.consume_keyword(Keyword::COUNT)?;
1391                parser.consume_token(Token::LParen)?;
1392                let distinct_span = parser.skip_keyword(Keyword::DISTINCT);
1393                let expr = parser.recovered("')'", &|t| matches!(t, Token::RParen), |parser| {
1394                    let expr = parse_expression_outer(parser)?;
1395                    Ok(Some(expr))
1396                })?;
1397                parser.consume_token(Token::RParen)?;
1398                if let Some(expr) = expr {
1399                    r.shift_expr(Expression::Count {
1400                        count_span,
1401                        distinct_span,
1402                        expr: Box::new(expr),
1403                    })
1404                } else {
1405                    r.shift_expr(Expression::Invalid(count_span))
1406                }
1407            }
1408            Token::Ident(_, Keyword::GROUP_CONCAT) => {
1409                let group_concat_span: core::ops::Range<usize> =
1410                    parser.consume_keyword(Keyword::GROUP_CONCAT)?;
1411                parser.consume_token(Token::LParen)?;
1412                let distinct_span: Option<core::ops::Range<usize>> =
1413                    parser.skip_keyword(Keyword::DISTINCT);
1414                let expr = parser.recovered("')'", &|t| matches!(t, Token::RParen), |parser| {
1415                    let expr = parse_expression_outer(parser)?;
1416                    Ok(Some(expr))
1417                })?;
1418                // TODO
1419                // [ORDER BY {unsigned_integer | col_name | expr}
1420                //     [ASC | DESC] [,col_name ...]]
1421                // [SEPARATOR str_val]
1422                // [LIMIT {[offset,] row_count | row_count OFFSET offset}])
1423                parser.consume_token(Token::RParen)?;
1424                if let Some(expr) = expr {
1425                    r.shift_expr(Expression::GroupConcat {
1426                        group_concat_span,
1427                        distinct_span,
1428                        expr: Box::new(expr),
1429                    })
1430                } else {
1431                    r.shift_expr(Expression::Invalid(group_concat_span))
1432                }
1433            }
1434            Token::Ident(_, Keyword::EXTRACT) => {
1435                let extract_span = parser.consume_keyword(Keyword::EXTRACT)?;
1436                parser.consume_token(Token::LParen)?;
1437                let parts = parser.recovered("')'", &|t| matches!(t, Token::RParen), |parser| {
1438                    let Some(u) = parse_time_unit(&parser.token) else {
1439                        parser.err_here("Expected time unit")?
1440                    };
1441                    let time_unit = (u, parser.consume());
1442                    let from_span = parser.consume_keyword(Keyword::FROM)?;
1443                    let date = parse_expression_outer(parser)?;
1444                    Ok(Some((time_unit, from_span, Box::new(date))))
1445                })?;
1446                parser.consume_token(Token::RParen)?;
1447                if let Some((time_unit, from_span, date)) = parts {
1448                    r.shift_expr(Expression::Extract {
1449                        extract_span,
1450                        time_unit,
1451                        from_span,
1452                        date,
1453                    })
1454                } else {
1455                    r.shift_expr(Expression::Invalid(extract_span))
1456                }
1457            }
1458            Token::Ident(_, Keyword::LEFT) if matches!(parser.peek(), Token::LParen) => {
1459                let i = parser.token.clone();
1460                let s = parser.span.clone();
1461                parser.consume();
1462                r.shift_expr(parse_function(parser, i, s)?)
1463            }
1464            Token::Ident(_, k) if k.expr_ident() => {
1465                let i = parser.token.clone();
1466                let s = parser.span.clone();
1467                parser.consume();
1468                if matches!(parser.token, Token::LParen) {
1469                    r.shift_expr(parse_function(parser, i, s)?)
1470                } else {
1471                    let f = match i {
1472                        Token::Ident(_, Keyword::CURRENT_TIMESTAMP) => {
1473                            Some(Function::CurrentTimestamp)
1474                        }
1475                        Token::Ident(_, Keyword::LOCALTIME | Keyword::LOCALTIMESTAMP) => {
1476                            Some(Function::Now)
1477                        }
1478                        Token::Ident(_, Keyword::UTC_TIMESTAMP) => Some(Function::UtcTimeStamp),
1479                        Token::Ident(_, Keyword::UTC_DATE) => Some(Function::UtcDate),
1480                        Token::Ident(_, Keyword::UTC_TIME) => Some(Function::UtcTime),
1481                        Token::Ident(_, Keyword::CURRENT_DATE) => Some(Function::CurDate),
1482                        Token::Ident(_, Keyword::CURRENT_TIME) => Some(Function::CurTime),
1483                        _ => None,
1484                    };
1485                    if let Some(f) = f {
1486                        r.shift_expr(Expression::Function(f, Vec::new(), s))
1487                    } else {
1488                        let mut parts = vec![IdentifierPart::Name(
1489                            parser.token_to_plain_identifier(&i, s)?,
1490                        )];
1491                        loop {
1492                            if parser.skip_token(Token::Period).is_none() {
1493                                break;
1494                            }
1495                            match &parser.token {
1496                                Token::Mul => parts
1497                                    .push(IdentifierPart::Star(parser.consume_token(Token::Mul)?)),
1498                                Token::Ident(_, _) => parts
1499                                    .push(IdentifierPart::Name(parser.consume_plain_identifier()?)),
1500                                _ => parser.expected_failure("Identifier or '*'")?,
1501                            }
1502                        }
1503                        r.shift_expr(Expression::Identifier(parts))
1504                    }
1505                }
1506            }
1507            Token::QuestionMark
1508                if matches!(parser.options.arguments, crate::SQLArguments::QuestionMark) =>
1509            {
1510                let arg = parser.arg;
1511                parser.arg += 1;
1512                r.shift_expr(Expression::Arg((
1513                    arg,
1514                    parser.consume_token(Token::QuestionMark)?,
1515                )))
1516            }
1517            Token::PercentS if matches!(parser.options.arguments, crate::SQLArguments::Percent) => {
1518                let arg = parser.arg;
1519                parser.arg += 1;
1520                r.shift_expr(Expression::Arg((
1521                    arg,
1522                    parser.consume_token(Token::PercentS)?,
1523                )))
1524            }
1525            Token::DollarArg(arg)
1526                if matches!(parser.options.arguments, crate::SQLArguments::Dollar) =>
1527            {
1528                r.shift_expr(Expression::Arg((arg - 1, parser.consume())))
1529            }
1530            Token::LParen => {
1531                parser.consume_token(Token::LParen)?;
1532                let ans = parse_expression_paren(parser)?;
1533                parser.consume_token(Token::RParen)?;
1534                r.shift_expr(ans)
1535            }
1536            Token::Ident(_, Keyword::EXISTS) => {
1537                parser.consume_keyword(Keyword::EXISTS)?;
1538                parser.consume_token(Token::LParen)?;
1539                let ans = Expression::Exists(Box::new(parse_compound_query(parser)?));
1540                parser.consume_token(Token::RParen)?;
1541                r.shift_expr(ans)
1542            }
1543            Token::Ident(_, Keyword::CASE) => {
1544                let case_span = parser.consume_keyword(Keyword::CASE)?;
1545                let value = if !matches!(parser.token, Token::Ident(_, Keyword::WHEN)) {
1546                    Some(Box::new(parse_expression(parser, false)?))
1547                } else {
1548                    None
1549                };
1550                let mut whens = Vec::new();
1551                let mut else_ = None;
1552                parser.recovered(
1553                    "'END'",
1554                    &|t| matches!(t, Token::Ident(_, Keyword::END)),
1555                    |parser| {
1556                        loop {
1557                            let when_span = parser.consume_keyword(Keyword::WHEN)?;
1558                            let when = parse_expression(parser, false)?;
1559                            let then_span = parser.consume_keyword(Keyword::THEN)?;
1560                            let then = parse_expression(parser, false)?;
1561                            whens.push(When {
1562                                when_span,
1563                                when,
1564                                then_span,
1565                                then,
1566                            });
1567                            if !matches!(parser.token, Token::Ident(_, Keyword::WHEN)) {
1568                                break;
1569                            }
1570                        }
1571                        if let Some(span) = parser.skip_keyword(Keyword::ELSE) {
1572                            else_ = Some((span, Box::new(parse_expression(parser, false)?)))
1573                        };
1574                        Ok(())
1575                    },
1576                )?;
1577                let end_span = parser.consume_keyword(Keyword::END)?;
1578                r.shift_expr(Expression::Case {
1579                    case_span,
1580                    value,
1581                    whens,
1582                    else_,
1583                    end_span,
1584                })
1585            }
1586            Token::AtAtGlobal | Token::AtAtSession => {
1587                let global = parser.skip_token(Token::AtAtGlobal);
1588                let session = if global.is_none() {
1589                    Some(parser.consume_token(Token::AtAtSession)?)
1590                } else {
1591                    None
1592                };
1593                let dot = Some(parser.consume_token(Token::Period)?);
1594                let variable = match &parser.token {
1595                    Token::Ident(_, Keyword::TIME_ZONE) => Variable::TimeZone,
1596                    Token::Ident(t, _) => Variable::Other(t),
1597                    _ => parser.expected_failure("Identifier")?,
1598                };
1599                let variable_span = parser.consume();
1600                r.shift_expr(Expression::Variable {
1601                    global,
1602                    session,
1603                    dot,
1604                    variable,
1605                    variable_span,
1606                })
1607            }
1608            _ => break,
1609        };
1610        if let Err(e) = e {
1611            parser.err_here(e.to_string())?;
1612        }
1613    }
1614    if r.reduce(99999).is_err() {
1615        parser.err_here("Expected expression")
1616    } else if r.stack.len() != 1 {
1617        parser.ice(file!(), line!())
1618    } else if let Some(ReduceMember::Expression(e)) = r.stack.pop() {
1619        Ok(e)
1620    } else {
1621        parser.ice(file!(), line!())
1622    }
1623}
1624
1625pub(crate) fn parse_expression_outer<'a>(
1626    parser: &mut Parser<'a, '_>,
1627) -> Result<Expression<'a>, ParseError> {
1628    if matches!(parser.token, Token::Ident(_, Keyword::SELECT)) {
1629        Ok(Expression::Subquery(Box::new(Statement::Select(
1630            parse_select(parser)?,
1631        ))))
1632    } else {
1633        parse_expression(parser, false)
1634    }
1635}
1636
1637pub(crate) fn parse_expression_paren<'a>(
1638    parser: &mut Parser<'a, '_>,
1639) -> Result<Expression<'a>, ParseError> {
1640    if matches!(parser.token, Token::Ident(_, Keyword::SELECT)) {
1641        Ok(Expression::Subquery(Box::new(parse_compound_query(
1642            parser,
1643        )?)))
1644    } else {
1645        parse_expression(parser, false)
1646    }
1647}
1648
1649#[cfg(test)]
1650mod tests {
1651    use core::ops::Deref;
1652
1653    use alloc::{
1654        format,
1655        string::{String, ToString},
1656    };
1657
1658    use crate::{
1659        expression::{BinaryOperator, Expression},
1660        issue::Issues,
1661        parser::Parser,
1662        Function, ParseOptions, SQLDialect,
1663    };
1664
1665    use super::{parse_expression, IdentifierPart};
1666
1667    fn test_ident<'a>(e: impl AsRef<Expression<'a>>, v: &str) -> Result<(), String> {
1668        let v = match e.as_ref() {
1669            Expression::Identifier(a) => match a.as_slice() {
1670                [IdentifierPart::Name(vv)] => vv.deref() == v,
1671                _ => false,
1672            },
1673            _ => false,
1674        };
1675        if !v {
1676            Err(format!("Expected identifier {} found {:?}", v, e.as_ref()))
1677        } else {
1678            Ok(())
1679        }
1680    }
1681
1682    fn test_expr(src: &'static str, f: impl FnOnce(&Expression<'_>) -> Result<(), String>) {
1683        let mut issues = Issues::new(src);
1684        let options = ParseOptions::new().dialect(SQLDialect::MariaDB);
1685        let mut parser = Parser::new(src, &mut issues, &options);
1686        let res = parse_expression(&mut parser, false).expect("Expression in test expr");
1687        if let Err(e) = f(&res) {
1688            panic!("Error parsing {}: {}\nGot {:#?}", src, e, res);
1689        }
1690    }
1691
1692    #[test]
1693    fn expressions() {
1694        test_expr("`a` + `b` * `c` + `d`", |e| {
1695            match e {
1696                Expression::Binary {
1697                    op: BinaryOperator::Add,
1698                    lhs,
1699                    rhs,
1700                    ..
1701                } => {
1702                    match lhs.as_ref() {
1703                        Expression::Binary {
1704                            op: BinaryOperator::Add,
1705                            lhs,
1706                            rhs,
1707                            ..
1708                        } => {
1709                            test_ident(lhs, "a")?;
1710                            match rhs.as_ref() {
1711                                Expression::Binary {
1712                                    op: BinaryOperator::Mult,
1713                                    lhs,
1714                                    rhs,
1715                                    ..
1716                                } => {
1717                                    test_ident(lhs, "b")?;
1718                                    test_ident(rhs, "c")?;
1719                                }
1720                                _ => return Err("Lhs.Rhs".to_string()),
1721                            }
1722                        }
1723                        _ => return Err("Lhs".to_string()),
1724                    }
1725                    test_ident(rhs, "d")?;
1726                }
1727                _ => return Err("Outer".to_string()),
1728            }
1729            Ok(())
1730        });
1731    }
1732
1733    #[test]
1734    fn mariadb_datetime_functions() {
1735        fn test_func(src: &'static str, f: Function, cnt: usize) {
1736            let mut issues = Issues::new(src);
1737            let options = ParseOptions::new().dialect(SQLDialect::MariaDB);
1738            let mut parser = Parser::new(src, &mut issues, &options);
1739            let res = match parse_expression(&mut parser, false) {
1740                Ok(res) => res,
1741                Err(e) => panic!("Unable to parse {}: {:?}", src, e),
1742            };
1743            let Expression::Function(pf, args, _) = res else {
1744                panic!("Should be parsed as function {}", src);
1745            };
1746            assert_eq!(pf, f, "Failure en expr {}", src);
1747            assert_eq!(args.len(), cnt, "Failure en expr {}", src);
1748        }
1749        test_func("ADD_MONTHS('2012-01-31', 2)", Function::AddMonths, 2);
1750        test_func(
1751            "ADDTIME('2007-12-31 23:59:59.999999', '1 1:1:1.000002')",
1752            Function::AddTime,
1753            2,
1754        );
1755        test_func(
1756            "DATE_ADD('2008-01-02', INTERVAL 31 DAY)",
1757            Function::AddDate,
1758            2,
1759        );
1760        test_func(
1761            "ADDDATE('2008-01-02', INTERVAL 31 DAY)",
1762            Function::AddDate,
1763            2,
1764        );
1765        test_func("ADDDATE('2008-01-02', 31)", Function::AddDate, 2);
1766        test_func(
1767            "CONVERT_TZ('2016-01-01 12:00:00','+00:00','+10:00')",
1768            Function::ConvertTz,
1769            3,
1770        );
1771        test_func("CURDATE()", Function::CurDate, 0);
1772        test_func("CURRENT_DATE", Function::CurDate, 0);
1773        test_func("CURRENT_DATE()", Function::CurDate, 0);
1774        test_func("CURRENT_TIME", Function::CurTime, 0);
1775        test_func("CURRENT_TIME()", Function::CurTime, 0);
1776        test_func("CURTIME()", Function::CurTime, 0);
1777        test_func("CURTIME(2)", Function::CurTime, 1);
1778        test_func("CURRENT_DATE", Function::CurDate, 0);
1779        test_func("CURRENT_DATE()", Function::CurDate, 0);
1780        test_func("CURDATE()", Function::CurDate, 0);
1781        test_func("CURRENT_TIMESTAMP", Function::CurrentTimestamp, 0);
1782        test_func("CURRENT_TIMESTAMP()", Function::CurrentTimestamp, 0);
1783        test_func("CURRENT_TIMESTAMP(10)", Function::CurrentTimestamp, 1);
1784        test_func("LOCALTIME", Function::Now, 0);
1785        test_func("LOCALTIME()", Function::Now, 0);
1786        test_func("LOCALTIME(10)", Function::Now, 1);
1787        test_func("LOCALTIMESTAMP", Function::Now, 0);
1788        test_func("LOCALTIMESTAMP()", Function::Now, 0);
1789        test_func("LOCALTIMESTAMP(10)", Function::Now, 1);
1790        test_func("DATE('2013-07-18 12:21:32')", Function::Date, 1);
1791        test_func(
1792            "DATE_FORMAT('2009-10-04 22:23:00', '%W %M %Y')",
1793            Function::DateFormat,
1794            2,
1795        );
1796        test_func(
1797            "DATE_SUB('1998-01-02', INTERVAL 31 DAY)",
1798            Function::DateSub,
1799            2,
1800        );
1801        test_func("DAY('2007-02-03')", Function::DayOfMonth, 1);
1802        test_func("DAYOFMONTH('2007-02-03')", Function::DayOfMonth, 1);
1803        test_func(
1804            "DATEDIFF('2007-12-31 23:59:59','2007-12-30')",
1805            Function::DateDiff,
1806            2,
1807        );
1808        test_func("DAYNAME('2007-02-03')", Function::DayName, 1);
1809        test_func("DAYOFYEAR('2018-02-16')", Function::DayOfYear, 1);
1810        test_func("DAYOFWEEK('2007-02-03')", Function::DayOfWeek, 1);
1811        test_expr("EXTRACT(YEAR_MONTH FROM '2009-07-02 01:02:03')", |e| {
1812            let Expression::Extract { .. } = e else {
1813                return Err("Wrong type".to_string());
1814            };
1815            Ok(())
1816        });
1817        //test_func("FORMAT_PICO_TIME(4321123443212345) AS h", Function::DayOfWeek, 1);
1818        test_func("FROM_DAYS(730669)", Function::FromDays, 1);
1819        test_func("FROM_UNIXTIME(1196440219)", Function::FromUnixTime, 1);
1820        test_func(
1821            "FROM_UNIXTIME(UNIX_TIMESTAMP(), '%Y %D %M %h:%i:%s %x')",
1822            Function::FromUnixTime,
1823            2,
1824        );
1825        //test_func("GET_FORMAT(DATE, 'EUR')", Function::GetFormat, 2);
1826        test_func("HOUR('10:05:03')", Function::Hour, 1);
1827        test_func("LAST_DAY('2004-01-01 01:01:01')", Function::LastDay, 1);
1828        test_func("MAKEDATE(2011,31)", Function::MakeDate, 2);
1829        test_func("MAKETIME(-13,57,33)", Function::MakeTime, 3);
1830        test_func("MICROSECOND('12:00:00.123456')", Function::MicroSecond, 1);
1831        test_func("MINUTE('2013-08-03 11:04:03')", Function::Minute, 1);
1832        test_func("MONTH('2019-01-03')", Function::Month, 1);
1833        test_func("MONTHNAME('2019-02-03')", Function::MonthName, 1);
1834        test_func("PERIOD_ADD(200801,2)", Function::PeriodAdd, 2);
1835        test_func("PERIOD_DIFF(200802,200703)", Function::PeriodDiff, 2);
1836        test_func("QUARTER('2008-04-01')", Function::Quarter, 1);
1837        test_func("SEC_TO_TIME(12414)", Function::SecToTime, 1);
1838        test_func("SECOND('10:05:03')", Function::Second, 1);
1839        test_func(
1840            "STR_TO_DATE('Wednesday, June 2, 2014', '%W, %M %e, %Y')",
1841            Function::StrToDate,
1842            2,
1843        );
1844        test_func(
1845            "DATE_SUB('2008-01-02', INTERVAL 31 DAY)",
1846            Function::DateSub,
1847            2,
1848        );
1849        test_func("SUBDATE('2008-01-02 12:00:00', 31)", Function::DateSub, 2);
1850        test_func(
1851            "SUBDATE('2008-01-02', INTERVAL 31 DAY)",
1852            Function::DateSub,
1853            2,
1854        );
1855        test_func(
1856            "SUBTIME('2007-12-31 23:59:59.999999','1 1:1:1.000002')",
1857            Function::SubTime,
1858            2,
1859        );
1860        test_func("SYSDATE()", Function::SysDate, 0);
1861        test_func("SYSDATE(4)", Function::SysDate, 1);
1862        test_func("TIME('2003-12-31 01:02:03')", Function::Time, 1);
1863        test_func(
1864            "TIME_FORMAT('100:00:00', '%H %k %h %I %l')",
1865            Function::TimeFormat,
1866            2,
1867        );
1868        test_func("TIME_TO_SEC('22:23:00')", Function::TimeToSec, 1);
1869        test_func(
1870            "TIMEDIFF('2008-12-31 23:59:59.000001', '2008-12-30 01:01:01.000002')",
1871            Function::TimeDiff,
1872            2,
1873        );
1874        test_func("TIMESTAMP('2003-12-31')", Function::Timestamp, 1);
1875        test_func(
1876            "TIMESTAMP('2003-12-31 12:00:00','6:30:00')",
1877            Function::Timestamp,
1878            2,
1879        );
1880        test_expr("TIMESTAMPADD(MINUTE,1,'2003-01-02')", |e| {
1881            let Expression::TimestampAdd { .. } = e else {
1882                return Err("Wrong type".to_string());
1883            };
1884            Ok(())
1885        });
1886        test_expr("TIMESTAMPDIFF(MONTH,'2003-02-01','2003-05-01');", |e| {
1887            let Expression::TimestampDiff { .. } = e else {
1888                return Err("Wrong type".to_string());
1889            };
1890            Ok(())
1891        });
1892        test_func("TO_DAYS('2007-10-07')", Function::ToDays, 1);
1893        test_func("UNIX_TIMESTAMP()", Function::UnixTimestamp, 0);
1894        test_func(
1895            "UNIX_TIMESTAMP('2007-11-30 10:30:19')",
1896            Function::UnixTimestamp,
1897            1,
1898        );
1899        test_func("UTC_DATE", Function::UtcDate, 0);
1900        test_func("UTC_DATE()", Function::UtcDate, 0);
1901        test_func("UTC_TIME", Function::UtcTime, 0);
1902        test_func("UTC_TIME()", Function::UtcTime, 0);
1903        test_func("UTC_TIME(5)", Function::UtcTime, 1);
1904        test_func("UTC_TIMESTAMP", Function::UtcTimeStamp, 0);
1905        test_func("UTC_TIMESTAMP()", Function::UtcTimeStamp, 0);
1906        test_func("UTC_TIMESTAMP(4)", Function::UtcTimeStamp, 1);
1907        test_func("WEEK('2008-02-20')", Function::Week, 1);
1908        test_func("WEEK('2008-02-20',0)", Function::Week, 2);
1909        test_func("WEEKDAY('2008-02-03 22:23:00')", Function::Weekday, 1);
1910        test_func("WEEKOFYEAR('2008-02-20')", Function::WeekOfYear, 1);
1911        test_func("YEAR('1987-01-01')", Function::Year, 1);
1912        test_func("YEARWEEK('1987-01-01')", Function::YearWeek, 1);
1913        test_func("YEARWEEK('1987-01-01',0)", Function::YearWeek, 2);
1914    }
1915}