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}
441
442impl Spanned for ExtractExpression<'_> {
443 fn span(&self) -> Span {
444 self.extract_span
445 .join_span(&self.time_unit.1)
446 .join_span(&self.from_span)
447 .join_span(&self.date)
448 }
449}
450
451#[derive(Debug, Clone)]
453pub enum TrimDirection {
454 Both(Span),
455 Leading(Span),
456 Trailing(Span),
457}
458
459impl Spanned for TrimDirection {
460 fn span(&self) -> Span {
461 match self {
462 TrimDirection::Both(s) | TrimDirection::Leading(s) | TrimDirection::Trailing(s) => {
463 s.clone()
464 }
465 }
466 }
467}
468
469#[derive(Debug, Clone)]
471pub struct TrimExpression<'a> {
472 pub trim_span: Span,
474 pub direction: Option<TrimDirection>,
476 pub what: Option<Expression<'a>>,
478 pub from_span: Option<Span>,
480 pub value: Expression<'a>,
482}
483
484impl Spanned for TrimExpression<'_> {
485 fn span(&self) -> Span {
486 self.trim_span
487 .join_span(&self.direction)
488 .join_span(&self.what)
489 .join_span(&self.from_span)
490 .join_span(&self.value)
491 }
492}
493
494#[derive(Debug, Clone)]
496pub struct InExpression<'a> {
497 pub lhs: Expression<'a>,
499 pub rhs: Vec<Expression<'a>>,
501 pub in_span: Span,
503 pub not_in: bool,
505}
506
507impl Spanned for InExpression<'_> {
508 fn span(&self) -> Span {
509 self.in_span.join_span(&self.lhs).join_span(&self.rhs)
510 }
511}
512
513#[derive(Debug, Clone)]
515pub struct BetweenExpression<'a> {
516 pub lhs: Expression<'a>,
518 pub low: Expression<'a>,
520 pub high: Expression<'a>,
522 pub between_span: Span,
524 pub not_between: bool,
526}
527
528impl Spanned for BetweenExpression<'_> {
529 fn span(&self) -> Span {
530 self.between_span
531 .join_span(&self.lhs)
532 .join_span(&self.low)
533 .join_span(&self.high)
534 }
535}
536
537#[derive(Debug, Clone)]
539pub struct MemberOfExpression<'a> {
540 pub lhs: Expression<'a>,
542 pub rhs: Expression<'a>,
544 pub member_of_span: Span,
546}
547
548impl Spanned for MemberOfExpression<'_> {
549 fn span(&self) -> Span {
550 self.member_of_span
551 .join_span(&self.lhs)
552 .join_span(&self.rhs)
553 }
554}
555
556#[derive(Debug, Clone)]
558pub struct CaseExpression<'a> {
559 pub case_span: Span,
561 pub value: Option<Expression<'a>>,
563 pub whens: Vec<When<'a>>,
565 pub else_: Option<(Span, Expression<'a>)>,
567 pub end_span: Span,
569}
570
571impl Spanned for CaseExpression<'_> {
572 fn span(&self) -> Span {
573 self.case_span
574 .join_span(&self.value)
575 .join_span(&self.whens)
576 .join_span(&self.else_)
577 .join_span(&self.end_span)
578 }
579}
580
581#[derive(Debug, Clone)]
583pub struct CastExpression<'a> {
584 pub cast_span: Span,
586 pub expr: Expression<'a>,
588 pub as_span: Span,
590 pub type_: DataType<'a>,
592}
593
594impl Spanned for CastExpression<'_> {
595 fn span(&self) -> Span {
596 self.cast_span
597 .join_span(&self.expr)
598 .join_span(&self.as_span)
599 .join_span(&self.type_)
600 }
601}
602
603#[derive(Debug, Clone)]
605pub struct ConvertExpression<'a> {
606 pub convert_span: Span,
608 pub expr: Expression<'a>,
610 pub type_: Option<DataType<'a>>,
612 pub using_charset: Option<(Span, Identifier<'a>)>,
614}
615
616impl Spanned for ConvertExpression<'_> {
617 fn span(&self) -> Span {
618 self.convert_span
619 .join_span(&self.expr)
620 .join_span(&self.type_)
621 .join_span(&self.using_charset)
622 }
623}
624
625#[derive(Debug, Clone)]
627pub struct TypeCastExpression<'a> {
628 pub expr: Expression<'a>,
630 pub doublecolon_span: Span,
632 pub type_: DataType<'a>,
634}
635
636impl Spanned for TypeCastExpression<'_> {
637 fn span(&self) -> Span {
638 self.expr
639 .span()
640 .join_span(&self.doublecolon_span)
641 .join_span(&self.type_)
642 }
643}
644
645#[derive(Debug, Clone)]
647pub struct ArrayExpression<'a> {
648 pub array_span: Span,
650 pub bracket_span: Span,
652 pub elements: Vec<Expression<'a>>,
654}
655
656impl Spanned for ArrayExpression<'_> {
657 fn span(&self) -> Span {
658 self.array_span.join_span(&self.bracket_span)
659 }
660}
661
662#[derive(Debug, Clone)]
664pub struct ArraySubscriptExpression<'a> {
665 pub expr: Expression<'a>,
667 pub bracket_span: Span,
669 pub lower: Expression<'a>,
671 pub upper: Option<Expression<'a>>,
673}
674
675impl Spanned for ArraySubscriptExpression<'_> {
676 fn span(&self) -> Span {
677 self.expr.span().join_span(&self.bracket_span)
678 }
679}
680
681#[derive(Debug, Clone)]
683pub struct FieldAccessExpression<'a> {
684 pub expr: Expression<'a>,
686 pub dot_span: Span,
688 pub field: Identifier<'a>,
690}
691
692impl Spanned for FieldAccessExpression<'_> {
693 fn span(&self) -> Span {
694 self.expr
695 .span()
696 .join_span(&self.dot_span)
697 .join_span(&self.field)
698 }
699}
700
701#[derive(Debug, Clone)]
703pub struct GroupConcatExpression<'a> {
704 pub group_concat_span: Span,
706 pub distinct_span: Option<Span>,
708 pub expr: Expression<'a>,
710}
711
712impl Spanned for GroupConcatExpression<'_> {
713 fn span(&self) -> Span {
714 self.group_concat_span
715 .join_span(&self.distinct_span)
716 .join_span(&self.expr)
717 }
718}
719
720#[derive(Debug, Clone)]
722pub struct VariableExpression<'a> {
723 pub global: Option<Span>,
725 pub session: Option<Span>,
727 pub dot: Option<Span>,
729 pub variable: Variable<'a>,
731 pub variable_span: Span,
733}
734
735impl Spanned for VariableExpression<'_> {
736 fn span(&self) -> Span {
737 self.variable_span
738 .join_span(&self.global)
739 .join_span(&self.session)
740 .join_span(&self.dot)
741 }
742}
743
744#[derive(Debug, Clone)]
746pub struct UserVariableExpression<'a> {
747 pub name: Identifier<'a>,
749 pub at_span: Span,
751}
752
753impl Spanned for UserVariableExpression<'_> {
754 fn span(&self) -> Span {
755 self.at_span.join_span(&self.name)
756 }
757}
758
759#[derive(Debug, Clone)]
761pub struct TimestampAddExpression<'a> {
762 pub timestamp_add_span: Span,
764 pub unit: (TimeUnit, Span),
766 pub interval: Expression<'a>,
768 pub datetime: Expression<'a>,
770}
771
772impl Spanned for TimestampAddExpression<'_> {
773 fn span(&self) -> Span {
774 self.timestamp_add_span
775 .join_span(&self.unit.1)
776 .join_span(&self.interval)
777 .join_span(&self.datetime)
778 }
779}
780
781#[derive(Debug, Clone)]
783pub struct TimestampDiffExpression<'a> {
784 pub timestamp_diff_span: Span,
786 pub unit: (TimeUnit, Span),
788 pub e1: Expression<'a>,
790 pub e2: Expression<'a>,
792}
793
794impl Spanned for TimestampDiffExpression<'_> {
795 fn span(&self) -> Span {
796 self.timestamp_diff_span
797 .join_span(&self.unit.1)
798 .join_span(&self.e1)
799 .join_span(&self.e2)
800 }
801}
802
803#[derive(Debug, Clone)]
805pub struct MatchAgainstExpression<'a> {
806 pub match_span: Span,
808 pub columns: Vec<Expression<'a>>,
810 pub against_span: Span,
812 pub expr: Expression<'a>,
814 pub mode: Option<MatchMode>,
816}
817
818impl Spanned for MatchAgainstExpression<'_> {
819 fn span(&self) -> Span {
820 self.match_span
821 .join_span(&self.columns)
822 .join_span(&self.against_span)
823 .join_span(&self.expr)
824 .join_span(&self.mode)
825 }
826}
827
828#[derive(Debug, Clone)]
830pub struct IsExpression<'a> {
831 pub lhs: Expression<'a>,
833 pub is: Is<'a>,
835 pub is_span: Span,
837}
838
839impl<'a> Spanned for IsExpression<'a> {
840 fn span(&self) -> Span {
841 match &self.is {
842 Is::DistinctFrom(rhs) | Is::NotDistinctFrom(rhs) => {
843 self.lhs.span().join_span(&self.is_span).join_span(rhs)
844 }
845 _ => self.lhs.span().join_span(&self.is_span),
846 }
847 }
848}
849
850#[derive(Debug, Clone)]
852pub struct NullExpression {
853 pub span: Span,
855}
856
857impl Spanned for NullExpression {
858 fn span(&self) -> Span {
859 self.span.clone()
860 }
861}
862
863#[derive(Debug, Clone)]
865pub struct DefaultExpression {
866 pub span: Span,
868}
869
870impl Spanned for DefaultExpression {
871 fn span(&self) -> Span {
872 self.span.clone()
873 }
874}
875
876#[derive(Debug, Clone)]
878pub struct BoolExpression {
879 pub value: bool,
881 pub span: Span,
883}
884
885impl Spanned for BoolExpression {
886 fn span(&self) -> Span {
887 self.span.clone()
888 }
889}
890
891#[derive(Debug, Clone)]
893pub struct IntegerExpression {
894 pub value: u64,
896 pub span: Span,
898}
899
900impl Spanned for IntegerExpression {
901 fn span(&self) -> Span {
902 self.span.clone()
903 }
904}
905
906#[derive(Debug, Clone)]
908pub struct ListHackExpression {
909 pub index: usize,
911 pub span: Span,
913}
914
915impl Spanned for ListHackExpression {
916 fn span(&self) -> Span {
917 self.span.clone()
918 }
919}
920
921#[derive(Debug, Clone)]
923pub struct FloatExpression {
924 pub value: f64,
926 pub span: Span,
928}
929
930impl Spanned for FloatExpression {
931 fn span(&self) -> Span {
932 self.span.clone()
933 }
934}
935
936#[derive(Debug, Clone)]
938pub struct ArgExpression {
939 pub index: usize,
941 pub span: Span,
943}
944
945impl Spanned for ArgExpression {
946 fn span(&self) -> Span {
947 self.span.clone()
948 }
949}
950
951#[derive(Debug, Clone)]
953pub struct InvalidExpression {
954 pub span: Span,
956}
957
958impl Spanned for InvalidExpression {
959 fn span(&self) -> Span {
960 self.span.clone()
961 }
962}
963
964#[derive(Debug, Clone)]
966pub struct IdentifierExpression<'a> {
967 pub parts: Vec<IdentifierPart<'a>>,
969}
970
971impl<'a> Spanned for IdentifierExpression<'a> {
972 fn span(&self) -> Span {
973 self.parts.opt_span().expect("Span of identifier parts")
974 }
975}
976
977#[derive(Debug, Clone)]
979pub struct SubqueryExpression<'a> {
980 pub expression: Statement<'a>,
982}
983
984impl Spanned for SubqueryExpression<'_> {
985 fn span(&self) -> Span {
986 self.expression.span()
987 }
988}
989
990#[derive(Debug, Clone)]
992pub struct ExistsExpression<'a> {
993 pub exists_span: Span,
995 pub subquery: Statement<'a>,
997}
998
999impl Spanned for ExistsExpression<'_> {
1000 fn span(&self) -> Span {
1001 self.exists_span.join_span(&self.subquery)
1002 }
1003}
1004
1005#[derive(Debug, Clone, PartialEq, Eq)]
1007pub enum Quantifier {
1008 Any(Span),
1010 Some(Span),
1012 All(Span),
1014}
1015
1016impl Spanned for Quantifier {
1017 fn span(&self) -> Span {
1018 match self {
1019 Quantifier::Any(s) | Quantifier::Some(s) | Quantifier::All(s) => s.clone(),
1020 }
1021 }
1022}
1023
1024#[derive(Debug, Clone)]
1029pub struct QuantifierExpression<'a> {
1030 pub quantifier: Quantifier,
1032 pub operand: Expression<'a>,
1034}
1035
1036impl Spanned for QuantifierExpression<'_> {
1037 fn span(&self) -> Span {
1038 self.quantifier.join_span(&self.operand)
1039 }
1040}
1041
1042#[derive(Debug, Clone)]
1044pub struct RowExpression<'a> {
1045 pub paren_span: Span,
1047 pub elements: Vec<Expression<'a>>,
1049}
1050
1051impl Spanned for RowExpression<'_> {
1052 fn span(&self) -> Span {
1053 self.paren_span.clone()
1054 }
1055}
1056
1057#[derive(Debug, Clone)]
1059pub enum Expression<'a> {
1060 Binary(Box<BinaryExpression<'a>>),
1062 Unary(Box<UnaryExpression<'a>>),
1064 Subquery(Box<SubqueryExpression<'a>>),
1066 Null(Box<NullExpression>),
1068 Default(Box<DefaultExpression>),
1070 Bool(Box<BoolExpression>),
1072 String(Box<SString<'a>>),
1075 Integer(Box<IntegerExpression>),
1077 ListHack(Box<ListHackExpression>),
1079 Float(Box<FloatExpression>),
1081 Function(Box<FunctionCallExpression<'a>>),
1083 WindowFunction(Box<WindowFunctionCallExpression<'a>>),
1085 AggregateFunction(Box<AggregateFunctionCallExpression<'a>>),
1087 Identifier(Box<IdentifierExpression<'a>>),
1089 Interval(Box<IntervalExpression>),
1091 Arg(Box<ArgExpression>),
1093 Exists(Box<ExistsExpression<'a>>),
1095 Extract(Box<ExtractExpression<'a>>),
1097 Trim(Box<TrimExpression<'a>>),
1099 In(Box<InExpression<'a>>),
1101 Between(Box<BetweenExpression<'a>>),
1103 MemberOf(Box<MemberOfExpression<'a>>),
1105 Is(Box<IsExpression<'a>>),
1107 Invalid(Box<InvalidExpression>),
1109 Case(Box<CaseExpression<'a>>),
1111 Cast(Box<CastExpression<'a>>),
1113 Convert(Box<ConvertExpression<'a>>),
1115 GroupConcat(Box<GroupConcatExpression<'a>>),
1117 Variable(Box<VariableExpression<'a>>),
1119 UserVariable(Box<UserVariableExpression<'a>>),
1121 TimestampAdd(Box<TimestampAddExpression<'a>>),
1123 TimestampDiff(Box<TimestampDiffExpression<'a>>),
1125 TypeCast(Box<TypeCastExpression<'a>>),
1127 MatchAgainst(Box<MatchAgainstExpression<'a>>),
1129 Array(Box<ArrayExpression<'a>>),
1131 ArraySubscript(Box<ArraySubscriptExpression<'a>>),
1133 Quantifier(Box<QuantifierExpression<'a>>),
1135 FieldAccess(Box<FieldAccessExpression<'a>>),
1137 Char(Box<CharFunctionExpression<'a>>),
1139 Row(Box<RowExpression<'a>>),
1141}
1142
1143impl<'a> Spanned for Expression<'a> {
1144 fn span(&self) -> Span {
1145 match &self {
1146 Expression::Binary(e) => e.span(),
1147 Expression::Unary(e) => e.span(),
1148 Expression::Subquery(v) => v.span(),
1149 Expression::Null(v) => v.span(),
1150 Expression::Default(v) => v.span(),
1151 Expression::Bool(v) => v.span(),
1152 Expression::String(v) => v.span(),
1153 Expression::Integer(v) => v.span(),
1154 Expression::Float(v) => v.span(),
1155 Expression::ListHack(v) => v.span(),
1156 Expression::Function(e) => e.span(),
1157 Expression::AggregateFunction(e) => e.span(),
1158 Expression::Identifier(e) => e.span(),
1159 Expression::Arg(v) => v.span(),
1160 Expression::Exists(v) => v.span(),
1161 Expression::In(e) => e.span(),
1162 Expression::Between(e) => e.span(),
1163 Expression::MemberOf(e) => e.span(),
1164 Expression::Is(e) => e.span(),
1165 Expression::Invalid(s) => s.span(),
1166 Expression::Case(e) => e.span(),
1167 Expression::Cast(e) => e.span(),
1168 Expression::Convert(e) => e.span(),
1169 Expression::TypeCast(e) => e.span(),
1170 Expression::GroupConcat(e) => e.span(),
1171 Expression::Variable(e) => e.span(),
1172 Expression::UserVariable(e) => e.span(),
1173 Expression::WindowFunction(e) => e.span(),
1174 Expression::Interval(e) => e.span(),
1175 Expression::Extract(e) => e.span(),
1176 Expression::Trim(e) => e.span(),
1177 Expression::TimestampAdd(e) => e.span(),
1178 Expression::TimestampDiff(e) => e.span(),
1179 Expression::MatchAgainst(e) => e.span(),
1180 Expression::Array(e) => e.span(),
1181 Expression::ArraySubscript(e) => e.span(),
1182 Expression::Quantifier(e) => e.span(),
1183 Expression::FieldAccess(e) => e.span(),
1184 Expression::Char(e) => e.span(),
1185 Expression::Row(e) => e.span(),
1186 }
1187 }
1188}
1189
1190pub(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;
1210
1211trait Priority {
1212 fn priority(&self) -> usize;
1213}
1214
1215impl<'a> Priority for BinaryOperator<'a> {
1216 fn priority(&self) -> usize {
1217 match self {
1218 BinaryOperator::Assignment(_) => PRIORITY_ASSIGN,
1219 BinaryOperator::Or(_) => PRIORITY_OR,
1220 BinaryOperator::Concat(_) => PRIORITY_ADD,
1221 BinaryOperator::Xor(_) => PRIORITY_XOR,
1222 BinaryOperator::And(_) => PRIORITY_AND,
1223 BinaryOperator::Eq(_) => PRIORITY_CMP,
1224 BinaryOperator::NullSafeEq(_) => PRIORITY_CMP,
1225 BinaryOperator::GtEq(_) => PRIORITY_CMP,
1226 BinaryOperator::Gt(_) => PRIORITY_CMP,
1227 BinaryOperator::LtEq(_) => PRIORITY_CMP,
1228 BinaryOperator::Lt(_) => PRIORITY_CMP,
1229 BinaryOperator::Neq(_) => PRIORITY_CMP,
1230 BinaryOperator::Like(_) => PRIORITY_CMP,
1231 BinaryOperator::NotLike(_) => PRIORITY_CMP,
1232 BinaryOperator::Regexp(_) => PRIORITY_CMP,
1233 BinaryOperator::NotRegexp(_) => PRIORITY_CMP,
1234 BinaryOperator::Rlike(_) => PRIORITY_CMP,
1235 BinaryOperator::NotRlike(_) => PRIORITY_CMP,
1236 BinaryOperator::ShiftLeft(_) => PRIORITY_SHIFT,
1237 BinaryOperator::ShiftRight(_) => PRIORITY_SHIFT,
1238 BinaryOperator::BitAnd(_) => PRIORITY_BITAND,
1239 BinaryOperator::BitOr(_) => PRIORITY_BITOR,
1240 BinaryOperator::BitXor(_) => PRIORITY_BITXOR,
1241 BinaryOperator::Add(_) => PRIORITY_ADD,
1242 BinaryOperator::Subtract(_) => PRIORITY_ADD,
1243 BinaryOperator::Divide(_) => PRIORITY_MULT,
1244 BinaryOperator::Div(_) => PRIORITY_MULT,
1245 BinaryOperator::Mod(_) => PRIORITY_MULT,
1246 BinaryOperator::Mult(_) => PRIORITY_MULT,
1247 BinaryOperator::Collate(_) => 20,
1248 BinaryOperator::JsonExtract(_) => PRIORITY_JSON_EXTRACT,
1249 BinaryOperator::JsonExtractUnquote(_) => PRIORITY_JSON_EXTRACT,
1250 BinaryOperator::Overlap(_)
1251 | BinaryOperator::Contains(_)
1252 | BinaryOperator::ContainedBy(_)
1253 | BinaryOperator::JsonPathMatch(_)
1254 | BinaryOperator::JsonPathExists(_)
1255 | BinaryOperator::JsonbKeyExists(_)
1256 | BinaryOperator::JsonbAnyKeyExists(_)
1257 | BinaryOperator::JsonbAllKeyExists(_)
1258 | BinaryOperator::JsonGetPath(_)
1259 | BinaryOperator::JsonGetPathText(_)
1260 | BinaryOperator::JsonDeletePath(_)
1261 | BinaryOperator::RegexMatch(_)
1262 | BinaryOperator::RegexIMatch(_)
1263 | BinaryOperator::NotRegexMatch(_)
1264 | BinaryOperator::NotRegexIMatch(_)
1265 | BinaryOperator::User(_, _)
1266 | BinaryOperator::Operator(_, _) => PRIORITY_PG_CUSTOM,
1267 }
1268 }
1269}
1270
1271impl Priority for UnaryOperator {
1272 fn priority(&self) -> usize {
1273 match self {
1274 UnaryOperator::Binary(_) => 20,
1275 UnaryOperator::LogicalNot(_) => 30,
1276 UnaryOperator::Minus(_) => 40,
1277 UnaryOperator::Not(_) => 130,
1278 }
1279 }
1280}
1281
1282#[derive(Debug)]
1283enum ReduceMember<'a> {
1284 Expression(Expression<'a>),
1285 Binary(BinaryOperator<'a>),
1286 Unary(UnaryOperator),
1287}
1288
1289struct Reducer<'a> {
1290 stack: Vec<ReduceMember<'a>>,
1291}
1292
1293impl<'a> Reducer<'a> {
1294 fn reduce(&mut self, priority: usize) -> Result<(), &'static str> {
1295 let mut e = match self.stack.pop() {
1296 Some(ReduceMember::Expression(e)) => e,
1297 _ => {
1298 return Err("Expected expression before here");
1299 }
1300 };
1301 loop {
1302 let v = self.stack.pop();
1303 match v {
1304 None => break,
1305 Some(ReduceMember::Expression(_)) => return Err("ICE Reduce stack error 1"),
1306 Some(ReduceMember::Unary(op)) if op.priority() > priority => {
1307 self.stack.push(ReduceMember::Unary(op));
1308 break;
1309 }
1310 Some(ReduceMember::Binary(op)) if op.priority() > priority => {
1311 self.stack.push(ReduceMember::Binary(op));
1312 break;
1313 }
1314 Some(ReduceMember::Unary(op)) => {
1315 e = Expression::Unary(Box::new(UnaryExpression { op, operand: e }));
1316 }
1317 Some(ReduceMember::Binary(op)) => {
1318 let lhs = match self.stack.pop() {
1319 Some(ReduceMember::Expression(e)) => e,
1320 _ => return Err("ICE Reduce stack error 2"),
1321 };
1322 e = Expression::Binary(Box::new(BinaryExpression { op, lhs, rhs: e }));
1323 }
1324 }
1325 }
1326 self.stack.push(ReduceMember::Expression(e));
1327 Ok(())
1328 }
1329
1330 fn shift_binop(&mut self, op: BinaryOperator<'a>) -> Result<(), &'static str> {
1331 self.reduce(op.priority())?;
1332 self.stack.push(ReduceMember::Binary(op));
1333 Ok(())
1334 }
1335
1336 fn shift_unary(&mut self, op: UnaryOperator) -> Result<(), &'static str> {
1337 if matches!(self.stack.last(), Some(ReduceMember::Expression(_))) {
1338 return Err("Unary operator cannot come before expression");
1339 }
1340 self.stack.push(ReduceMember::Unary(op));
1341 Ok(())
1342 }
1343
1344 fn shift_expr(&mut self, e: Expression<'a>) -> Result<(), &'static str> {
1345 if matches!(self.stack.last(), Some(ReduceMember::Expression(_))) {
1346 return Err("Expression should not follow expression");
1348 }
1349 self.stack.push(ReduceMember::Expression(e));
1350 Ok(())
1351 }
1352}
1353
1354fn parse_array_element<'a>(parser: &mut Parser<'a, '_>) -> Result<Expression<'a>, ParseError> {
1358 if matches!(parser.token, Token::LBracket) {
1359 let lbracket = parser.consume_token(Token::LBracket)?;
1360 let mut elements = Vec::new();
1361 if !matches!(parser.token, Token::RBracket) {
1362 loop {
1363 parser.recovered(
1364 "']' or ','",
1365 &|t| matches!(t, Token::RBracket | Token::Comma),
1366 |parser| {
1367 elements.push(parse_array_element(parser)?);
1368 Ok(())
1369 },
1370 )?;
1371 if parser.skip_token(Token::Comma).is_none() {
1372 break;
1373 }
1374 }
1375 }
1376 let rbracket = parser.consume_token(Token::RBracket)?;
1377 let bracket_span = lbracket.join_span(&rbracket);
1378 Ok(Expression::Array(Box::new(ArrayExpression {
1379 array_span: bracket_span.clone(),
1380 bracket_span,
1381 elements,
1382 })))
1383 } else {
1384 parse_expression_unreserved(parser, PRIORITY_MAX)
1385 }
1386}
1387
1388pub(crate) fn parse_expression_restricted<'a>(
1389 parser: &mut Parser<'a, '_>,
1390 max_priority: usize,
1391 restrict: Restrict,
1392) -> Result<Expression<'a>, ParseError> {
1393 let mut r = Reducer { stack: Vec::new() };
1394 loop {
1395 if matches!(r.stack.last(), Some(ReduceMember::Expression(_)))
1396 && matches!(
1397 parser.token,
1398 Token::Ident(
1399 _,
1400 Keyword::NULLS
1401 | Keyword::FIRST
1402 | Keyword::LAST
1403 | Keyword::ROW
1404 | Keyword::ROWS
1405 | Keyword::RANGE
1406 | Keyword::ONLY
1407 | Keyword::FILTER
1408 | Keyword::PRECEDING
1409 | Keyword::FOLLOWING
1410 )
1411 )
1412 {
1413 break;
1414 }
1415 if matches!(r.stack.last(), Some(ReduceMember::Expression(_)))
1419 && matches!(parser.token, Token::Ident(_, Keyword::NOT))
1420 && matches!(parser.peek(), Token::Ident(_, Keyword::NULL))
1421 {
1422 break;
1423 }
1424 let e = match parser.token.clone() {
1425 Token::ColonEq if PRIORITY_ASSIGN < max_priority => {
1426 r.shift_binop(BinaryOperator::Assignment(parser.consume()))
1427 }
1428 Token::Ident(_, Keyword::OR) if PRIORITY_OR < max_priority => {
1429 r.shift_binop(BinaryOperator::Or(parser.consume()))
1430 }
1431 Token::DoublePipe if PRIORITY_ADD < max_priority => {
1432 r.shift_binop(BinaryOperator::Concat(parser.consume()))
1433 }
1434 Token::Ident(_, Keyword::XOR) if PRIORITY_XOR < max_priority => {
1435 r.shift_binop(BinaryOperator::Xor(parser.consume()))
1436 }
1437 Token::Ident(_, Keyword::AND) if PRIORITY_AND < max_priority => {
1438 r.shift_binop(BinaryOperator::And(parser.consume()))
1439 }
1440 Token::DoubleAmpersand
1441 if PRIORITY_AND < max_priority && !parser.options.dialect.is_postgresql() =>
1442 {
1443 r.shift_binop(BinaryOperator::And(parser.consume()))
1444 }
1445 Token::DoubleAmpersand
1446 if PRIORITY_PG_CUSTOM < max_priority && parser.options.dialect.is_postgresql() =>
1447 {
1448 r.shift_binop(BinaryOperator::Overlap(parser.consume()))
1449 }
1450 Token::Eq if PRIORITY_CMP < max_priority => {
1451 r.shift_binop(BinaryOperator::Eq(parser.consume()))
1452 }
1453 Token::Spaceship if PRIORITY_CMP < max_priority => {
1454 r.shift_binop(BinaryOperator::NullSafeEq(parser.consume()))
1455 }
1456 Token::GtEq if PRIORITY_CMP < max_priority => {
1457 r.shift_binop(BinaryOperator::GtEq(parser.consume()))
1458 }
1459 Token::Gt if PRIORITY_CMP < max_priority => {
1460 r.shift_binop(BinaryOperator::Gt(parser.consume()))
1461 }
1462 Token::LtEq if PRIORITY_CMP < max_priority => {
1463 r.shift_binop(BinaryOperator::LtEq(parser.consume()))
1464 }
1465 Token::Lt if PRIORITY_CMP < max_priority => {
1466 r.shift_binop(BinaryOperator::Lt(parser.consume()))
1467 }
1468 Token::Neq if PRIORITY_CMP < max_priority => {
1469 r.shift_binop(BinaryOperator::Neq(parser.consume()))
1470 }
1471 Token::ShiftLeft if PRIORITY_SHIFT < max_priority => {
1472 r.shift_binop(BinaryOperator::ShiftLeft(parser.consume()))
1473 }
1474 Token::ShiftRight if PRIORITY_SHIFT < max_priority => {
1475 r.shift_binop(BinaryOperator::ShiftRight(parser.consume()))
1476 }
1477 Token::Ampersand => r.shift_binop(BinaryOperator::BitAnd(parser.consume())),
1478 Token::Pipe if PRIORITY_BITOR < max_priority => {
1479 r.shift_binop(BinaryOperator::BitOr(parser.consume()))
1480 }
1481 Token::Ident(_, Keyword::BINARY) if PRIORITY_JSON_EXTRACT < max_priority => {
1482 r.shift_unary(UnaryOperator::Binary(parser.consume()))
1483 }
1484 Token::Ident(_, Keyword::COLLATE)
1485 if 20 < max_priority
1486 && matches!(r.stack.last(), Some(ReduceMember::Expression(_))) =>
1487 {
1488 let collate_span = parser.consume_keyword(Keyword::COLLATE)?;
1490 let collation = parser.consume_plain_identifier_unreserved()?;
1491 if let Err(e) = r.shift_binop(BinaryOperator::Collate(collate_span)) {
1492 parser.err_here(e)?;
1493 }
1494 r.shift_expr(Expression::Identifier(Box::new(IdentifierExpression {
1495 parts: vec![IdentifierPart::Name(collation)],
1496 })))
1497 }
1498 Token::ExclamationMark if PRIORITY_JSON_EXTRACT < max_priority => {
1499 r.shift_unary(UnaryOperator::LogicalNot(parser.consume()))
1500 }
1501 Token::Minus if !matches!(r.stack.last(), Some(ReduceMember::Expression(_))) => {
1502 r.shift_unary(UnaryOperator::Minus(parser.consume()))
1503 }
1504 Token::Minus
1505 if PRIORITY_ADD < max_priority
1506 && matches!(r.stack.last(), Some(ReduceMember::Expression(_))) =>
1507 {
1508 r.shift_binop(BinaryOperator::Subtract(parser.consume()))
1509 }
1510 Token::Ident(_, Keyword::IN) if PRIORITY_CMP < max_priority => {
1511 if let Err(e) = r.reduce(PRIORITY_CMP) {
1512 parser.err_here(e)?;
1513 }
1514 let lhs = match r.stack.pop() {
1515 Some(ReduceMember::Expression(e)) => e,
1516 _ => parser.err_here("Expected expression before here 3")?,
1517 };
1518 let op = parser.consume_keyword(Keyword::IN)?;
1519 parser.consume_token(Token::LParen)?;
1520 let mut rhs = Vec::new();
1521 loop {
1522 parser.recovered(
1523 "')' or ','",
1524 &|t| matches!(t, Token::RParen | Token::Comma),
1525 |parser| {
1526 rhs.push(parse_expression_paren(parser)?);
1527 Ok(())
1528 },
1529 )?;
1530 if parser.skip_token(Token::Comma).is_none() {
1531 break;
1532 }
1533 }
1534 parser.consume_token(Token::RParen)?;
1535 r.shift_expr(Expression::In(Box::new(InExpression {
1536 lhs,
1537 rhs,
1538 in_span: op,
1539 not_in: false,
1540 })))
1541 }
1542 Token::Ident(_, Keyword::IS) if PRIORITY_CMP < max_priority => {
1543 if let Err(e) = r.reduce(PRIORITY_CMP) {
1544 parser.err_here(e)?;
1545 }
1546 let lhs = match r.stack.pop() {
1547 Some(ReduceMember::Expression(e)) => e,
1548 _ => parser.err_here("Expected expression before here 4")?,
1549 };
1550 let op = parser.consume_keyword(Keyword::IS)?;
1551 let (is, op) = match &parser.token {
1552 Token::Ident(_, Keyword::NOT) => {
1553 parser.consume();
1554 match &parser.token {
1555 Token::Ident(_, Keyword::TRUE) => {
1556 (Is::NotTrue, parser.consume().join_span(&op))
1557 }
1558 Token::Ident(_, Keyword::FALSE) => {
1559 (Is::NotFalse, parser.consume().join_span(&op))
1560 }
1561 Token::Ident(_, Keyword::NULL) => {
1562 (Is::NotNull, parser.consume().join_span(&op))
1563 }
1564 Token::Ident(_, Keyword::UNKNOWN) => {
1565 (Is::NotUnknown, parser.consume().join_span(&op))
1566 }
1567 Token::Ident(_, Keyword::DISTINCT) => {
1568 let op_span = parser
1569 .consume_keywords(&[Keyword::DISTINCT, Keyword::FROM])?
1570 .join_span(&op);
1571 parser.postgres_only(&op_span);
1572 let rhs = parse_expression_unreserved(parser, PRIORITY_AND)?;
1573 (Is::NotDistinctFrom(rhs), op_span)
1574 }
1575 _ => parser.expected_failure(
1576 "'TRUE', 'FALSE', 'UNKNOWN', 'NULL' or 'DISTINCT'",
1577 )?,
1578 }
1579 }
1580 Token::Ident(_, Keyword::TRUE) => (Is::True, parser.consume().join_span(&op)),
1581 Token::Ident(_, Keyword::FALSE) => (Is::False, parser.consume().join_span(&op)),
1582 Token::Ident(_, Keyword::NULL) => (Is::Null, parser.consume().join_span(&op)),
1583 Token::Ident(_, Keyword::DISTINCT) => {
1584 let op_span = parser
1585 .consume_keywords(&[Keyword::DISTINCT, Keyword::FROM])?
1586 .join_span(&op);
1587 parser.postgres_only(&op_span);
1588 let rhs = parse_expression_unreserved(parser, PRIORITY_AND)?;
1589 (Is::DistinctFrom(rhs), op_span)
1590 }
1591 Token::Ident(_, Keyword::UNKNOWN) => {
1592 (Is::Unknown, parser.consume().join_span(&op))
1593 }
1594 _ => parser.expected_failure(
1595 "'NOT', 'TRUE', 'FALSE', 'UNKNOWN', 'NULL' or 'DISTINCT'",
1596 )?,
1597 };
1598 r.shift_expr(Expression::Is(Box::new(IsExpression {
1599 lhs,
1600 is,
1601 is_span: op,
1602 })))
1603 }
1604 Token::DoubleColon
1605 if parser.options.dialect.is_postgresql()
1606 && matches!(r.stack.last(), Some(ReduceMember::Expression(_))) =>
1607 {
1608 if let Err(e) = r.reduce(PRIORITY_TYPECAST) {
1611 parser.err_here(e)?;
1612 }
1613 let expr = match r.stack.pop() {
1614 Some(ReduceMember::Expression(e)) => e,
1615 _ => parser.err_here("Expected expression before '::'")?,
1616 };
1617 let doublecolon_span = parser.consume_token(Token::DoubleColon)?;
1618 let type_ = parse_data_type(parser, DataTypeContext::TypeRef)?;
1619 r.shift_expr(Expression::TypeCast(Box::new(TypeCastExpression {
1620 expr,
1621 doublecolon_span,
1622 type_,
1623 })))
1624 }
1625 Token::LBracket
1626 if parser.options.dialect.is_postgresql()
1627 && PRIORITY_TYPECAST < max_priority
1628 && matches!(r.stack.last(), Some(ReduceMember::Expression(_))) =>
1629 {
1630 if let Err(e) = r.reduce(PRIORITY_TYPECAST) {
1632 parser.err_here(e)?;
1633 }
1634 let expr = match r.stack.pop() {
1635 Some(ReduceMember::Expression(e)) => e,
1636 _ => parser.err_here("Expected expression before '['")?,
1637 };
1638 let lbracket = parser.consume_token(Token::LBracket)?;
1639 let lower = parse_expression_unreserved(parser, PRIORITY_MAX)?;
1640 let upper = if parser.skip_token(Token::Colon).is_some() {
1641 Some(parse_expression_unreserved(parser, PRIORITY_MAX)?)
1642 } else {
1643 None
1644 };
1645 let rbracket = parser.consume_token(Token::RBracket)?;
1646 let bracket_span = lbracket.join_span(&rbracket);
1647 r.shift_expr(Expression::ArraySubscript(Box::new(
1648 ArraySubscriptExpression {
1649 expr,
1650 bracket_span,
1651 lower,
1652 upper,
1653 },
1654 )))
1655 }
1656 Token::Period
1657 if parser.options.dialect.is_postgresql()
1658 && PRIORITY_TYPECAST < max_priority
1659 && matches!(r.stack.last(), Some(ReduceMember::Expression(_))) =>
1660 {
1661 if let Err(e) = r.reduce(PRIORITY_TYPECAST) {
1663 parser.err_here(e)?;
1664 }
1665 let expr = match r.stack.pop() {
1666 Some(ReduceMember::Expression(e)) => e,
1667 _ => parser.err_here("Expected expression before '.'")?,
1668 };
1669 let dot_span = parser.consume_token(Token::Period)?;
1670 let field = parser.consume_plain_identifier_unreserved()?;
1671 r.shift_expr(Expression::FieldAccess(Box::new(FieldAccessExpression {
1672 expr,
1673 dot_span,
1674 field,
1675 })))
1676 }
1677 Token::Ident(_, Keyword::NOT)
1678 if !matches!(r.stack.last(), Some(ReduceMember::Expression(_))) =>
1679 {
1680 r.shift_unary(UnaryOperator::Not(parser.consume()))
1681 }
1682 Token::Ident(_, Keyword::NOT)
1683 if PRIORITY_CMP < max_priority
1684 && matches!(r.stack.last(), Some(ReduceMember::Expression(_))) =>
1685 {
1686 if let Err(e) = r.reduce(PRIORITY_CMP) {
1687 parser.err_here(e)?;
1688 }
1689 let lhs = match r.stack.pop() {
1690 Some(ReduceMember::Expression(e)) => e,
1691 _ => parser.err_here("Expected expression before here 2")?,
1692 };
1693 let op = parser.consume_keyword(Keyword::NOT)?;
1694 match &parser.token {
1695 Token::Ident(_, Keyword::IN) => {
1696 let op = parser.consume_keyword(Keyword::IN)?.join_span(&op);
1697 parser.consume_token(Token::LParen)?;
1698 let mut rhs = Vec::new();
1699 loop {
1700 parser.recovered(
1701 "')' or ','",
1702 &|t| matches!(t, Token::RParen | Token::Comma),
1703 |parser| {
1704 rhs.push(parse_expression_paren(parser)?);
1705 Ok(())
1706 },
1707 )?;
1708 if parser.skip_token(Token::Comma).is_none() {
1709 break;
1710 }
1711 }
1712 parser.consume_token(Token::RParen)?;
1713 r.shift_expr(Expression::In(Box::new(InExpression {
1714 lhs,
1715 rhs,
1716 in_span: op,
1717 not_in: true,
1718 })))
1719 }
1720 Token::Ident(_, Keyword::LIKE) => {
1721 r.stack.push(ReduceMember::Expression(lhs));
1722 r.shift_binop(BinaryOperator::NotLike(parser.consume().join_span(&op)))
1723 }
1724 Token::Ident(_, Keyword::REGEXP) if parser.options.dialect.is_maria() => {
1725 r.stack.push(ReduceMember::Expression(lhs));
1726 r.shift_binop(BinaryOperator::NotRegexp(parser.consume().join_span(&op)))
1727 }
1728 Token::Ident(_, Keyword::RLIKE) if parser.options.dialect.is_maria() => {
1729 r.stack.push(ReduceMember::Expression(lhs));
1730 r.shift_binop(BinaryOperator::NotRlike(parser.consume().join_span(&op)))
1731 }
1732 Token::Ident(_, Keyword::BETWEEN) => {
1733 let between_span = parser.consume_keyword(Keyword::BETWEEN)?.join_span(&op);
1734 let low = parse_expression_unreserved(parser, PRIORITY_AND)?;
1735 let and_span = parser.consume_keyword(Keyword::AND)?;
1736 let high = parse_expression_unreserved(parser, PRIORITY_AND)?;
1737 r.shift_expr(Expression::Between(Box::new(BetweenExpression {
1738 lhs,
1739 low,
1740 high,
1741 between_span: between_span.join_span(&and_span),
1742 not_between: true,
1743 })))
1744 }
1745 _ => parser.expected_failure("'IN', 'LIKE', 'REGEXP', 'RLIKE' or 'BETWEEN'")?,
1746 }
1747 }
1748 Token::Ident(_, Keyword::BETWEEN)
1749 if PRIORITY_CMP < max_priority
1750 && matches!(r.stack.last(), Some(ReduceMember::Expression(_))) =>
1751 {
1752 if let Err(e) = r.reduce(PRIORITY_CMP) {
1753 parser.err_here(e)?;
1754 }
1755 let lhs = match r.stack.pop() {
1756 Some(ReduceMember::Expression(e)) => e,
1757 _ => parser.err_here("Expected expression before BETWEEN")?,
1758 };
1759 let between_span = parser.consume_keyword(Keyword::BETWEEN)?;
1760 let low = parse_expression_unreserved(parser, PRIORITY_AND)?;
1761 let and_span = parser.consume_keyword(Keyword::AND)?;
1762 let high = parse_expression_unreserved(parser, PRIORITY_AND)?;
1763 r.shift_expr(Expression::Between(Box::new(BetweenExpression {
1764 lhs,
1765 low,
1766 high,
1767 between_span: between_span.join_span(&and_span),
1768 not_between: false,
1769 })))
1770 }
1771 Token::Ident(_, Keyword::LIKE) if PRIORITY_CMP < max_priority => {
1772 r.shift_binop(BinaryOperator::Like(parser.consume()))
1773 }
1774 Token::Ident(_, Keyword::SIMILAR)
1775 if PRIORITY_CMP < max_priority
1776 && matches!(r.stack.last(), Some(ReduceMember::Expression(_))) =>
1777 {
1778 if let Err(e) = r.reduce(PRIORITY_CMP) {
1780 parser.err_here(e)?;
1781 }
1782 let lhs = match r.stack.pop() {
1783 Some(ReduceMember::Expression(e)) => e,
1784 _ => parser.err_here("Expected expression before SIMILAR")?,
1785 };
1786 let op_span = parser.consume_keywords(&[Keyword::SIMILAR, Keyword::TO])?;
1787 parser.postgres_only(&op_span);
1788 r.stack.push(ReduceMember::Expression(lhs));
1789 r.shift_binop(BinaryOperator::Like(op_span))
1790 }
1791 Token::Ident(_, Keyword::REGEXP)
1792 if PRIORITY_CMP < max_priority && parser.options.dialect.is_maria() =>
1793 {
1794 r.shift_binop(BinaryOperator::Regexp(parser.consume()))
1795 }
1796 Token::Ident(_, Keyword::RLIKE)
1797 if PRIORITY_CMP < max_priority && parser.options.dialect.is_maria() =>
1798 {
1799 r.shift_binop(BinaryOperator::Rlike(parser.consume()))
1800 }
1801 Token::RArrowJson if PRIORITY_JSON_EXTRACT < max_priority => {
1802 r.shift_binop(BinaryOperator::JsonExtract(parser.consume()))
1803 }
1804 Token::RDoubleArrowJson if PRIORITY_JSON_EXTRACT < max_priority => {
1805 r.shift_binop(BinaryOperator::JsonExtractUnquote(parser.consume()))
1806 }
1807 Token::Contains if PRIORITY_PG_CUSTOM < max_priority => {
1809 r.shift_binop(BinaryOperator::Contains(parser.consume()))
1810 }
1811 Token::ContainedBy if PRIORITY_PG_CUSTOM < max_priority => {
1812 r.shift_binop(BinaryOperator::ContainedBy(parser.consume()))
1813 }
1814 Token::AtQuestion if PRIORITY_PG_CUSTOM < max_priority => {
1815 r.shift_binop(BinaryOperator::JsonPathExists(parser.consume()))
1816 }
1817 Token::QuestionPipe if PRIORITY_PG_CUSTOM < max_priority => {
1818 r.shift_binop(BinaryOperator::JsonbAnyKeyExists(parser.consume()))
1819 }
1820 Token::QuestionAmpersand if PRIORITY_PG_CUSTOM < max_priority => {
1821 r.shift_binop(BinaryOperator::JsonbAllKeyExists(parser.consume()))
1822 }
1823 Token::HashArrow if PRIORITY_PG_CUSTOM < max_priority => {
1824 r.shift_binop(BinaryOperator::JsonGetPath(parser.consume()))
1825 }
1826 Token::HashDoubleArrow if PRIORITY_PG_CUSTOM < max_priority => {
1827 r.shift_binop(BinaryOperator::JsonGetPathText(parser.consume()))
1828 }
1829 Token::HashMinus if PRIORITY_PG_CUSTOM < max_priority => {
1830 r.shift_binop(BinaryOperator::JsonDeletePath(parser.consume()))
1831 }
1832 Token::TildeStar if PRIORITY_PG_CUSTOM < max_priority => {
1833 r.shift_binop(BinaryOperator::RegexIMatch(parser.consume()))
1834 }
1835 Token::NotTilde if PRIORITY_PG_CUSTOM < max_priority => {
1836 r.shift_binop(BinaryOperator::NotRegexMatch(parser.consume()))
1837 }
1838 Token::NotTildeStar if PRIORITY_PG_CUSTOM < max_priority => {
1839 r.shift_binop(BinaryOperator::NotRegexIMatch(parser.consume()))
1840 }
1841 Token::LikeTilde if PRIORITY_CMP < max_priority => {
1842 r.shift_binop(BinaryOperator::Like(parser.consume()))
1843 }
1844 Token::NotLikeTilde if PRIORITY_CMP < max_priority => {
1845 r.shift_binop(BinaryOperator::NotLike(parser.consume()))
1846 }
1847 Token::AtAt
1849 if PRIORITY_PG_CUSTOM < max_priority
1850 && parser.options.dialect.is_postgresql()
1851 && matches!(r.stack.last(), Some(ReduceMember::Expression(_))) =>
1852 {
1853 r.shift_binop(BinaryOperator::JsonPathMatch(parser.consume()))
1854 }
1855 Token::Tilde
1857 if PRIORITY_PG_CUSTOM < max_priority
1858 && parser.options.dialect.is_postgresql()
1859 && matches!(r.stack.last(), Some(ReduceMember::Expression(_))) =>
1860 {
1861 r.shift_binop(BinaryOperator::RegexMatch(parser.consume()))
1862 }
1863 Token::QuestionMark
1865 if PRIORITY_PG_CUSTOM < max_priority
1866 && parser.options.dialect.is_postgresql()
1867 && !matches!(parser.options.arguments, crate::SQLArguments::QuestionMark)
1868 && matches!(r.stack.last(), Some(ReduceMember::Expression(_))) =>
1869 {
1870 r.shift_binop(BinaryOperator::JsonbKeyExists(parser.consume()))
1871 }
1872 Token::PostgresOperator(op)
1874 if PRIORITY_PG_CUSTOM < max_priority
1875 && parser.options.dialect.is_postgresql()
1876 && matches!(r.stack.last(), Some(ReduceMember::Expression(_))) =>
1877 {
1878 r.shift_binop(BinaryOperator::User(op, parser.consume()))
1879 }
1880 Token::Ident(_, Keyword::OPERATOR)
1881 if PRIORITY_PG_CUSTOM < max_priority
1882 && parser.options.dialect.is_postgresql()
1883 && matches!(r.stack.last(), Some(ReduceMember::Expression(_))) =>
1884 {
1885 let operator_span = parser.consume_keyword(Keyword::OPERATOR)?;
1886 parser.consume_token(Token::LParen)?;
1887 let op_name = parse_operator_name(parser)?;
1888 let rparen_span = parser.consume_token(Token::RParen)?;
1889 let full_span = operator_span.join_span(&rparen_span);
1890 r.shift_binop(BinaryOperator::Operator(op_name, full_span))
1891 }
1892 Token::Ident(_, Keyword::MEMBER)
1893 if PRIORITY_CMP < max_priority
1894 && matches!(r.stack.last(), Some(ReduceMember::Expression(_))) =>
1895 {
1896 if let Err(e) = r.reduce(PRIORITY_CMP) {
1897 parser.err_here(e)?;
1898 }
1899 let lhs = match r.stack.pop() {
1900 Some(ReduceMember::Expression(e)) => e,
1901 _ => parser.err_here("Expected expression before here")?,
1902 };
1903 let member_span = parser.consume_keyword(Keyword::MEMBER)?;
1904 let of_span = parser.consume_keyword(Keyword::OF)?;
1905 parser.consume_token(Token::LParen)?;
1906 let rhs = parse_expression_paren(parser)?;
1907 parser.consume_token(Token::RParen)?;
1908 r.shift_expr(Expression::MemberOf(Box::new(MemberOfExpression {
1909 lhs,
1910 rhs,
1911 member_of_span: member_span.join_span(&of_span),
1912 })))
1913 }
1914 Token::Ident(_, Keyword::INTERVAL) => {
1915 let interval_span = parser.consume();
1916 let (time_interval, embedded_unit) = match parser.token {
1917 Token::String(..) => {
1918 let v = parser.consume_string()?;
1919 let str_span = v.span();
1920 let mut nums = Vec::new();
1921 let mut embedded: Option<TimeUnit> = None;
1922 for part in v.split([':', '!', ',', '.', '-', ' ']) {
1923 if let Ok(n) = part.parse::<i64>() {
1924 nums.push(n);
1925 } else if !part.is_empty() {
1926 embedded = parse_time_unit_from_str(part);
1927 }
1928 }
1929 ((nums, str_span), embedded)
1930 }
1931 Token::Integer(_) => {
1932 let (v, s) = parser.consume_int()?;
1933 ((vec![v], s), None)
1934 }
1935 _ => parser.err_here("Expected integer or string")?,
1936 };
1937 let time_unit = if let Some(u) = parse_time_unit(&parser.token) {
1938 (u, parser.consume())
1939 } else if let Some(u) = embedded_unit {
1940 (u, time_interval.1.clone())
1941 } else {
1942 parser.err_here("Expected time unit")?
1943 };
1944 let e = Expression::Interval(Box::new(IntervalExpression {
1945 interval_span,
1946 time_interval,
1947 time_unit,
1948 }));
1949 r.shift_expr(e)
1950 }
1951 Token::Ident(_, Keyword::TIMESTAMPADD) => {
1952 let timestamp_add_span = parser.consume();
1953 parser.consume_token(Token::LParen)?;
1954 let parts = parser.recovered("')'", &|t| matches!(t, Token::RParen), |parser| {
1955 let Some(u) = parse_time_unit(&parser.token) else {
1956 parser.err_here("Expected time unit")?
1957 };
1958 let unit = (u, parser.consume());
1959 parser.consume_token(Token::Comma)?;
1960 let interval = parse_expression_outer(parser)?;
1961 parser.consume_token(Token::Comma)?;
1962 let datetime = parse_expression_outer(parser)?;
1963 Ok(Some((unit, interval, datetime)))
1964 })?;
1965 parser.consume_token(Token::RParen)?;
1966 if let Some((unit, interval, datetime)) = parts {
1967 r.shift_expr(Expression::TimestampAdd(Box::new(TimestampAddExpression {
1968 timestamp_add_span,
1969 unit,
1970 interval,
1971 datetime,
1972 })))
1973 } else {
1974 r.shift_expr(Expression::Invalid(Box::new(InvalidExpression {
1975 span: timestamp_add_span,
1976 })))
1977 }
1978 }
1979 Token::Ident(_, Keyword::TIMESTAMPDIFF) => {
1980 let timestamp_diff_span = parser.consume();
1981 parser.consume_token(Token::LParen)?;
1982 let parts = parser.recovered("')'", &|t| matches!(t, Token::RParen), |parser| {
1983 let Some(u) = parse_time_unit(&parser.token) else {
1984 parser.err_here("Expected time unit")?
1985 };
1986 let unit = (u, parser.consume());
1987 parser.consume_token(Token::Comma)?;
1988 let e1 = parse_expression_outer(parser)?;
1989 parser.consume_token(Token::Comma)?;
1990 let e2 = parse_expression_outer(parser)?;
1991 Ok(Some((unit, e1, e2)))
1992 })?;
1993 parser.consume_token(Token::RParen)?;
1994 if let Some((unit, e1, e2)) = parts {
1995 r.shift_expr(Expression::TimestampDiff(Box::new(
1996 TimestampDiffExpression {
1997 timestamp_diff_span,
1998 unit,
1999 e1,
2000 e2,
2001 },
2002 )))
2003 } else {
2004 r.shift_expr(Expression::Invalid(Box::new(InvalidExpression {
2005 span: timestamp_diff_span,
2006 })))
2007 }
2008 }
2009 Token::Plus if PRIORITY_ADD < max_priority => {
2010 r.shift_binop(BinaryOperator::Add(parser.consume()))
2011 }
2012 Token::Div if PRIORITY_MULT < max_priority => {
2013 r.shift_binop(BinaryOperator::Divide(parser.consume()))
2014 }
2015 Token::Ident(_, Keyword::DIV) if PRIORITY_MULT < max_priority => {
2016 r.shift_binop(BinaryOperator::Div(parser.consume()))
2017 }
2018 Token::Minus if PRIORITY_ADD < max_priority => {
2019 r.shift_binop(BinaryOperator::Subtract(parser.consume()))
2020 }
2021 Token::Ident(_, Keyword::LIKE) if PRIORITY_CMP < max_priority => {
2022 r.shift_binop(BinaryOperator::Like(parser.consume()))
2023 }
2024 Token::Mul if !matches!(r.stack.last(), Some(ReduceMember::Expression(_))) => r
2025 .shift_expr(Expression::Identifier(Box::new(IdentifierExpression {
2026 parts: vec![IdentifierPart::Star(parser.consume_token(Token::Mul)?)],
2027 }))),
2028 Token::Mul
2029 if PRIORITY_MULT < max_priority
2030 && matches!(r.stack.last(), Some(ReduceMember::Expression(_))) =>
2031 {
2032 r.shift_binop(BinaryOperator::Mult(parser.consume()))
2033 }
2034 Token::Mod if PRIORITY_MULT < max_priority => {
2035 r.shift_binop(BinaryOperator::Mod(parser.consume()))
2036 }
2037 Token::Ident(_, Keyword::MOD)
2038 if PRIORITY_MULT < max_priority
2039 && matches!(r.stack.last(), Some(ReduceMember::Expression(_))) =>
2040 {
2041 r.shift_binop(BinaryOperator::Mod(parser.consume()))
2042 }
2043 Token::Ident(_, Keyword::TRUE) => {
2044 r.shift_expr(Expression::Bool(Box::new(BoolExpression {
2045 value: true,
2046 span: parser.consume_keyword(Keyword::TRUE)?,
2047 })))
2048 }
2049 Token::Ident(_, Keyword::FALSE) => {
2050 r.shift_expr(Expression::Bool(Box::new(BoolExpression {
2051 value: false,
2052 span: parser.consume_keyword(Keyword::FALSE)?,
2053 })))
2054 }
2055 Token::Ident(_, Keyword::NULL) => {
2056 r.shift_expr(Expression::Null(Box::new(NullExpression {
2057 span: parser.consume_keyword(Keyword::NULL)?,
2058 })))
2059 }
2060 Token::Ident(_, Keyword::_LIST_) if parser.options.list_hack => {
2061 let arg = parser.arg;
2062 parser.arg += 1;
2063 r.shift_expr(Expression::ListHack(Box::new(ListHackExpression {
2064 index: arg,
2065 span: parser.consume_keyword(Keyword::_LIST_)?,
2066 })))
2067 }
2068 Token::String(..) => {
2069 r.shift_expr(Expression::String(Box::new(parser.consume_string()?)))
2070 }
2071 Token::Integer(_) => {
2072 let (value, span) = parser.consume_int()?;
2073 r.shift_expr(Expression::Integer(Box::new(IntegerExpression {
2074 value,
2075 span,
2076 })))
2077 }
2078 Token::Float(_) => {
2079 let (value, span) = parser.consume_float()?;
2080 r.shift_expr(Expression::Float(Box::new(FloatExpression { value, span })))
2081 }
2082 Token::Ident(_, Keyword::CAST) => {
2083 let cast_span = parser.consume_keyword(Keyword::CAST)?;
2084 parser.consume_token(Token::LParen)?;
2085 let cast = parser.recovered("')'", &|t| matches!(t, Token::RParen), |parser| {
2086 let expr = parse_expression_outer(parser)?;
2087 let as_span = parser.consume_keyword(Keyword::AS)?;
2088 let type_ = parse_data_type(parser, DataTypeContext::TypeRef)?;
2089 Ok(Some((expr, as_span, type_)))
2090 })?;
2091 parser.consume_token(Token::RParen)?;
2092 if let Some((expr, as_span, type_)) = cast {
2093 r.shift_expr(Expression::Cast(Box::new(CastExpression {
2094 cast_span,
2095 expr,
2096 as_span,
2097 type_,
2098 })))
2099 } else {
2100 r.shift_expr(Expression::Invalid(Box::new(InvalidExpression {
2101 span: cast_span,
2102 })))
2103 }
2104 }
2105 Token::Ident(_, Keyword::CONVERT) => {
2106 let convert_span = parser.consume_keyword(Keyword::CONVERT)?;
2107 parser.consume_token(Token::LParen)?;
2108 let convert =
2109 parser.recovered("')'", &|t| matches!(t, Token::RParen), |parser| {
2110 let expr = parse_expression_outer(parser)?;
2111 if parser.skip_keyword(Keyword::USING).is_some() {
2113 let charset = parser.consume_plain_identifier_unreserved()?;
2115 Ok(Some((expr, None, Some(charset))))
2116 } else {
2117 parser.consume_token(Token::Comma)?;
2119 let type_ = parse_data_type(parser, DataTypeContext::TypeRef)?;
2120 Ok(Some((expr, Some(type_), None)))
2121 }
2122 })?;
2123 parser.consume_token(Token::RParen)?;
2124 if let Some((expr, type_, charset)) = convert {
2125 r.shift_expr(Expression::Convert(Box::new(ConvertExpression {
2126 convert_span,
2127 expr,
2128 type_,
2129 using_charset: charset.map(|c| (c.span(), c)),
2130 })))
2131 } else {
2132 r.shift_expr(Expression::Invalid(Box::new(InvalidExpression {
2133 span: convert_span,
2134 })))
2135 }
2136 }
2137 Token::Ident(_, Keyword::GROUP_CONCAT) => {
2138 let group_concat_span: core::ops::Range<usize> =
2139 parser.consume_keyword(Keyword::GROUP_CONCAT)?;
2140 parser.consume_token(Token::LParen)?;
2141 let distinct_span: Option<core::ops::Range<usize>> =
2142 parser.skip_keyword(Keyword::DISTINCT);
2143 let expr = parser.recovered("')'", &|t| matches!(t, Token::RParen), |parser| {
2144 let expr = parse_expression_outer(parser)?;
2145 Ok(Some(expr))
2146 })?;
2147 parser.consume_token(Token::RParen)?;
2153 if let Some(expr) = expr {
2154 r.shift_expr(Expression::GroupConcat(Box::new(GroupConcatExpression {
2155 group_concat_span,
2156 distinct_span,
2157 expr,
2158 })))
2159 } else {
2160 r.shift_expr(Expression::Invalid(Box::new(InvalidExpression {
2161 span: group_concat_span,
2162 })))
2163 }
2164 }
2165 Token::Ident(_, Keyword::TRIM) if matches!(parser.peek(), Token::LParen) => {
2166 let trim_span = parser.consume_keyword(Keyword::TRIM)?;
2167 parser.consume_token(Token::LParen)?;
2168 let parts = parser.recovered("')'", &|t| matches!(t, Token::RParen), |parser| {
2169 let direction = match &parser.token {
2171 Token::Ident(_, Keyword::BOTH) => {
2172 Some(TrimDirection::Both(parser.consume()))
2173 }
2174 Token::Ident(_, Keyword::LEADING) => {
2175 Some(TrimDirection::Leading(parser.consume()))
2176 }
2177 Token::Ident(_, Keyword::TRAILING) => {
2178 Some(TrimDirection::Trailing(parser.consume()))
2179 }
2180 _ => None,
2181 };
2182
2183 let (what, from_span, value) = if direction.is_some() {
2184 if let Some(from_s) = parser.skip_keyword(Keyword::FROM) {
2186 let value = parse_expression_outer(parser)?;
2188 (None, Some(from_s), value)
2189 } else {
2190 let what = parse_expression_outer(parser)?;
2192 let from_s = parser.consume_keyword(Keyword::FROM)?;
2193 let value = parse_expression_outer(parser)?;
2194 (Some(what), Some(from_s), value)
2195 }
2196 } else {
2197 let first = parse_expression_outer(parser)?;
2199 if let Some(from_s) = parser.skip_keyword(Keyword::FROM) {
2200 let value = parse_expression_outer(parser)?;
2202 (Some(first), Some(from_s), value)
2203 } else {
2204 (None, None, first)
2206 }
2207 };
2208 Ok(Some((direction, what, from_span, value)))
2209 })?;
2210 parser.consume_token(Token::RParen)?;
2211 if let Some((direction, what, from_span, value)) = parts {
2212 r.shift_expr(Expression::Trim(Box::new(TrimExpression {
2213 trim_span,
2214 direction,
2215 what,
2216 from_span,
2217 value,
2218 })))
2219 } else {
2220 r.shift_expr(Expression::Invalid(Box::new(InvalidExpression {
2221 span: trim_span,
2222 })))
2223 }
2224 }
2225 Token::Ident(_, Keyword::EXTRACT) => {
2226 let extract_span = parser.consume_keyword(Keyword::EXTRACT)?;
2227 parser.consume_token(Token::LParen)?;
2228 let parts = parser.recovered("')'", &|t| matches!(t, Token::RParen), |parser| {
2229 let Some(u) = parse_time_unit(&parser.token) else {
2230 parser.err_here("Expected time unit")?
2231 };
2232 let time_unit = (u, parser.consume());
2233 let from_span = parser.consume_keyword(Keyword::FROM)?;
2234 let date = parse_expression_outer(parser)?;
2235 Ok(Some((time_unit, from_span, date)))
2236 })?;
2237 parser.consume_token(Token::RParen)?;
2238 if let Some((time_unit, from_span, date)) = parts {
2239 r.shift_expr(Expression::Extract(Box::new(ExtractExpression {
2240 extract_span,
2241 time_unit,
2242 from_span,
2243 date,
2244 })))
2245 } else {
2246 r.shift_expr(Expression::Invalid(Box::new(InvalidExpression {
2247 span: extract_span,
2248 })))
2249 }
2250 }
2251 Token::Ident(_, Keyword::MATCH) => {
2252 let match_span = parser.consume_keyword(Keyword::MATCH)?;
2253 parser.consume_token(Token::LParen)?;
2254 let mut cols = Vec::new();
2255 loop {
2256 parser.recovered(
2257 "')' or ','",
2258 &|t| matches!(t, Token::RParen | Token::Comma),
2259 |parser| {
2260 cols.push(parse_expression_paren(parser)?);
2261 Ok(())
2262 },
2263 )?;
2264 if parser.skip_token(Token::Comma).is_none() {
2265 break;
2266 }
2267 }
2268 parser.consume_token(Token::RParen)?;
2269 let against_span = parser.consume_keyword(Keyword::AGAINST)?;
2270 parser.consume_token(Token::LParen)?;
2271
2272 let expr = parse_expression_unreserved(parser, PRIORITY_CMP)?;
2277
2278 let mut mode: Option<MatchMode> = None;
2280 if parser.skip_keyword(Keyword::IN).is_some() {
2281 if let Some(boolean_span) = parser.skip_keyword(Keyword::BOOLEAN) {
2282 let mode_span = parser.consume_keyword(Keyword::MODE)?;
2283 mode = Some(MatchMode::InBoolean(boolean_span.join_span(&mode_span)));
2284 } else if let Some(natural_span) = parser.skip_keyword(Keyword::NATURAL) {
2285 let _language_span = parser.skip_keyword(Keyword::LANGUAGE);
2287 let mode_span = parser.consume_keyword(Keyword::MODE)?;
2288 let natural_total = natural_span.join_span(&mode_span);
2289 if let Some(with_span) = parser.skip_keyword(Keyword::WITH) {
2291 let expansion_total = with_span.join_span(
2292 &parser.consume_keywords(&[Keyword::QUERY, Keyword::EXPANSION])?,
2293 );
2294 mode = Some(MatchMode::InNaturalLanguageWithQueryExpansion(
2295 natural_total.join_span(&expansion_total),
2296 ));
2297 } else {
2298 mode = Some(MatchMode::InNaturalLanguage(natural_total));
2299 }
2300 }
2301 } else if let Some(with_span) = parser.skip_keyword(Keyword::WITH) {
2302 mode = Some(MatchMode::WithQueryExpansion(with_span.join_span(
2303 &parser.consume_keywords(&[Keyword::QUERY, Keyword::EXPANSION])?,
2304 )));
2305 }
2306
2307 parser.consume_token(Token::RParen)?;
2308
2309 if mode.is_none() {
2312 if parser.skip_keyword(Keyword::IN).is_some() {
2313 if let Some(boolean_span) = parser.skip_keyword(Keyword::BOOLEAN) {
2314 let mode_span = parser.consume_keyword(Keyword::MODE)?;
2315 mode = Some(MatchMode::InBoolean(boolean_span.join_span(&mode_span)));
2316 } else if let Some(natural_span) = parser.skip_keyword(Keyword::NATURAL) {
2317 let _language_span = parser.skip_keyword(Keyword::LANGUAGE);
2318 let mode_span = parser.consume_keyword(Keyword::MODE)?;
2319 let natural_total = natural_span.join_span(&mode_span);
2320 if let Some(with_span) = parser.skip_keyword(Keyword::WITH) {
2322 let expansion_total = with_span.join_span(
2323 &parser
2324 .consume_keywords(&[Keyword::QUERY, Keyword::EXPANSION])?,
2325 );
2326 mode = Some(MatchMode::InNaturalLanguageWithQueryExpansion(
2327 natural_total.join_span(&expansion_total),
2328 ));
2329 } else {
2330 mode = Some(MatchMode::InNaturalLanguage(natural_total));
2331 }
2332 }
2333 } else if let Some(with_span) = parser.skip_keyword(Keyword::WITH) {
2334 mode = Some(MatchMode::WithQueryExpansion(with_span.join_span(
2335 &parser.consume_keywords(&[Keyword::QUERY, Keyword::EXPANSION])?,
2336 )));
2337 }
2338 }
2339
2340 r.shift_expr(Expression::MatchAgainst(Box::new(MatchAgainstExpression {
2341 match_span,
2342 columns: cols,
2343 against_span,
2344 expr,
2345 mode,
2346 })))
2347 }
2348 Token::Ident(_, Keyword::LEFT) if matches!(parser.peek(), Token::LParen) => {
2349 let i = parser.token.clone();
2350 let s = parser.span.clone();
2351 parser.consume();
2352 r.shift_expr(parse_function(parser, i, s)?)
2353 }
2354 Token::Ident(_, Keyword::CHAR) if matches!(parser.peek(), Token::LParen) => {
2355 let s = parser.span.clone();
2356 parser.consume();
2357 r.shift_expr(parse_char_function(parser, s)?)
2358 }
2359 Token::Ident(_, keyword)
2360 if matches!(parser.peek(), Token::LParen)
2361 && is_aggregate_function_ident(&keyword) =>
2362 {
2363 let i = parser.token.clone();
2364 let s = parser.span.clone();
2365 parser.consume();
2366 r.shift_expr(parse_aggregate_function(parser, i, s)?)
2367 }
2368 Token::Ident(charset, _)
2370 if charset.starts_with('_') && matches!(parser.peek(), Token::String(..)) =>
2371 {
2372 parser.consume();
2374 r.shift_expr(Expression::String(Box::new(parser.consume_string()?)))
2376 }
2377 Token::Ident(_, Keyword::ARRAY) if matches!(parser.peek(), Token::LBracket) => {
2379 let array_span = parser.consume_keyword(Keyword::ARRAY)?;
2380 parser.postgres_only(&array_span);
2381 let lbracket = parser.consume_token(Token::LBracket)?;
2382 let mut elements = Vec::new();
2383 if !matches!(parser.token, Token::RBracket) {
2384 loop {
2385 parser.recovered(
2386 "']' or ','",
2387 &|t| matches!(t, Token::RBracket | Token::Comma),
2388 |parser| {
2389 elements.push(parse_array_element(parser)?);
2390 Ok(())
2391 },
2392 )?;
2393 if parser.skip_token(Token::Comma).is_none() {
2394 break;
2395 }
2396 }
2397 }
2398 let rbracket = parser.consume_token(Token::RBracket)?;
2399 let bracket_span = lbracket.join_span(&rbracket);
2400 r.shift_expr(Expression::Array(Box::new(ArrayExpression {
2401 array_span,
2402 bracket_span,
2403 elements,
2404 })))
2405 }
2406 Token::Ident(_, k)
2407 if (k.expr_ident() || !k.restricted(restrict))
2408 && !matches!(r.stack.last(), Some(ReduceMember::Expression(_))) =>
2409 {
2410 let i = parser.token.clone();
2411 let s = parser.span.clone();
2412 parser.consume();
2413 if matches!(parser.token, Token::LParen) {
2414 r.shift_expr(parse_function(parser, i, s)?)
2415 } else {
2416 let f = match i {
2417 Token::Ident(_, Keyword::CURRENT_TIMESTAMP) => {
2418 Some(Function::CurrentTimestamp)
2419 }
2420 Token::Ident(_, Keyword::LOCALTIME | Keyword::LOCALTIMESTAMP) => {
2421 Some(Function::Now)
2422 }
2423 Token::Ident(_, Keyword::UTC_TIMESTAMP) => Some(Function::UtcTimeStamp),
2424 Token::Ident(_, Keyword::UTC_DATE) => Some(Function::UtcDate),
2425 Token::Ident(_, Keyword::UTC_TIME) => Some(Function::UtcTime),
2426 Token::Ident(_, Keyword::CURRENT_DATE) => Some(Function::CurDate),
2427 Token::Ident(_, Keyword::CURRENT_TIME) => Some(Function::CurTime),
2428 Token::Ident(_, Keyword::CURRENT_USER) => Some(Function::CurrentUser),
2429 Token::Ident(_, Keyword::CURRENT_ROLE) => Some(Function::CurrentRole),
2430 Token::Ident(_, Keyword::CURRENT_CATALOG) => Some(Function::CurrentCatalog),
2431 Token::Ident(_, Keyword::SESSION_USER) => Some(Function::SessionUser),
2432 Token::Ident(_, Keyword::USER)
2433 if parser.options.dialect.is_postgresql() =>
2434 {
2435 Some(Function::CurrentUser)
2436 }
2437 _ => None,
2438 };
2439 if let Some(f) = f {
2440 r.shift_expr(Expression::Function(Box::new(FunctionCallExpression {
2441 function: f,
2442 args: Vec::new(),
2443 function_span: s,
2444 })))
2445 } else {
2446 let mut parts = vec![IdentifierPart::Name(
2447 parser.token_to_plain_identifier(&i, s)?,
2448 )];
2449 let mut last_ident_tok: Option<(Token<'a>, Span)> = None;
2452 loop {
2453 if parser.skip_token(Token::Period).is_none() {
2454 break;
2455 }
2456 match &parser.token {
2457 Token::Mul => {
2458 last_ident_tok = None;
2459 parts.push(IdentifierPart::Star(
2460 parser.consume_token(Token::Mul)?,
2461 ));
2462 }
2463 Token::Ident(_, _) => {
2464 let fn_tok = parser.token.clone();
2465 let fn_span = parser.span.clone();
2466 last_ident_tok = Some((fn_tok, fn_span));
2467 parts.push(IdentifierPart::Name(
2468 parser.consume_plain_identifier_unreserved()?,
2469 ));
2470 }
2471 _ => parser.expected_failure("Identifier or '*'")?,
2472 }
2473 }
2474 if matches!(parser.token, Token::LParen) {
2476 if let Some((fn_tok, fn_span)) = last_ident_tok {
2477 let mut all_idents: Vec<Identifier<'a>> = parts[..parts.len() - 1]
2479 .iter()
2480 .filter_map(|p| match p {
2481 IdentifierPart::Name(id) => Some(id.clone()),
2482 _ => None,
2483 })
2484 .collect();
2485 let fn_ident = Identifier {
2486 value: match &fn_tok {
2487 Token::Ident(v, _) => v,
2488 _ => "",
2489 },
2490 span: fn_span.clone(),
2491 };
2492 all_idents.push(fn_ident);
2493 let function_span = if all_idents.len() > 1 {
2495 all_idents[0].span.join_span(&fn_span)
2496 } else {
2497 fn_span
2498 };
2499 r.shift_expr(parse_function_call(
2500 parser,
2501 Function::Other(all_idents),
2502 function_span,
2503 )?)
2504 } else {
2505 r.shift_expr(Expression::Identifier(Box::new(
2506 IdentifierExpression { parts },
2507 )))
2508 }
2509 } else {
2510 r.shift_expr(Expression::Identifier(Box::new(IdentifierExpression {
2511 parts,
2512 })))
2513 }
2514 }
2515 }
2516 }
2517 Token::QuestionMark
2518 if matches!(parser.options.arguments, crate::SQLArguments::QuestionMark) =>
2519 {
2520 let arg = parser.arg;
2521 parser.arg += 1;
2522 r.shift_expr(Expression::Arg(Box::new(ArgExpression {
2523 index: arg,
2524 span: parser.consume_token(Token::QuestionMark)?,
2525 })))
2526 }
2527 Token::PercentS if matches!(parser.options.arguments, crate::SQLArguments::Percent) => {
2528 let arg = parser.arg;
2529 parser.arg += 1;
2530 r.shift_expr(Expression::Arg(Box::new(ArgExpression {
2531 index: arg,
2532 span: parser.consume_token(Token::PercentS)?,
2533 })))
2534 }
2535 Token::DollarArg(arg)
2536 if matches!(parser.options.arguments, crate::SQLArguments::Dollar) =>
2537 {
2538 r.shift_expr(Expression::Arg(Box::new(ArgExpression {
2539 index: arg - 1,
2540 span: parser.consume(),
2541 })))
2542 }
2543 Token::LParen => {
2544 let paren_start = parser.consume_token(Token::LParen)?;
2545 let first = parse_expression_paren(parser)?;
2546 if parser.skip_token(Token::Comma).is_some() {
2547 let mut elements = vec![first];
2549 loop {
2550 if matches!(parser.token, Token::RParen) {
2551 break;
2552 }
2553 parser.recovered(
2554 "')' or ','",
2555 &|t| matches!(t, Token::RParen | Token::Comma),
2556 |parser| {
2557 elements.push(parse_expression_paren(parser)?);
2558 Ok(())
2559 },
2560 )?;
2561 if parser.skip_token(Token::Comma).is_none() {
2562 break;
2563 }
2564 }
2565 let paren_end = parser.consume_token(Token::RParen)?;
2566 r.shift_expr(Expression::Row(Box::new(RowExpression {
2567 paren_span: paren_start.join_span(&paren_end),
2568 elements,
2569 })))
2570 } else {
2571 parser.consume_token(Token::RParen)?;
2572 r.shift_expr(first)
2573 }
2574 }
2575 Token::Ident(_, Keyword::EXISTS) => {
2576 let exists_span = parser.consume_keyword(Keyword::EXISTS)?;
2577 parser.consume_token(Token::LParen)?;
2578 let subquery = parse_compound_query(parser)?;
2579 parser.consume_token(Token::RParen)?;
2580 let ans = Expression::Exists(Box::new(ExistsExpression {
2581 exists_span,
2582 subquery,
2583 }));
2584 r.shift_expr(ans)
2585 }
2586 Token::Ident(_, Keyword::ANY | Keyword::SOME | Keyword::ALL)
2587 if parser.options.dialect.is_postgresql()
2588 && !matches!(r.stack.last(), Some(ReduceMember::Expression(_))) =>
2589 {
2590 let quantifier = match &parser.token {
2591 Token::Ident(_, Keyword::ANY) => {
2592 Quantifier::Any(parser.consume_keyword(Keyword::ANY)?)
2593 }
2594 Token::Ident(_, Keyword::SOME) => {
2595 Quantifier::Some(parser.consume_keyword(Keyword::SOME)?)
2596 }
2597 _ => Quantifier::All(parser.consume_keyword(Keyword::ALL)?),
2598 };
2599 parser.consume_token(Token::LParen)?;
2600 let operand = parse_expression_paren(parser)?;
2601 parser.consume_token(Token::RParen)?;
2602 r.shift_expr(Expression::Quantifier(Box::new(QuantifierExpression {
2603 quantifier,
2604 operand,
2605 })))
2606 }
2607 Token::Ident(_, Keyword::CASE) => {
2608 let case_span = parser.consume_keyword(Keyword::CASE)?;
2609 let value = if !matches!(parser.token, Token::Ident(_, Keyword::WHEN)) {
2610 Some(parse_expression_unreserved(parser, PRIORITY_MAX)?)
2611 } else {
2612 None
2613 };
2614 let mut whens = Vec::new();
2615 let mut else_ = None;
2616 parser.recovered(
2617 "'END'",
2618 &|t| matches!(t, Token::Ident(_, Keyword::END)),
2619 |parser| {
2620 loop {
2621 let when_span = parser.consume_keyword(Keyword::WHEN)?;
2622 let when = parse_expression_unreserved(parser, PRIORITY_MAX)?;
2623 let then_span = parser.consume_keyword(Keyword::THEN)?;
2624 let then = parse_expression_unreserved(parser, PRIORITY_MAX)?;
2625 whens.push(When {
2626 when_span,
2627 when,
2628 then_span,
2629 then,
2630 });
2631 if !matches!(parser.token, Token::Ident(_, Keyword::WHEN)) {
2632 break;
2633 }
2634 }
2635 if let Some(span) = parser.skip_keyword(Keyword::ELSE) {
2636 else_ = Some((span, parse_expression_unreserved(parser, PRIORITY_MAX)?))
2637 };
2638 Ok(())
2639 },
2640 )?;
2641 let end_span = parser.consume_keyword(Keyword::END)?;
2642 r.shift_expr(Expression::Case(Box::new(CaseExpression {
2643 case_span,
2644 value,
2645 whens,
2646 else_,
2647 end_span,
2648 })))
2649 }
2650 Token::AtAtGlobal | Token::AtAtSession => {
2651 let global = parser.skip_token(Token::AtAtGlobal);
2652 let session = if global.is_none() {
2653 Some(parser.consume_token(Token::AtAtSession)?)
2654 } else {
2655 None
2656 };
2657 let dot = Some(parser.consume_token(Token::Period)?);
2658 let variable = match &parser.token {
2659 Token::Ident(_, Keyword::TIME_ZONE) => Variable::TimeZone,
2660 Token::Ident(t, _) => Variable::Other(t),
2661 _ => parser.expected_failure("Identifier")?,
2662 };
2663 let variable_span = parser.consume();
2664 r.shift_expr(Expression::Variable(Box::new(VariableExpression {
2665 global,
2666 session,
2667 dot,
2668 variable,
2669 variable_span,
2670 })))
2671 }
2672 Token::At => {
2673 let at_span = parser.consume_token(Token::At)?;
2675 let name = parser.consume_plain_identifier_unreserved()?;
2676 r.shift_expr(Expression::UserVariable(Box::new(UserVariableExpression {
2677 name,
2678 at_span,
2679 })))
2680 }
2681 _ => break,
2682 };
2683 if let Err(e) = e {
2684 parser.err_here(e.to_string())?;
2685 }
2686 }
2687 if r.reduce(99999).is_err() {
2688 parser.err_here("Expected expression")
2689 } else if r.stack.len() != 1 {
2690 parser.ice(file!(), line!())
2691 } else if let Some(ReduceMember::Expression(e)) = r.stack.pop() {
2692 Ok(e)
2693 } else {
2694 parser.ice(file!(), line!())
2695 }
2696}
2697
2698pub(crate) fn parse_expression_unreserved<'a>(
2699 parser: &mut Parser<'a, '_>,
2700 max_priority: usize,
2701) -> Result<Expression<'a>, ParseError> {
2702 parse_expression_restricted(parser, max_priority, parser.reserved())
2703}
2704
2705pub(crate) fn parse_expression_or_default<'a>(
2707 parser: &mut Parser<'a, '_>,
2708 max_priority: usize,
2709) -> Result<Expression<'a>, ParseError> {
2710 if matches!(parser.token, Token::Ident(_, Keyword::DEFAULT)) {
2711 Ok(Expression::Default(Box::new(DefaultExpression {
2712 span: parser.consume_keyword(Keyword::DEFAULT)?,
2713 })))
2714 } else {
2715 parse_expression_unreserved(parser, max_priority)
2716 }
2717}
2718
2719pub(crate) fn parse_expression_outer<'a>(
2720 parser: &mut Parser<'a, '_>,
2721) -> Result<Expression<'a>, ParseError> {
2722 if matches!(parser.token, Token::Ident(_, Keyword::SELECT)) {
2723 Ok(Expression::Subquery(Box::new(SubqueryExpression {
2724 expression: parse_compound_query(parser)?,
2725 })))
2726 } else {
2727 parse_expression_unreserved(parser, PRIORITY_MAX)
2728 }
2729}
2730
2731pub(crate) fn parse_expression_paren<'a>(
2732 parser: &mut Parser<'a, '_>,
2733) -> Result<Expression<'a>, ParseError> {
2734 if matches!(parser.token, Token::Ident(_, Keyword::SELECT)) {
2735 Ok(Expression::Subquery(Box::new(SubqueryExpression {
2736 expression: parse_compound_query(parser)?,
2737 })))
2738 } else {
2739 parse_expression_unreserved(parser, PRIORITY_MAX)
2740 }
2741}
2742
2743#[cfg(test)]
2744mod tests {
2745 use core::ops::Deref;
2746
2747 use alloc::{
2748 format,
2749 string::{String, ToString},
2750 };
2751
2752 use crate::{
2753 BinaryExpression, ParseOptions, SQLDialect,
2754 expression::{BinaryOperator, Expression, PRIORITY_MAX, Quantifier},
2755 issue::Issues,
2756 parser::Parser,
2757 };
2758
2759 use super::{IdentifierPart, parse_expression_unreserved};
2760
2761 fn test_ident<'a>(e: &Expression<'a>, v: &str) -> Result<(), String> {
2762 let v = match e {
2763 Expression::Identifier(a) => match a.parts.as_slice() {
2764 [IdentifierPart::Name(vv)] => vv.deref() == v,
2765 _ => false,
2766 },
2767 _ => false,
2768 };
2769 if !v {
2770 Err(format!("Expected identifier {} found {:?}", v, e))
2771 } else {
2772 Ok(())
2773 }
2774 }
2775
2776 fn test_expr(src: &'static str, f: impl FnOnce(&Expression<'_>) -> Result<(), String>) {
2777 let mut issues = Issues::new(src);
2778 let options = ParseOptions::new().dialect(SQLDialect::MariaDB);
2779 let mut parser = Parser::new(src, &mut issues, &options);
2780 let res = parse_expression_unreserved(&mut parser, PRIORITY_MAX)
2781 .expect("Expression in test expr");
2782 if let Err(e) = f(&res) {
2783 panic!("Error parsing {}: {}\nGot {:#?}", src, e, res);
2784 }
2785 }
2786
2787 #[test]
2788 fn expressions() {
2789 test_expr("`a` + `b` * `c` + `d`", |e| {
2790 match e {
2791 Expression::Binary(b) => {
2792 let BinaryExpression {
2793 op: BinaryOperator::Add(_),
2794 lhs,
2795 rhs,
2796 ..
2797 } = b.as_ref()
2798 else {
2799 return Err("Expected outer +".to_string());
2800 };
2801 match lhs {
2802 Expression::Binary(b) => {
2803 let BinaryExpression {
2804 op: BinaryOperator::Add(_),
2805 lhs,
2806 rhs,
2807 ..
2808 } = b.as_ref()
2809 else {
2810 return Err("Expected inner +".to_string());
2811 };
2812 test_ident(lhs, "a")?;
2813 match rhs {
2814 Expression::Binary(b) => {
2815 let BinaryExpression {
2816 op: BinaryOperator::Mult(_),
2817 lhs,
2818 rhs,
2819 ..
2820 } = b.as_ref()
2821 else {
2822 return Err("Expected *".to_string());
2823 };
2824 test_ident(lhs, "b")?;
2825 test_ident(rhs, "c")?;
2826 }
2827 _ => return Err("Lhs.Rhs".to_string()),
2828 }
2829 }
2830 _ => return Err("Lhs".to_string()),
2831 }
2832 test_ident(rhs, "d")?;
2833 }
2834 _ => return Err("Outer".to_string()),
2835 }
2836 Ok(())
2837 });
2838 }
2839
2840 fn test_expr_pg(src: &'static str, f: impl FnOnce(&Expression<'_>) -> Result<(), String>) {
2841 let mut issues = Issues::new(src);
2842 let options = ParseOptions::new().dialect(SQLDialect::PostgreSQL);
2843 let mut parser = Parser::new(src, &mut issues, &options);
2844 let res = parse_expression_unreserved(&mut parser, PRIORITY_MAX)
2845 .expect("Expression in test_expr_pg");
2846 if let Err(e) = f(&res) {
2847 panic!("Error parsing {}: {}\nGot {:#?}", src, e, res);
2848 }
2849 }
2850
2851 #[test]
2852 fn quantifier_any() {
2853 test_expr_pg(
2854 "salary > ANY (SELECT max_salary FROM departments)",
2855 |e| match e {
2856 Expression::Binary(b) => match &b.rhs {
2857 Expression::Quantifier(q) => {
2858 assert!(matches!(q.quantifier, Quantifier::Any(_)));
2859 Ok(())
2860 }
2861 _ => Err(format!("Expected Quantifier RHS, got {:?}", b.rhs)),
2862 },
2863 _ => Err(format!("Expected Binary expression, got {:?}", e)),
2864 },
2865 );
2866 }
2867
2868 #[test]
2869 fn quantifier_some() {
2870 test_expr_pg("x = SOME (ARRAY[1, 2, 3])", |e| match e {
2871 Expression::Binary(b) => match &b.rhs {
2872 Expression::Quantifier(q) => {
2873 assert!(matches!(q.quantifier, Quantifier::Some(_)));
2874 Ok(())
2875 }
2876 _ => Err(format!("Expected Quantifier RHS, got {:?}", b.rhs)),
2877 },
2878 _ => Err(format!("Expected Binary expression, got {:?}", e)),
2879 });
2880 }
2881
2882 #[test]
2883 fn quantifier_all() {
2884 test_expr_pg("price <= ALL (SELECT price FROM products)", |e| match e {
2885 Expression::Binary(b) => match &b.rhs {
2886 Expression::Quantifier(q) => {
2887 assert!(matches!(q.quantifier, Quantifier::All(_)));
2888 Ok(())
2889 }
2890 _ => Err(format!("Expected Quantifier RHS, got {:?}", b.rhs)),
2891 },
2892 _ => Err(format!("Expected Binary expression, got {:?}", e)),
2893 });
2894 }
2895}