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