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