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)]
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    ConvertTs,
48    Cos,
49    Cot,
50    Crc32,
51    Crc32c,
52    CurDate,
53    CurrentTimestamp,
54    CurTime,
55    Date,
56    DateAdd,
57    DateDiff,
58    DateFormat,
59    DateSub,
60    Datetime,
61    DayName,
62    DayOfMonth,
63    DayOfWeek,
64    DayOfYear,
65    Degrees,
66    Elt,
67    Exists,
68    Exp,
69    ExportSet,
70    ExtractValue,
71    Field,
72    FindInSet,
73    Floor,
74    Format,
75    FromBase64,
76    FromDays,
77    FromUnixTime,
78    Greatest,
79    Hex,
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    LCase,
124    Least,
125    Left,
126    Length,
127    LengthB,
128    Ln,
129    LoadFile,
130    Locate,
131    Log,
132    Log10,
133    Log2,
134    Lower,
135    LPad,
136    LTrim,
137    MakeDate,
138    MakeSet,
139    MakeTime,
140    Max,
141    MicroSecond,
142    Mid,
143    Min,
144    Minute,
145    MonthName,
146    NaturalSortkey,
147    Now,
148    NullIf,
149    NVL2,
150    Oct,
151    OctetLength,
152    Ord,
153    PeriodAdd,
154    PeriodDiff,
155    Pi,
156    Position,
157    Pow,
158    Quarter,
159    Quote,
160    Radians,
161    Rand,
162    Repeat,
163    Replace,
164    Reverse,
165    Right,
166    Round,
167    RPad,
168    RTrim,
169    Second,
170    SecToTime,
171    SFormat,
172    Sign,
173    Sin,
174    SoundEx,
175    Space,
176    Sqrt,
177    StrCmp,
178    Strftime,
179    StrToDate,
180    SubDate,
181    SubStr,
182    SubStringIndex,
183    SubTime,
184    Sum,
185    Tan,
186    Time,
187    TimeDiff,
188    TimeFormat,
189    Timestamp,
190    TimestampAdd,
191    TimestampDiff,
192    TimeToSec,
193    ToBase64,
194    ToChar,
195    ToDays,
196    ToSeconds,
197    Truncate,
198    UCase,
199    UncompressedLength,
200    UnHex,
201    UnixTimestamp,
202    Unknown,
203    UpdateXml,
204    Upper,
205    UtcDate,
206    UtcTime,
207    UtcTimeStamp,
208    Value,
209    Week,
210    Weekday,
211    WeekOfYear,
212    Lead,
213    Lag,
214    Other(&'a str),
215}
216
217/// Function to execute
218#[derive(Debug, Clone)]
219pub enum Variable<'a> {
220    TimeZone,
221    Other(&'a str),
222}
223
224/// Binary operator to apply
225#[derive(Debug, Clone, Copy)]
226pub enum BinaryOperator {
227    Or,
228    Xor,
229    And,
230    Eq,
231    NullSafeEq,
232    GtEq,
233    Gt,
234    LtEq,
235    Lt,
236    Neq,
237    ShiftLeft,
238    ShiftRight,
239    BitAnd,
240    BitOr,
241    BitXor,
242    Add,
243    Subtract,
244    Divide,
245    Div,
246    Mod,
247    Mult,
248    Like,
249    NotLike,
250}
251
252/// Type of is expression
253#[derive(Debug, Clone, Copy)]
254pub enum Is {
255    Null,
256    NotNull,
257    True,
258    NotTrue,
259    False,
260    NotFalse,
261    Unknown,
262    NotUnknown,
263}
264
265/// Unary operator to apply
266#[derive(Debug, Clone, Copy)]
267pub enum UnaryOperator {
268    Binary,
269    Collate,
270    LogicalNot,
271    Minus,
272    Not,
273}
274
275/// Part of a full identifier
276#[derive(Debug, Clone)]
277pub enum IdentifierPart<'a> {
278    Name(Identifier<'a>),
279    Star(Span),
280}
281
282impl<'a> Spanned for IdentifierPart<'a> {
283    fn span(&self) -> Span {
284        match &self {
285            IdentifierPart::Name(v) => v.span(),
286            IdentifierPart::Star(v) => v.span(),
287        }
288    }
289}
290
291/// When part of CASE
292#[derive(Debug, Clone)]
293pub struct When<'a> {
294    /// Span of WHEN
295    pub when_span: Span,
296    /// When to return then
297    pub when: Expression<'a>,
298    /// Span of THEN
299    pub then_span: Span,
300    /// What to return when when applyes
301    pub then: Expression<'a>,
302}
303
304impl<'a> Spanned for When<'a> {
305    fn span(&self) -> Span {
306        self.when_span
307            .join_span(&self.when)
308            .join_span(&self.then_span)
309            .join_span(&self.then)
310    }
311}
312
313/// When part of CASE
314#[derive(Debug, Clone)]
315pub struct WindowSpec<'a> {
316    /// Span of "ORDER BY" and list of order expression and directions, if specified
317    pub order_by: (Span, Vec<(Expression<'a>, OrderFlag)>),
318}
319
320impl<'a> Spanned for WindowSpec<'a> {
321    fn span(&self) -> Span {
322        self.order_by.span()
323    }
324}
325
326/// Representation of an expression
327#[derive(Debug, Clone)]
328pub enum Expression<'a> {
329    /// Expression with binary operator
330    Binary {
331        /// The operator to apply
332        op: BinaryOperator,
333        /// The span of the operator
334        op_span: Span,
335        /// Expression on the left hand side
336        lhs: Box<Expression<'a>>,
337        /// Expression on the right hand side
338        rhs: Box<Expression<'a>>,
339    },
340    /// Expression with a unary (prefix) operator
341    Unary {
342        /// The operator to apply
343        op: UnaryOperator,
344        /// The span of the operator
345        op_span: Span,
346        /// The expression on the right hand side
347        operand: Box<Expression<'a>>,
348    },
349    /// Subquery expression
350    Subquery(Box<Statement<'a>>),
351    /// Literal NULL expression
352    Null(Span),
353    /// Literal bool expression "TRUE" or "FALSE"
354    Bool(bool, Span),
355    /// Literal string expression, the SString contains the represented string
356    /// with escaping removed
357    String(SString<'a>),
358    /// Literal integer expression
359    Integer((u64, Span)),
360    /// Literal _LIST_
361    ListHack((usize, Span)),
362    /// Literal floating point expression
363    Float((f64, Span)),
364    /// Function call expression,
365    Function(Function<'a>, Vec<Expression<'a>>, Span),
366    /// A window function call expression
367    WindowFunction {
368        function: Function<'a>,
369        args: Vec<Expression<'a>>,
370        function_span: Span,
371        over_span: Span,
372        window_spec: WindowSpec<'a>,
373    },
374    /// Identifier pointing to column
375    Identifier(Vec<IdentifierPart<'a>>),
376    /// Input argument to query, the first argument is the occurrence number of the argumnet
377    Arg((usize, Span)),
378    /// Exists expression
379    Exists(Box<Statement<'a>>),
380    /// In expression
381    In {
382        /// Left hand side expression
383        lhs: Box<Expression<'a>>,
384        /// Right hand side expression
385        rhs: Vec<Expression<'a>>,
386        /// Span of "IN" or "NOT IN"
387        in_span: Span,
388        /// True if not in
389        not_in: bool,
390    },
391    /// Is expression
392    Is(Box<Expression<'a>>, Is, Span),
393    /// Invalid expression, returned on recovery of a parse error
394    Invalid(Span),
395    /// Case expression
396    Case {
397        /// Span of "CASE"
398        case_span: Span,
399        /// Optional value to switch over
400        value: Option<Box<Expression<'a>>>,
401        /// When parts
402        whens: Vec<When<'a>>,
403        /// Span of "ELSE" and else value if specified
404        else_: Option<(Span, Box<Expression<'a>>)>,
405        /// Span of "END"
406        end_span: Span,
407    },
408    /// Cast expression
409    Cast {
410        /// Span of "CAST"
411        cast_span: Span,
412        /// Value to cast
413        expr: Box<Expression<'a>>,
414        /// Span of "AS"
415        as_span: Span,
416        /// Type to cast to
417        type_: DataType<'a>,
418    },
419    /// Count expression
420    Count {
421        /// Span of "COUNT"
422        count_span: Span,
423        /// Span of "DISTINCT" if specified
424        distinct_span: Option<Span>,
425        /// Expression to count
426        expr: Box<Expression<'a>>,
427    },
428    /// Group contat expression
429    GroupConcat {
430        /// Span of "GROUP_CONCAT"
431        group_concat_span: Span,
432        /// Span of "DISTINCT" if specified
433        distinct_span: Option<Span>,
434        /// Expression to count
435        expr: Box<Expression<'a>>,
436    },
437    /// Variable expression
438    Variable {
439        /// Span of "@@GLOBAL"
440        global: Option<Span>,
441        /// Span of "@@SESSION"
442        session: Option<Span>,
443        /// Span of '.'
444        dot: Option<Span>,
445        /// variable
446        variable: Variable<'a>,
447        // Span of variable
448        variable_span: Span,
449    },
450}
451
452impl<'a> Spanned for Expression<'a> {
453    fn span(&self) -> Span {
454        match &self {
455            Expression::Binary {
456                op_span, lhs, rhs, ..
457            } => op_span.join_span(lhs).join_span(rhs),
458            Expression::Unary {
459                op_span, operand, ..
460            } => op_span.join_span(operand),
461            Expression::Subquery(v) => v.span(),
462            Expression::Null(v) => v.span(),
463            Expression::Bool(_, v) => v.span(),
464            Expression::String(v) => v.span(),
465            Expression::Integer(v) => v.span(),
466            Expression::Float(v) => v.span(),
467            Expression::ListHack((_, s)) => s.span(),
468            Expression::Function(_, b, c) => c.join_span(b),
469            Expression::Identifier(v) => v.opt_span().expect("Span of identifier parts"),
470            Expression::Arg(v) => v.span(),
471            Expression::Exists(v) => v.span(),
472            Expression::In {
473                lhs, rhs, in_span, ..
474            } => in_span.join_span(lhs).join_span(rhs),
475            Expression::Is(a, _, b) => b.join_span(a),
476            Expression::Invalid(s) => s.span(),
477            Expression::Case {
478                case_span,
479                value,
480                whens,
481                else_,
482                end_span,
483            } => case_span
484                .join_span(value)
485                .join_span(whens)
486                .join_span(else_)
487                .join_span(end_span),
488            Expression::Cast {
489                cast_span,
490                expr,
491                as_span,
492                type_,
493            } => cast_span
494                .join_span(expr)
495                .join_span(as_span)
496                .join_span(type_),
497            Expression::Count {
498                count_span,
499                distinct_span,
500                expr,
501            } => count_span.join_span(distinct_span).join_span(expr),
502            Expression::GroupConcat {
503                group_concat_span,
504                distinct_span,
505                expr,
506            } => group_concat_span.join_span(distinct_span).join_span(expr),
507            Expression::Variable {
508                global,
509                session,
510                dot,
511                variable_span,
512                variable: _,
513            } => variable_span
514                .join_span(global)
515                .join_span(session)
516                .join_span(dot),
517            Expression::WindowFunction {
518                function: _,
519                args,
520                function_span,
521                over_span,
522                window_spec,
523            } => function_span
524                .join_span(args)
525                .join_span(over_span)
526                .join_span(window_spec),
527        }
528    }
529}
530
531fn parse_function<'a>(
532    parser: &mut Parser<'a, '_>,
533    t: Token<'a>,
534    span: Span,
535) -> Result<Expression<'a>, ParseError> {
536    parser.consume_token(Token::LParen)?;
537    let func = match &t {
538        // https://mariadb.com/kb/en/string-functions/
539        Token::Ident(_, Keyword::ASCII) => Function::Ascii,
540        Token::Ident(_, Keyword::BIN) => Function::Bin,
541        Token::Ident(_, Keyword::BIT_LENGTH) => Function::BitLength,
542        Token::Ident(_, Keyword::CHAR_LENGTH) => Function::CharacterLength,
543        Token::Ident(_, Keyword::CHARACTER_LENGTH) => Function::CharacterLength,
544        Token::Ident(_, Keyword::CHR) => Function::Chr,
545        Token::Ident(_, Keyword::CONCAT) => Function::Concat,
546        Token::Ident(_, Keyword::CONCAT_WS) => Function::ConcatWs,
547        Token::Ident(_, Keyword::ELT) => Function::Elt,
548        Token::Ident(_, Keyword::EXPORT_SET) => Function::ExportSet,
549        Token::Ident(_, Keyword::EXTRACTVALUE) => Function::ExtractValue,
550        Token::Ident(_, Keyword::FIELD) => Function::Field,
551        Token::Ident(_, Keyword::FIND_IN_SET) => Function::FindInSet,
552        Token::Ident(_, Keyword::FORMAT) => Function::Format,
553        Token::Ident(_, Keyword::FROM_BASE64) => Function::FromBase64,
554        Token::Ident(_, Keyword::HEX) => Function::Hex,
555        Token::Ident(_, Keyword::INSERT) => Function::Insert,
556        Token::Ident(_, Keyword::INSTR) => Function::InStr,
557        Token::Ident(_, Keyword::LCASE) => Function::LCase,
558        Token::Ident(_, Keyword::LEFT) => Function::Left,
559        Token::Ident(_, Keyword::LENGTH) => Function::Length,
560        Token::Ident(_, Keyword::LENGTHB) => Function::LengthB,
561        Token::Ident(_, Keyword::LOAD_FILE) => Function::LoadFile,
562        Token::Ident(_, Keyword::LOCATE) => Function::Locate,
563        Token::Ident(_, Keyword::LOWER) => Function::Lower,
564        Token::Ident(_, Keyword::LPAD) => Function::LPad,
565        Token::Ident(_, Keyword::LTRIM) => Function::LTrim,
566        Token::Ident(_, Keyword::MAKE_SET) => Function::MakeSet,
567        Token::Ident(_, Keyword::MID) => Function::Mid,
568        Token::Ident(_, Keyword::NATURAL_SORT_KEY) => Function::NaturalSortkey,
569        Token::Ident(_, Keyword::OCTET_LENGTH) => Function::OctetLength,
570        Token::Ident(_, Keyword::ORD) => Function::Ord,
571        Token::Ident(_, Keyword::POSITION) => Function::Position,
572        Token::Ident(_, Keyword::QUOTE) => Function::Quote,
573        Token::Ident(_, Keyword::REPEAT) => Function::Repeat,
574        Token::Ident(_, Keyword::REPLACE) => Function::Replace,
575        Token::Ident(_, Keyword::REVERSE) => Function::Reverse,
576        Token::Ident(_, Keyword::RIGHT) => Function::Right,
577        Token::Ident(_, Keyword::RPAD) => Function::RPad,
578        Token::Ident(_, Keyword::RTRIM) => Function::RTrim,
579        Token::Ident(_, Keyword::SOUNDEX) => Function::SoundEx,
580        Token::Ident(_, Keyword::SPACE) => Function::Space,
581        Token::Ident(_, Keyword::STRCMP) => Function::StrCmp,
582        Token::Ident(_, Keyword::SUBSTR) => Function::SubStr,
583        Token::Ident(_, Keyword::SUBSTRING) => Function::SubStr,
584        Token::Ident(_, Keyword::SUBSTRING_INDEX) => Function::SubStringIndex,
585        Token::Ident(_, Keyword::TO_BASE64) => Function::ToBase64,
586        Token::Ident(_, Keyword::TO_CHAR) => Function::ToChar,
587        Token::Ident(_, Keyword::UCASE) => Function::UCase,
588        Token::Ident(_, Keyword::UNCOMPRESSED_LENGTH) => Function::UncompressedLength,
589        Token::Ident(_, Keyword::UNHEX) => Function::UnHex,
590        Token::Ident(_, Keyword::UPDATEXML) => Function::UpdateXml,
591        Token::Ident(_, Keyword::UPPER) => Function::Upper,
592        Token::Ident(_, Keyword::SFORMAT) => Function::SFormat,
593
594        // TODO uncat
595        Token::Ident(_, Keyword::EXISTS) => Function::Exists,
596        Token::Ident(_, Keyword::MIN) => Function::Min,
597        Token::Ident(_, Keyword::MAX) => Function::Max,
598        Token::Ident(_, Keyword::SUM) => Function::Sum,
599        Token::Ident(_, Keyword::VALUE) => Function::Value,
600        Token::Ident(_, Keyword::VALUES) => Function::Value,
601        Token::Ident(_, Keyword::LEAD) => Function::Lead,
602        Token::Ident(_, Keyword::LAG) => Function::Lag,
603
604        //https://mariadb.com/kb/en/control-flow-functions/
605        Token::Ident(_, Keyword::IFNULL) => Function::IfNull,
606        Token::Ident(_, Keyword::NULLIF) => Function::NullIf,
607        Token::Ident(_, Keyword::NVL) => Function::IfNull,
608        Token::Ident(_, Keyword::NVL2) => Function::NVL2,
609        Token::Ident(_, Keyword::IF) => Function::If,
610
611        //https://mariadb.com/kb/en/numeric-functions/
612        Token::Ident(_, Keyword::ABS) => Function::Abs,
613        Token::Ident(_, Keyword::ACOS) => Function::Acos,
614        Token::Ident(_, Keyword::ASIN) => Function::Asin,
615        Token::Ident(_, Keyword::ATAN) => Function::Atan,
616        Token::Ident(_, Keyword::ATAN2) => Function::Atan2,
617        Token::Ident(_, Keyword::CEIL | Keyword::CEILING) => Function::Ceil,
618        Token::Ident(_, Keyword::CONV) => Function::Conv,
619        Token::Ident(_, Keyword::COS) => Function::Cos,
620        Token::Ident(_, Keyword::COT) => Function::Cot,
621        Token::Ident(_, Keyword::CRC32) => Function::Crc32,
622        Token::Ident(_, Keyword::DEGREES) => Function::Degrees,
623        Token::Ident(_, Keyword::EXP) => Function::Exp,
624        Token::Ident(_, Keyword::FLOOR) => Function::Floor,
625        Token::Ident(_, Keyword::GREATEST) => Function::Greatest,
626        Token::Ident(_, Keyword::LN) => Function::Ln,
627        Token::Ident(_, Keyword::LOG) => Function::Log,
628        Token::Ident(_, Keyword::LOG10) => Function::Log10,
629        Token::Ident(_, Keyword::LOG2) => Function::Log2,
630        Token::Ident(_, Keyword::OCT) => Function::Oct,
631        Token::Ident(_, Keyword::PI) => Function::Pi,
632        Token::Ident(_, Keyword::POW | Keyword::POWER) => Function::Pow,
633        Token::Ident(_, Keyword::RADIANS) => Function::Radians,
634        Token::Ident(_, Keyword::RAND) => Function::Rand,
635        Token::Ident(_, Keyword::ROUND) => Function::Round,
636        Token::Ident(_, Keyword::SIGN) => Function::Sign,
637        Token::Ident(_, Keyword::SIN) => Function::Sin,
638        Token::Ident(_, Keyword::SQRT) => Function::Sqrt,
639        Token::Ident(_, Keyword::TAN) => Function::Tan,
640        Token::Ident(_, Keyword::TRUNCATE) => Function::Truncate,
641        Token::Ident(_, Keyword::CRC32C) => Function::Crc32c,
642        Token::Ident(_, Keyword::LEAST) => Function::Least,
643
644        // https://mariadb.com/kb/en/date-time-functions/
645        Token::Ident(_, Keyword::ADDDATE) => Function::AddDate,
646        Token::Ident(_, Keyword::ADDTIME) => Function::AddTime,
647        Token::Ident(_, Keyword::CONVERT_TS) => Function::ConvertTs,
648        Token::Ident(_, Keyword::CURDATE) => Function::CurDate,
649        Token::Ident(_, Keyword::CURRENT_DATE) => Function::CurDate,
650        Token::Ident(_, Keyword::CURRENT_TIME) => Function::CurTime,
651        Token::Ident(_, Keyword::CURTIME) => Function::CurTime,
652        Token::Ident(_, Keyword::DATE) => Function::Date,
653        Token::Ident(_, Keyword::DATEDIFF) => Function::DateDiff,
654        Token::Ident(_, Keyword::DATE_ADD) => Function::DateAdd,
655        Token::Ident(_, Keyword::DATE_FORMAT) => Function::DateFormat,
656        Token::Ident(_, Keyword::DATE_SUB) => Function::DateSub,
657        Token::Ident(_, Keyword::DAY | Keyword::DAYOFMONTH) => Function::DayOfMonth,
658        Token::Ident(_, Keyword::DAYNAME) => Function::DayName,
659        Token::Ident(_, Keyword::DAYOFWEEK) => Function::DayOfWeek,
660        Token::Ident(_, Keyword::DAYOFYEAR) => Function::DayOfYear,
661        Token::Ident(_, Keyword::FROM_DAYS) => Function::FromDays,
662        Token::Ident(
663            _,
664            Keyword::LOCALTIME | Keyword::LOCALTIMESTAMP | Keyword::CURRENT_TIMESTAMP,
665        ) => Function::Now,
666        Token::Ident(_, Keyword::MAKEDATE) => Function::MakeDate,
667        Token::Ident(_, Keyword::MAKETIME) => Function::MakeTime,
668        Token::Ident(_, Keyword::MICROSECOND) => Function::MicroSecond,
669        Token::Ident(_, Keyword::MINUTE) => Function::Minute,
670        Token::Ident(_, Keyword::MONTHNAME) => Function::MonthName,
671        Token::Ident(_, Keyword::NOW) => Function::Now,
672        Token::Ident(_, Keyword::PERIOD_ADD) => Function::PeriodAdd,
673        Token::Ident(_, Keyword::PERIOD_DIFF) => Function::PeriodDiff,
674        Token::Ident(_, Keyword::QUARTER) => Function::Quarter,
675        Token::Ident(_, Keyword::SECOND) => Function::Second,
676        Token::Ident(_, Keyword::SEC_TO_TIME) => Function::SecToTime,
677        Token::Ident(_, Keyword::STR_TO_DATE) => Function::StrToDate,
678        Token::Ident(_, Keyword::SUBDATE) => Function::SubDate,
679        Token::Ident(_, Keyword::SUBTIME) => Function::SubTime,
680        Token::Ident(_, Keyword::TIME) => Function::Time,
681        Token::Ident(_, Keyword::TIMEDIFF) => Function::TimeDiff,
682        Token::Ident(_, Keyword::TIMESTAMP) => Function::Timestamp,
683        Token::Ident(_, Keyword::TIMESTAMPADD) => Function::TimestampAdd,
684        Token::Ident(_, Keyword::TIMESTAMPDIFF) => Function::TimestampDiff,
685        Token::Ident(_, Keyword::TIME_FORMAT) => Function::TimeFormat,
686        Token::Ident(_, Keyword::TIME_TO_SEC) => Function::TimeToSec,
687        Token::Ident(_, Keyword::TO_DAYS) => Function::ToDays,
688        Token::Ident(_, Keyword::TO_SECONDS) => Function::ToSeconds,
689        Token::Ident(_, Keyword::UNIX_TIMESTAMP) => Function::UnixTimestamp,
690        Token::Ident(_, Keyword::UTC_DATE) => Function::UtcDate,
691        Token::Ident(_, Keyword::UTC_TIME) => Function::UtcTime,
692        Token::Ident(_, Keyword::UTC_TIMESTAMP) => Function::UtcTimeStamp,
693        Token::Ident(_, Keyword::WEEK) => Function::Week,
694        Token::Ident(_, Keyword::WEEKDAY) => Function::Weekday,
695        Token::Ident(_, Keyword::WEEKOFYEAR) => Function::WeekOfYear,
696        Token::Ident(_, Keyword::ADD_MONTHS) => Function::AddMonths,
697        Token::Ident(_, Keyword::FROM_UNIXTIME) => Function::FromUnixTime,
698
699        // https://mariadb.com/kb/en/json-functions/
700        Token::Ident(_, Keyword::JSON_ARRAY) => Function::JsonArray,
701        Token::Ident(_, Keyword::JSON_ARRAYAGG) => Function::JsonArrayAgg,
702        Token::Ident(_, Keyword::JSON_ARRAY_APPEND) => Function::JsonArrayAppend,
703        Token::Ident(_, Keyword::JSON_ARRAY_INSERT) => Function::JsonArrayInsert,
704        Token::Ident(_, Keyword::JSON_ARRAY_INTERSECT) => Function::JsonArrayIntersect,
705        Token::Ident(_, Keyword::JSON_COMPACT) => Function::JsonCompact,
706        Token::Ident(_, Keyword::JSON_CONTAINS) => Function::JsonContains,
707        Token::Ident(_, Keyword::JSON_CONTAINS_PATH) => Function::JsonContainsPath,
708        Token::Ident(_, Keyword::JSON_DEPTH) => Function::JsonDepth,
709        Token::Ident(_, Keyword::JSON_DETAILED) => Function::JsonDetailed,
710        Token::Ident(_, Keyword::JSON_EQUALS) => Function::JsonEquals,
711        Token::Ident(_, Keyword::JSON_EXISTS) => Function::JsonExists,
712        Token::Ident(_, Keyword::JSON_EXTRACT) => Function::JsonExtract,
713        Token::Ident(_, Keyword::JSON_INSERT) => Function::JsonInsert,
714        Token::Ident(_, Keyword::JSON_KEYS) => Function::JsonKeys,
715        Token::Ident(_, Keyword::JSON_LENGTH) => Function::JsonLength,
716        Token::Ident(_, Keyword::JSON_LOOSE) => Function::JsonLoose,
717        Token::Ident(_, Keyword::JSON_MERGE) => Function::JsonMerge,
718        Token::Ident(_, Keyword::JSON_MERGE_PATCH) => Function::JsonMergePath,
719        Token::Ident(_, Keyword::JSON_MERGE_PRESERVE) => Function::JsonMergePerserve,
720        Token::Ident(_, Keyword::JSON_NORMALIZE) => Function::JsonNormalize,
721        Token::Ident(_, Keyword::JSON_OBJECT) => Function::JsonObject,
722        Token::Ident(_, Keyword::JSON_OBJECT_FILTER_KEYS) => Function::JsonObjectFilterKeys,
723        Token::Ident(_, Keyword::JSON_OBJECT_TO_ARRAY) => Function::JsonObjectToArray,
724        Token::Ident(_, Keyword::JSON_OBJECTAGG) => Function::JsonObjectAgg,
725        Token::Ident(_, Keyword::JSON_OVERLAPS) => Function::JsonOverlaps,
726        Token::Ident(_, Keyword::JSON_PRETTY) => Function::JsonPretty,
727        Token::Ident(_, Keyword::JSON_QUERY) => Function::JsonQuery,
728        Token::Ident(_, Keyword::JSON_QUOTE) => Function::JsonQuote,
729        Token::Ident(_, Keyword::JSON_REMOVE) => Function::JsonRemove,
730        Token::Ident(_, Keyword::JSON_REPLACE) => Function::JsonReplace,
731        Token::Ident(_, Keyword::JSON_SCHEMA_VALID) => Function::JsonSchemaValid,
732        Token::Ident(_, Keyword::JSON_SEARCH) => Function::JsonSearch,
733        Token::Ident(_, Keyword::JSON_SET) => Function::JsonSet,
734        Token::Ident(_, Keyword::JSON_TABLE) => Function::JsonTable,
735        Token::Ident(_, Keyword::JSON_TYPE) => Function::JsonType,
736        Token::Ident(_, Keyword::JSON_UNQUOTE) => Function::JsonUnquote,
737        Token::Ident(_, Keyword::JSON_VALID) => Function::JsonValid,
738        Token::Ident(_, Keyword::JSON_VALUE) => Function::JsonValue,
739
740        // Sqlite
741        Token::Ident(_, Keyword::STRFTIME) => Function::Strftime,
742        Token::Ident(_, Keyword::DATETIME) => Function::Datetime,
743        Token::Ident(v, k) if !k.reserved() => Function::Other(v),
744        _ => {
745            parser.err("Unknown function", &span);
746            Function::Unknown
747        }
748    };
749
750    let mut args = Vec::new();
751    if !matches!(parser.token, Token::RParen) {
752        loop {
753            parser.recovered(
754                "')' or ','",
755                &|t| matches!(t, Token::RParen | Token::Comma),
756                |parser| {
757                    args.push(parse_expression_outer(parser)?);
758                    Ok(())
759                },
760            )?;
761            if parser.skip_token(Token::Comma).is_none() {
762                break;
763            }
764        }
765    }
766    parser.consume_token(Token::RParen)?;
767
768    if let Some(over_span) = parser.skip_keyword(Keyword::OVER) {
769        parser.consume_token(Token::LParen)?;
770        let order_span = parser.consume_keywords(&[Keyword::ORDER, Keyword::BY])?;
771        let mut order = Vec::new();
772        loop {
773            let e = parse_expression(parser, false)?;
774            let f = match &parser.token {
775                Token::Ident(_, Keyword::ASC) => OrderFlag::Asc(parser.consume()),
776                Token::Ident(_, Keyword::DESC) => OrderFlag::Desc(parser.consume()),
777                _ => OrderFlag::None,
778            };
779            order.push((e, f));
780            if parser.skip_token(Token::Comma).is_none() {
781                break;
782            }
783        }
784        parser.consume_token(Token::RParen)?;
785        Ok(Expression::WindowFunction {
786            function: func,
787            args,
788            function_span: span,
789            over_span,
790            window_spec: WindowSpec {
791                order_by: (order_span, order),
792            },
793        })
794    } else {
795        Ok(Expression::Function(func, args, span))
796    }
797}
798
799//const INTERVAL_PRIORITY: usize = 10;
800const IN_PRIORITY: usize = 110;
801
802trait Priority {
803    fn priority(&self) -> usize;
804}
805
806impl Priority for BinaryOperator {
807    fn priority(&self) -> usize {
808        match self {
809            BinaryOperator::Or => 140,
810            BinaryOperator::Xor => 150,
811            BinaryOperator::And => 160,
812            BinaryOperator::Eq => 110,
813            BinaryOperator::NullSafeEq => 110,
814            BinaryOperator::GtEq => 110,
815            BinaryOperator::Gt => 110,
816            BinaryOperator::LtEq => 110,
817            BinaryOperator::Lt => 110,
818            BinaryOperator::Neq => 110,
819            BinaryOperator::Like => 110,
820            BinaryOperator::NotLike => 110,
821            BinaryOperator::ShiftLeft => 80,
822            BinaryOperator::ShiftRight => 80,
823            BinaryOperator::BitAnd => 90,
824            BinaryOperator::BitOr => 100,
825            BinaryOperator::BitXor => 50,
826            BinaryOperator::Add => 70,
827            BinaryOperator::Subtract => 70,
828            BinaryOperator::Divide => 60,
829            BinaryOperator::Div => 60,
830            BinaryOperator::Mod => 60,
831            BinaryOperator::Mult => 60,
832        }
833    }
834}
835
836impl Priority for UnaryOperator {
837    fn priority(&self) -> usize {
838        match self {
839            UnaryOperator::Binary => 20,
840            UnaryOperator::Collate => 20,
841            UnaryOperator::LogicalNot => 30,
842            UnaryOperator::Minus => 40,
843            UnaryOperator::Not => 130,
844        }
845    }
846}
847
848#[derive(Debug)]
849enum ReduceMember<'a> {
850    Expression(Expression<'a>),
851    Binary(BinaryOperator, Span),
852    Unary(UnaryOperator, Span),
853}
854
855struct Reducer<'a> {
856    stack: Vec<ReduceMember<'a>>,
857}
858
859impl<'a> Reducer<'a> {
860    fn reduce(&mut self, priority: usize) -> Result<(), &'static str> {
861        let mut e = match self.stack.pop() {
862            Some(ReduceMember::Expression(e)) => e,
863            _ => {
864                return Err("Expected expression before here");
865            }
866        };
867        loop {
868            let v = self.stack.pop();
869            match v {
870                None => break,
871                Some(ReduceMember::Expression(_)) => return Err("ICE Reduce stack error 1"),
872                Some(ReduceMember::Unary(op, span)) if op.priority() > priority => {
873                    self.stack.push(ReduceMember::Unary(op, span));
874                    break;
875                }
876                Some(ReduceMember::Binary(op, span)) if op.priority() > priority => {
877                    self.stack.push(ReduceMember::Binary(op, span));
878                    break;
879                }
880                Some(ReduceMember::Unary(op, op_span)) => {
881                    e = Expression::Unary {
882                        op,
883                        op_span,
884                        operand: Box::new(e),
885                    };
886                }
887                Some(ReduceMember::Binary(op, op_span)) => {
888                    let lhs = match self.stack.pop() {
889                        Some(ReduceMember::Expression(e)) => e,
890                        _ => return Err("ICE Reduce stack error 2"),
891                    };
892                    e = Expression::Binary {
893                        op,
894                        op_span,
895                        lhs: Box::new(lhs),
896                        rhs: Box::new(e),
897                    };
898                }
899            }
900        }
901        self.stack.push(ReduceMember::Expression(e));
902        Ok(())
903    }
904
905    fn shift_binop(&mut self, span: Span, op: BinaryOperator) -> Result<(), &'static str> {
906        self.reduce(op.priority())?;
907        self.stack.push(ReduceMember::Binary(op, span));
908        Ok(())
909    }
910
911    fn shift_unary(&mut self, span: Span, op: UnaryOperator) -> Result<(), &'static str> {
912        if matches!(self.stack.last(), Some(ReduceMember::Expression(_))) {
913            return Err("Unary operator cannot come before expression");
914        }
915        self.stack.push(ReduceMember::Unary(op, span));
916        Ok(())
917    }
918
919    fn shift_expr(&mut self, e: Expression<'a>) -> Result<(), &'static str> {
920        if matches!(self.stack.last(), Some(ReduceMember::Expression(_))) {
921            //panic!();
922            return Err("Expression should not follow expression");
923        }
924        self.stack.push(ReduceMember::Expression(e));
925        Ok(())
926    }
927}
928
929pub(crate) fn parse_expression<'a>(
930    parser: &mut Parser<'a, '_>,
931    inner: bool,
932) -> Result<Expression<'a>, ParseError> {
933    let mut r = Reducer { stack: Vec::new() };
934    loop {
935        let e = match &parser.token {
936            Token::Ident(_, Keyword::OR) | Token::DoublePipe if !inner => {
937                r.shift_binop(parser.consume(), BinaryOperator::Or)
938            }
939            Token::Ident(_, Keyword::XOR) if !inner => {
940                r.shift_binop(parser.consume(), BinaryOperator::Xor)
941            }
942            Token::Ident(_, Keyword::AND) | Token::DoubleAmpersand if !inner => {
943                r.shift_binop(parser.consume(), BinaryOperator::And)
944            }
945            Token::Eq if !inner => r.shift_binop(parser.consume(), BinaryOperator::Eq),
946            Token::Spaceship if !inner => {
947                r.shift_binop(parser.consume(), BinaryOperator::NullSafeEq)
948            }
949            Token::GtEq if !inner => r.shift_binop(parser.consume(), BinaryOperator::GtEq),
950            Token::Gt if !inner => r.shift_binop(parser.consume(), BinaryOperator::Gt),
951            Token::LtEq if !inner => r.shift_binop(parser.consume(), BinaryOperator::LtEq),
952            Token::Lt if !inner => r.shift_binop(parser.consume(), BinaryOperator::Lt),
953            Token::Neq if !inner => r.shift_binop(parser.consume(), BinaryOperator::Neq),
954            Token::ShiftLeft if !inner => {
955                r.shift_binop(parser.consume(), BinaryOperator::ShiftLeft)
956            }
957            Token::ShiftRight if !inner => {
958                r.shift_binop(parser.consume(), BinaryOperator::ShiftRight)
959            }
960            Token::Ampersand => r.shift_binop(parser.consume(), BinaryOperator::BitAnd),
961            Token::Pipe if !inner => r.shift_binop(parser.consume(), BinaryOperator::BitOr),
962            Token::Ident(_, Keyword::BINARY) if !inner => {
963                r.shift_unary(parser.consume(), UnaryOperator::Binary)
964            }
965            Token::Ident(_, Keyword::COLLATE) if !inner => {
966                r.shift_unary(parser.consume(), UnaryOperator::Collate)
967            }
968            Token::ExclamationMark if !inner => {
969                r.shift_unary(parser.consume(), UnaryOperator::LogicalNot)
970            }
971            Token::Minus if !matches!(r.stack.last(), Some(ReduceMember::Expression(_))) => {
972                r.shift_unary(parser.consume(), UnaryOperator::Minus)
973            }
974            Token::Minus
975                if !inner && matches!(r.stack.last(), Some(ReduceMember::Expression(_))) =>
976            {
977                r.shift_binop(parser.consume(), BinaryOperator::Subtract)
978            }
979            Token::Ident(_, Keyword::IN) if !inner => {
980                if let Err(e) = r.reduce(IN_PRIORITY) {
981                    parser.err_here(e)?;
982                }
983                let lhs = match r.stack.pop() {
984                    Some(ReduceMember::Expression(e)) => e,
985                    _ => parser.err_here("Expected expression before here 3")?,
986                };
987                let op = parser.consume_keyword(Keyword::IN)?;
988                parser.consume_token(Token::LParen)?;
989                let mut rhs = Vec::new();
990                loop {
991                    parser.recovered(
992                        "')' or ','",
993                        &|t| matches!(t, Token::RParen | Token::Comma),
994                        |parser| {
995                            rhs.push(parse_expression_paren(parser)?);
996                            Ok(())
997                        },
998                    )?;
999                    if parser.skip_token(Token::Comma).is_none() {
1000                        break;
1001                    }
1002                }
1003                parser.consume_token(Token::RParen)?;
1004                r.shift_expr(Expression::In {
1005                    lhs: Box::new(lhs),
1006                    rhs,
1007                    in_span: op,
1008                    not_in: false,
1009                })
1010            }
1011            Token::Ident(_, Keyword::IS) if !inner => {
1012                if let Err(e) = r.reduce(IN_PRIORITY) {
1013                    parser.err_here(e)?;
1014                }
1015                let lhs = match r.stack.pop() {
1016                    Some(ReduceMember::Expression(e)) => e,
1017                    _ => parser.err_here("Expected expression before here 4")?,
1018                };
1019                let op = parser.consume_keyword(Keyword::IS)?;
1020                let (is, op) = match &parser.token {
1021                    Token::Ident(_, Keyword::NOT) => {
1022                        parser.consume();
1023                        match &parser.token {
1024                            Token::Ident(_, Keyword::TRUE) => {
1025                                (Is::NotTrue, parser.consume().join_span(&op))
1026                            }
1027                            Token::Ident(_, Keyword::FALSE) => {
1028                                (Is::NotFalse, parser.consume().join_span(&op))
1029                            }
1030                            Token::Ident(_, Keyword::NULL) => {
1031                                (Is::NotNull, parser.consume().join_span(&op))
1032                            }
1033                            Token::Ident(_, Keyword::UNKNOWN) => {
1034                                (Is::NotUnknown, parser.consume().join_span(&op))
1035                            }
1036                            _ => parser.expected_failure("'TRUE', 'FALSE', 'UNKNOWN' or 'NULL'")?,
1037                        }
1038                    }
1039                    Token::Ident(_, Keyword::TRUE) => (Is::True, parser.consume().join_span(&op)),
1040                    Token::Ident(_, Keyword::FALSE) => (Is::False, parser.consume().join_span(&op)),
1041                    Token::Ident(_, Keyword::NULL) => (Is::Null, parser.consume().join_span(&op)),
1042                    Token::Ident(_, Keyword::UNKNOWN) => {
1043                        (Is::Unknown, parser.consume().join_span(&op))
1044                    }
1045                    _ => parser.expected_failure("'NOT', 'TRUE', 'FALSE', 'UNKNOWN' or 'NULL'")?,
1046                };
1047                r.shift_expr(Expression::Is(Box::new(lhs), is, op))
1048            }
1049            Token::Ident(_, Keyword::NOT)
1050                if !matches!(r.stack.last(), Some(ReduceMember::Expression(_))) =>
1051            {
1052                r.shift_unary(parser.consume(), UnaryOperator::Not)
1053            }
1054            Token::Ident(_, Keyword::NOT)
1055                if !inner && matches!(r.stack.last(), Some(ReduceMember::Expression(_))) =>
1056            {
1057                if let Err(e) = r.reduce(IN_PRIORITY) {
1058                    parser.err_here(e)?;
1059                }
1060                let lhs = match r.stack.pop() {
1061                    Some(ReduceMember::Expression(e)) => e,
1062                    _ => parser.err_here("Expected expression before here 2")?,
1063                };
1064                let op = parser.consume_keyword(Keyword::NOT)?;
1065                match &parser.token {
1066                    Token::Ident(_, Keyword::IN) => {
1067                        let op = parser.consume_keyword(Keyword::IN)?.join_span(&op);
1068                        parser.consume_token(Token::LParen)?;
1069                        let mut rhs = Vec::new();
1070                        loop {
1071                            parser.recovered(
1072                                "')' or ','",
1073                                &|t| matches!(t, Token::RParen | Token::Comma),
1074                                |parser| {
1075                                    rhs.push(parse_expression_paren(parser)?);
1076                                    Ok(())
1077                                },
1078                            )?;
1079                            if parser.skip_token(Token::Comma).is_none() {
1080                                break;
1081                            }
1082                        }
1083                        parser.consume_token(Token::RParen)?;
1084                        r.shift_expr(Expression::In {
1085                            lhs: Box::new(lhs),
1086                            rhs,
1087                            in_span: op,
1088                            not_in: true,
1089                        })
1090                    }
1091                    Token::Ident(_, Keyword::LIKE) => {
1092                        r.stack.push(ReduceMember::Expression(lhs));
1093                        r.shift_binop(parser.consume().join_span(&op), BinaryOperator::NotLike)
1094                    }
1095                    _ => parser.expected_failure("'IN' or 'LIKE'")?,
1096                }
1097            }
1098            Token::Ident(_, Keyword::LIKE) if !inner => {
1099                r.shift_binop(parser.consume(), BinaryOperator::Like)
1100            }
1101            Token::Plus if !inner => r.shift_binop(parser.consume(), BinaryOperator::Add),
1102            Token::Div if !inner => r.shift_binop(parser.consume(), BinaryOperator::Divide),
1103            Token::Minus if !inner => r.shift_binop(parser.consume(), BinaryOperator::Subtract),
1104            Token::Ident(_, Keyword::LIKE) if !inner => {
1105                r.shift_binop(parser.consume(), BinaryOperator::Like)
1106            }
1107            Token::Mul if !matches!(r.stack.last(), Some(ReduceMember::Expression(_))) => r
1108                .shift_expr(Expression::Identifier(vec![IdentifierPart::Star(
1109                    parser.consume_token(Token::Mul)?,
1110                )])),
1111            Token::Mul if !inner && matches!(r.stack.last(), Some(ReduceMember::Expression(_))) => {
1112                r.shift_binop(parser.consume(), BinaryOperator::Mult)
1113            }
1114            Token::Ident(_, Keyword::TRUE) => r.shift_expr(Expression::Bool(
1115                true,
1116                parser.consume_keyword(Keyword::TRUE)?,
1117            )),
1118            Token::Ident(_, Keyword::FALSE) => r.shift_expr(Expression::Bool(
1119                false,
1120                parser.consume_keyword(Keyword::FALSE)?,
1121            )),
1122            Token::Ident(_, Keyword::NULL) => {
1123                r.shift_expr(Expression::Null(parser.consume_keyword(Keyword::NULL)?))
1124            }
1125            Token::Ident(_, Keyword::_LIST_) if parser.options.list_hack => {
1126                let arg = parser.arg;
1127                parser.arg += 1;
1128                r.shift_expr(Expression::ListHack((
1129                    arg,
1130                    parser.consume_keyword(Keyword::_LIST_)?,
1131                )))
1132            }
1133            Token::SingleQuotedString(_) | Token::DoubleQuotedString(_) => {
1134                r.shift_expr(Expression::String(parser.consume_string()?))
1135            }
1136            Token::Integer(_) => r.shift_expr(Expression::Integer(parser.consume_int()?)),
1137            Token::Float(_) => r.shift_expr(Expression::Float(parser.consume_float()?)),
1138
1139            Token::Ident(_, Keyword::CAST) => {
1140                let cast_span = parser.consume_keyword(Keyword::CAST)?;
1141                parser.consume_token(Token::LParen)?;
1142                let cast = parser.recovered("')'", &|t| matches!(t, Token::RParen), |parser| {
1143                    let expr = parse_expression_outer(parser)?;
1144                    let as_span = parser.consume_keyword(Keyword::AS)?;
1145                    let type_ = parse_data_type(parser, false)?;
1146                    Ok(Some((expr, as_span, type_)))
1147                })?;
1148                parser.consume_token(Token::RParen)?;
1149                if let Some((expr, as_span, type_)) = cast {
1150                    r.shift_expr(Expression::Cast {
1151                        cast_span,
1152                        expr: Box::new(expr),
1153                        as_span,
1154                        type_,
1155                    })
1156                } else {
1157                    r.shift_expr(Expression::Invalid(cast_span))
1158                }
1159            }
1160            Token::Ident(_, Keyword::COUNT) => {
1161                let count_span = parser.consume_keyword(Keyword::COUNT)?;
1162                parser.consume_token(Token::LParen)?;
1163                let distinct_span = parser.skip_keyword(Keyword::DISTINCT);
1164                let expr = parser.recovered("')'", &|t| matches!(t, Token::RParen), |parser| {
1165                    let expr = parse_expression_outer(parser)?;
1166                    Ok(Some(expr))
1167                })?;
1168                parser.consume_token(Token::RParen)?;
1169                if let Some(expr) = expr {
1170                    r.shift_expr(Expression::Count {
1171                        count_span,
1172                        distinct_span,
1173                        expr: Box::new(expr),
1174                    })
1175                } else {
1176                    r.shift_expr(Expression::Invalid(count_span))
1177                }
1178            }
1179            Token::Ident(_, Keyword::GROUP_CONCAT) => {
1180                let group_concat_span = parser.consume_keyword(Keyword::GROUP_CONCAT)?;
1181                parser.consume_token(Token::LParen)?;
1182                let distinct_span = parser.skip_keyword(Keyword::DISTINCT);
1183                let expr = parser.recovered("')'", &|t| matches!(t, Token::RParen), |parser| {
1184                    let expr = parse_expression_outer(parser)?;
1185                    Ok(Some(expr))
1186                })?;
1187                // TODO
1188                // [ORDER BY {unsigned_integer | col_name | expr}
1189                //     [ASC | DESC] [,col_name ...]]
1190                // [SEPARATOR str_val]
1191                // [LIMIT {[offset,] row_count | row_count OFFSET offset}])
1192                parser.consume_token(Token::RParen)?;
1193                if let Some(expr) = expr {
1194                    r.shift_expr(Expression::GroupConcat {
1195                        group_concat_span,
1196                        distinct_span,
1197                        expr: Box::new(expr),
1198                    })
1199                } else {
1200                    r.shift_expr(Expression::Invalid(group_concat_span))
1201                }
1202            }
1203            Token::Ident(_, k) if k.expr_ident() => {
1204                let i = parser.token.clone();
1205                let s = parser.span.clone();
1206                parser.consume();
1207                if matches!(parser.token, Token::LParen) {
1208                    r.shift_expr(parse_function(parser, i, s)?)
1209                } else {
1210                    let f = match i {
1211                        Token::Ident(_, Keyword::CURRENT_TIMESTAMP) => {
1212                            Some(Function::CurrentTimestamp)
1213                        }
1214                        _ => None,
1215                    };
1216                    if let Some(f) = f {
1217                        r.shift_expr(Expression::Function(f, Vec::new(), s))
1218                    } else {
1219                        let mut parts = vec![IdentifierPart::Name(
1220                            parser.token_to_plain_identifier(&i, s)?,
1221                        )];
1222                        loop {
1223                            if parser.skip_token(Token::Period).is_none() {
1224                                break;
1225                            }
1226                            match &parser.token {
1227                                Token::Mul => parts
1228                                    .push(IdentifierPart::Star(parser.consume_token(Token::Mul)?)),
1229                                Token::Ident(_, _) => parts
1230                                    .push(IdentifierPart::Name(parser.consume_plain_identifier()?)),
1231                                _ => parser.expected_failure("Identifier or '*'")?,
1232                            }
1233                        }
1234                        r.shift_expr(Expression::Identifier(parts))
1235                    }
1236                }
1237            }
1238            Token::QuestionMark
1239                if matches!(parser.options.arguments, crate::SQLArguments::QuestionMark) =>
1240            {
1241                let arg = parser.arg;
1242                parser.arg += 1;
1243                r.shift_expr(Expression::Arg((
1244                    arg,
1245                    parser.consume_token(Token::QuestionMark)?,
1246                )))
1247            }
1248            Token::PercentS if matches!(parser.options.arguments, crate::SQLArguments::Percent) => {
1249                let arg = parser.arg;
1250                parser.arg += 1;
1251                r.shift_expr(Expression::Arg((
1252                    arg,
1253                    parser.consume_token(Token::PercentS)?,
1254                )))
1255            }
1256            Token::DollarArg(arg)
1257                if matches!(parser.options.arguments, crate::SQLArguments::Dollar) =>
1258            {
1259                r.shift_expr(Expression::Arg((arg - 1, parser.consume())))
1260            }
1261            Token::LParen => {
1262                parser.consume_token(Token::LParen)?;
1263                let ans = parse_expression_paren(parser)?;
1264                parser.consume_token(Token::RParen)?;
1265                r.shift_expr(ans)
1266            }
1267            Token::Ident(_, Keyword::EXISTS) => {
1268                parser.consume_keyword(Keyword::EXISTS)?;
1269                parser.consume_token(Token::LParen)?;
1270                let ans = Expression::Exists(Box::new(parse_compound_query(parser)?));
1271                parser.consume_token(Token::RParen)?;
1272                r.shift_expr(ans)
1273            }
1274            Token::Ident(_, Keyword::CASE) => {
1275                let case_span = parser.consume_keyword(Keyword::CASE)?;
1276                let value = if !matches!(parser.token, Token::Ident(_, Keyword::WHEN)) {
1277                    Some(Box::new(parse_expression(parser, false)?))
1278                } else {
1279                    None
1280                };
1281                let mut whens = Vec::new();
1282                let mut else_ = None;
1283                parser.recovered(
1284                    "'END'",
1285                    &|t| matches!(t, Token::Ident(_, Keyword::END)),
1286                    |parser| {
1287                        loop {
1288                            let when_span = parser.consume_keyword(Keyword::WHEN)?;
1289                            let when = parse_expression(parser, false)?;
1290                            let then_span = parser.consume_keyword(Keyword::THEN)?;
1291                            let then = parse_expression(parser, false)?;
1292                            whens.push(When {
1293                                when_span,
1294                                when,
1295                                then_span,
1296                                then,
1297                            });
1298                            if !matches!(parser.token, Token::Ident(_, Keyword::WHEN)) {
1299                                break;
1300                            }
1301                        }
1302                        if let Some(span) = parser.skip_keyword(Keyword::ELSE) {
1303                            else_ = Some((span, Box::new(parse_expression(parser, false)?)))
1304                        };
1305                        Ok(())
1306                    },
1307                )?;
1308                let end_span = parser.consume_keyword(Keyword::END)?;
1309                r.shift_expr(Expression::Case {
1310                    case_span,
1311                    value,
1312                    whens,
1313                    else_,
1314                    end_span,
1315                })
1316            }
1317            Token::AtAtGlobal | Token::AtAtSession => {
1318                let global = parser.skip_token(Token::AtAtGlobal);
1319                let session = if global.is_none() {
1320                    Some(parser.consume_token(Token::AtAtSession)?)
1321                } else {
1322                    None
1323                };
1324                let dot = Some(parser.consume_token(Token::Period)?);
1325                let variable = match &parser.token {
1326                    Token::Ident(_, Keyword::TIME_ZONE) => Variable::TimeZone,
1327                    Token::Ident(t, _) => Variable::Other(t),
1328                    _ => parser.expected_failure("Identifier")?,
1329                };
1330                let variable_span = parser.consume();
1331                r.shift_expr(Expression::Variable {
1332                    global,
1333                    session,
1334                    dot,
1335                    variable,
1336                    variable_span,
1337                })
1338            }
1339            _ => break,
1340        };
1341        if let Err(e) = e {
1342            parser.err_here(e.to_string())?;
1343        }
1344    }
1345    if r.reduce(99999).is_err() {
1346        parser.err_here("Expected expression")
1347    } else if r.stack.len() != 1 {
1348        parser.ice(file!(), line!())
1349    } else if let Some(ReduceMember::Expression(e)) = r.stack.pop() {
1350        Ok(e)
1351    } else {
1352        parser.ice(file!(), line!())
1353    }
1354}
1355
1356pub(crate) fn parse_expression_outer<'a>(
1357    parser: &mut Parser<'a, '_>,
1358) -> Result<Expression<'a>, ParseError> {
1359    if matches!(parser.token, Token::Ident(_, Keyword::SELECT)) {
1360        Ok(Expression::Subquery(Box::new(Statement::Select(
1361            parse_select(parser)?,
1362        ))))
1363    } else {
1364        parse_expression(parser, false)
1365    }
1366}
1367
1368pub(crate) fn parse_expression_paren<'a>(
1369    parser: &mut Parser<'a, '_>,
1370) -> Result<Expression<'a>, ParseError> {
1371    if matches!(parser.token, Token::Ident(_, Keyword::SELECT)) {
1372        Ok(Expression::Subquery(Box::new(parse_compound_query(
1373            parser,
1374        )?)))
1375    } else {
1376        parse_expression(parser, false)
1377    }
1378}
1379
1380#[cfg(test)]
1381mod tests {
1382    use core::ops::Deref;
1383
1384    use alloc::{
1385        format,
1386        string::{String, ToString},
1387    };
1388
1389    use crate::{
1390        expression::{BinaryOperator, Expression},
1391        issue::Issues,
1392        parser::Parser,
1393        ParseOptions, SQLDialect,
1394    };
1395
1396    use super::{parse_expression, IdentifierPart};
1397
1398    fn test_ident<'a>(e: impl AsRef<Expression<'a>>, v: &str) -> Result<(), String> {
1399        let v = match e.as_ref() {
1400            Expression::Identifier(a) => match a.as_slice() {
1401                [IdentifierPart::Name(vv)] => vv.deref() == v,
1402                _ => false,
1403            },
1404            _ => false,
1405        };
1406        if !v {
1407            Err(format!("Expected identifier {} found {:?}", v, e.as_ref()))
1408        } else {
1409            Ok(())
1410        }
1411    }
1412
1413    fn test_expr(src: &'static str, f: impl FnOnce(&Expression<'_>) -> Result<(), String>) {
1414        let mut issues = Issues::new(src);
1415        let options = ParseOptions::new().dialect(SQLDialect::MariaDB);
1416        let mut parser = Parser::new(src, &mut issues, &options);
1417        let res = parse_expression(&mut parser, false).expect("Expression in test expr");
1418        if let Err(e) = f(&res) {
1419            panic!("Error parsing {}: {}\nGot {:#?}", src, e, res);
1420        }
1421    }
1422
1423    #[test]
1424    fn expressions() {
1425        test_expr("`a` + `b` * `c` + `d`", |e| {
1426            match e {
1427                Expression::Binary {
1428                    op: BinaryOperator::Add,
1429                    lhs,
1430                    rhs,
1431                    ..
1432                } => {
1433                    match lhs.as_ref() {
1434                        Expression::Binary {
1435                            op: BinaryOperator::Add,
1436                            lhs,
1437                            rhs,
1438                            ..
1439                        } => {
1440                            test_ident(lhs, "a")?;
1441                            match rhs.as_ref() {
1442                                Expression::Binary {
1443                                    op: BinaryOperator::Mult,
1444                                    lhs,
1445                                    rhs,
1446                                    ..
1447                                } => {
1448                                    test_ident(lhs, "b")?;
1449                                    test_ident(rhs, "c")?;
1450                                }
1451                                _ => return Err("Lhs.Rhs".to_string()),
1452                            }
1453                        }
1454                        _ => return Err("Lhs".to_string()),
1455                    }
1456                    test_ident(rhs, "d")?;
1457                }
1458                _ => return Err("Outer".to_string()),
1459            }
1460            Ok(())
1461        });
1462    }
1463}