Skip to main content

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