1use crate::{
14 Expression, Identifier, OptSpanned, Span, Spanned,
15 expression::{PRIORITY_MAX, parse_expression_outer, parse_expression_unreserved},
16 keywords::Keyword,
17 lexer::Token,
18 parser::{ParseError, Parser},
19 select::OrderFlag,
20};
21use alloc::{boxed::Box, vec::Vec};
22
23#[derive(Debug, Clone, PartialEq, Eq)]
25pub enum Function<'a> {
26 Abs,
27 Acos,
28 AddDate,
29 AddMonths,
30 AddTime,
31 Ascii,
32 Asin,
33 Atan,
34 Atan2,
35 Bin,
36 BitLength,
37 Ceil,
38 Char,
39 CharacterLength,
40 Chr,
41 Concat,
42 ConcatWs,
43 Conv,
44 ConvertTz,
45 Cos,
46 Cot,
47 Crc32,
48 Crc32c,
49 CurrentCatalog,
50 CurrentRole,
51 CurrentUser,
52 CurDate,
53 CurrentTimestamp,
54 CurTime,
55 SessionUser,
56 Date,
57 DateDiff,
58 DateFormat,
59 DateSub,
60 Datetime,
61 DayName,
62 DayOfMonth,
63 DayOfWeek,
64 DayOfYear,
65 Degrees,
66 Elt,
67 Exists,
68 Exp,
69 ExportSet,
70 ExtractValue,
71 Field,
72 FindInSet,
73 Floor,
74 Format,
75 FromBase64,
76 FromDays,
77 FromUnixTime,
78 Greatest,
79 Hex,
80 Hour,
81 If,
82 IfNull,
83 Insert,
84 InStr,
85 JsonArray,
86 JsonArrayAgg,
87 JsonArrayAppend,
88 JsonArrayInsert,
89 JsonArrayIntersect,
90 JsonCompact,
91 JsonContains,
92 JsonContainsPath,
93 JsonDepth,
94 JsonDetailed,
95 JsonEquals,
96 JsonExists,
97 JsonExtract,
98 JsonInsert,
99 JsonKeys,
100 JsonLength,
101 JsonLoose,
102 JsonMerge,
103 JsonMergePath,
104 JsonMergePerserve,
105 JsonNormalize,
106 JsonObject,
107 JsonObjectAgg,
108 JsonObjectFilterKeys,
109 JsonObjectToArray,
110 JsonOverlaps,
111 JsonPretty,
112 JsonQuery,
113 JsonQuote,
114 JsonRemove,
115 JsonReplace,
116 JsonSchemaValid,
117 JsonSearch,
118 JsonSet,
119 JsonTable,
120 JsonType,
121 JsonUnquote,
122 JsonValid,
123 JsonValue,
124 Lag,
125 LastDay,
126 Avg,
127 Count,
128 LCase,
129 Lead,
130 Least,
131 Left,
132 Length,
133 LengthB,
134 Ln,
135 LoadFile,
136 Locate,
137 Log,
138 Log10,
139 Log2,
140 Lower,
141 LPad,
142 LTrim,
143 MakeDate,
144 MakeSet,
145 MakeTime,
146 Max,
147 MicroSecond,
148 Mid,
149 Min,
150 Minute,
151 Mod,
152 Month,
153 MonthName,
154 NaturalSortkey,
155 Now,
156 NullIf,
157 NVL2,
158 Oct,
159 OctetLength,
160 Ord,
161 PeriodAdd,
162 PeriodDiff,
163 Pi,
164 Position,
165 Pow,
166 Quarter,
167 Quote,
168 Radians,
169 Rand,
170 Repeat,
171 Replace,
172 Reverse,
173 Right,
174 Round,
175 RPad,
176 RTrim,
177 Second,
178 SecToTime,
179 SFormat,
180 Sign,
181 Sin,
182 Sleep,
183 SoundEx,
184 Space,
185 Sqrt,
186 StartsWith,
187 StrCmp,
188 Strftime,
189 StrToDate,
190 SubStr,
191 SubStringIndex,
192 SubTime,
193 Sum,
194 SysDate,
195 Tan,
196 Time,
197 TimeDiff,
198 TimeFormat,
199 Timestamp,
200 TimeToSec,
201 ToBase64,
202 ToChar,
203 ToDays,
204 ToSeconds,
205 Truncate,
206 UCase,
207 UncompressedLength,
208 UnHex,
209 UnixTimestamp,
210 Unknown,
211 UpdateXml,
212 Upper,
213 UtcDate,
214 UtcTime,
215 UtcTimeStamp,
216 Value,
217 Week,
218 Weekday,
219 WeekOfYear,
220 Year,
221 YearWeek,
222 AesDecrypt,
224 AesEncrypt,
225 AnyValue,
226 Benchmark,
227 BinToUuid,
228 BitCount,
229 Charset,
230 Coercibility,
231 Collation,
232 Compress,
233 ConnectionId,
234 DatabaseFunc,
235 FirstValue,
236 FormatBytes,
237 FormatPicoTime,
238 FoundRows,
239 GetFormat,
240 GetLock,
241 Grouping,
242 IcuVersion,
243 Inet6Aton,
244 Inet6Ntoa,
245 InetAton,
246 InetNtoa,
247 IsFreeLock,
248 IsIPv4,
249 IsIPv4Compat,
250 IsIPv4Mapped,
251 IsIPv6,
252 IsUsedLock,
253 IsUuid,
254 LastInsertId,
255 LastValue,
256 Md5,
257 NameConst,
258 NthValue,
259 Ntile,
260 PsCurrentThreadId,
261 PsThreadId,
262 RandomBytes,
263 RegexpInstr,
264 RegexpLike,
265 RegexpReplace,
266 RegexpSubstr,
267 ReleaseAllLocks,
268 ReleaseLock,
269 RolesGraphml,
270 RowCount,
271 RowNumber,
272 SchemaFunc,
273 SessionUserFunc,
274 Sha,
275 Sha1,
276 Sha2,
277 StatementDigest,
278 StatementDigestText,
279 SystemUser,
280 Uncompress,
281 UserFunc,
282 Uuid,
283 UuidShort,
284 UuidToBin,
285 ValidatePasswordStrength,
286 Version,
287 WeightString,
288 ArrayAgg,
289 BitAnd,
290 BitOr,
291 BitXor,
292 BoolAnd,
293 BoolOr,
294 Corr,
295 CovarPop,
296 CovarSamp,
297 CumeDist,
298 DenseRank,
299 JsonAgg,
300 JsonbAgg,
301 JsonbObjectAgg,
302 PercentRank,
303 PercentileCont,
304 PercentileDisc,
305 Rank,
306 RegrAvgx,
307 RegrAvgy,
308 RegrCount,
309 RegrIntercept,
310 RegrR2,
311 RegrSlope,
312 RegrSxx,
313 RegrSxy,
314 RegrSyy,
315 Mode,
316 Std,
317 Stddev,
318 StddevPop,
319 StddevSamp,
320 StringAgg,
321 Variance,
322 VarPop,
323 VarSamp,
324 Xmlagg,
325 Other(Vec<Identifier<'a>>),
326}
327
328#[derive(Debug, Clone)]
330pub struct FunctionCallExpression<'a> {
331 pub function: Function<'a>,
332 pub args: Vec<Expression<'a>>,
333 pub function_span: Span,
334}
335
336impl Spanned for FunctionCallExpression<'_> {
337 fn span(&self) -> Span {
338 self.function_span.join_span(&self.args)
339 }
340}
341
342#[derive(Debug, Clone)]
344pub struct CharFunctionExpression<'a> {
345 pub char_span: Span,
347 pub args: Vec<Expression<'a>>,
349 pub using_charset: Option<(Span, Identifier<'a>)>,
351}
352
353impl<'a> Spanned for CharFunctionExpression<'a> {
354 fn span(&self) -> Span {
355 self.char_span
356 .join_span(&self.args)
357 .join_span(&self.using_charset)
358 }
359}
360
361#[derive(Debug, Clone)]
363pub enum WindowFrameMode {
364 Rows(Span),
365 Range(Span),
366 Groups(Span),
367}
368
369impl Spanned for WindowFrameMode {
370 fn span(&self) -> Span {
371 match self {
372 WindowFrameMode::Rows(s) | WindowFrameMode::Range(s) | WindowFrameMode::Groups(s) => {
373 s.clone()
374 }
375 }
376 }
377}
378
379#[derive(Debug, Clone)]
381pub enum WindowFrameBound<'a> {
382 UnboundedPreceding(Span),
384 Preceding(Expression<'a>, Span),
386 CurrentRow(Span),
388 Following(Expression<'a>, Span),
390 UnboundedFollowing(Span),
392}
393
394impl<'a> Spanned for WindowFrameBound<'a> {
395 fn span(&self) -> Span {
396 match self {
397 WindowFrameBound::UnboundedPreceding(s) => s.clone(),
398 WindowFrameBound::Preceding(e, s) => e.span().join_span(s),
399 WindowFrameBound::CurrentRow(s) => s.clone(),
400 WindowFrameBound::Following(e, s) => e.span().join_span(s),
401 WindowFrameBound::UnboundedFollowing(s) => s.clone(),
402 }
403 }
404}
405
406#[derive(Debug, Clone)]
408pub struct WindowFrame<'a> {
409 pub mode: WindowFrameMode,
411 pub start: WindowFrameBound<'a>,
413 pub between: Option<(Span, WindowFrameBound<'a>)>,
415}
416
417impl<'a> Spanned for WindowFrame<'a> {
418 fn span(&self) -> Span {
419 let s = self.mode.span().join_span(&self.start);
420 if let Some((and_span, end)) = &self.between {
421 s.join_span(and_span).join_span(end)
422 } else {
423 s
424 }
425 }
426}
427
428#[derive(Debug, Clone)]
430pub struct WindowSpec<'a> {
431 pub partition_by: Option<(Span, Vec<Expression<'a>>)>,
433 pub order_by: Option<(Span, Vec<(Expression<'a>, OrderFlag)>)>,
435 pub frame: Option<WindowFrame<'a>>,
437}
438
439impl<'a> Spanned for WindowSpec<'a> {
440 fn span(&self) -> Span {
441 self.partition_by
442 .opt_join_span(&self.order_by)
443 .opt_join_span(&self.frame)
444 .expect("Either partition_by, order_by, or frame must be specified")
445 }
446}
447
448#[derive(Debug, Clone)]
449pub struct WindowClause<'a> {
450 pub over_span: Span,
451 pub window_spec: WindowSpec<'a>,
452}
453
454impl Spanned for WindowClause<'_> {
455 fn span(&self) -> Span {
456 self.over_span.join_span(&self.window_spec)
457 }
458}
459
460#[derive(Debug, Clone)]
462pub struct WindowFunctionCallExpression<'a> {
463 pub function: Function<'a>,
464 pub args: Vec<Expression<'a>>,
465 pub function_span: Span,
466 pub over: WindowClause<'a>,
467}
468
469impl Spanned for WindowFunctionCallExpression<'_> {
470 fn span(&self) -> Span {
471 self.function_span
472 .join_span(&self.args)
473 .join_span(&self.over)
474 }
475}
476
477#[derive(Debug, Clone)]
478pub struct AggregateFunctionCallExpression<'a> {
479 pub function: Function<'a>,
480 pub args: Vec<Expression<'a>>,
481 pub function_span: Span,
482 pub distinct_span: Option<Span>,
483 pub within_group: Option<(Span, Vec<(Expression<'a>, OrderFlag)>)>,
484 pub filter: Option<(Span, Expression<'a>)>,
485 pub over: Option<WindowClause<'a>>,
486}
487
488impl Spanned for AggregateFunctionCallExpression<'_> {
489 fn span(&self) -> Span {
490 self.function_span
491 .join_span(&self.args)
492 .join_span(&self.distinct_span)
493 .join_span(&self.within_group)
494 .join_span(&self.filter)
495 .join_span(&self.over)
496 }
497}
498
499pub(crate) fn is_aggregate_function_ident(keyword: &Keyword) -> bool {
500 matches!(
501 keyword,
502 Keyword::COUNT
503 | Keyword::AVG
504 | Keyword::SUM
505 | Keyword::MIN
506 | Keyword::MAX
507 | Keyword::JSON_ARRAYAGG
508 | Keyword::JSON_OBJECTAGG
509 | Keyword::ARRAY_AGG
510 | Keyword::BIT_AND
511 | Keyword::BIT_OR
512 | Keyword::BIT_XOR
513 | Keyword::BOOL_AND
514 | Keyword::BOOL_OR
515 | Keyword::CORR
516 | Keyword::COVAR_POP
517 | Keyword::COVAR_SAMP
518 | Keyword::CUME_DIST
519 | Keyword::DENSE_RANK
520 | Keyword::EVERY
521 | Keyword::JSON_AGG
522 | Keyword::JSONB_AGG
523 | Keyword::JSONB_OBJECT_AGG
524 | Keyword::PERCENT_RANK
525 | Keyword::PERCENTILE_CONT
526 | Keyword::PERCENTILE_DISC
527 | Keyword::RANK
528 | Keyword::REGR_AVGX
529 | Keyword::REGR_AVGY
530 | Keyword::REGR_COUNT
531 | Keyword::REGR_INTERCEPT
532 | Keyword::REGR_R2
533 | Keyword::REGR_SLOPE
534 | Keyword::REGR_SXX
535 | Keyword::REGR_SXY
536 | Keyword::REGR_SYY
537 | Keyword::STD
538 | Keyword::STDDEV
539 | Keyword::STDDEV_POP
540 | Keyword::STDDEV_SAMP
541 | Keyword::STRING_AGG
542 | Keyword::VARIANCE
543 | Keyword::VAR_POP
544 | Keyword::VAR_SAMP
545 | Keyword::XMLAGG
546 | Keyword::MODE
547 )
548}
549
550fn parse_window_frame_bound<'a>(
551 parser: &mut Parser<'a, '_>,
552) -> Result<WindowFrameBound<'a>, ParseError> {
553 match &parser.token {
554 Token::Ident(_, Keyword::UNBOUNDED) => {
555 let kw_span = parser.consume_keyword(Keyword::UNBOUNDED)?;
556 if let Some(span) = parser.skip_keyword(Keyword::PRECEDING) {
557 Ok(WindowFrameBound::UnboundedPreceding(
558 kw_span.join_span(&span),
559 ))
560 } else {
561 Ok(WindowFrameBound::UnboundedFollowing(
562 parser
563 .consume_keyword(Keyword::FOLLOWING)?
564 .join_span(&kw_span),
565 ))
566 }
567 }
568 Token::Ident(_, Keyword::CURRENT) => {
569 let current_row_span = parser.consume_keywords(&[Keyword::CURRENT, Keyword::ROW])?;
570 Ok(WindowFrameBound::CurrentRow(current_row_span))
571 }
572 _ => {
573 let expr = parse_expression_unreserved(parser, PRIORITY_MAX)?;
574 if let Some(s) = parser.skip_keyword(Keyword::PRECEDING) {
575 Ok(WindowFrameBound::Preceding(expr, s))
576 } else {
577 let s = parser.consume_keyword(Keyword::FOLLOWING)?;
578 Ok(WindowFrameBound::Following(expr, s))
579 }
580 }
581 }
582}
583
584fn parse_window_frame<'a>(
585 parser: &mut Parser<'a, '_>,
586 mode: WindowFrameMode,
587) -> Result<WindowFrame<'a>, ParseError> {
588 if let Some(between_span) = parser.skip_keyword(Keyword::BETWEEN) {
589 let start = parse_window_frame_bound(parser)?;
590 let and_span = parser.consume_keyword(Keyword::AND)?;
591 let end = parse_window_frame_bound(parser)?;
592 Ok(WindowFrame {
593 mode,
594 start,
595 between: Some((between_span.join_span(&and_span), end)),
596 })
597 } else {
598 let start = parse_window_frame_bound(parser)?;
599 Ok(WindowFrame {
600 mode,
601 start,
602 between: None,
603 })
604 }
605}
606
607fn parse_over_clause<'a>(
608 parser: &mut Parser<'a, '_>,
609) -> Result<Option<WindowClause<'a>>, ParseError> {
610 let Some(over_span) = parser.skip_keyword(Keyword::OVER) else {
611 return Ok(None);
612 };
613
614 parser.consume_token(Token::LParen)?;
615
616 let partition_by = if let Some(partition_span) = parser.skip_keyword(Keyword::PARTITION) {
617 let partition_by_span = partition_span.join_span(&parser.consume_keyword(Keyword::BY)?);
618 let mut partition_exprs = Vec::new();
619 loop {
620 partition_exprs.push(parse_expression_unreserved(parser, PRIORITY_MAX)?);
621 if parser.skip_token(Token::Comma).is_none() {
622 break;
623 }
624 }
625 Some((partition_by_span, partition_exprs))
626 } else {
627 None
628 };
629
630 let order_by = if let Some(span) = parser.skip_keyword(Keyword::ORDER) {
631 let order_span = span.join_span(&parser.consume_keyword(Keyword::BY)?);
632 let mut order = Vec::new();
633 loop {
634 let e = parse_expression_unreserved(parser, PRIORITY_MAX)?;
635 let f = match &parser.token {
636 Token::Ident(_, Keyword::ASC) => OrderFlag::Asc(parser.consume()),
637 Token::Ident(_, Keyword::DESC) => OrderFlag::Desc(parser.consume()),
638 _ => OrderFlag::None,
639 };
640 order.push((e, f));
641 if parser.skip_token(Token::Comma).is_none() {
642 break;
643 }
644 }
645 Some((order_span, order))
646 } else {
647 None
648 };
649
650 let frame = if let Some(s) = parser.skip_keyword(Keyword::ROWS) {
652 Some(parse_window_frame(parser, WindowFrameMode::Rows(s))?)
653 } else if let Some(s) = parser.skip_keyword(Keyword::RANGE) {
654 Some(parse_window_frame(parser, WindowFrameMode::Range(s))?)
655 } else {
656 None
657 };
658
659 parser.consume_token(Token::RParen)?;
660
661 Ok(Some(WindowClause {
662 over_span,
663 window_spec: WindowSpec {
664 partition_by,
665 order_by,
666 frame,
667 },
668 }))
669}
670
671pub(crate) fn parse_aggregate_function<'a>(
672 parser: &mut Parser<'a, '_>,
673 t: Token<'a>,
674 span: Span,
675) -> Result<Expression<'a>, ParseError> {
676 parser.consume_token(Token::LParen)?;
677 let func = match &t {
678 Token::Ident(_, Keyword::COUNT) => Function::Count,
679 Token::Ident(_, Keyword::AVG) => Function::Avg,
680 Token::Ident(_, Keyword::SUM) => Function::Sum,
681 Token::Ident(_, Keyword::MIN) => Function::Min,
682 Token::Ident(_, Keyword::MAX) => Function::Max,
683 Token::Ident(_, Keyword::JSON_ARRAYAGG) => Function::JsonArrayAgg,
684 Token::Ident(_, Keyword::JSON_OBJECTAGG) => Function::JsonObjectAgg,
685 Token::Ident(_, Keyword::ARRAY_AGG) => Function::ArrayAgg,
686 Token::Ident(_, Keyword::BIT_AND) => Function::BitAnd,
687 Token::Ident(_, Keyword::BIT_OR) => Function::BitOr,
688 Token::Ident(_, Keyword::BIT_XOR) => Function::BitXor,
689 Token::Ident(_, Keyword::BOOL_AND) => Function::BoolAnd,
690 Token::Ident(_, Keyword::BOOL_OR) => Function::BoolOr,
691 Token::Ident(_, Keyword::CORR) => Function::Corr,
692 Token::Ident(_, Keyword::COVAR_POP) => Function::CovarPop,
693 Token::Ident(_, Keyword::COVAR_SAMP) => Function::CovarSamp,
694 Token::Ident(_, Keyword::CUME_DIST) => Function::CumeDist,
695 Token::Ident(_, Keyword::DENSE_RANK) => Function::DenseRank,
696 Token::Ident(_, Keyword::EVERY) => Function::BoolAnd,
697 Token::Ident(_, Keyword::JSON_AGG) => Function::JsonAgg,
698 Token::Ident(_, Keyword::JSONB_AGG) => Function::JsonbAgg,
699 Token::Ident(_, Keyword::JSONB_OBJECT_AGG) => Function::JsonbObjectAgg,
700 Token::Ident(_, Keyword::PERCENT_RANK) => Function::PercentRank,
701 Token::Ident(_, Keyword::PERCENTILE_CONT) => Function::PercentileCont,
702 Token::Ident(_, Keyword::PERCENTILE_DISC) => Function::PercentileDisc,
703 Token::Ident(_, Keyword::RANK) => Function::Rank,
704 Token::Ident(_, Keyword::REGR_AVGX) => Function::RegrAvgx,
705 Token::Ident(_, Keyword::REGR_AVGY) => Function::RegrAvgy,
706 Token::Ident(_, Keyword::REGR_COUNT) => Function::RegrCount,
707 Token::Ident(_, Keyword::REGR_INTERCEPT) => Function::RegrIntercept,
708 Token::Ident(_, Keyword::REGR_R2) => Function::RegrR2,
709 Token::Ident(_, Keyword::REGR_SLOPE) => Function::RegrSlope,
710 Token::Ident(_, Keyword::REGR_SXX) => Function::RegrSxx,
711 Token::Ident(_, Keyword::REGR_SXY) => Function::RegrSxy,
712 Token::Ident(_, Keyword::REGR_SYY) => Function::RegrSyy,
713 Token::Ident(_, Keyword::STD) => Function::Std,
714 Token::Ident(_, Keyword::STDDEV) => Function::Stddev,
715 Token::Ident(_, Keyword::STDDEV_POP) => Function::StddevPop,
716 Token::Ident(_, Keyword::STDDEV_SAMP) => Function::StddevSamp,
717 Token::Ident(_, Keyword::STRING_AGG) => Function::StringAgg,
718 Token::Ident(_, Keyword::VARIANCE) => Function::Variance,
719 Token::Ident(_, Keyword::VAR_POP) => Function::VarPop,
720 Token::Ident(_, Keyword::VAR_SAMP) => Function::VarSamp,
721 Token::Ident(_, Keyword::XMLAGG) => Function::Xmlagg,
722 Token::Ident(_, Keyword::MODE) => Function::Mode,
723 _ => {
724 parser.err("Unknown aggregate function", &span);
725 Function::Unknown
726 }
727 };
728
729 let distinct_span = parser.skip_keyword(Keyword::DISTINCT);
730 let mut args = Vec::new();
731 if !matches!(parser.token, Token::RParen) {
732 loop {
733 parser.recovered(
734 "')' or ','",
735 &|t| matches!(t, Token::RParen | Token::Comma),
736 |parser| {
737 args.push(parse_expression_outer(parser)?);
738 Ok(())
739 },
740 )?;
741 if parser.skip_token(Token::Comma).is_none() {
742 break;
743 }
744 }
745 }
746 parser.consume_token(Token::RParen)?;
747
748 let within_group = if let Some(within_span) = parser.skip_keyword(Keyword::WITHIN) {
749 let within_group_span = within_span.join_span(&parser.consume_keyword(Keyword::GROUP)?);
750 parser.consume_token(Token::LParen)?;
751 let order_span = parser.consume_keyword(Keyword::ORDER)?;
752 let order_by_span = order_span.join_span(&parser.consume_keyword(Keyword::BY)?);
753 let mut order = Vec::new();
754 loop {
755 let e = parse_expression_unreserved(parser, PRIORITY_MAX)?;
756 let f = match &parser.token {
757 Token::Ident(_, Keyword::ASC) => OrderFlag::Asc(parser.consume()),
758 Token::Ident(_, Keyword::DESC) => OrderFlag::Desc(parser.consume()),
759 _ => OrderFlag::None,
760 };
761 order.push((e, f));
762 if parser.skip_token(Token::Comma).is_none() {
763 break;
764 }
765 }
766 parser.consume_token(Token::RParen)?;
767 Some((within_group_span.join_span(&order_by_span), order))
768 } else {
769 None
770 };
771
772 let filter = if let Some(filter_span) = parser.skip_keyword(Keyword::FILTER) {
773 parser.postgres_only(&filter_span);
774 parser.consume_token(Token::LParen)?;
775 parser.consume_keyword(Keyword::WHERE)?;
776 let condition = parse_expression_unreserved(parser, PRIORITY_MAX)?;
777 parser.consume_token(Token::RParen)?;
778 Some((filter_span, condition))
779 } else {
780 None
781 };
782
783 let over = parse_over_clause(parser)?;
784
785 Ok(Expression::AggregateFunction(Box::new(
786 AggregateFunctionCallExpression {
787 function: func,
788 args,
789 function_span: span,
790 distinct_span,
791 within_group,
792 filter,
793 over,
794 },
795 )))
796}
797
798pub(crate) fn parse_function<'a>(
799 parser: &mut Parser<'a, '_>,
800 t: Token<'a>,
801 span: Span,
802) -> Result<Expression<'a>, ParseError> {
803 parser.consume_token(Token::LParen)?;
804
805 let func = match &t {
806 Token::Ident(_, Keyword::ASCII) => Function::Ascii,
808 Token::Ident(_, Keyword::BIN) => Function::Bin,
809 Token::Ident(_, Keyword::BIT_LENGTH) => Function::BitLength,
810 Token::Ident(_, Keyword::CHAR_LENGTH) => Function::CharacterLength,
811 Token::Ident(_, Keyword::CHARACTER_LENGTH) => Function::CharacterLength,
812 Token::Ident(_, Keyword::CHR) => Function::Chr,
813 Token::Ident(_, Keyword::CONCAT) => Function::Concat,
814 Token::Ident(_, Keyword::CONCAT_WS) => Function::ConcatWs,
815 Token::Ident(_, Keyword::ELT) => Function::Elt,
816 Token::Ident(_, Keyword::EXPORT_SET) => Function::ExportSet,
817 Token::Ident(_, Keyword::EXTRACTVALUE) => Function::ExtractValue,
818 Token::Ident(_, Keyword::FIELD) => Function::Field,
819 Token::Ident(_, Keyword::FIND_IN_SET) => Function::FindInSet,
820 Token::Ident(_, Keyword::FORMAT) => Function::Format,
821 Token::Ident(_, Keyword::FROM_BASE64) => Function::FromBase64,
822 Token::Ident(_, Keyword::HEX) => Function::Hex,
823 Token::Ident(_, Keyword::INSERT) => Function::Insert,
824 Token::Ident(_, Keyword::INSTR) => Function::InStr,
825 Token::Ident(_, Keyword::LCASE) => Function::LCase,
826 Token::Ident(_, Keyword::LEFT) => Function::Left,
827 Token::Ident(_, Keyword::LENGTH) => Function::Length,
828 Token::Ident(_, Keyword::LENGTHB) => Function::LengthB,
829 Token::Ident(_, Keyword::LOAD_FILE) => Function::LoadFile,
830 Token::Ident(_, Keyword::LOCATE) => Function::Locate,
831 Token::Ident(_, Keyword::LOWER) => Function::Lower,
832 Token::Ident(_, Keyword::LPAD) => Function::LPad,
833 Token::Ident(_, Keyword::LTRIM) => Function::LTrim,
834 Token::Ident(_, Keyword::MAKE_SET) => Function::MakeSet,
835 Token::Ident(_, Keyword::MID) => Function::Mid,
836 Token::Ident(_, Keyword::NATURAL_SORT_KEY) => Function::NaturalSortkey,
837 Token::Ident(_, Keyword::OCTET_LENGTH) => Function::OctetLength,
838 Token::Ident(_, Keyword::ORD) => Function::Ord,
839 Token::Ident(_, Keyword::POSITION) => Function::Position,
840 Token::Ident(_, Keyword::QUOTE) => Function::Quote,
841 Token::Ident(_, Keyword::REPEAT) => Function::Repeat,
842 Token::Ident(_, Keyword::REPLACE) => Function::Replace,
843 Token::Ident(_, Keyword::REVERSE) => Function::Reverse,
844 Token::Ident(_, Keyword::RIGHT) => Function::Right,
845 Token::Ident(_, Keyword::RPAD) => Function::RPad,
846 Token::Ident(_, Keyword::RTRIM) => Function::RTrim,
847 Token::Ident(_, Keyword::SOUNDEX) => Function::SoundEx,
848 Token::Ident(_, Keyword::SLEEP) => Function::Sleep,
849 Token::Ident(_, Keyword::SPACE) => Function::Space,
850 Token::Ident(_, Keyword::STRCMP) => Function::StrCmp,
851 Token::Ident(_, Keyword::SUBSTR) => Function::SubStr,
852 Token::Ident(_, Keyword::SUBSTRING) => Function::SubStr,
853 Token::Ident(_, Keyword::SUBSTRING_INDEX) => Function::SubStringIndex,
854 Token::Ident(_, Keyword::TO_BASE64) => Function::ToBase64,
855 Token::Ident(_, Keyword::TO_CHAR) => Function::ToChar,
856 Token::Ident(_, Keyword::UCASE) => Function::UCase,
857 Token::Ident(_, Keyword::UNCOMPRESSED_LENGTH) => Function::UncompressedLength,
858 Token::Ident(_, Keyword::UNHEX) => Function::UnHex,
859 Token::Ident(_, Keyword::UPDATEXML) => Function::UpdateXml,
860 Token::Ident(_, Keyword::UPPER) => Function::Upper,
861 Token::Ident(_, Keyword::SFORMAT) => Function::SFormat,
862
863 Token::Ident(_, Keyword::EXISTS) => Function::Exists,
865 Token::Ident(_, Keyword::COUNT) => Function::Count,
866 Token::Ident(_, Keyword::AVG) => Function::Avg,
867 Token::Ident(_, Keyword::MIN) => Function::Min,
868 Token::Ident(_, Keyword::MAX) => Function::Max,
869 Token::Ident(_, Keyword::SUM) => Function::Sum,
870 Token::Ident(_, Keyword::VALUE) => Function::Value,
871 Token::Ident(_, Keyword::VALUES) => Function::Value,
872 Token::Ident(_, Keyword::LEAD) => Function::Lead,
873 Token::Ident(_, Keyword::LAG) => Function::Lag,
874 Token::Ident(_, Keyword::STARTS_WITH) => Function::StartsWith,
875
876 Token::Ident(_, Keyword::IFNULL) => Function::IfNull,
878 Token::Ident(_, Keyword::NULLIF) => Function::NullIf,
879 Token::Ident(_, Keyword::NVL) => Function::IfNull,
880 Token::Ident(_, Keyword::NVL2) => Function::NVL2,
881 Token::Ident(_, Keyword::IF) => Function::If,
882
883 Token::Ident(_, Keyword::ABS) => Function::Abs,
885 Token::Ident(_, Keyword::ACOS) => Function::Acos,
886 Token::Ident(_, Keyword::ASIN) => Function::Asin,
887 Token::Ident(_, Keyword::ATAN) => Function::Atan,
888 Token::Ident(_, Keyword::ATAN2) => Function::Atan2,
889 Token::Ident(_, Keyword::CEIL | Keyword::CEILING) => Function::Ceil,
890 Token::Ident(_, Keyword::CONV) => Function::Conv,
891 Token::Ident(_, Keyword::COS) => Function::Cos,
892 Token::Ident(_, Keyword::COT) => Function::Cot,
893 Token::Ident(_, Keyword::CRC32) => Function::Crc32,
894 Token::Ident(_, Keyword::DEGREES) => Function::Degrees,
895 Token::Ident(_, Keyword::EXP) => Function::Exp,
896 Token::Ident(_, Keyword::FLOOR) => Function::Floor,
897 Token::Ident(_, Keyword::GREATEST) => Function::Greatest,
898 Token::Ident(_, Keyword::LN) => Function::Ln,
899 Token::Ident(_, Keyword::LOG) => Function::Log,
900 Token::Ident(_, Keyword::LOG10) => Function::Log10,
901 Token::Ident(_, Keyword::LOG2) => Function::Log2,
902 Token::Ident(_, Keyword::MOD) => Function::Mod,
903 Token::Ident(_, Keyword::OCT) => Function::Oct,
904 Token::Ident(_, Keyword::PI) => Function::Pi,
905 Token::Ident(_, Keyword::POW | Keyword::POWER) => Function::Pow,
906 Token::Ident(_, Keyword::RADIANS) => Function::Radians,
907 Token::Ident(_, Keyword::RAND) => Function::Rand,
908 Token::Ident(_, Keyword::ROUND) => Function::Round,
909 Token::Ident(_, Keyword::SIGN) => Function::Sign,
910 Token::Ident(_, Keyword::SIN) => Function::Sin,
911 Token::Ident(_, Keyword::SQRT) => Function::Sqrt,
912 Token::Ident(_, Keyword::TAN) => Function::Tan,
913 Token::Ident(_, Keyword::TRUNCATE) => Function::Truncate,
914 Token::Ident(_, Keyword::CRC32C) => Function::Crc32c,
915 Token::Ident(_, Keyword::LEAST) => Function::Least,
916
917 Token::Ident(_, Keyword::ADDDATE) => Function::AddDate,
919 Token::Ident(_, Keyword::ADDTIME) => Function::AddTime,
920 Token::Ident(_, Keyword::CONVERT_TZ) => Function::ConvertTz,
921 Token::Ident(_, Keyword::CURDATE) => Function::CurDate,
922 Token::Ident(_, Keyword::CURRENT_DATE) => Function::CurDate,
923 Token::Ident(_, Keyword::CURRENT_TIME) => Function::CurTime,
924 Token::Ident(_, Keyword::CURTIME) => Function::CurTime,
925 Token::Ident(_, Keyword::DATE) => Function::Date,
926 Token::Ident(_, Keyword::HOUR) => Function::Hour,
927 Token::Ident(_, Keyword::DATEDIFF) => Function::DateDiff,
928 Token::Ident(_, Keyword::DATE_ADD) => Function::AddDate,
929 Token::Ident(_, Keyword::DATE_FORMAT) => Function::DateFormat,
930 Token::Ident(_, Keyword::DATE_SUB) => Function::DateSub,
931 Token::Ident(_, Keyword::DAY | Keyword::DAYOFMONTH) => Function::DayOfMonth,
932 Token::Ident(_, Keyword::DAYNAME) => Function::DayName,
933 Token::Ident(_, Keyword::DAYOFWEEK) => Function::DayOfWeek,
934 Token::Ident(_, Keyword::DAYOFYEAR) => Function::DayOfYear,
935 Token::Ident(_, Keyword::FROM_DAYS) => Function::FromDays,
936 Token::Ident(_, Keyword::CURRENT_TIMESTAMP) => Function::CurrentTimestamp,
937 Token::Ident(_, Keyword::LOCALTIME | Keyword::LOCALTIMESTAMP | Keyword::NOW) => {
938 Function::Now
939 }
940 Token::Ident(_, Keyword::MAKEDATE) => Function::MakeDate,
941 Token::Ident(_, Keyword::MAKETIME) => Function::MakeTime,
942 Token::Ident(_, Keyword::MICROSECOND) => Function::MicroSecond,
943 Token::Ident(_, Keyword::MINUTE) => Function::Minute,
944 Token::Ident(_, Keyword::MONTH) => Function::Month,
945 Token::Ident(_, Keyword::MONTHNAME) => Function::MonthName,
946 Token::Ident(_, Keyword::PERIOD_ADD) => Function::PeriodAdd,
947 Token::Ident(_, Keyword::PERIOD_DIFF) => Function::PeriodDiff,
948 Token::Ident(_, Keyword::QUARTER) => Function::Quarter,
949 Token::Ident(_, Keyword::SECOND) => Function::Second,
950 Token::Ident(_, Keyword::SEC_TO_TIME) => Function::SecToTime,
951 Token::Ident(_, Keyword::STR_TO_DATE) => Function::StrToDate,
952 Token::Ident(_, Keyword::SUBDATE) => Function::DateSub,
953 Token::Ident(_, Keyword::SUBTIME) => Function::SubTime,
954 Token::Ident(_, Keyword::TIME) => Function::Time,
955 Token::Ident(_, Keyword::LAST_DAY) => Function::LastDay,
956 Token::Ident(_, Keyword::TIMEDIFF) => Function::TimeDiff,
957 Token::Ident(_, Keyword::TIMESTAMP) => Function::Timestamp,
958 Token::Ident(_, Keyword::TIME_FORMAT) => Function::TimeFormat,
959 Token::Ident(_, Keyword::TIME_TO_SEC) => Function::TimeToSec,
960 Token::Ident(_, Keyword::TO_DAYS) => Function::ToDays,
961 Token::Ident(_, Keyword::TO_SECONDS) => Function::ToSeconds,
962 Token::Ident(_, Keyword::UNIX_TIMESTAMP) => Function::UnixTimestamp,
963 Token::Ident(_, Keyword::UTC_DATE) => Function::UtcDate,
964 Token::Ident(_, Keyword::UTC_TIME) => Function::UtcTime,
965 Token::Ident(_, Keyword::UTC_TIMESTAMP) => Function::UtcTimeStamp,
966 Token::Ident(_, Keyword::WEEK) => Function::Week,
967 Token::Ident(_, Keyword::WEEKDAY) => Function::Weekday,
968 Token::Ident(_, Keyword::WEEKOFYEAR) => Function::WeekOfYear,
969 Token::Ident(_, Keyword::ADD_MONTHS) => Function::AddMonths,
970 Token::Ident(_, Keyword::FROM_UNIXTIME) => Function::FromUnixTime,
971 Token::Ident(_, Keyword::YEAR) => Function::Year,
972 Token::Ident(_, Keyword::YEARWEEK) => Function::YearWeek,
973 Token::Ident(_, Keyword::SYSDATE) => Function::SysDate,
974
975 Token::Ident(_, Keyword::JSON_ARRAY) => Function::JsonArray,
977 Token::Ident(_, Keyword::JSON_ARRAYAGG) => Function::JsonArrayAgg,
978 Token::Ident(_, Keyword::JSON_ARRAY_APPEND) => Function::JsonArrayAppend,
979 Token::Ident(_, Keyword::JSON_ARRAY_INSERT) => Function::JsonArrayInsert,
980 Token::Ident(_, Keyword::JSON_ARRAY_INTERSECT) => Function::JsonArrayIntersect,
981 Token::Ident(_, Keyword::JSON_COMPACT) => Function::JsonCompact,
982 Token::Ident(_, Keyword::JSON_CONTAINS) => Function::JsonContains,
983 Token::Ident(_, Keyword::JSON_CONTAINS_PATH) => Function::JsonContainsPath,
984 Token::Ident(_, Keyword::JSON_DEPTH) => Function::JsonDepth,
985 Token::Ident(_, Keyword::JSON_DETAILED) => Function::JsonDetailed,
986 Token::Ident(_, Keyword::JSON_EQUALS) => Function::JsonEquals,
987 Token::Ident(_, Keyword::JSON_EXISTS) => Function::JsonExists,
988 Token::Ident(_, Keyword::JSON_EXTRACT) => Function::JsonExtract,
989 Token::Ident(_, Keyword::JSON_INSERT) => Function::JsonInsert,
990 Token::Ident(_, Keyword::JSON_KEYS) => Function::JsonKeys,
991 Token::Ident(_, Keyword::JSON_LENGTH) => Function::JsonLength,
992 Token::Ident(_, Keyword::JSON_LOOSE) => Function::JsonLoose,
993 Token::Ident(_, Keyword::JSON_MERGE) => Function::JsonMerge,
994 Token::Ident(_, Keyword::JSON_MERGE_PATCH) => Function::JsonMergePath,
995 Token::Ident(_, Keyword::JSON_MERGE_PRESERVE) => Function::JsonMergePerserve,
996 Token::Ident(_, Keyword::JSON_NORMALIZE) => Function::JsonNormalize,
997 Token::Ident(_, Keyword::JSON_OBJECT) => Function::JsonObject,
998 Token::Ident(_, Keyword::JSON_OBJECT_FILTER_KEYS) => Function::JsonObjectFilterKeys,
999 Token::Ident(_, Keyword::JSON_OBJECT_TO_ARRAY) => Function::JsonObjectToArray,
1000 Token::Ident(_, Keyword::JSON_OBJECTAGG) => Function::JsonObjectAgg,
1001 Token::Ident(_, Keyword::JSON_OVERLAPS) => Function::JsonOverlaps,
1002 Token::Ident(_, Keyword::JSON_PRETTY) => Function::JsonPretty,
1003 Token::Ident(_, Keyword::JSON_QUERY) => Function::JsonQuery,
1004 Token::Ident(_, Keyword::JSON_QUOTE) => Function::JsonQuote,
1005 Token::Ident(_, Keyword::JSON_REMOVE) => Function::JsonRemove,
1006 Token::Ident(_, Keyword::JSON_REPLACE) => Function::JsonReplace,
1007 Token::Ident(_, Keyword::JSON_SCHEMA_VALID) => Function::JsonSchemaValid,
1008 Token::Ident(_, Keyword::JSON_SEARCH) => Function::JsonSearch,
1009 Token::Ident(_, Keyword::JSON_SET) => Function::JsonSet,
1010 Token::Ident(_, Keyword::JSON_TABLE) => Function::JsonTable,
1011 Token::Ident(_, Keyword::JSON_TYPE) => Function::JsonType,
1012 Token::Ident(_, Keyword::JSON_UNQUOTE) => Function::JsonUnquote,
1013 Token::Ident(_, Keyword::JSON_VALID) => Function::JsonValid,
1014 Token::Ident(_, Keyword::JSON_VALUE) => Function::JsonValue,
1015
1016 Token::Ident(_, Keyword::STRFTIME) => Function::Strftime,
1018 Token::Ident(_, Keyword::DATETIME) => Function::Datetime,
1019
1020 Token::Ident(_, Keyword::AES_DECRYPT) => Function::AesDecrypt,
1022 Token::Ident(_, Keyword::AES_ENCRYPT) => Function::AesEncrypt,
1023 Token::Ident(_, Keyword::COMPRESS) => Function::Compress,
1024 Token::Ident(_, Keyword::MD5) => Function::Md5,
1025 Token::Ident(_, Keyword::RANDOM_BYTES) => Function::RandomBytes,
1026 Token::Ident(_, Keyword::SHA) => Function::Sha,
1027 Token::Ident(_, Keyword::SHA1) => Function::Sha1,
1028 Token::Ident(_, Keyword::SHA2) => Function::Sha2,
1029 Token::Ident(_, Keyword::STATEMENT_DIGEST) => Function::StatementDigest,
1030 Token::Ident(_, Keyword::STATEMENT_DIGEST_TEXT) => Function::StatementDigestText,
1031 Token::Ident(_, Keyword::UNCOMPRESS) => Function::Uncompress,
1032 Token::Ident(_, Keyword::VALIDATE_PASSWORD_STRENGTH) => Function::ValidatePasswordStrength,
1033
1034 Token::Ident(_, Keyword::GET_LOCK) => Function::GetLock,
1036 Token::Ident(_, Keyword::IS_FREE_LOCK) => Function::IsFreeLock,
1037 Token::Ident(_, Keyword::IS_USED_LOCK) => Function::IsUsedLock,
1038 Token::Ident(_, Keyword::RELEASE_ALL_LOCKS) => Function::ReleaseAllLocks,
1039 Token::Ident(_, Keyword::RELEASE_LOCK) => Function::ReleaseLock,
1040
1041 Token::Ident(_, Keyword::BENCHMARK) => Function::Benchmark,
1043 Token::Ident(_, Keyword::CHARSET) => Function::Charset,
1044 Token::Ident(_, Keyword::COERCIBILITY) => Function::Coercibility,
1045 Token::Ident(_, Keyword::COLLATION) => Function::Collation,
1046 Token::Ident(_, Keyword::CONNECTION_ID) => Function::ConnectionId,
1047 Token::Ident(_, Keyword::CURRENT_ROLE) => Function::CurrentRole,
1048 Token::Ident(_, Keyword::CURRENT_USER) => Function::CurrentUser,
1049 Token::Ident(_, Keyword::DATABASE) => Function::DatabaseFunc,
1050 Token::Ident(_, Keyword::FOUND_ROWS) => Function::FoundRows,
1051 Token::Ident(_, Keyword::ICU_VERSION) => Function::IcuVersion,
1052 Token::Ident(_, Keyword::LAST_INSERT_ID) => Function::LastInsertId,
1053 Token::Ident(_, Keyword::ROLES_GRAPHML) => Function::RolesGraphml,
1054 Token::Ident(_, Keyword::ROW_COUNT) => Function::RowCount,
1055 Token::Ident(_, Keyword::SCHEMA) => Function::SchemaFunc,
1056 Token::Ident(_, Keyword::SESSION_USER) => Function::SessionUserFunc,
1057 Token::Ident(_, Keyword::SYSTEM_USER) => Function::SystemUser,
1058 Token::Ident(_, Keyword::USER) => Function::UserFunc,
1059 Token::Ident(_, Keyword::VERSION) => Function::Version,
1060
1061 Token::Ident(_, Keyword::REGEXP_INSTR) => Function::RegexpInstr,
1063 Token::Ident(_, Keyword::REGEXP_LIKE) => Function::RegexpLike,
1064 Token::Ident(_, Keyword::REGEXP_REPLACE) => Function::RegexpReplace,
1065 Token::Ident(_, Keyword::REGEXP_SUBSTR) => Function::RegexpSubstr,
1066 Token::Ident(_, Keyword::WEIGHT_STRING) => Function::WeightString,
1067
1068 Token::Ident(_, Keyword::GET_FORMAT) => Function::GetFormat,
1070
1071 Token::Ident(_, Keyword::FIRST_VALUE) => Function::FirstValue,
1073 Token::Ident(_, Keyword::LAST_VALUE) => Function::LastValue,
1074 Token::Ident(_, Keyword::NTH_VALUE) => Function::NthValue,
1075 Token::Ident(_, Keyword::NTILE) => Function::Ntile,
1076 Token::Ident(_, Keyword::ROW_NUMBER) => Function::RowNumber,
1077
1078 Token::Ident(_, Keyword::FORMAT_BYTES) => Function::FormatBytes,
1080 Token::Ident(_, Keyword::FORMAT_PICO_TIME) => Function::FormatPicoTime,
1081 Token::Ident(_, Keyword::PS_CURRENT_THREAD_ID) => Function::PsCurrentThreadId,
1082 Token::Ident(_, Keyword::PS_THREAD_ID) => Function::PsThreadId,
1083
1084 Token::Ident(_, Keyword::ANY_VALUE) => Function::AnyValue,
1086 Token::Ident(_, Keyword::BIN_TO_UUID) => Function::BinToUuid,
1087 Token::Ident(_, Keyword::BIT_COUNT) => Function::BitCount,
1088 Token::Ident(_, Keyword::GROUPING) => Function::Grouping,
1089 Token::Ident(_, Keyword::INET6_ATON) => Function::Inet6Aton,
1090 Token::Ident(_, Keyword::INET6_NTOA) => Function::Inet6Ntoa,
1091 Token::Ident(_, Keyword::INET_ATON) => Function::InetAton,
1092 Token::Ident(_, Keyword::INET_NTOA) => Function::InetNtoa,
1093 Token::Ident(_, Keyword::IS_IPV4) => Function::IsIPv4,
1094 Token::Ident(_, Keyword::IS_IPV4_COMPAT) => Function::IsIPv4Compat,
1095 Token::Ident(_, Keyword::IS_IPV4_MAPPED) => Function::IsIPv4Mapped,
1096 Token::Ident(_, Keyword::IS_IPV6) => Function::IsIPv6,
1097 Token::Ident(_, Keyword::IS_UUID) => Function::IsUuid,
1098 Token::Ident(_, Keyword::NAME_CONST) => Function::NameConst,
1099 Token::Ident(_, Keyword::UUID) => Function::Uuid,
1100 Token::Ident(_, Keyword::UUID_SHORT) => Function::UuidShort,
1101 Token::Ident(_, Keyword::UUID_TO_BIN) => Function::UuidToBin,
1102
1103 Token::Ident(v, k) if !k.restricted(parser.reserved()) => {
1104 Function::Other(alloc::vec![Identifier {
1105 value: v,
1106 span: span.clone()
1107 }])
1108 }
1109 _ => {
1110 parser.err("Unknown function", &span);
1111 Function::Unknown
1112 }
1113 };
1114
1115 let mut args = Vec::new();
1116
1117 if matches!(func, Function::SubStr) && !matches!(parser.token, Token::RParen) {
1119 let expr = parse_expression_outer(parser)?;
1120 if let Some(_from) = parser.skip_keyword(Keyword::FROM) {
1121 let pos = parse_expression_outer(parser)?;
1122 args.push(expr);
1123 args.push(pos);
1124 if parser.skip_keyword(Keyword::FOR).is_some() {
1125 args.push(parse_expression_outer(parser)?);
1126 }
1127 parser.consume_token(Token::RParen)?;
1128 return Ok(Expression::Function(Box::new(FunctionCallExpression {
1129 function: func,
1130 args,
1131 function_span: span,
1132 })));
1133 } else {
1134 args.push(expr);
1136 while parser.skip_token(Token::Comma).is_some() {
1137 parser.recovered(
1138 "')' or ','",
1139 &|t| matches!(t, Token::RParen | Token::Comma),
1140 |parser| {
1141 args.push(parse_expression_outer(parser)?);
1142 Ok(())
1143 },
1144 )?;
1145 }
1146 parser.consume_token(Token::RParen)?;
1147 if let Some(over) = parse_over_clause(parser)? {
1148 return Ok(Expression::WindowFunction(Box::new(
1149 WindowFunctionCallExpression {
1150 function: func,
1151 args,
1152 function_span: span,
1153 over,
1154 },
1155 )));
1156 }
1157 return Ok(Expression::Function(Box::new(FunctionCallExpression {
1158 function: func,
1159 args,
1160 function_span: span,
1161 })));
1162 }
1163 }
1164
1165 if !matches!(parser.token, Token::RParen) {
1166 loop {
1167 parser.recovered(
1168 "')' or ','",
1169 &|t| matches!(t, Token::RParen | Token::Comma),
1170 |parser| {
1171 args.push(parse_expression_outer(parser)?);
1172 Ok(())
1173 },
1174 )?;
1175 if parser.skip_token(Token::Comma).is_none() {
1176 break;
1177 }
1178 }
1179 }
1180 parser.consume_token(Token::RParen)?;
1181
1182 if let Some(over) = parse_over_clause(parser)? {
1183 Ok(Expression::WindowFunction(Box::new(
1184 WindowFunctionCallExpression {
1185 function: func,
1186 args,
1187 function_span: span,
1188 over,
1189 },
1190 )))
1191 } else {
1192 Ok(Expression::Function(Box::new(FunctionCallExpression {
1193 function: func,
1194 args,
1195 function_span: span,
1196 })))
1197 }
1198}
1199
1200pub(crate) fn parse_char_function<'a>(
1204 parser: &mut Parser<'a, '_>,
1205 char_span: Span,
1206) -> Result<Expression<'a>, ParseError> {
1207 parser.consume_token(Token::LParen)?;
1208 let mut args = Vec::new();
1209 if !matches!(parser.token, Token::RParen) {
1210 loop {
1211 parser.recovered(
1212 "')' or ','",
1213 &|t| {
1214 matches!(
1215 t,
1216 Token::RParen | Token::Comma | Token::Ident(_, Keyword::USING)
1217 )
1218 },
1219 |parser| {
1220 args.push(parse_expression_outer(parser)?);
1221 Ok(())
1222 },
1223 )?;
1224 if parser.skip_token(Token::Comma).is_none() {
1225 break;
1226 }
1227 }
1228 }
1229 let using_charset = if let Some(using_span) = parser.skip_keyword(Keyword::USING) {
1231 let charset = parser.consume_plain_identifier_unreserved()?;
1232 Some((using_span, charset))
1233 } else {
1234 None
1235 };
1236 parser.consume_token(Token::RParen)?;
1237 Ok(Expression::Char(Box::new(CharFunctionExpression {
1238 char_span,
1239 args,
1240 using_charset,
1241 })))
1242}
1243
1244pub(crate) fn parse_function_call<'a>(
1245 parser: &mut Parser<'a, '_>,
1246 func: Function<'a>,
1247 function_span: Span,
1248) -> Result<Expression<'a>, ParseError> {
1249 parser.consume_token(Token::LParen)?;
1250 let mut args = Vec::new();
1251 if !matches!(parser.token, Token::RParen) {
1252 loop {
1253 parser.recovered(
1254 "')' or ','",
1255 &|t| matches!(t, Token::RParen | Token::Comma),
1256 |parser| {
1257 args.push(parse_expression_outer(parser)?);
1258 Ok(())
1259 },
1260 )?;
1261 if parser.skip_token(Token::Comma).is_none() {
1262 break;
1263 }
1264 }
1265 }
1266 parser.consume_token(Token::RParen)?;
1267 if let Some(over) = parse_over_clause(parser)? {
1268 Ok(Expression::WindowFunction(Box::new(
1269 WindowFunctionCallExpression {
1270 function: func,
1271 args,
1272 function_span,
1273 over,
1274 },
1275 )))
1276 } else {
1277 Ok(Expression::Function(Box::new(FunctionCallExpression {
1278 function: func,
1279 args,
1280 function_span,
1281 })))
1282 }
1283}
1284
1285#[cfg(test)]
1286mod tests {
1287 use core::ops::Deref;
1288
1289 use alloc::string::{String, ToString};
1290
1291 use crate::{
1292 Function, FunctionCallExpression, ParseOptions, SQLDialect,
1293 expression::{Expression, PRIORITY_MAX},
1294 issue::Issues,
1295 parser::Parser,
1296 };
1297
1298 use super::parse_expression_unreserved;
1299
1300 fn test_expr(src: &'static str, f: impl FnOnce(&Expression<'_>) -> Result<(), String>) {
1301 let mut issues = Issues::new(src);
1302 let options = ParseOptions::new().dialect(SQLDialect::MariaDB);
1303 let mut parser = Parser::new(src, &mut issues, &options);
1304 let res = parse_expression_unreserved(&mut parser, PRIORITY_MAX)
1305 .expect("Expression in test expr");
1306 if let Err(e) = f(&res) {
1307 panic!("Error parsing {}: {}\nGot {:#?}", src, e, res);
1308 }
1309 }
1310
1311 #[test]
1312 fn mariadb_datetime_functions() {
1313 fn test_func(src: &'static str, f: Function, cnt: usize) {
1314 let mut issues = Issues::new(src);
1315 let options = ParseOptions::new().dialect(SQLDialect::MariaDB);
1316 let mut parser = Parser::new(src, &mut issues, &options);
1317 let res = match parse_expression_unreserved(&mut parser, PRIORITY_MAX) {
1318 Ok(res) => res,
1319 Err(e) => panic!("Unable to parse {}: {:?}", src, e),
1320 };
1321 let Expression::Function(r) = res else {
1322 panic!("Should be parsed as function {}", src);
1323 };
1324 let FunctionCallExpression {
1325 function: pf, args, ..
1326 } = r.deref();
1327 assert_eq!(pf, &f, "Failure en expr {}", src);
1328 assert_eq!(args.len(), cnt, "Failure en expr {}", src);
1329 }
1330 test_func("ADD_MONTHS('2012-01-31', 2)", Function::AddMonths, 2);
1331 test_func(
1332 "ADDTIME('2007-12-31 23:59:59.999999', '1 1:1:1.000002')",
1333 Function::AddTime,
1334 2,
1335 );
1336 test_func(
1337 "DATE_ADD('2008-01-02', INTERVAL 31 DAY)",
1338 Function::AddDate,
1339 2,
1340 );
1341 test_func(
1342 "ADDDATE('2008-01-02', INTERVAL 31 DAY)",
1343 Function::AddDate,
1344 2,
1345 );
1346 test_func("ADDDATE('2008-01-02', 31)", Function::AddDate, 2);
1347 test_func(
1348 "CONVERT_TZ('2016-01-01 12:00:00','+00:00','+10:00')",
1349 Function::ConvertTz,
1350 3,
1351 );
1352 test_func("CURDATE()", Function::CurDate, 0);
1353 test_func("CURRENT_DATE", Function::CurDate, 0);
1354 test_func("CURRENT_DATE()", Function::CurDate, 0);
1355 test_func("CURRENT_TIME", Function::CurTime, 0);
1356 test_func("CURRENT_TIME()", Function::CurTime, 0);
1357 test_func("CURTIME()", Function::CurTime, 0);
1358 test_func("CURTIME(2)", Function::CurTime, 1);
1359 test_func("CURRENT_DATE", Function::CurDate, 0);
1360 test_func("CURRENT_DATE()", Function::CurDate, 0);
1361 test_func("CURDATE()", Function::CurDate, 0);
1362 test_func("CURRENT_TIMESTAMP", Function::CurrentTimestamp, 0);
1363 test_func("CURRENT_TIMESTAMP()", Function::CurrentTimestamp, 0);
1364 test_func("CURRENT_TIMESTAMP(10)", Function::CurrentTimestamp, 1);
1365 test_func("LOCALTIME", Function::Now, 0);
1366 test_func("LOCALTIME()", Function::Now, 0);
1367 test_func("LOCALTIME(10)", Function::Now, 1);
1368 test_func("LOCALTIMESTAMP", Function::Now, 0);
1369 test_func("LOCALTIMESTAMP()", Function::Now, 0);
1370 test_func("LOCALTIMESTAMP(10)", Function::Now, 1);
1371 test_func("DATE('2013-07-18 12:21:32')", Function::Date, 1);
1372 test_func(
1373 "DATE_FORMAT('2009-10-04 22:23:00', '%W %M %Y')",
1374 Function::DateFormat,
1375 2,
1376 );
1377 test_func(
1378 "DATE_SUB('1998-01-02', INTERVAL 31 DAY)",
1379 Function::DateSub,
1380 2,
1381 );
1382 test_func("DAY('2007-02-03')", Function::DayOfMonth, 1);
1383 test_func("DAYOFMONTH('2007-02-03')", Function::DayOfMonth, 1);
1384 test_func(
1385 "DATEDIFF('2007-12-31 23:59:59','2007-12-30')",
1386 Function::DateDiff,
1387 2,
1388 );
1389 test_func("DAYNAME('2007-02-03')", Function::DayName, 1);
1390 test_func("DAYOFYEAR('2018-02-16')", Function::DayOfYear, 1);
1391 test_func("DAYOFWEEK('2007-02-03')", Function::DayOfWeek, 1);
1392 test_expr("EXTRACT(YEAR_MONTH FROM '2009-07-02 01:02:03')", |e| {
1393 let Expression::Extract { .. } = e else {
1394 return Err("Wrong type".to_string());
1395 };
1396 Ok(())
1397 });
1398 test_func("FROM_DAYS(730669)", Function::FromDays, 1);
1400 test_func("FROM_UNIXTIME(1196440219)", Function::FromUnixTime, 1);
1401 test_func(
1402 "FROM_UNIXTIME(UNIX_TIMESTAMP(), '%Y %D %M %h:%i:%s %x')",
1403 Function::FromUnixTime,
1404 2,
1405 );
1406 test_func("HOUR('10:05:03')", Function::Hour, 1);
1408 test_func("LAST_DAY('2004-01-01 01:01:01')", Function::LastDay, 1);
1409 test_func("MAKEDATE(2011,31)", Function::MakeDate, 2);
1410 test_func("MAKETIME(-13,57,33)", Function::MakeTime, 3);
1411 test_func("MICROSECOND('12:00:00.123456')", Function::MicroSecond, 1);
1412 test_func("MINUTE('2013-08-03 11:04:03')", Function::Minute, 1);
1413 test_func("MONTH('2019-01-03')", Function::Month, 1);
1414 test_func("MONTHNAME('2019-02-03')", Function::MonthName, 1);
1415 test_func("PERIOD_ADD(200801,2)", Function::PeriodAdd, 2);
1416 test_func("PERIOD_DIFF(200802,200703)", Function::PeriodDiff, 2);
1417 test_func("QUARTER('2008-04-01')", Function::Quarter, 1);
1418 test_func("SEC_TO_TIME(12414)", Function::SecToTime, 1);
1419 test_func("SECOND('10:05:03')", Function::Second, 1);
1420 test_func(
1421 "STR_TO_DATE('Wednesday, June 2, 2014', '%W, %M %e, %Y')",
1422 Function::StrToDate,
1423 2,
1424 );
1425 test_func(
1426 "DATE_SUB('2008-01-02', INTERVAL 31 DAY)",
1427 Function::DateSub,
1428 2,
1429 );
1430 test_func("SUBDATE('2008-01-02 12:00:00', 31)", Function::DateSub, 2);
1431 test_func(
1432 "SUBDATE('2008-01-02', INTERVAL 31 DAY)",
1433 Function::DateSub,
1434 2,
1435 );
1436 test_func(
1437 "SUBTIME('2007-12-31 23:59:59.999999','1 1:1:1.000002')",
1438 Function::SubTime,
1439 2,
1440 );
1441 test_func("SYSDATE()", Function::SysDate, 0);
1442 test_func("SYSDATE(4)", Function::SysDate, 1);
1443 test_func("TIME('2003-12-31 01:02:03')", Function::Time, 1);
1444 test_func(
1445 "TIME_FORMAT('100:00:00', '%H %k %h %I %l')",
1446 Function::TimeFormat,
1447 2,
1448 );
1449 test_func("TIME_TO_SEC('22:23:00')", Function::TimeToSec, 1);
1450 test_func(
1451 "TIMEDIFF('2008-12-31 23:59:59.000001', '2008-12-30 01:01:01.000002')",
1452 Function::TimeDiff,
1453 2,
1454 );
1455 test_func("TIMESTAMP('2003-12-31')", Function::Timestamp, 1);
1456 test_func(
1457 "TIMESTAMP('2003-12-31 12:00:00','6:30:00')",
1458 Function::Timestamp,
1459 2,
1460 );
1461 test_expr("TIMESTAMPADD(MINUTE,1,'2003-01-02')", |e| {
1462 let Expression::TimestampAdd { .. } = e else {
1463 return Err("Wrong type".to_string());
1464 };
1465 Ok(())
1466 });
1467 test_expr("TIMESTAMPDIFF(MONTH,'2003-02-01','2003-05-01');", |e| {
1468 let Expression::TimestampDiff { .. } = e else {
1469 return Err("Wrong type".to_string());
1470 };
1471 Ok(())
1472 });
1473 test_func("TO_DAYS('2007-10-07')", Function::ToDays, 1);
1474 test_func("UNIX_TIMESTAMP()", Function::UnixTimestamp, 0);
1475 test_func(
1476 "UNIX_TIMESTAMP('2007-11-30 10:30:19')",
1477 Function::UnixTimestamp,
1478 1,
1479 );
1480 test_func("UTC_DATE", Function::UtcDate, 0);
1481 test_func("UTC_DATE()", Function::UtcDate, 0);
1482 test_func("UTC_TIME", Function::UtcTime, 0);
1483 test_func("UTC_TIME()", Function::UtcTime, 0);
1484 test_func("UTC_TIME(5)", Function::UtcTime, 1);
1485 test_func("UTC_TIMESTAMP", Function::UtcTimeStamp, 0);
1486 test_func("UTC_TIMESTAMP()", Function::UtcTimeStamp, 0);
1487 test_func("UTC_TIMESTAMP(4)", Function::UtcTimeStamp, 1);
1488 test_func("WEEK('2008-02-20')", Function::Week, 1);
1489 test_func("WEEK('2008-02-20',0)", Function::Week, 2);
1490 test_func("WEEKDAY('2008-02-03 22:23:00')", Function::Weekday, 1);
1491 test_func("WEEKOFYEAR('2008-02-20')", Function::WeekOfYear, 1);
1492 test_func("YEAR('1987-01-01')", Function::Year, 1);
1493 test_func("YEARWEEK('1987-01-01')", Function::YearWeek, 1);
1494 test_func("YEARWEEK('1987-01-01',0)", Function::YearWeek, 2);
1495 }
1496}