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