1use crate::{
14 DataType, Identifier, QualifiedName, SString, Span, Spanned, Statement,
15 data_type::{DataTypeContext, parse_data_type},
16 function_expression::{
17 AggregateFunctionCallExpression, CharFunctionExpression, Function, FunctionCallExpression,
18 WindowFunctionCallExpression, is_aggregate_function_ident, parse_aggregate_function,
19 parse_char_function, parse_function, parse_function_call,
20 },
21 keywords::{Keyword, Restrict},
22 lexer::Token,
23 operator::parse_operator_name,
24 parser::{ParseError, Parser},
25 span::OptSpanned,
26 statement::parse_compound_query,
27};
28use alloc::string::ToString;
29use alloc::vec;
30use alloc::{boxed::Box, vec::Vec};
31
32#[derive(Debug, Clone)]
34pub enum Variable<'a> {
35 TimeZone,
36 Other(&'a str),
37}
38
39#[derive(Debug, Clone)]
41pub enum BinaryOperator<'a> {
42 Or(Span),
43 Xor(Span),
44 And(Span),
45 Eq(Span),
46 NullSafeEq(Span),
47 GtEq(Span),
48 Gt(Span),
49 LtEq(Span),
50 Lt(Span),
51 Neq(Span),
52 ShiftLeft(Span),
53 ShiftRight(Span),
54 BitAnd(Span),
55 BitOr(Span),
56 BitXor(Span),
57 Add(Span),
58 Subtract(Span),
59 Divide(Span),
60 Div(Span),
61 Mod(Span),
62 Mult(Span),
63 Like(Span),
64 NotLike(Span),
65 Regexp(Span),
66 NotRegexp(Span),
67 Rlike(Span),
68 NotRlike(Span),
69 Collate(Span),
70 JsonExtract(Span),
71 JsonExtractUnquote(Span),
72 Assignment(Span),
73 Concat(Span),
75 Overlap(Span),
78 Contains(Span),
80 ContainedBy(Span),
82 JsonPathMatch(Span),
84 JsonPathExists(Span),
86 JsonbKeyExists(Span),
88 JsonbAnyKeyExists(Span),
90 JsonbAllKeyExists(Span),
92 JsonGetPath(Span),
94 JsonGetPathText(Span),
96 JsonDeletePath(Span),
98 RegexMatch(Span),
100 RegexIMatch(Span),
102 NotRegexMatch(Span),
104 NotRegexIMatch(Span),
106 User(&'a str, Span),
108 Operator(QualifiedName<'a>, Span),
110}
111
112impl<'a> Spanned for BinaryOperator<'a> {
113 fn span(&self) -> Span {
114 match self {
115 BinaryOperator::Or(s)
116 | BinaryOperator::Xor(s)
117 | BinaryOperator::And(s)
118 | BinaryOperator::Eq(s)
119 | BinaryOperator::NullSafeEq(s)
120 | BinaryOperator::GtEq(s)
121 | BinaryOperator::Gt(s)
122 | BinaryOperator::LtEq(s)
123 | BinaryOperator::Lt(s)
124 | BinaryOperator::Neq(s)
125 | BinaryOperator::ShiftLeft(s)
126 | BinaryOperator::ShiftRight(s)
127 | BinaryOperator::BitAnd(s)
128 | BinaryOperator::BitOr(s)
129 | BinaryOperator::BitXor(s)
130 | BinaryOperator::Add(s)
131 | BinaryOperator::Subtract(s)
132 | BinaryOperator::Divide(s)
133 | BinaryOperator::Div(s)
134 | BinaryOperator::Mod(s)
135 | BinaryOperator::Mult(s)
136 | BinaryOperator::Like(s)
137 | BinaryOperator::NotLike(s)
138 | BinaryOperator::Regexp(s)
139 | BinaryOperator::NotRegexp(s)
140 | BinaryOperator::Rlike(s)
141 | BinaryOperator::NotRlike(s)
142 | BinaryOperator::Collate(s)
143 | BinaryOperator::JsonExtract(s)
144 | BinaryOperator::JsonExtractUnquote(s)
145 | BinaryOperator::Assignment(s)
146 | BinaryOperator::Concat(s)
147 | BinaryOperator::Overlap(s)
148 | BinaryOperator::Contains(s)
149 | BinaryOperator::ContainedBy(s)
150 | BinaryOperator::JsonPathMatch(s)
151 | BinaryOperator::JsonPathExists(s)
152 | BinaryOperator::JsonbKeyExists(s)
153 | BinaryOperator::JsonbAnyKeyExists(s)
154 | BinaryOperator::JsonbAllKeyExists(s)
155 | BinaryOperator::JsonGetPath(s)
156 | BinaryOperator::JsonGetPathText(s)
157 | BinaryOperator::JsonDeletePath(s)
158 | BinaryOperator::RegexMatch(s)
159 | BinaryOperator::RegexIMatch(s)
160 | BinaryOperator::NotRegexMatch(s)
161 | BinaryOperator::NotRegexIMatch(s) => s.clone(),
162 BinaryOperator::User(_, s) => s.clone(),
163 BinaryOperator::Operator(_, s) => s.clone(),
164 }
165 }
166}
167
168#[derive(Debug, Clone)]
170pub enum MatchMode {
171 InBoolean(Span),
172 InNaturalLanguage(Span),
173 InNaturalLanguageWithQueryExpansion(Span),
174 WithQueryExpansion(Span),
175}
176
177impl Spanned for MatchMode {
178 fn span(&self) -> Span {
179 match self {
180 MatchMode::InBoolean(s) => s.clone(),
181 MatchMode::InNaturalLanguage(s) => s.clone(),
182 MatchMode::InNaturalLanguageWithQueryExpansion(s) => s.clone(),
183 MatchMode::WithQueryExpansion(s) => s.clone(),
184 }
185 }
186}
187
188#[derive(Debug, Clone)]
190pub enum Is<'a> {
191 Null,
192 NotNull,
193 True,
194 NotTrue,
195 False,
196 NotFalse,
197 Unknown,
198 NotUnknown,
199 DistinctFrom(Expression<'a>),
200 NotDistinctFrom(Expression<'a>),
201}
202
203#[derive(Debug, Clone)]
205pub enum UnaryOperator {
206 Binary(Span),
207 LogicalNot(Span),
208 Minus(Span),
209 Not(Span),
210}
211
212impl Spanned for UnaryOperator {
213 fn span(&self) -> Span {
214 match self {
215 UnaryOperator::Binary(s)
216 | UnaryOperator::LogicalNot(s)
217 | UnaryOperator::Minus(s)
218 | UnaryOperator::Not(s) => s.clone(),
219 }
220 }
221}
222
223#[derive(Debug, Clone)]
225pub enum IdentifierPart<'a> {
226 Name(Identifier<'a>),
227 Star(Span),
228}
229
230impl<'a> Spanned for IdentifierPart<'a> {
231 fn span(&self) -> Span {
232 match &self {
233 IdentifierPart::Name(v) => v.span(),
234 IdentifierPart::Star(v) => v.span(),
235 }
236 }
237}
238
239#[derive(Debug, Clone)]
241pub struct When<'a> {
242 pub when_span: Span,
244 pub when: Expression<'a>,
246 pub then_span: Span,
248 pub then: Expression<'a>,
250}
251
252impl<'a> Spanned for When<'a> {
253 fn span(&self) -> Span {
254 self.when_span
255 .join_span(&self.when)
256 .join_span(&self.then_span)
257 .join_span(&self.then)
258 }
259}
260
261#[derive(Debug, Clone, PartialEq, Eq)]
263pub enum TimeUnit {
264 Microsecond,
266 Second,
268 Minute,
270 Hour,
272 Day,
274 Week,
276 Month,
278 Quarter,
280 Year,
282 SecondMicrosecond,
284 MinuteMicrosecond,
286 MinuteSecond,
288 HourMicrosecond,
290 HourSecond,
292 HourMinute,
294 DayMicrosecond,
296 DaySecond,
298 DayMinute,
300 DayHour,
302 YearMonth,
304 Epoch,
306 Dow,
308 Doy,
310 Century,
312 Decade,
314 IsoDow,
316 IsoYear,
318 Julian,
320 Millennium,
322 Timezone,
324 TimezoneHour,
326 TimezoneMinute,
328}
329
330fn parse_time_unit_from_str(s: &str) -> Option<TimeUnit> {
331 match s.to_ascii_lowercase().trim_end_matches('s') {
332 "microsecond" => Some(TimeUnit::Microsecond),
333 "second" => Some(TimeUnit::Second),
334 "minute" => Some(TimeUnit::Minute),
335 "hour" => Some(TimeUnit::Hour),
336 "day" => Some(TimeUnit::Day),
337 "week" => Some(TimeUnit::Week),
338 "month" => Some(TimeUnit::Month),
339 "quarter" => Some(TimeUnit::Quarter),
340 "year" => Some(TimeUnit::Year),
341 "epoch" => Some(TimeUnit::Epoch),
342 "dow" => Some(TimeUnit::Dow),
343 "doy" => Some(TimeUnit::Doy),
344 "century" | "centurie" => Some(TimeUnit::Century),
345 "decade" => Some(TimeUnit::Decade),
346 "isodow" => Some(TimeUnit::IsoDow),
347 "isoyear" => Some(TimeUnit::IsoYear),
348 "julian" => Some(TimeUnit::Julian),
349 "millennium" | "millennia" | "millenniu" => Some(TimeUnit::Millennium),
350 "timezone" => Some(TimeUnit::Timezone),
351 "timezone_hour" => Some(TimeUnit::TimezoneHour),
352 "timezone_minute" => Some(TimeUnit::TimezoneMinute),
353 _ => None,
354 }
355}
356
357fn parse_time_unit(t: &Token<'_>) -> Option<TimeUnit> {
358 match t {
359 Token::Ident(_, Keyword::MICROSECOND) => Some(TimeUnit::Microsecond),
360 Token::Ident(_, Keyword::SECOND) => Some(TimeUnit::Second),
361 Token::Ident(_, Keyword::MINUTE) => Some(TimeUnit::Minute),
362 Token::Ident(_, Keyword::HOUR) => Some(TimeUnit::Hour),
363 Token::Ident(_, Keyword::DAY) => Some(TimeUnit::Day),
364 Token::Ident(_, Keyword::WEEK) => Some(TimeUnit::Week),
365 Token::Ident(_, Keyword::MONTH) => Some(TimeUnit::Month),
366 Token::Ident(_, Keyword::QUARTER) => Some(TimeUnit::Quarter),
367 Token::Ident(_, Keyword::YEAR) => Some(TimeUnit::Year),
368 Token::Ident(_, Keyword::SECOND_MICROSECOND) => Some(TimeUnit::SecondMicrosecond),
369 Token::Ident(_, Keyword::MINUTE_MICROSECOND) => Some(TimeUnit::MinuteMicrosecond),
370 Token::Ident(_, Keyword::MINUTE_SECOND) => Some(TimeUnit::MinuteSecond),
371 Token::Ident(_, Keyword::HOUR_MICROSECOND) => Some(TimeUnit::HourMicrosecond),
372 Token::Ident(_, Keyword::HOUR_SECOND) => Some(TimeUnit::HourSecond),
373 Token::Ident(_, Keyword::HOUR_MINUTE) => Some(TimeUnit::HourMinute),
374 Token::Ident(_, Keyword::DAY_MICROSECOND) => Some(TimeUnit::DayMicrosecond),
375 Token::Ident(_, Keyword::DAY_SECOND) => Some(TimeUnit::DaySecond),
376 Token::Ident(_, Keyword::DAY_MINUTE) => Some(TimeUnit::DayMinute),
377 Token::Ident(_, Keyword::DAY_HOUR) => Some(TimeUnit::DayHour),
378 Token::Ident(_, Keyword::YEAR_MONTH) => Some(TimeUnit::YearMonth),
379 Token::Ident(s, Keyword::NOT_A_KEYWORD) => parse_time_unit_from_str(s),
380 _ => None,
381 }
382}
383
384#[derive(Debug, Clone)]
386pub struct BinaryExpression<'a> {
387 pub op: BinaryOperator<'a>,
388 pub lhs: Expression<'a>,
389 pub rhs: Expression<'a>,
390}
391
392impl Spanned for BinaryExpression<'_> {
393 fn span(&self) -> Span {
394 self.op.span().join_span(&self.lhs).join_span(&self.rhs)
395 }
396}
397
398#[derive(Debug, Clone)]
400pub struct UnaryExpression<'a> {
401 pub op: UnaryOperator,
402 pub operand: Expression<'a>,
403}
404
405impl Spanned for UnaryExpression<'_> {
406 fn span(&self) -> Span {
407 self.op.span().join_span(&self.operand)
408 }
409}
410#[derive(Debug, Clone)]
412pub struct IntervalExpression {
413 pub interval_span: Span,
415 pub time_interval: (Vec<i64>, Span),
417 pub time_unit: (TimeUnit, Span),
419}
420
421impl Spanned for IntervalExpression {
422 fn span(&self) -> Span {
423 self.interval_span
424 .join_span(&self.time_interval.1)
425 .join_span(&self.time_unit.1)
426 }
427}
428
429#[derive(Debug, Clone)]
431pub struct ExtractExpression<'a> {
432 pub extract_span: Span,
434 pub time_unit: (TimeUnit, Span),
436 pub from_span: Span,
438 pub date: Expression<'a>,
440 pub r_paren_span: Span,
442}
443
444impl Spanned for ExtractExpression<'_> {
445 fn span(&self) -> Span {
446 self.extract_span
447 .join_span(&self.time_unit.1)
448 .join_span(&self.from_span)
449 .join_span(&self.date)
450 .join_span(&self.r_paren_span)
451 }
452}
453
454#[derive(Debug, Clone)]
456pub enum TrimDirection {
457 Both(Span),
458 Leading(Span),
459 Trailing(Span),
460}
461
462impl Spanned for TrimDirection {
463 fn span(&self) -> Span {
464 match self {
465 TrimDirection::Both(s) | TrimDirection::Leading(s) | TrimDirection::Trailing(s) => {
466 s.clone()
467 }
468 }
469 }
470}
471
472#[derive(Debug, Clone)]
474pub struct TrimExpression<'a> {
475 pub trim_span: Span,
477 pub direction: Option<TrimDirection>,
479 pub what: Option<Expression<'a>>,
481 pub from_span: Option<Span>,
483 pub value: Expression<'a>,
485 pub r_paren_span: Span,
487}
488
489impl Spanned for TrimExpression<'_> {
490 fn span(&self) -> Span {
491 self.trim_span
492 .join_span(&self.direction)
493 .join_span(&self.what)
494 .join_span(&self.from_span)
495 .join_span(&self.value)
496 .join_span(&self.r_paren_span)
497 }
498}
499
500#[derive(Debug, Clone)]
502pub struct InExpression<'a> {
503 pub lhs: Expression<'a>,
505 pub rhs: Vec<Expression<'a>>,
507 pub in_span: Span,
509 pub not_in: bool,
511 pub r_paren_span: Span,
513}
514
515impl Spanned for InExpression<'_> {
516 fn span(&self) -> Span {
517 self.in_span
518 .join_span(&self.lhs)
519 .join_span(&self.rhs)
520 .join_span(&self.r_paren_span)
521 }
522}
523
524#[derive(Debug, Clone)]
526pub struct BetweenExpression<'a> {
527 pub lhs: Expression<'a>,
529 pub low: Expression<'a>,
531 pub high: Expression<'a>,
533 pub between_span: Span,
535 pub not_between: bool,
537}
538
539impl Spanned for BetweenExpression<'_> {
540 fn span(&self) -> Span {
541 self.between_span
542 .join_span(&self.lhs)
543 .join_span(&self.low)
544 .join_span(&self.high)
545 }
546}
547
548#[derive(Debug, Clone)]
550pub struct MemberOfExpression<'a> {
551 pub lhs: Expression<'a>,
553 pub rhs: Expression<'a>,
555 pub member_of_span: Span,
557 pub r_paren_span: Span,
559}
560
561impl Spanned for MemberOfExpression<'_> {
562 fn span(&self) -> Span {
563 self.member_of_span
564 .join_span(&self.lhs)
565 .join_span(&self.rhs)
566 .join_span(&self.r_paren_span)
567 }
568}
569
570#[derive(Debug, Clone)]
572pub struct CaseExpression<'a> {
573 pub case_span: Span,
575 pub value: Option<Expression<'a>>,
577 pub whens: Vec<When<'a>>,
579 pub else_: Option<(Span, Expression<'a>)>,
581 pub end_span: Span,
583}
584
585impl Spanned for CaseExpression<'_> {
586 fn span(&self) -> Span {
587 self.case_span
588 .join_span(&self.value)
589 .join_span(&self.whens)
590 .join_span(&self.else_)
591 .join_span(&self.end_span)
592 }
593}
594
595#[derive(Debug, Clone)]
597pub struct CastExpression<'a> {
598 pub cast_span: Span,
600 pub expr: Expression<'a>,
602 pub as_span: Span,
604 pub type_: DataType<'a>,
606 pub r_paren_span: Span,
608}
609
610impl Spanned for CastExpression<'_> {
611 fn span(&self) -> Span {
612 self.cast_span
613 .join_span(&self.expr)
614 .join_span(&self.as_span)
615 .join_span(&self.type_)
616 .join_span(&self.r_paren_span)
617 }
618}
619
620#[derive(Debug, Clone)]
622pub struct ConvertExpression<'a> {
623 pub convert_span: Span,
625 pub expr: Expression<'a>,
627 pub type_: Option<DataType<'a>>,
629 pub using_charset: Option<(Span, Identifier<'a>)>,
631 pub r_paren_span: Span,
633}
634
635impl Spanned for ConvertExpression<'_> {
636 fn span(&self) -> Span {
637 self.convert_span
638 .join_span(&self.expr)
639 .join_span(&self.type_)
640 .join_span(&self.using_charset)
641 .join_span(&self.r_paren_span)
642 }
643}
644
645#[derive(Debug, Clone)]
647pub struct TypeCastExpression<'a> {
648 pub expr: Expression<'a>,
650 pub doublecolon_span: Span,
652 pub type_: DataType<'a>,
654}
655
656impl Spanned for TypeCastExpression<'_> {
657 fn span(&self) -> Span {
658 self.expr
659 .span()
660 .join_span(&self.doublecolon_span)
661 .join_span(&self.type_)
662 }
663}
664
665#[derive(Debug, Clone)]
667pub struct ArrayExpression<'a> {
668 pub array_span: Span,
670 pub bracket_span: Span,
672 pub elements: Vec<Expression<'a>>,
674}
675
676impl Spanned for ArrayExpression<'_> {
677 fn span(&self) -> Span {
678 self.array_span.join_span(&self.bracket_span)
679 }
680}
681
682#[derive(Debug, Clone)]
684pub struct ArraySubscriptExpression<'a> {
685 pub expr: Expression<'a>,
687 pub bracket_span: Span,
689 pub lower: Expression<'a>,
691 pub upper: Option<Expression<'a>>,
693}
694
695impl Spanned for ArraySubscriptExpression<'_> {
696 fn span(&self) -> Span {
697 self.expr.span().join_span(&self.bracket_span)
698 }
699}
700
701#[derive(Debug, Clone)]
703pub struct FieldAccessExpression<'a> {
704 pub expr: Expression<'a>,
706 pub dot_span: Span,
708 pub field: Identifier<'a>,
710}
711
712impl Spanned for FieldAccessExpression<'_> {
713 fn span(&self) -> Span {
714 self.expr
715 .span()
716 .join_span(&self.dot_span)
717 .join_span(&self.field)
718 }
719}
720
721#[derive(Debug, Clone)]
723pub struct GroupConcatExpression<'a> {
724 pub group_concat_span: Span,
726 pub distinct_span: Option<Span>,
728 pub expr: Expression<'a>,
730 pub r_paren_span: Span,
732}
733
734impl Spanned for GroupConcatExpression<'_> {
735 fn span(&self) -> Span {
736 self.group_concat_span
737 .join_span(&self.distinct_span)
738 .join_span(&self.expr)
739 .join_span(&self.r_paren_span)
740 }
741}
742
743#[derive(Debug, Clone)]
745pub struct VariableExpression<'a> {
746 pub global: Option<Span>,
748 pub session: Option<Span>,
750 pub dot: Option<Span>,
752 pub variable: Variable<'a>,
754 pub variable_span: Span,
756}
757
758impl Spanned for VariableExpression<'_> {
759 fn span(&self) -> Span {
760 self.variable_span
761 .join_span(&self.global)
762 .join_span(&self.session)
763 .join_span(&self.dot)
764 }
765}
766
767#[derive(Debug, Clone)]
769pub struct UserVariableExpression<'a> {
770 pub name: Identifier<'a>,
772 pub at_span: Span,
774}
775
776impl Spanned for UserVariableExpression<'_> {
777 fn span(&self) -> Span {
778 self.at_span.join_span(&self.name)
779 }
780}
781
782#[derive(Debug, Clone)]
784pub struct TimestampAddExpression<'a> {
785 pub timestamp_add_span: Span,
787 pub unit: (TimeUnit, Span),
789 pub interval: Expression<'a>,
791 pub datetime: Expression<'a>,
793 pub r_paren_span: Span,
795}
796
797impl Spanned for TimestampAddExpression<'_> {
798 fn span(&self) -> Span {
799 self.timestamp_add_span
800 .join_span(&self.unit.1)
801 .join_span(&self.interval)
802 .join_span(&self.datetime)
803 .join_span(&self.r_paren_span)
804 }
805}
806
807#[derive(Debug, Clone)]
809pub struct TimestampDiffExpression<'a> {
810 pub timestamp_diff_span: Span,
812 pub unit: (TimeUnit, Span),
814 pub e1: Expression<'a>,
816 pub e2: Expression<'a>,
818 pub r_paren_span: Span,
820}
821
822impl Spanned for TimestampDiffExpression<'_> {
823 fn span(&self) -> Span {
824 self.timestamp_diff_span
825 .join_span(&self.unit.1)
826 .join_span(&self.e1)
827 .join_span(&self.e2)
828 .join_span(&self.r_paren_span)
829 }
830}
831
832#[derive(Debug, Clone)]
834pub struct MatchAgainstExpression<'a> {
835 pub match_span: Span,
837 pub columns: Vec<Expression<'a>>,
839 pub against_span: Span,
841 pub expr: Expression<'a>,
843 pub mode: Option<MatchMode>,
845 pub r_paren_span: Span,
847}
848
849impl Spanned for MatchAgainstExpression<'_> {
850 fn span(&self) -> Span {
851 self.match_span
852 .join_span(&self.columns)
853 .join_span(&self.against_span)
854 .join_span(&self.expr)
855 .join_span(&self.mode)
856 .join_span(&self.r_paren_span)
857 }
858}
859
860#[derive(Debug, Clone)]
862pub struct IsExpression<'a> {
863 pub lhs: Expression<'a>,
865 pub is: Is<'a>,
867 pub is_span: Span,
869}
870
871impl<'a> Spanned for IsExpression<'a> {
872 fn span(&self) -> Span {
873 match &self.is {
874 Is::DistinctFrom(rhs) | Is::NotDistinctFrom(rhs) => {
875 self.lhs.span().join_span(&self.is_span).join_span(rhs)
876 }
877 _ => self.lhs.span().join_span(&self.is_span),
878 }
879 }
880}
881
882#[derive(Debug, Clone)]
884pub struct NullExpression {
885 pub span: Span,
887}
888
889impl Spanned for NullExpression {
890 fn span(&self) -> Span {
891 self.span.clone()
892 }
893}
894
895#[derive(Debug, Clone)]
897pub struct DefaultExpression {
898 pub span: Span,
900}
901
902impl Spanned for DefaultExpression {
903 fn span(&self) -> Span {
904 self.span.clone()
905 }
906}
907
908#[derive(Debug, Clone)]
910pub struct BoolExpression {
911 pub value: bool,
913 pub span: Span,
915}
916
917impl Spanned for BoolExpression {
918 fn span(&self) -> Span {
919 self.span.clone()
920 }
921}
922
923#[derive(Debug, Clone)]
925pub struct IntegerExpression {
926 pub value: u64,
928 pub span: Span,
930}
931
932impl Spanned for IntegerExpression {
933 fn span(&self) -> Span {
934 self.span.clone()
935 }
936}
937
938#[derive(Debug, Clone)]
940pub struct ListHackExpression {
941 pub index: usize,
943 pub span: Span,
945}
946
947impl Spanned for ListHackExpression {
948 fn span(&self) -> Span {
949 self.span.clone()
950 }
951}
952
953#[derive(Debug, Clone)]
955pub struct FloatExpression {
956 pub value: f64,
958 pub span: Span,
960}
961
962impl Spanned for FloatExpression {
963 fn span(&self) -> Span {
964 self.span.clone()
965 }
966}
967
968#[derive(Debug, Clone)]
970pub struct ArgExpression {
971 pub index: usize,
973 pub span: Span,
975}
976
977impl Spanned for ArgExpression {
978 fn span(&self) -> Span {
979 self.span.clone()
980 }
981}
982
983#[derive(Debug, Clone)]
985pub struct InvalidExpression {
986 pub span: Span,
988}
989
990impl Spanned for InvalidExpression {
991 fn span(&self) -> Span {
992 self.span.clone()
993 }
994}
995
996#[derive(Debug, Clone)]
998pub struct IdentifierExpression<'a> {
999 pub parts: Vec<IdentifierPart<'a>>,
1001}
1002
1003impl<'a> Spanned for IdentifierExpression<'a> {
1004 fn span(&self) -> Span {
1005 self.parts.opt_span().expect("Span of identifier parts")
1006 }
1007}
1008
1009#[derive(Debug, Clone)]
1011pub struct SubqueryExpression<'a> {
1012 pub expression: Statement<'a>,
1014}
1015
1016impl Spanned for SubqueryExpression<'_> {
1017 fn span(&self) -> Span {
1018 self.expression.span()
1019 }
1020}
1021
1022#[derive(Debug, Clone)]
1024pub struct ExistsExpression<'a> {
1025 pub exists_span: Span,
1027 pub subquery: Statement<'a>,
1029 pub r_paren_span: Span,
1031}
1032
1033impl Spanned for ExistsExpression<'_> {
1034 fn span(&self) -> Span {
1035 self.exists_span
1036 .join_span(&self.subquery)
1037 .join_span(&self.r_paren_span)
1038 }
1039}
1040
1041#[derive(Debug, Clone, PartialEq, Eq)]
1043pub enum Quantifier {
1044 Any(Span),
1046 Some(Span),
1048 All(Span),
1050}
1051
1052impl Spanned for Quantifier {
1053 fn span(&self) -> Span {
1054 match self {
1055 Quantifier::Any(s) | Quantifier::Some(s) | Quantifier::All(s) => s.clone(),
1056 }
1057 }
1058}
1059
1060#[derive(Debug, Clone)]
1065pub struct QuantifierExpression<'a> {
1066 pub quantifier: Quantifier,
1068 pub operand: Expression<'a>,
1070 pub r_paren_span: Span,
1072}
1073
1074impl Spanned for QuantifierExpression<'_> {
1075 fn span(&self) -> Span {
1076 self.quantifier
1077 .join_span(&self.operand)
1078 .join_span(&self.r_paren_span)
1079 }
1080}
1081
1082#[derive(Debug, Clone)]
1084pub struct RowExpression<'a> {
1085 pub paren_span: Span,
1087 pub elements: Vec<Expression<'a>>,
1089}
1090
1091impl Spanned for RowExpression<'_> {
1092 fn span(&self) -> Span {
1093 self.paren_span.clone()
1094 }
1095}
1096
1097#[derive(Debug, Clone)]
1099pub enum Expression<'a> {
1100 Binary(Box<BinaryExpression<'a>>),
1102 Unary(Box<UnaryExpression<'a>>),
1104 Subquery(Box<SubqueryExpression<'a>>),
1106 Null(Box<NullExpression>),
1108 Default(Box<DefaultExpression>),
1110 Bool(Box<BoolExpression>),
1112 String(Box<SString<'a>>),
1115 Integer(Box<IntegerExpression>),
1117 ListHack(Box<ListHackExpression>),
1119 Float(Box<FloatExpression>),
1121 Function(Box<FunctionCallExpression<'a>>),
1123 WindowFunction(Box<WindowFunctionCallExpression<'a>>),
1125 AggregateFunction(Box<AggregateFunctionCallExpression<'a>>),
1127 Identifier(Box<IdentifierExpression<'a>>),
1129 Interval(Box<IntervalExpression>),
1131 Arg(Box<ArgExpression>),
1133 Exists(Box<ExistsExpression<'a>>),
1135 Extract(Box<ExtractExpression<'a>>),
1137 Trim(Box<TrimExpression<'a>>),
1139 In(Box<InExpression<'a>>),
1141 Between(Box<BetweenExpression<'a>>),
1143 MemberOf(Box<MemberOfExpression<'a>>),
1145 Is(Box<IsExpression<'a>>),
1147 Invalid(Box<InvalidExpression>),
1149 Case(Box<CaseExpression<'a>>),
1151 Cast(Box<CastExpression<'a>>),
1153 Convert(Box<ConvertExpression<'a>>),
1155 GroupConcat(Box<GroupConcatExpression<'a>>),
1157 Variable(Box<VariableExpression<'a>>),
1159 UserVariable(Box<UserVariableExpression<'a>>),
1161 TimestampAdd(Box<TimestampAddExpression<'a>>),
1163 TimestampDiff(Box<TimestampDiffExpression<'a>>),
1165 TypeCast(Box<TypeCastExpression<'a>>),
1167 MatchAgainst(Box<MatchAgainstExpression<'a>>),
1169 Array(Box<ArrayExpression<'a>>),
1171 ArraySubscript(Box<ArraySubscriptExpression<'a>>),
1173 Quantifier(Box<QuantifierExpression<'a>>),
1175 FieldAccess(Box<FieldAccessExpression<'a>>),
1177 Char(Box<CharFunctionExpression<'a>>),
1179 Row(Box<RowExpression<'a>>),
1181}
1182
1183impl<'a> Spanned for Expression<'a> {
1184 fn span(&self) -> Span {
1185 match &self {
1186 Expression::Binary(e) => e.span(),
1187 Expression::Unary(e) => e.span(),
1188 Expression::Subquery(v) => v.span(),
1189 Expression::Null(v) => v.span(),
1190 Expression::Default(v) => v.span(),
1191 Expression::Bool(v) => v.span(),
1192 Expression::String(v) => v.span(),
1193 Expression::Integer(v) => v.span(),
1194 Expression::Float(v) => v.span(),
1195 Expression::ListHack(v) => v.span(),
1196 Expression::Function(e) => e.span(),
1197 Expression::AggregateFunction(e) => e.span(),
1198 Expression::Identifier(e) => e.span(),
1199 Expression::Arg(v) => v.span(),
1200 Expression::Exists(v) => v.span(),
1201 Expression::In(e) => e.span(),
1202 Expression::Between(e) => e.span(),
1203 Expression::MemberOf(e) => e.span(),
1204 Expression::Is(e) => e.span(),
1205 Expression::Invalid(s) => s.span(),
1206 Expression::Case(e) => e.span(),
1207 Expression::Cast(e) => e.span(),
1208 Expression::Convert(e) => e.span(),
1209 Expression::TypeCast(e) => e.span(),
1210 Expression::GroupConcat(e) => e.span(),
1211 Expression::Variable(e) => e.span(),
1212 Expression::UserVariable(e) => e.span(),
1213 Expression::WindowFunction(e) => e.span(),
1214 Expression::Interval(e) => e.span(),
1215 Expression::Extract(e) => e.span(),
1216 Expression::Trim(e) => e.span(),
1217 Expression::TimestampAdd(e) => e.span(),
1218 Expression::TimestampDiff(e) => e.span(),
1219 Expression::MatchAgainst(e) => e.span(),
1220 Expression::Array(e) => e.span(),
1221 Expression::ArraySubscript(e) => e.span(),
1222 Expression::Quantifier(e) => e.span(),
1223 Expression::FieldAccess(e) => e.span(),
1224 Expression::Char(e) => e.span(),
1225 Expression::Row(e) => e.span(),
1226 }
1227 }
1228}
1229
1230pub(crate) const PRIORITY_TYPECAST: usize = 10; pub(crate) const PRIORITY_JSON_EXTRACT: usize = 30; pub(crate) const PRIORITY_BITXOR: usize = 50; pub(crate) const PRIORITY_MULT: usize = 60; pub(crate) const PRIORITY_ADD: usize = 70; pub(crate) const PRIORITY_PG_CUSTOM: usize = 75; pub(crate) const PRIORITY_SHIFT: usize = 80; pub(crate) const PRIORITY_BITAND: usize = 90; pub(crate) const PRIORITY_BITOR: usize = 100; pub(crate) const PRIORITY_CMP: usize = 110; pub(crate) const PRIORITY_AND: usize = 140; pub(crate) const PRIORITY_XOR: usize = 150; pub(crate) const PRIORITY_OR: usize = 160; pub(crate) const PRIORITY_ASSIGN: usize = 200; pub(crate) const PRIORITY_MAX: usize = usize::MAX;
1250
1251trait Priority {
1252 fn priority(&self) -> usize;
1253}
1254
1255impl<'a> Priority for BinaryOperator<'a> {
1256 fn priority(&self) -> usize {
1257 match self {
1258 BinaryOperator::Assignment(_) => PRIORITY_ASSIGN,
1259 BinaryOperator::Or(_) => PRIORITY_OR,
1260 BinaryOperator::Concat(_) => PRIORITY_ADD,
1261 BinaryOperator::Xor(_) => PRIORITY_XOR,
1262 BinaryOperator::And(_) => PRIORITY_AND,
1263 BinaryOperator::Eq(_) => PRIORITY_CMP,
1264 BinaryOperator::NullSafeEq(_) => PRIORITY_CMP,
1265 BinaryOperator::GtEq(_) => PRIORITY_CMP,
1266 BinaryOperator::Gt(_) => PRIORITY_CMP,
1267 BinaryOperator::LtEq(_) => PRIORITY_CMP,
1268 BinaryOperator::Lt(_) => PRIORITY_CMP,
1269 BinaryOperator::Neq(_) => PRIORITY_CMP,
1270 BinaryOperator::Like(_) => PRIORITY_CMP,
1271 BinaryOperator::NotLike(_) => PRIORITY_CMP,
1272 BinaryOperator::Regexp(_) => PRIORITY_CMP,
1273 BinaryOperator::NotRegexp(_) => PRIORITY_CMP,
1274 BinaryOperator::Rlike(_) => PRIORITY_CMP,
1275 BinaryOperator::NotRlike(_) => PRIORITY_CMP,
1276 BinaryOperator::ShiftLeft(_) => PRIORITY_SHIFT,
1277 BinaryOperator::ShiftRight(_) => PRIORITY_SHIFT,
1278 BinaryOperator::BitAnd(_) => PRIORITY_BITAND,
1279 BinaryOperator::BitOr(_) => PRIORITY_BITOR,
1280 BinaryOperator::BitXor(_) => PRIORITY_BITXOR,
1281 BinaryOperator::Add(_) => PRIORITY_ADD,
1282 BinaryOperator::Subtract(_) => PRIORITY_ADD,
1283 BinaryOperator::Divide(_) => PRIORITY_MULT,
1284 BinaryOperator::Div(_) => PRIORITY_MULT,
1285 BinaryOperator::Mod(_) => PRIORITY_MULT,
1286 BinaryOperator::Mult(_) => PRIORITY_MULT,
1287 BinaryOperator::Collate(_) => 20,
1288 BinaryOperator::JsonExtract(_) => PRIORITY_JSON_EXTRACT,
1289 BinaryOperator::JsonExtractUnquote(_) => PRIORITY_JSON_EXTRACT,
1290 BinaryOperator::Overlap(_)
1291 | BinaryOperator::Contains(_)
1292 | BinaryOperator::ContainedBy(_)
1293 | BinaryOperator::JsonPathMatch(_)
1294 | BinaryOperator::JsonPathExists(_)
1295 | BinaryOperator::JsonbKeyExists(_)
1296 | BinaryOperator::JsonbAnyKeyExists(_)
1297 | BinaryOperator::JsonbAllKeyExists(_)
1298 | BinaryOperator::JsonGetPath(_)
1299 | BinaryOperator::JsonGetPathText(_)
1300 | BinaryOperator::JsonDeletePath(_)
1301 | BinaryOperator::RegexMatch(_)
1302 | BinaryOperator::RegexIMatch(_)
1303 | BinaryOperator::NotRegexMatch(_)
1304 | BinaryOperator::NotRegexIMatch(_)
1305 | BinaryOperator::User(_, _)
1306 | BinaryOperator::Operator(_, _) => PRIORITY_PG_CUSTOM,
1307 }
1308 }
1309}
1310
1311impl Priority for UnaryOperator {
1312 fn priority(&self) -> usize {
1313 match self {
1314 UnaryOperator::Binary(_) => 20,
1315 UnaryOperator::LogicalNot(_) => 30,
1316 UnaryOperator::Minus(_) => 40,
1317 UnaryOperator::Not(_) => 130,
1318 }
1319 }
1320}
1321
1322#[derive(Debug)]
1323enum ReduceMember<'a> {
1324 Expression(Expression<'a>),
1325 Binary(BinaryOperator<'a>),
1326 Unary(UnaryOperator),
1327}
1328
1329struct Reducer<'a> {
1330 stack: Vec<ReduceMember<'a>>,
1331}
1332
1333impl<'a> Reducer<'a> {
1334 fn reduce(&mut self, priority: usize) -> Result<(), &'static str> {
1335 let mut e = match self.stack.pop() {
1336 Some(ReduceMember::Expression(e)) => e,
1337 _ => {
1338 return Err("Expected expression before here");
1339 }
1340 };
1341 loop {
1342 let v = self.stack.pop();
1343 match v {
1344 None => break,
1345 Some(ReduceMember::Expression(_)) => return Err("ICE Reduce stack error 1"),
1346 Some(ReduceMember::Unary(op)) if op.priority() > priority => {
1347 self.stack.push(ReduceMember::Unary(op));
1348 break;
1349 }
1350 Some(ReduceMember::Binary(op)) if op.priority() > priority => {
1351 self.stack.push(ReduceMember::Binary(op));
1352 break;
1353 }
1354 Some(ReduceMember::Unary(op)) => {
1355 e = Expression::Unary(Box::new(UnaryExpression { op, operand: e }));
1356 }
1357 Some(ReduceMember::Binary(op)) => {
1358 let lhs = match self.stack.pop() {
1359 Some(ReduceMember::Expression(e)) => e,
1360 _ => return Err("ICE Reduce stack error 2"),
1361 };
1362 e = Expression::Binary(Box::new(BinaryExpression { op, lhs, rhs: e }));
1363 }
1364 }
1365 }
1366 self.stack.push(ReduceMember::Expression(e));
1367 Ok(())
1368 }
1369
1370 fn shift_binop(&mut self, op: BinaryOperator<'a>) -> Result<(), &'static str> {
1371 self.reduce(op.priority())?;
1372 self.stack.push(ReduceMember::Binary(op));
1373 Ok(())
1374 }
1375
1376 fn shift_unary(&mut self, op: UnaryOperator) -> Result<(), &'static str> {
1377 if matches!(self.stack.last(), Some(ReduceMember::Expression(_))) {
1378 return Err("Unary operator cannot come before expression");
1379 }
1380 self.stack.push(ReduceMember::Unary(op));
1381 Ok(())
1382 }
1383
1384 fn shift_expr(&mut self, e: Expression<'a>) -> Result<(), &'static str> {
1385 if matches!(self.stack.last(), Some(ReduceMember::Expression(_))) {
1386 return Err("Expression should not follow expression");
1388 }
1389 self.stack.push(ReduceMember::Expression(e));
1390 Ok(())
1391 }
1392}
1393
1394fn parse_array_element<'a>(parser: &mut Parser<'a, '_>) -> Result<Expression<'a>, ParseError> {
1398 if matches!(parser.token, Token::LBracket) {
1399 let lbracket = parser.consume_token(Token::LBracket)?;
1400 let mut elements = Vec::new();
1401 if !matches!(parser.token, Token::RBracket) {
1402 loop {
1403 parser.recovered(
1404 "']' or ','",
1405 &|t| matches!(t, Token::RBracket | Token::Comma),
1406 |parser| {
1407 elements.push(parse_array_element(parser)?);
1408 Ok(())
1409 },
1410 )?;
1411 if parser.skip_token(Token::Comma).is_none() {
1412 break;
1413 }
1414 }
1415 }
1416 let rbracket = parser.consume_token(Token::RBracket)?;
1417 let bracket_span = lbracket.join_span(&rbracket);
1418 Ok(Expression::Array(Box::new(ArrayExpression {
1419 array_span: bracket_span.clone(),
1420 bracket_span,
1421 elements,
1422 })))
1423 } else {
1424 parse_expression_unreserved(parser, PRIORITY_MAX)
1425 }
1426}
1427
1428pub(crate) fn parse_expression_restricted<'a>(
1429 parser: &mut Parser<'a, '_>,
1430 max_priority: usize,
1431 restrict: Restrict,
1432) -> Result<Expression<'a>, ParseError> {
1433 let mut r = Reducer { stack: Vec::new() };
1434 loop {
1435 if matches!(r.stack.last(), Some(ReduceMember::Expression(_)))
1436 && matches!(
1437 parser.token,
1438 Token::Ident(
1439 _,
1440 Keyword::NULLS
1441 | Keyword::FIRST
1442 | Keyword::LAST
1443 | Keyword::ROW
1444 | Keyword::ROWS
1445 | Keyword::RANGE
1446 | Keyword::ONLY
1447 | Keyword::FILTER
1448 | Keyword::PRECEDING
1449 | Keyword::FOLLOWING
1450 )
1451 )
1452 {
1453 break;
1454 }
1455 if matches!(r.stack.last(), Some(ReduceMember::Expression(_)))
1459 && matches!(parser.token, Token::Ident(_, Keyword::NOT))
1460 && matches!(parser.peek(), Token::Ident(_, Keyword::NULL))
1461 {
1462 break;
1463 }
1464 let e = match parser.token.clone() {
1465 Token::ColonEq if PRIORITY_ASSIGN < max_priority => {
1466 r.shift_binop(BinaryOperator::Assignment(parser.consume()))
1467 }
1468 Token::Ident(_, Keyword::OR) if PRIORITY_OR < max_priority => {
1469 r.shift_binop(BinaryOperator::Or(parser.consume()))
1470 }
1471 Token::DoublePipe if PRIORITY_ADD < max_priority => {
1472 r.shift_binop(BinaryOperator::Concat(parser.consume()))
1473 }
1474 Token::Ident(_, Keyword::XOR) if PRIORITY_XOR < max_priority => {
1475 r.shift_binop(BinaryOperator::Xor(parser.consume()))
1476 }
1477 Token::Ident(_, Keyword::AND) if PRIORITY_AND < max_priority => {
1478 r.shift_binop(BinaryOperator::And(parser.consume()))
1479 }
1480 Token::DoubleAmpersand
1481 if PRIORITY_AND < max_priority && !parser.options.dialect.is_postgresql() =>
1482 {
1483 r.shift_binop(BinaryOperator::And(parser.consume()))
1484 }
1485 Token::DoubleAmpersand
1486 if PRIORITY_PG_CUSTOM < max_priority && parser.options.dialect.is_postgresql() =>
1487 {
1488 r.shift_binop(BinaryOperator::Overlap(parser.consume()))
1489 }
1490 Token::Eq if PRIORITY_CMP < max_priority => {
1491 r.shift_binop(BinaryOperator::Eq(parser.consume()))
1492 }
1493 Token::Spaceship if PRIORITY_CMP < max_priority => {
1494 r.shift_binop(BinaryOperator::NullSafeEq(parser.consume()))
1495 }
1496 Token::GtEq if PRIORITY_CMP < max_priority => {
1497 r.shift_binop(BinaryOperator::GtEq(parser.consume()))
1498 }
1499 Token::Gt if PRIORITY_CMP < max_priority => {
1500 r.shift_binop(BinaryOperator::Gt(parser.consume()))
1501 }
1502 Token::LtEq if PRIORITY_CMP < max_priority => {
1503 r.shift_binop(BinaryOperator::LtEq(parser.consume()))
1504 }
1505 Token::Lt if PRIORITY_CMP < max_priority => {
1506 r.shift_binop(BinaryOperator::Lt(parser.consume()))
1507 }
1508 Token::Neq if PRIORITY_CMP < max_priority => {
1509 r.shift_binop(BinaryOperator::Neq(parser.consume()))
1510 }
1511 Token::ShiftLeft if PRIORITY_SHIFT < max_priority => {
1512 r.shift_binop(BinaryOperator::ShiftLeft(parser.consume()))
1513 }
1514 Token::ShiftRight if PRIORITY_SHIFT < max_priority => {
1515 r.shift_binop(BinaryOperator::ShiftRight(parser.consume()))
1516 }
1517 Token::Ampersand => r.shift_binop(BinaryOperator::BitAnd(parser.consume())),
1518 Token::Pipe if PRIORITY_BITOR < max_priority => {
1519 r.shift_binop(BinaryOperator::BitOr(parser.consume()))
1520 }
1521 Token::Ident(_, Keyword::BINARY) if PRIORITY_JSON_EXTRACT < max_priority => {
1522 r.shift_unary(UnaryOperator::Binary(parser.consume()))
1523 }
1524 Token::Ident(_, Keyword::COLLATE)
1525 if 20 < max_priority
1526 && matches!(r.stack.last(), Some(ReduceMember::Expression(_))) =>
1527 {
1528 let collate_span = parser.consume_keyword(Keyword::COLLATE)?;
1530 let collation = parser.consume_plain_identifier_unreserved()?;
1531 if let Err(e) = r.shift_binop(BinaryOperator::Collate(collate_span)) {
1532 parser.err_here(e)?;
1533 }
1534 r.shift_expr(Expression::Identifier(Box::new(IdentifierExpression {
1535 parts: vec![IdentifierPart::Name(collation)],
1536 })))
1537 }
1538 Token::ExclamationMark if PRIORITY_JSON_EXTRACT < max_priority => {
1539 r.shift_unary(UnaryOperator::LogicalNot(parser.consume()))
1540 }
1541 Token::Minus if !matches!(r.stack.last(), Some(ReduceMember::Expression(_))) => {
1542 r.shift_unary(UnaryOperator::Minus(parser.consume()))
1543 }
1544 Token::Minus
1545 if PRIORITY_ADD < max_priority
1546 && matches!(r.stack.last(), Some(ReduceMember::Expression(_))) =>
1547 {
1548 r.shift_binop(BinaryOperator::Subtract(parser.consume()))
1549 }
1550 Token::Ident(_, Keyword::IN) if PRIORITY_CMP < max_priority => {
1551 if let Err(e) = r.reduce(PRIORITY_CMP) {
1552 parser.err_here(e)?;
1553 }
1554 let lhs = match r.stack.pop() {
1555 Some(ReduceMember::Expression(e)) => e,
1556 _ => parser.err_here("Expected expression before here 3")?,
1557 };
1558 let op = parser.consume_keyword(Keyword::IN)?;
1559 parser.consume_token(Token::LParen)?;
1560 let mut rhs = Vec::new();
1561 loop {
1562 parser.recovered(
1563 "')' or ','",
1564 &|t| matches!(t, Token::RParen | Token::Comma),
1565 |parser| {
1566 rhs.push(parse_expression_paren(parser)?);
1567 Ok(())
1568 },
1569 )?;
1570 if parser.skip_token(Token::Comma).is_none() {
1571 break;
1572 }
1573 }
1574 let r_paren_span = parser.consume_token(Token::RParen)?;
1575 r.shift_expr(Expression::In(Box::new(InExpression {
1576 lhs,
1577 rhs,
1578 in_span: op,
1579 not_in: false,
1580 r_paren_span,
1581 })))
1582 }
1583 Token::Ident(_, Keyword::IS) if PRIORITY_CMP < max_priority => {
1584 if let Err(e) = r.reduce(PRIORITY_CMP) {
1585 parser.err_here(e)?;
1586 }
1587 let lhs = match r.stack.pop() {
1588 Some(ReduceMember::Expression(e)) => e,
1589 _ => parser.err_here("Expected expression before here 4")?,
1590 };
1591 let op = parser.consume_keyword(Keyword::IS)?;
1592 let (is, op) = match &parser.token {
1593 Token::Ident(_, Keyword::NOT) => {
1594 parser.consume();
1595 match &parser.token {
1596 Token::Ident(_, Keyword::TRUE) => {
1597 (Is::NotTrue, parser.consume().join_span(&op))
1598 }
1599 Token::Ident(_, Keyword::FALSE) => {
1600 (Is::NotFalse, parser.consume().join_span(&op))
1601 }
1602 Token::Ident(_, Keyword::NULL) => {
1603 (Is::NotNull, parser.consume().join_span(&op))
1604 }
1605 Token::Ident(_, Keyword::UNKNOWN) => {
1606 (Is::NotUnknown, parser.consume().join_span(&op))
1607 }
1608 Token::Ident(_, Keyword::DISTINCT) => {
1609 let op_span = parser
1610 .consume_keywords(&[Keyword::DISTINCT, Keyword::FROM])?
1611 .join_span(&op);
1612 parser.postgres_only(&op_span);
1613 let rhs = parse_expression_unreserved(parser, PRIORITY_AND)?;
1614 (Is::NotDistinctFrom(rhs), op_span)
1615 }
1616 _ => parser.expected_failure(
1617 "'TRUE', 'FALSE', 'UNKNOWN', 'NULL' or 'DISTINCT'",
1618 )?,
1619 }
1620 }
1621 Token::Ident(_, Keyword::TRUE) => (Is::True, parser.consume().join_span(&op)),
1622 Token::Ident(_, Keyword::FALSE) => (Is::False, parser.consume().join_span(&op)),
1623 Token::Ident(_, Keyword::NULL) => (Is::Null, parser.consume().join_span(&op)),
1624 Token::Ident(_, Keyword::DISTINCT) => {
1625 let op_span = parser
1626 .consume_keywords(&[Keyword::DISTINCT, Keyword::FROM])?
1627 .join_span(&op);
1628 parser.postgres_only(&op_span);
1629 let rhs = parse_expression_unreserved(parser, PRIORITY_AND)?;
1630 (Is::DistinctFrom(rhs), op_span)
1631 }
1632 Token::Ident(_, Keyword::UNKNOWN) => {
1633 (Is::Unknown, parser.consume().join_span(&op))
1634 }
1635 _ => parser.expected_failure(
1636 "'NOT', 'TRUE', 'FALSE', 'UNKNOWN', 'NULL' or 'DISTINCT'",
1637 )?,
1638 };
1639 r.shift_expr(Expression::Is(Box::new(IsExpression {
1640 lhs,
1641 is,
1642 is_span: op,
1643 })))
1644 }
1645 Token::DoubleColon
1646 if parser.options.dialect.is_postgresql()
1647 && matches!(r.stack.last(), Some(ReduceMember::Expression(_))) =>
1648 {
1649 if let Err(e) = r.reduce(PRIORITY_TYPECAST) {
1652 parser.err_here(e)?;
1653 }
1654 let expr = match r.stack.pop() {
1655 Some(ReduceMember::Expression(e)) => e,
1656 _ => parser.err_here("Expected expression before '::'")?,
1657 };
1658 let doublecolon_span = parser.consume_token(Token::DoubleColon)?;
1659 let type_ = parse_data_type(parser, DataTypeContext::TypeRef)?;
1660 r.shift_expr(Expression::TypeCast(Box::new(TypeCastExpression {
1661 expr,
1662 doublecolon_span,
1663 type_,
1664 })))
1665 }
1666 Token::LBracket
1667 if parser.options.dialect.is_postgresql()
1668 && PRIORITY_TYPECAST < max_priority
1669 && matches!(r.stack.last(), Some(ReduceMember::Expression(_))) =>
1670 {
1671 if let Err(e) = r.reduce(PRIORITY_TYPECAST) {
1673 parser.err_here(e)?;
1674 }
1675 let expr = match r.stack.pop() {
1676 Some(ReduceMember::Expression(e)) => e,
1677 _ => parser.err_here("Expected expression before '['")?,
1678 };
1679 let lbracket = parser.consume_token(Token::LBracket)?;
1680 let lower = parse_expression_unreserved(parser, PRIORITY_MAX)?;
1681 let upper = if parser.skip_token(Token::Colon).is_some() {
1682 Some(parse_expression_unreserved(parser, PRIORITY_MAX)?)
1683 } else {
1684 None
1685 };
1686 let rbracket = parser.consume_token(Token::RBracket)?;
1687 let bracket_span = lbracket.join_span(&rbracket);
1688 r.shift_expr(Expression::ArraySubscript(Box::new(
1689 ArraySubscriptExpression {
1690 expr,
1691 bracket_span,
1692 lower,
1693 upper,
1694 },
1695 )))
1696 }
1697 Token::Period
1698 if parser.options.dialect.is_postgresql()
1699 && PRIORITY_TYPECAST < max_priority
1700 && matches!(r.stack.last(), Some(ReduceMember::Expression(_))) =>
1701 {
1702 if let Err(e) = r.reduce(PRIORITY_TYPECAST) {
1704 parser.err_here(e)?;
1705 }
1706 let expr = match r.stack.pop() {
1707 Some(ReduceMember::Expression(e)) => e,
1708 _ => parser.err_here("Expected expression before '.'")?,
1709 };
1710 let dot_span = parser.consume_token(Token::Period)?;
1711 let field = parser.consume_plain_identifier_unreserved()?;
1712 r.shift_expr(Expression::FieldAccess(Box::new(FieldAccessExpression {
1713 expr,
1714 dot_span,
1715 field,
1716 })))
1717 }
1718 Token::Ident(_, Keyword::NOT)
1719 if !matches!(r.stack.last(), Some(ReduceMember::Expression(_))) =>
1720 {
1721 r.shift_unary(UnaryOperator::Not(parser.consume()))
1722 }
1723 Token::Ident(_, Keyword::NOT)
1724 if PRIORITY_CMP < max_priority
1725 && matches!(r.stack.last(), Some(ReduceMember::Expression(_))) =>
1726 {
1727 if let Err(e) = r.reduce(PRIORITY_CMP) {
1728 parser.err_here(e)?;
1729 }
1730 let lhs = match r.stack.pop() {
1731 Some(ReduceMember::Expression(e)) => e,
1732 _ => parser.err_here("Expected expression before here 2")?,
1733 };
1734 let op = parser.consume_keyword(Keyword::NOT)?;
1735 match &parser.token {
1736 Token::Ident(_, Keyword::IN) => {
1737 let op = parser.consume_keyword(Keyword::IN)?.join_span(&op);
1738 parser.consume_token(Token::LParen)?;
1739 let mut rhs = Vec::new();
1740 loop {
1741 parser.recovered(
1742 "')' or ','",
1743 &|t| matches!(t, Token::RParen | Token::Comma),
1744 |parser| {
1745 rhs.push(parse_expression_paren(parser)?);
1746 Ok(())
1747 },
1748 )?;
1749 if parser.skip_token(Token::Comma).is_none() {
1750 break;
1751 }
1752 }
1753 let r_paren_span = parser.consume_token(Token::RParen)?;
1754 r.shift_expr(Expression::In(Box::new(InExpression {
1755 lhs,
1756 rhs,
1757 in_span: op,
1758 not_in: true,
1759 r_paren_span,
1760 })))
1761 }
1762 Token::Ident(_, Keyword::LIKE) => {
1763 r.stack.push(ReduceMember::Expression(lhs));
1764 r.shift_binop(BinaryOperator::NotLike(parser.consume().join_span(&op)))
1765 }
1766 Token::Ident(_, Keyword::REGEXP) if parser.options.dialect.is_maria() => {
1767 r.stack.push(ReduceMember::Expression(lhs));
1768 r.shift_binop(BinaryOperator::NotRegexp(parser.consume().join_span(&op)))
1769 }
1770 Token::Ident(_, Keyword::RLIKE) if parser.options.dialect.is_maria() => {
1771 r.stack.push(ReduceMember::Expression(lhs));
1772 r.shift_binop(BinaryOperator::NotRlike(parser.consume().join_span(&op)))
1773 }
1774 Token::Ident(_, Keyword::BETWEEN) => {
1775 let between_span = parser.consume_keyword(Keyword::BETWEEN)?.join_span(&op);
1776 let low = parse_expression_unreserved(parser, PRIORITY_AND)?;
1777 let and_span = parser.consume_keyword(Keyword::AND)?;
1778 let high = parse_expression_unreserved(parser, PRIORITY_AND)?;
1779 r.shift_expr(Expression::Between(Box::new(BetweenExpression {
1780 lhs,
1781 low,
1782 high,
1783 between_span: between_span.join_span(&and_span),
1784 not_between: true,
1785 })))
1786 }
1787 _ => parser.expected_failure("'IN', 'LIKE', 'REGEXP', 'RLIKE' or 'BETWEEN'")?,
1788 }
1789 }
1790 Token::Ident(_, Keyword::BETWEEN)
1791 if PRIORITY_CMP < max_priority
1792 && matches!(r.stack.last(), Some(ReduceMember::Expression(_))) =>
1793 {
1794 if let Err(e) = r.reduce(PRIORITY_CMP) {
1795 parser.err_here(e)?;
1796 }
1797 let lhs = match r.stack.pop() {
1798 Some(ReduceMember::Expression(e)) => e,
1799 _ => parser.err_here("Expected expression before BETWEEN")?,
1800 };
1801 let between_span = parser.consume_keyword(Keyword::BETWEEN)?;
1802 let low = parse_expression_unreserved(parser, PRIORITY_AND)?;
1803 let and_span = parser.consume_keyword(Keyword::AND)?;
1804 let high = parse_expression_unreserved(parser, PRIORITY_AND)?;
1805 r.shift_expr(Expression::Between(Box::new(BetweenExpression {
1806 lhs,
1807 low,
1808 high,
1809 between_span: between_span.join_span(&and_span),
1810 not_between: false,
1811 })))
1812 }
1813 Token::Ident(_, Keyword::LIKE) if PRIORITY_CMP < max_priority => {
1814 r.shift_binop(BinaryOperator::Like(parser.consume()))
1815 }
1816 Token::Ident(_, Keyword::SIMILAR)
1817 if PRIORITY_CMP < max_priority
1818 && matches!(r.stack.last(), Some(ReduceMember::Expression(_))) =>
1819 {
1820 if let Err(e) = r.reduce(PRIORITY_CMP) {
1822 parser.err_here(e)?;
1823 }
1824 let lhs = match r.stack.pop() {
1825 Some(ReduceMember::Expression(e)) => e,
1826 _ => parser.err_here("Expected expression before SIMILAR")?,
1827 };
1828 let op_span = parser.consume_keywords(&[Keyword::SIMILAR, Keyword::TO])?;
1829 parser.postgres_only(&op_span);
1830 r.stack.push(ReduceMember::Expression(lhs));
1831 r.shift_binop(BinaryOperator::Like(op_span))
1832 }
1833 Token::Ident(_, Keyword::REGEXP)
1834 if PRIORITY_CMP < max_priority && parser.options.dialect.is_maria() =>
1835 {
1836 r.shift_binop(BinaryOperator::Regexp(parser.consume()))
1837 }
1838 Token::Ident(_, Keyword::RLIKE)
1839 if PRIORITY_CMP < max_priority && parser.options.dialect.is_maria() =>
1840 {
1841 r.shift_binop(BinaryOperator::Rlike(parser.consume()))
1842 }
1843 Token::RArrowJson if PRIORITY_JSON_EXTRACT < max_priority => {
1844 r.shift_binop(BinaryOperator::JsonExtract(parser.consume()))
1845 }
1846 Token::RDoubleArrowJson if PRIORITY_JSON_EXTRACT < max_priority => {
1847 r.shift_binop(BinaryOperator::JsonExtractUnquote(parser.consume()))
1848 }
1849 Token::Contains if PRIORITY_PG_CUSTOM < max_priority => {
1851 r.shift_binop(BinaryOperator::Contains(parser.consume()))
1852 }
1853 Token::ContainedBy if PRIORITY_PG_CUSTOM < max_priority => {
1854 r.shift_binop(BinaryOperator::ContainedBy(parser.consume()))
1855 }
1856 Token::AtQuestion if PRIORITY_PG_CUSTOM < max_priority => {
1857 r.shift_binop(BinaryOperator::JsonPathExists(parser.consume()))
1858 }
1859 Token::QuestionPipe if PRIORITY_PG_CUSTOM < max_priority => {
1860 r.shift_binop(BinaryOperator::JsonbAnyKeyExists(parser.consume()))
1861 }
1862 Token::QuestionAmpersand if PRIORITY_PG_CUSTOM < max_priority => {
1863 r.shift_binop(BinaryOperator::JsonbAllKeyExists(parser.consume()))
1864 }
1865 Token::HashArrow if PRIORITY_PG_CUSTOM < max_priority => {
1866 r.shift_binop(BinaryOperator::JsonGetPath(parser.consume()))
1867 }
1868 Token::HashDoubleArrow if PRIORITY_PG_CUSTOM < max_priority => {
1869 r.shift_binop(BinaryOperator::JsonGetPathText(parser.consume()))
1870 }
1871 Token::HashMinus if PRIORITY_PG_CUSTOM < max_priority => {
1872 r.shift_binop(BinaryOperator::JsonDeletePath(parser.consume()))
1873 }
1874 Token::TildeStar if PRIORITY_PG_CUSTOM < max_priority => {
1875 r.shift_binop(BinaryOperator::RegexIMatch(parser.consume()))
1876 }
1877 Token::NotTilde if PRIORITY_PG_CUSTOM < max_priority => {
1878 r.shift_binop(BinaryOperator::NotRegexMatch(parser.consume()))
1879 }
1880 Token::NotTildeStar if PRIORITY_PG_CUSTOM < max_priority => {
1881 r.shift_binop(BinaryOperator::NotRegexIMatch(parser.consume()))
1882 }
1883 Token::LikeTilde if PRIORITY_CMP < max_priority => {
1884 r.shift_binop(BinaryOperator::Like(parser.consume()))
1885 }
1886 Token::NotLikeTilde if PRIORITY_CMP < max_priority => {
1887 r.shift_binop(BinaryOperator::NotLike(parser.consume()))
1888 }
1889 Token::AtAt
1891 if PRIORITY_PG_CUSTOM < max_priority
1892 && parser.options.dialect.is_postgresql()
1893 && matches!(r.stack.last(), Some(ReduceMember::Expression(_))) =>
1894 {
1895 r.shift_binop(BinaryOperator::JsonPathMatch(parser.consume()))
1896 }
1897 Token::Tilde
1899 if PRIORITY_PG_CUSTOM < max_priority
1900 && parser.options.dialect.is_postgresql()
1901 && matches!(r.stack.last(), Some(ReduceMember::Expression(_))) =>
1902 {
1903 r.shift_binop(BinaryOperator::RegexMatch(parser.consume()))
1904 }
1905 Token::QuestionMark
1907 if PRIORITY_PG_CUSTOM < max_priority
1908 && parser.options.dialect.is_postgresql()
1909 && !matches!(parser.options.arguments, crate::SQLArguments::QuestionMark)
1910 && matches!(r.stack.last(), Some(ReduceMember::Expression(_))) =>
1911 {
1912 r.shift_binop(BinaryOperator::JsonbKeyExists(parser.consume()))
1913 }
1914 Token::PostgresOperator(op)
1916 if PRIORITY_PG_CUSTOM < max_priority
1917 && parser.options.dialect.is_postgresql()
1918 && matches!(r.stack.last(), Some(ReduceMember::Expression(_))) =>
1919 {
1920 r.shift_binop(BinaryOperator::User(op, parser.consume()))
1921 }
1922 Token::Ident(_, Keyword::OPERATOR)
1923 if PRIORITY_PG_CUSTOM < max_priority
1924 && parser.options.dialect.is_postgresql()
1925 && matches!(r.stack.last(), Some(ReduceMember::Expression(_))) =>
1926 {
1927 let operator_span = parser.consume_keyword(Keyword::OPERATOR)?;
1928 parser.consume_token(Token::LParen)?;
1929 let op_name = parse_operator_name(parser)?;
1930 let rparen_span = parser.consume_token(Token::RParen)?;
1931 let full_span = operator_span.join_span(&rparen_span);
1932 r.shift_binop(BinaryOperator::Operator(op_name, full_span))
1933 }
1934 Token::Ident(_, Keyword::MEMBER)
1935 if PRIORITY_CMP < max_priority
1936 && matches!(r.stack.last(), Some(ReduceMember::Expression(_))) =>
1937 {
1938 if let Err(e) = r.reduce(PRIORITY_CMP) {
1939 parser.err_here(e)?;
1940 }
1941 let lhs = match r.stack.pop() {
1942 Some(ReduceMember::Expression(e)) => e,
1943 _ => parser.err_here("Expected expression before here")?,
1944 };
1945 let member_span = parser.consume_keyword(Keyword::MEMBER)?;
1946 let of_span = parser.consume_keyword(Keyword::OF)?;
1947 parser.consume_token(Token::LParen)?;
1948 let rhs = parse_expression_paren(parser)?;
1949 let r_paren_span = parser.consume_token(Token::RParen)?;
1950 r.shift_expr(Expression::MemberOf(Box::new(MemberOfExpression {
1951 lhs,
1952 rhs,
1953 member_of_span: member_span.join_span(&of_span),
1954 r_paren_span,
1955 })))
1956 }
1957 Token::Ident(_, Keyword::INTERVAL) => {
1958 let interval_span = parser.consume();
1959 let (time_interval, embedded_unit) = match parser.token {
1960 Token::String(..) => {
1961 let v = parser.consume_string()?;
1962 let str_span = v.span();
1963 let mut nums = Vec::new();
1964 let mut embedded: Option<TimeUnit> = None;
1965 for part in v.split([':', '!', ',', '.', '-', ' ']) {
1966 if let Ok(n) = part.parse::<i64>() {
1967 nums.push(n);
1968 } else if !part.is_empty() {
1969 embedded = parse_time_unit_from_str(part);
1970 }
1971 }
1972 ((nums, str_span), embedded)
1973 }
1974 Token::Integer(_) => {
1975 let (v, s) = parser.consume_int()?;
1976 ((vec![v], s), None)
1977 }
1978 _ => parser.err_here("Expected integer or string")?,
1979 };
1980 let time_unit = if let Some(u) = parse_time_unit(&parser.token) {
1981 (u, parser.consume())
1982 } else if let Some(u) = embedded_unit {
1983 (u, time_interval.1.clone())
1984 } else {
1985 parser.err_here("Expected time unit")?
1986 };
1987 let e = Expression::Interval(Box::new(IntervalExpression {
1988 interval_span,
1989 time_interval,
1990 time_unit,
1991 }));
1992 r.shift_expr(e)
1993 }
1994 Token::Ident(_, Keyword::TIMESTAMPADD) => {
1995 let timestamp_add_span = parser.consume();
1996 parser.consume_token(Token::LParen)?;
1997 let parts = parser.recovered("')'", &|t| matches!(t, Token::RParen), |parser| {
1998 let Some(u) = parse_time_unit(&parser.token) else {
1999 parser.err_here("Expected time unit")?
2000 };
2001 let unit = (u, parser.consume());
2002 parser.consume_token(Token::Comma)?;
2003 let interval = parse_expression_outer(parser)?;
2004 parser.consume_token(Token::Comma)?;
2005 let datetime = parse_expression_outer(parser)?;
2006 Ok(Some((unit, interval, datetime)))
2007 })?;
2008 let r_paren_span = parser.consume_token(Token::RParen)?;
2009 if let Some((unit, interval, datetime)) = parts {
2010 r.shift_expr(Expression::TimestampAdd(Box::new(TimestampAddExpression {
2011 timestamp_add_span,
2012 unit,
2013 interval,
2014 datetime,
2015 r_paren_span,
2016 })))
2017 } else {
2018 r.shift_expr(Expression::Invalid(Box::new(InvalidExpression {
2019 span: timestamp_add_span,
2020 })))
2021 }
2022 }
2023 Token::Ident(_, Keyword::TIMESTAMPDIFF) => {
2024 let timestamp_diff_span = parser.consume();
2025 parser.consume_token(Token::LParen)?;
2026 let parts = parser.recovered("')'", &|t| matches!(t, Token::RParen), |parser| {
2027 let Some(u) = parse_time_unit(&parser.token) else {
2028 parser.err_here("Expected time unit")?
2029 };
2030 let unit = (u, parser.consume());
2031 parser.consume_token(Token::Comma)?;
2032 let e1 = parse_expression_outer(parser)?;
2033 parser.consume_token(Token::Comma)?;
2034 let e2 = parse_expression_outer(parser)?;
2035 Ok(Some((unit, e1, e2)))
2036 })?;
2037 let r_paren_span = parser.consume_token(Token::RParen)?;
2038 if let Some((unit, e1, e2)) = parts {
2039 r.shift_expr(Expression::TimestampDiff(Box::new(
2040 TimestampDiffExpression {
2041 timestamp_diff_span,
2042 unit,
2043 e1,
2044 e2,
2045 r_paren_span,
2046 },
2047 )))
2048 } else {
2049 r.shift_expr(Expression::Invalid(Box::new(InvalidExpression {
2050 span: timestamp_diff_span,
2051 })))
2052 }
2053 }
2054 Token::Plus if PRIORITY_ADD < max_priority => {
2055 r.shift_binop(BinaryOperator::Add(parser.consume()))
2056 }
2057 Token::Div if PRIORITY_MULT < max_priority => {
2058 r.shift_binop(BinaryOperator::Divide(parser.consume()))
2059 }
2060 Token::Ident(_, Keyword::DIV) if PRIORITY_MULT < max_priority => {
2061 r.shift_binop(BinaryOperator::Div(parser.consume()))
2062 }
2063 Token::Minus if PRIORITY_ADD < max_priority => {
2064 r.shift_binop(BinaryOperator::Subtract(parser.consume()))
2065 }
2066 Token::Ident(_, Keyword::LIKE) if PRIORITY_CMP < max_priority => {
2067 r.shift_binop(BinaryOperator::Like(parser.consume()))
2068 }
2069 Token::Mul if !matches!(r.stack.last(), Some(ReduceMember::Expression(_))) => r
2070 .shift_expr(Expression::Identifier(Box::new(IdentifierExpression {
2071 parts: vec![IdentifierPart::Star(parser.consume_token(Token::Mul)?)],
2072 }))),
2073 Token::Mul
2074 if PRIORITY_MULT < max_priority
2075 && matches!(r.stack.last(), Some(ReduceMember::Expression(_))) =>
2076 {
2077 r.shift_binop(BinaryOperator::Mult(parser.consume()))
2078 }
2079 Token::Mod if PRIORITY_MULT < max_priority => {
2080 r.shift_binop(BinaryOperator::Mod(parser.consume()))
2081 }
2082 Token::Ident(_, Keyword::MOD)
2083 if PRIORITY_MULT < max_priority
2084 && matches!(r.stack.last(), Some(ReduceMember::Expression(_))) =>
2085 {
2086 r.shift_binop(BinaryOperator::Mod(parser.consume()))
2087 }
2088 Token::Ident(_, Keyword::TRUE) => {
2089 r.shift_expr(Expression::Bool(Box::new(BoolExpression {
2090 value: true,
2091 span: parser.consume_keyword(Keyword::TRUE)?,
2092 })))
2093 }
2094 Token::Ident(_, Keyword::FALSE) => {
2095 r.shift_expr(Expression::Bool(Box::new(BoolExpression {
2096 value: false,
2097 span: parser.consume_keyword(Keyword::FALSE)?,
2098 })))
2099 }
2100 Token::Ident(_, Keyword::NULL) => {
2101 r.shift_expr(Expression::Null(Box::new(NullExpression {
2102 span: parser.consume_keyword(Keyword::NULL)?,
2103 })))
2104 }
2105 Token::Ident(_, Keyword::_LIST_) if parser.options.list_hack => {
2106 let arg = parser.arg;
2107 parser.arg += 1;
2108 r.shift_expr(Expression::ListHack(Box::new(ListHackExpression {
2109 index: arg,
2110 span: parser.consume_keyword(Keyword::_LIST_)?,
2111 })))
2112 }
2113 Token::String(..) => {
2114 r.shift_expr(Expression::String(Box::new(parser.consume_string()?)))
2115 }
2116 Token::Integer(_) => {
2117 let (value, span) = parser.consume_int()?;
2118 r.shift_expr(Expression::Integer(Box::new(IntegerExpression {
2119 value,
2120 span,
2121 })))
2122 }
2123 Token::Float(_) => {
2124 let (value, span) = parser.consume_float()?;
2125 r.shift_expr(Expression::Float(Box::new(FloatExpression { value, span })))
2126 }
2127 Token::Ident(_, Keyword::CAST) => {
2128 let cast_span = parser.consume_keyword(Keyword::CAST)?;
2129 parser.consume_token(Token::LParen)?;
2130 let cast = parser.recovered("')'", &|t| matches!(t, Token::RParen), |parser| {
2131 let expr = parse_expression_outer(parser)?;
2132 let as_span = parser.consume_keyword(Keyword::AS)?;
2133 let type_ = parse_data_type(parser, DataTypeContext::TypeRef)?;
2134 Ok(Some((expr, as_span, type_)))
2135 })?;
2136 let r_paren_span = parser.consume_token(Token::RParen)?;
2137 if let Some((expr, as_span, type_)) = cast {
2138 r.shift_expr(Expression::Cast(Box::new(CastExpression {
2139 cast_span,
2140 expr,
2141 as_span,
2142 type_,
2143 r_paren_span,
2144 })))
2145 } else {
2146 r.shift_expr(Expression::Invalid(Box::new(InvalidExpression {
2147 span: cast_span,
2148 })))
2149 }
2150 }
2151 Token::Ident(_, Keyword::CONVERT) => {
2152 let convert_span = parser.consume_keyword(Keyword::CONVERT)?;
2153 parser.consume_token(Token::LParen)?;
2154 let convert =
2155 parser.recovered("')'", &|t| matches!(t, Token::RParen), |parser| {
2156 let expr = parse_expression_outer(parser)?;
2157 if parser.skip_keyword(Keyword::USING).is_some() {
2159 let charset = parser.consume_plain_identifier_unreserved()?;
2161 Ok(Some((expr, None, Some(charset))))
2162 } else {
2163 parser.consume_token(Token::Comma)?;
2165 let type_ = parse_data_type(parser, DataTypeContext::TypeRef)?;
2166 Ok(Some((expr, Some(type_), None)))
2167 }
2168 })?;
2169 let r_paren_span = parser.consume_token(Token::RParen)?;
2170 if let Some((expr, type_, charset)) = convert {
2171 r.shift_expr(Expression::Convert(Box::new(ConvertExpression {
2172 convert_span,
2173 expr,
2174 type_,
2175 using_charset: charset.map(|c| (c.span(), c)),
2176 r_paren_span,
2177 })))
2178 } else {
2179 r.shift_expr(Expression::Invalid(Box::new(InvalidExpression {
2180 span: convert_span,
2181 })))
2182 }
2183 }
2184 Token::Ident(_, Keyword::GROUP_CONCAT) => {
2185 let group_concat_span: core::ops::Range<usize> =
2186 parser.consume_keyword(Keyword::GROUP_CONCAT)?;
2187 parser.consume_token(Token::LParen)?;
2188 let distinct_span: Option<core::ops::Range<usize>> =
2189 parser.skip_keyword(Keyword::DISTINCT);
2190 let expr = parser.recovered("')'", &|t| matches!(t, Token::RParen), |parser| {
2191 let expr = parse_expression_outer(parser)?;
2192 Ok(Some(expr))
2193 })?;
2194 let r_paren_span = parser.consume_token(Token::RParen)?;
2200 if let Some(expr) = expr {
2201 r.shift_expr(Expression::GroupConcat(Box::new(GroupConcatExpression {
2202 group_concat_span,
2203 distinct_span,
2204 expr,
2205 r_paren_span,
2206 })))
2207 } else {
2208 r.shift_expr(Expression::Invalid(Box::new(InvalidExpression {
2209 span: group_concat_span,
2210 })))
2211 }
2212 }
2213 Token::Ident(_, Keyword::TRIM) if matches!(parser.peek(), Token::LParen) => {
2214 let trim_span = parser.consume_keyword(Keyword::TRIM)?;
2215 parser.consume_token(Token::LParen)?;
2216 let parts = parser.recovered("')'", &|t| matches!(t, Token::RParen), |parser| {
2217 let direction = match &parser.token {
2219 Token::Ident(_, Keyword::BOTH) => {
2220 Some(TrimDirection::Both(parser.consume()))
2221 }
2222 Token::Ident(_, Keyword::LEADING) => {
2223 Some(TrimDirection::Leading(parser.consume()))
2224 }
2225 Token::Ident(_, Keyword::TRAILING) => {
2226 Some(TrimDirection::Trailing(parser.consume()))
2227 }
2228 _ => None,
2229 };
2230
2231 let (what, from_span, value) = if direction.is_some() {
2232 if let Some(from_s) = parser.skip_keyword(Keyword::FROM) {
2234 let value = parse_expression_outer(parser)?;
2236 (None, Some(from_s), value)
2237 } else {
2238 let what = parse_expression_outer(parser)?;
2240 let from_s = parser.consume_keyword(Keyword::FROM)?;
2241 let value = parse_expression_outer(parser)?;
2242 (Some(what), Some(from_s), value)
2243 }
2244 } else {
2245 let first = parse_expression_outer(parser)?;
2247 if let Some(from_s) = parser.skip_keyword(Keyword::FROM) {
2248 let value = parse_expression_outer(parser)?;
2250 (Some(first), Some(from_s), value)
2251 } else {
2252 (None, None, first)
2254 }
2255 };
2256 Ok(Some((direction, what, from_span, value)))
2257 })?;
2258 let r_paren_span = parser.consume_token(Token::RParen)?;
2259 if let Some((direction, what, from_span, value)) = parts {
2260 r.shift_expr(Expression::Trim(Box::new(TrimExpression {
2261 trim_span,
2262 direction,
2263 what,
2264 from_span,
2265 value,
2266 r_paren_span,
2267 })))
2268 } else {
2269 r.shift_expr(Expression::Invalid(Box::new(InvalidExpression {
2270 span: trim_span,
2271 })))
2272 }
2273 }
2274 Token::Ident(_, Keyword::EXTRACT) => {
2275 let extract_span = parser.consume_keyword(Keyword::EXTRACT)?;
2276 parser.consume_token(Token::LParen)?;
2277 let parts = parser.recovered("')'", &|t| matches!(t, Token::RParen), |parser| {
2278 let Some(u) = parse_time_unit(&parser.token) else {
2279 parser.err_here("Expected time unit")?
2280 };
2281 let time_unit = (u, parser.consume());
2282 let from_span = parser.consume_keyword(Keyword::FROM)?;
2283 let date = parse_expression_outer(parser)?;
2284 Ok(Some((time_unit, from_span, date)))
2285 })?;
2286 let r_paren_span = parser.consume_token(Token::RParen)?;
2287 if let Some((time_unit, from_span, date)) = parts {
2288 r.shift_expr(Expression::Extract(Box::new(ExtractExpression {
2289 extract_span,
2290 time_unit,
2291 from_span,
2292 date,
2293 r_paren_span,
2294 })))
2295 } else {
2296 r.shift_expr(Expression::Invalid(Box::new(InvalidExpression {
2297 span: extract_span,
2298 })))
2299 }
2300 }
2301 Token::Ident(_, Keyword::MATCH) => {
2302 let match_span = parser.consume_keyword(Keyword::MATCH)?;
2303 parser.consume_token(Token::LParen)?;
2304 let mut cols = Vec::new();
2305 loop {
2306 parser.recovered(
2307 "')' or ','",
2308 &|t| matches!(t, Token::RParen | Token::Comma),
2309 |parser| {
2310 cols.push(parse_expression_paren(parser)?);
2311 Ok(())
2312 },
2313 )?;
2314 if parser.skip_token(Token::Comma).is_none() {
2315 break;
2316 }
2317 }
2318 parser.consume_token(Token::RParen)?;
2319 let against_span = parser.consume_keyword(Keyword::AGAINST)?;
2320 parser.consume_token(Token::LParen)?;
2321
2322 let expr = parse_expression_unreserved(parser, PRIORITY_CMP)?;
2327
2328 let mut mode: Option<MatchMode> = None;
2330 if parser.skip_keyword(Keyword::IN).is_some() {
2331 if let Some(boolean_span) = parser.skip_keyword(Keyword::BOOLEAN) {
2332 let mode_span = parser.consume_keyword(Keyword::MODE)?;
2333 mode = Some(MatchMode::InBoolean(boolean_span.join_span(&mode_span)));
2334 } else if let Some(natural_span) = parser.skip_keyword(Keyword::NATURAL) {
2335 let _language_span = parser.skip_keyword(Keyword::LANGUAGE);
2337 let mode_span = parser.consume_keyword(Keyword::MODE)?;
2338 let natural_total = natural_span.join_span(&mode_span);
2339 if let Some(with_span) = parser.skip_keyword(Keyword::WITH) {
2341 let expansion_total = with_span.join_span(
2342 &parser.consume_keywords(&[Keyword::QUERY, Keyword::EXPANSION])?,
2343 );
2344 mode = Some(MatchMode::InNaturalLanguageWithQueryExpansion(
2345 natural_total.join_span(&expansion_total),
2346 ));
2347 } else {
2348 mode = Some(MatchMode::InNaturalLanguage(natural_total));
2349 }
2350 }
2351 } else if let Some(with_span) = parser.skip_keyword(Keyword::WITH) {
2352 mode = Some(MatchMode::WithQueryExpansion(with_span.join_span(
2353 &parser.consume_keywords(&[Keyword::QUERY, Keyword::EXPANSION])?,
2354 )));
2355 }
2356
2357 let r_paren_span = parser.consume_token(Token::RParen)?;
2358
2359 if mode.is_none() {
2362 if parser.skip_keyword(Keyword::IN).is_some() {
2363 if let Some(boolean_span) = parser.skip_keyword(Keyword::BOOLEAN) {
2364 let mode_span = parser.consume_keyword(Keyword::MODE)?;
2365 mode = Some(MatchMode::InBoolean(boolean_span.join_span(&mode_span)));
2366 } else if let Some(natural_span) = parser.skip_keyword(Keyword::NATURAL) {
2367 let _language_span = parser.skip_keyword(Keyword::LANGUAGE);
2368 let mode_span = parser.consume_keyword(Keyword::MODE)?;
2369 let natural_total = natural_span.join_span(&mode_span);
2370 if let Some(with_span) = parser.skip_keyword(Keyword::WITH) {
2372 let expansion_total = with_span.join_span(
2373 &parser
2374 .consume_keywords(&[Keyword::QUERY, Keyword::EXPANSION])?,
2375 );
2376 mode = Some(MatchMode::InNaturalLanguageWithQueryExpansion(
2377 natural_total.join_span(&expansion_total),
2378 ));
2379 } else {
2380 mode = Some(MatchMode::InNaturalLanguage(natural_total));
2381 }
2382 }
2383 } else if let Some(with_span) = parser.skip_keyword(Keyword::WITH) {
2384 mode = Some(MatchMode::WithQueryExpansion(with_span.join_span(
2385 &parser.consume_keywords(&[Keyword::QUERY, Keyword::EXPANSION])?,
2386 )));
2387 }
2388 }
2389
2390 r.shift_expr(Expression::MatchAgainst(Box::new(MatchAgainstExpression {
2391 match_span,
2392 columns: cols,
2393 against_span,
2394 expr,
2395 mode,
2396 r_paren_span,
2397 })))
2398 }
2399 Token::Ident(_, Keyword::LEFT) if matches!(parser.peek(), Token::LParen) => {
2400 let i = parser.token.clone();
2401 let s = parser.span.clone();
2402 parser.consume();
2403 r.shift_expr(parse_function(parser, i, s)?)
2404 }
2405 Token::Ident(_, Keyword::CHAR) if matches!(parser.peek(), Token::LParen) => {
2406 let s = parser.span.clone();
2407 parser.consume();
2408 r.shift_expr(parse_char_function(parser, s)?)
2409 }
2410 Token::Ident(_, keyword)
2411 if matches!(parser.peek(), Token::LParen)
2412 && is_aggregate_function_ident(&keyword) =>
2413 {
2414 let i = parser.token.clone();
2415 let s = parser.span.clone();
2416 parser.consume();
2417 r.shift_expr(parse_aggregate_function(parser, i, s)?)
2418 }
2419 Token::Ident(charset, _)
2421 if charset.starts_with('_') && matches!(parser.peek(), Token::String(..)) =>
2422 {
2423 parser.consume();
2425 r.shift_expr(Expression::String(Box::new(parser.consume_string()?)))
2427 }
2428 Token::Ident(_, Keyword::ARRAY) if matches!(parser.peek(), Token::LBracket) => {
2430 let array_span = parser.consume_keyword(Keyword::ARRAY)?;
2431 parser.postgres_only(&array_span);
2432 let lbracket = parser.consume_token(Token::LBracket)?;
2433 let mut elements = Vec::new();
2434 if !matches!(parser.token, Token::RBracket) {
2435 loop {
2436 parser.recovered(
2437 "']' or ','",
2438 &|t| matches!(t, Token::RBracket | Token::Comma),
2439 |parser| {
2440 elements.push(parse_array_element(parser)?);
2441 Ok(())
2442 },
2443 )?;
2444 if parser.skip_token(Token::Comma).is_none() {
2445 break;
2446 }
2447 }
2448 }
2449 let rbracket = parser.consume_token(Token::RBracket)?;
2450 let bracket_span = lbracket.join_span(&rbracket);
2451 r.shift_expr(Expression::Array(Box::new(ArrayExpression {
2452 array_span,
2453 bracket_span,
2454 elements,
2455 })))
2456 }
2457 Token::Ident(_, k)
2458 if (k.expr_ident() || !k.restricted(restrict))
2459 && !matches!(r.stack.last(), Some(ReduceMember::Expression(_))) =>
2460 {
2461 let i = parser.token.clone();
2462 let s = parser.span.clone();
2463 parser.consume();
2464 if matches!(parser.token, Token::LParen) {
2465 r.shift_expr(parse_function(parser, i, s)?)
2466 } else {
2467 let f = match i {
2468 Token::Ident(_, Keyword::CURRENT_TIMESTAMP) => {
2469 Some(Function::CurrentTimestamp)
2470 }
2471 Token::Ident(_, Keyword::LOCALTIME | Keyword::LOCALTIMESTAMP) => {
2472 Some(Function::Now)
2473 }
2474 Token::Ident(_, Keyword::UTC_TIMESTAMP) => Some(Function::UtcTimeStamp),
2475 Token::Ident(_, Keyword::UTC_DATE) => Some(Function::UtcDate),
2476 Token::Ident(_, Keyword::UTC_TIME) => Some(Function::UtcTime),
2477 Token::Ident(_, Keyword::CURRENT_DATE) => Some(Function::CurDate),
2478 Token::Ident(_, Keyword::CURRENT_TIME) => Some(Function::CurTime),
2479 Token::Ident(_, Keyword::CURRENT_USER) => Some(Function::CurrentUser),
2480 Token::Ident(_, Keyword::CURRENT_ROLE) => Some(Function::CurrentRole),
2481 Token::Ident(_, Keyword::CURRENT_CATALOG) => Some(Function::CurrentCatalog),
2482 Token::Ident(_, Keyword::SESSION_USER) => Some(Function::SessionUser),
2483 Token::Ident(_, Keyword::USER)
2484 if parser.options.dialect.is_postgresql() =>
2485 {
2486 Some(Function::CurrentUser)
2487 }
2488 _ => None,
2489 };
2490 if let Some(f) = f {
2491 r.shift_expr(Expression::Function(Box::new(FunctionCallExpression {
2492 function: f,
2493 args: Vec::new(),
2494 function_span: s.clone(),
2495 r_paren_span: s,
2496 })))
2497 } else {
2498 let mut parts = vec![IdentifierPart::Name(
2499 parser.token_to_plain_identifier(&i, s)?,
2500 )];
2501 let mut last_ident_tok: Option<(Token<'a>, Span)> = None;
2504 loop {
2505 if parser.skip_token(Token::Period).is_none() {
2506 break;
2507 }
2508 match &parser.token {
2509 Token::Mul => {
2510 last_ident_tok = None;
2511 parts.push(IdentifierPart::Star(
2512 parser.consume_token(Token::Mul)?,
2513 ));
2514 }
2515 Token::Ident(_, _) => {
2516 let fn_tok = parser.token.clone();
2517 let fn_span = parser.span.clone();
2518 last_ident_tok = Some((fn_tok, fn_span));
2519 parts.push(IdentifierPart::Name(
2520 parser.consume_plain_identifier_unreserved()?,
2521 ));
2522 }
2523 _ => parser.expected_failure("Identifier or '*'")?,
2524 }
2525 }
2526 if matches!(parser.token, Token::LParen) {
2528 if let Some((fn_tok, fn_span)) = last_ident_tok {
2529 let mut all_idents: Vec<Identifier<'a>> = parts[..parts.len() - 1]
2531 .iter()
2532 .filter_map(|p| match p {
2533 IdentifierPart::Name(id) => Some(id.clone()),
2534 _ => None,
2535 })
2536 .collect();
2537 let fn_ident = Identifier {
2538 value: match &fn_tok {
2539 Token::Ident(v, _) => v,
2540 _ => "",
2541 },
2542 span: fn_span.clone(),
2543 };
2544 all_idents.push(fn_ident);
2545 let function_span = if all_idents.len() > 1 {
2547 all_idents[0].span.join_span(&fn_span)
2548 } else {
2549 fn_span
2550 };
2551 r.shift_expr(parse_function_call(
2552 parser,
2553 Function::Other(all_idents),
2554 function_span,
2555 )?)
2556 } else {
2557 r.shift_expr(Expression::Identifier(Box::new(
2558 IdentifierExpression { parts },
2559 )))
2560 }
2561 } else {
2562 r.shift_expr(Expression::Identifier(Box::new(IdentifierExpression {
2563 parts,
2564 })))
2565 }
2566 }
2567 }
2568 }
2569 Token::QuestionMark
2570 if matches!(parser.options.arguments, crate::SQLArguments::QuestionMark) =>
2571 {
2572 let arg = parser.arg;
2573 parser.arg += 1;
2574 r.shift_expr(Expression::Arg(Box::new(ArgExpression {
2575 index: arg,
2576 span: parser.consume_token(Token::QuestionMark)?,
2577 })))
2578 }
2579 Token::PercentS if matches!(parser.options.arguments, crate::SQLArguments::Percent) => {
2580 let arg = parser.arg;
2581 parser.arg += 1;
2582 r.shift_expr(Expression::Arg(Box::new(ArgExpression {
2583 index: arg,
2584 span: parser.consume_token(Token::PercentS)?,
2585 })))
2586 }
2587 Token::DollarArg(arg)
2588 if matches!(parser.options.arguments, crate::SQLArguments::Dollar) =>
2589 {
2590 r.shift_expr(Expression::Arg(Box::new(ArgExpression {
2591 index: arg - 1,
2592 span: parser.consume(),
2593 })))
2594 }
2595 Token::LParen => {
2596 let paren_start = parser.consume_token(Token::LParen)?;
2597 let first = parse_expression_paren(parser)?;
2598 if parser.skip_token(Token::Comma).is_some() {
2599 let mut elements = vec![first];
2601 loop {
2602 if matches!(parser.token, Token::RParen) {
2603 break;
2604 }
2605 parser.recovered(
2606 "')' or ','",
2607 &|t| matches!(t, Token::RParen | Token::Comma),
2608 |parser| {
2609 elements.push(parse_expression_paren(parser)?);
2610 Ok(())
2611 },
2612 )?;
2613 if parser.skip_token(Token::Comma).is_none() {
2614 break;
2615 }
2616 }
2617 let paren_end = parser.consume_token(Token::RParen)?;
2618 r.shift_expr(Expression::Row(Box::new(RowExpression {
2619 paren_span: paren_start.join_span(&paren_end),
2620 elements,
2621 })))
2622 } else {
2623 parser.consume_token(Token::RParen)?;
2624 r.shift_expr(first)
2625 }
2626 }
2627 Token::Ident(_, Keyword::EXISTS) => {
2628 let exists_span = parser.consume_keyword(Keyword::EXISTS)?;
2629 parser.consume_token(Token::LParen)?;
2630 let subquery = parse_compound_query(parser)?;
2631 let r_paren_span = parser.consume_token(Token::RParen)?;
2632 let ans = Expression::Exists(Box::new(ExistsExpression {
2633 exists_span,
2634 subquery,
2635 r_paren_span,
2636 }));
2637 r.shift_expr(ans)
2638 }
2639 Token::Ident(_, Keyword::ANY | Keyword::SOME | Keyword::ALL)
2640 if parser.options.dialect.is_postgresql()
2641 && !matches!(r.stack.last(), Some(ReduceMember::Expression(_))) =>
2642 {
2643 let quantifier = match &parser.token {
2644 Token::Ident(_, Keyword::ANY) => {
2645 Quantifier::Any(parser.consume_keyword(Keyword::ANY)?)
2646 }
2647 Token::Ident(_, Keyword::SOME) => {
2648 Quantifier::Some(parser.consume_keyword(Keyword::SOME)?)
2649 }
2650 _ => Quantifier::All(parser.consume_keyword(Keyword::ALL)?),
2651 };
2652 parser.consume_token(Token::LParen)?;
2653 let operand = parse_expression_paren(parser)?;
2654 let r_paren_span = parser.consume_token(Token::RParen)?;
2655 r.shift_expr(Expression::Quantifier(Box::new(QuantifierExpression {
2656 quantifier,
2657 operand,
2658 r_paren_span,
2659 })))
2660 }
2661 Token::Ident(_, Keyword::CASE) => {
2662 let case_span = parser.consume_keyword(Keyword::CASE)?;
2663 let value = if !matches!(parser.token, Token::Ident(_, Keyword::WHEN)) {
2664 Some(parse_expression_unreserved(parser, PRIORITY_MAX)?)
2665 } else {
2666 None
2667 };
2668 let mut whens = Vec::new();
2669 let mut else_ = None;
2670 parser.recovered(
2671 "'END'",
2672 &|t| matches!(t, Token::Ident(_, Keyword::END)),
2673 |parser| {
2674 loop {
2675 let when_span = parser.consume_keyword(Keyword::WHEN)?;
2676 let when = parse_expression_unreserved(parser, PRIORITY_MAX)?;
2677 let then_span = parser.consume_keyword(Keyword::THEN)?;
2678 let then = parse_expression_unreserved(parser, PRIORITY_MAX)?;
2679 whens.push(When {
2680 when_span,
2681 when,
2682 then_span,
2683 then,
2684 });
2685 if !matches!(parser.token, Token::Ident(_, Keyword::WHEN)) {
2686 break;
2687 }
2688 }
2689 if let Some(span) = parser.skip_keyword(Keyword::ELSE) {
2690 else_ = Some((span, parse_expression_unreserved(parser, PRIORITY_MAX)?))
2691 };
2692 Ok(())
2693 },
2694 )?;
2695 let end_span = parser.consume_keyword(Keyword::END)?;
2696 r.shift_expr(Expression::Case(Box::new(CaseExpression {
2697 case_span,
2698 value,
2699 whens,
2700 else_,
2701 end_span,
2702 })))
2703 }
2704 Token::AtAtGlobal | Token::AtAtSession => {
2705 let global = parser.skip_token(Token::AtAtGlobal);
2706 let session = if global.is_none() {
2707 Some(parser.consume_token(Token::AtAtSession)?)
2708 } else {
2709 None
2710 };
2711 let dot = Some(parser.consume_token(Token::Period)?);
2712 let variable = match &parser.token {
2713 Token::Ident(_, Keyword::TIME_ZONE) => Variable::TimeZone,
2714 Token::Ident(t, _) => Variable::Other(t),
2715 _ => parser.expected_failure("Identifier")?,
2716 };
2717 let variable_span = parser.consume();
2718 r.shift_expr(Expression::Variable(Box::new(VariableExpression {
2719 global,
2720 session,
2721 dot,
2722 variable,
2723 variable_span,
2724 })))
2725 }
2726 Token::At => {
2727 let at_span = parser.consume_token(Token::At)?;
2729 let name = parser.consume_plain_identifier_unreserved()?;
2730 r.shift_expr(Expression::UserVariable(Box::new(UserVariableExpression {
2731 name,
2732 at_span,
2733 })))
2734 }
2735 _ => break,
2736 };
2737 if let Err(e) = e {
2738 parser.err_here(e.to_string())?;
2739 }
2740 }
2741 if r.reduce(99999).is_err() {
2742 parser.err_here("Expected expression")
2743 } else if r.stack.len() != 1 {
2744 parser.ice(file!(), line!())
2745 } else if let Some(ReduceMember::Expression(e)) = r.stack.pop() {
2746 Ok(e)
2747 } else {
2748 parser.ice(file!(), line!())
2749 }
2750}
2751
2752pub(crate) fn parse_expression_unreserved<'a>(
2753 parser: &mut Parser<'a, '_>,
2754 max_priority: usize,
2755) -> Result<Expression<'a>, ParseError> {
2756 parse_expression_restricted(parser, max_priority, parser.reserved())
2757}
2758
2759pub(crate) fn parse_expression_or_default<'a>(
2761 parser: &mut Parser<'a, '_>,
2762 max_priority: usize,
2763) -> Result<Expression<'a>, ParseError> {
2764 if matches!(parser.token, Token::Ident(_, Keyword::DEFAULT)) {
2765 Ok(Expression::Default(Box::new(DefaultExpression {
2766 span: parser.consume_keyword(Keyword::DEFAULT)?,
2767 })))
2768 } else {
2769 parse_expression_unreserved(parser, max_priority)
2770 }
2771}
2772
2773pub(crate) fn parse_expression_outer<'a>(
2774 parser: &mut Parser<'a, '_>,
2775) -> Result<Expression<'a>, ParseError> {
2776 if matches!(parser.token, Token::Ident(_, Keyword::SELECT)) {
2777 Ok(Expression::Subquery(Box::new(SubqueryExpression {
2778 expression: parse_compound_query(parser)?,
2779 })))
2780 } else {
2781 parse_expression_unreserved(parser, PRIORITY_MAX)
2782 }
2783}
2784
2785pub(crate) fn parse_expression_paren<'a>(
2786 parser: &mut Parser<'a, '_>,
2787) -> Result<Expression<'a>, ParseError> {
2788 if matches!(parser.token, Token::Ident(_, Keyword::SELECT)) {
2789 Ok(Expression::Subquery(Box::new(SubqueryExpression {
2790 expression: parse_compound_query(parser)?,
2791 })))
2792 } else {
2793 parse_expression_unreserved(parser, PRIORITY_MAX)
2794 }
2795}
2796
2797#[cfg(test)]
2798mod tests {
2799 use core::ops::Deref;
2800
2801 use alloc::{
2802 format,
2803 string::{String, ToString},
2804 };
2805
2806 use crate::{
2807 BinaryExpression, ParseOptions, SQLDialect,
2808 expression::{BinaryOperator, Expression, PRIORITY_MAX, Quantifier},
2809 issue::Issues,
2810 parser::Parser,
2811 };
2812
2813 use super::{IdentifierPart, parse_expression_unreserved};
2814
2815 fn test_ident<'a>(e: &Expression<'a>, v: &str) -> Result<(), String> {
2816 let v = match e {
2817 Expression::Identifier(a) => match a.parts.as_slice() {
2818 [IdentifierPart::Name(vv)] => vv.deref() == v,
2819 _ => false,
2820 },
2821 _ => false,
2822 };
2823 if !v {
2824 Err(format!("Expected identifier {} found {:?}", v, e))
2825 } else {
2826 Ok(())
2827 }
2828 }
2829
2830 fn test_expr(src: &'static str, f: impl FnOnce(&Expression<'_>) -> Result<(), String>) {
2831 let mut issues = Issues::new(src);
2832 let options = ParseOptions::new().dialect(SQLDialect::MariaDB);
2833 let mut parser = Parser::new(src, &mut issues, &options);
2834 let res = parse_expression_unreserved(&mut parser, PRIORITY_MAX)
2835 .expect("Expression in test expr");
2836 if let Err(e) = f(&res) {
2837 panic!("Error parsing {}: {}\nGot {:#?}", src, e, res);
2838 }
2839 }
2840
2841 #[test]
2842 fn expressions() {
2843 test_expr("`a` + `b` * `c` + `d`", |e| {
2844 match e {
2845 Expression::Binary(b) => {
2846 let BinaryExpression {
2847 op: BinaryOperator::Add(_),
2848 lhs,
2849 rhs,
2850 ..
2851 } = b.as_ref()
2852 else {
2853 return Err("Expected outer +".to_string());
2854 };
2855 match lhs {
2856 Expression::Binary(b) => {
2857 let BinaryExpression {
2858 op: BinaryOperator::Add(_),
2859 lhs,
2860 rhs,
2861 ..
2862 } = b.as_ref()
2863 else {
2864 return Err("Expected inner +".to_string());
2865 };
2866 test_ident(lhs, "a")?;
2867 match rhs {
2868 Expression::Binary(b) => {
2869 let BinaryExpression {
2870 op: BinaryOperator::Mult(_),
2871 lhs,
2872 rhs,
2873 ..
2874 } = b.as_ref()
2875 else {
2876 return Err("Expected *".to_string());
2877 };
2878 test_ident(lhs, "b")?;
2879 test_ident(rhs, "c")?;
2880 }
2881 _ => return Err("Lhs.Rhs".to_string()),
2882 }
2883 }
2884 _ => return Err("Lhs".to_string()),
2885 }
2886 test_ident(rhs, "d")?;
2887 }
2888 _ => return Err("Outer".to_string()),
2889 }
2890 Ok(())
2891 });
2892 }
2893
2894 fn test_expr_pg(src: &'static str, f: impl FnOnce(&Expression<'_>) -> Result<(), String>) {
2895 let mut issues = Issues::new(src);
2896 let options = ParseOptions::new().dialect(SQLDialect::PostgreSQL);
2897 let mut parser = Parser::new(src, &mut issues, &options);
2898 let res = parse_expression_unreserved(&mut parser, PRIORITY_MAX)
2899 .expect("Expression in test_expr_pg");
2900 if let Err(e) = f(&res) {
2901 panic!("Error parsing {}: {}\nGot {:#?}", src, e, res);
2902 }
2903 }
2904
2905 #[test]
2906 fn quantifier_any() {
2907 test_expr_pg(
2908 "salary > ANY (SELECT max_salary FROM departments)",
2909 |e| match e {
2910 Expression::Binary(b) => match &b.rhs {
2911 Expression::Quantifier(q) => {
2912 assert!(matches!(q.quantifier, Quantifier::Any(_)));
2913 Ok(())
2914 }
2915 _ => Err(format!("Expected Quantifier RHS, got {:?}", b.rhs)),
2916 },
2917 _ => Err(format!("Expected Binary expression, got {:?}", e)),
2918 },
2919 );
2920 }
2921
2922 #[test]
2923 fn quantifier_some() {
2924 test_expr_pg("x = SOME (ARRAY[1, 2, 3])", |e| match e {
2925 Expression::Binary(b) => match &b.rhs {
2926 Expression::Quantifier(q) => {
2927 assert!(matches!(q.quantifier, Quantifier::Some(_)));
2928 Ok(())
2929 }
2930 _ => Err(format!("Expected Quantifier RHS, got {:?}", b.rhs)),
2931 },
2932 _ => Err(format!("Expected Binary expression, got {:?}", e)),
2933 });
2934 }
2935
2936 #[test]
2937 fn quantifier_all() {
2938 test_expr_pg("price <= ALL (SELECT price FROM products)", |e| match e {
2939 Expression::Binary(b) => match &b.rhs {
2940 Expression::Quantifier(q) => {
2941 assert!(matches!(q.quantifier, Quantifier::All(_)));
2942 Ok(())
2943 }
2944 _ => Err(format!("Expected Quantifier RHS, got {:?}", b.rhs)),
2945 },
2946 _ => Err(format!("Expected Binary expression, got {:?}", e)),
2947 });
2948 }
2949}