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