1use 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#[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#[derive(Debug, Clone)]
220pub enum Variable<'a> {
221 TimeZone,
222 Other(&'a str),
223}
224
225#[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#[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#[derive(Debug, Clone, Copy)]
268pub enum UnaryOperator {
269 Binary,
270 Collate,
271 LogicalNot,
272 Minus,
273 Not,
274}
275
276#[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#[derive(Debug, Clone)]
294pub struct When<'a> {
295 pub when_span: Span,
297 pub when: Expression<'a>,
299 pub then_span: Span,
301 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#[derive(Debug, Clone)]
316pub struct WindowSpec<'a> {
317 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#[derive(Debug, Clone)]
329pub enum Expression<'a> {
330 Binary {
332 op: BinaryOperator,
334 op_span: Span,
336 lhs: Box<Expression<'a>>,
338 rhs: Box<Expression<'a>>,
340 },
341 Unary {
343 op: UnaryOperator,
345 op_span: Span,
347 operand: Box<Expression<'a>>,
349 },
350 Subquery(Box<Statement<'a>>),
352 Null(Span),
354 Bool(bool, Span),
356 String(SString<'a>),
359 Integer((u64, Span)),
361 ListHack((usize, Span)),
363 Float((f64, Span)),
365 Function(Function<'a>, Vec<Expression<'a>>, Span),
367 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(Vec<IdentifierPart<'a>>),
377 Arg((usize, Span)),
379 Exists(Box<Statement<'a>>),
381 In {
383 lhs: Box<Expression<'a>>,
385 rhs: Vec<Expression<'a>>,
387 in_span: Span,
389 not_in: bool,
391 },
392 Is(Box<Expression<'a>>, Is, Span),
394 Invalid(Span),
396 Case {
398 case_span: Span,
400 value: Option<Box<Expression<'a>>>,
402 whens: Vec<When<'a>>,
404 else_: Option<(Span, Box<Expression<'a>>)>,
406 end_span: Span,
408 },
409 Cast {
411 cast_span: Span,
413 expr: Box<Expression<'a>>,
415 as_span: Span,
417 type_: DataType<'a>,
419 },
420 Count {
422 count_span: Span,
424 distinct_span: Option<Span>,
426 expr: Box<Expression<'a>>,
428 },
429 GroupConcat {
431 group_concat_span: Span,
433 distinct_span: Option<Span>,
435 expr: Box<Expression<'a>>,
437 },
438 Variable {
440 global: Option<Span>,
442 session: Option<Span>,
444 dot: Option<Span>,
446 variable: Variable<'a>,
448 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 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 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 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 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 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 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 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
801const 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 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 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}