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 if !matches!(parser.token, Token::RParen) {
1117 loop {
1118 parser.recovered(
1119 "')' or ','",
1120 &|t| matches!(t, Token::RParen | Token::Comma),
1121 |parser| {
1122 args.push(parse_expression_outer(parser)?);
1123 Ok(())
1124 },
1125 )?;
1126 if parser.skip_token(Token::Comma).is_none() {
1127 break;
1128 }
1129 }
1130 }
1131 parser.consume_token(Token::RParen)?;
1132
1133 if let Some(over) = parse_over_clause(parser)? {
1134 Ok(Expression::WindowFunction(Box::new(
1135 WindowFunctionCallExpression {
1136 function: func,
1137 args,
1138 function_span: span,
1139 over,
1140 },
1141 )))
1142 } else {
1143 Ok(Expression::Function(Box::new(FunctionCallExpression {
1144 function: func,
1145 args,
1146 function_span: span,
1147 })))
1148 }
1149}
1150
1151pub(crate) fn parse_char_function<'a>(
1155 parser: &mut Parser<'a, '_>,
1156 char_span: Span,
1157) -> Result<Expression<'a>, ParseError> {
1158 parser.consume_token(Token::LParen)?;
1159 let mut args = Vec::new();
1160 if !matches!(parser.token, Token::RParen) {
1161 loop {
1162 parser.recovered(
1163 "')' or ','",
1164 &|t| {
1165 matches!(
1166 t,
1167 Token::RParen | Token::Comma | Token::Ident(_, Keyword::USING)
1168 )
1169 },
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 let using_charset = if let Some(using_span) = parser.skip_keyword(Keyword::USING) {
1182 let charset = parser.consume_plain_identifier_unreserved()?;
1183 Some((using_span, charset))
1184 } else {
1185 None
1186 };
1187 parser.consume_token(Token::RParen)?;
1188 Ok(Expression::Char(Box::new(CharFunctionExpression {
1189 char_span,
1190 args,
1191 using_charset,
1192 })))
1193}
1194
1195pub(crate) fn parse_function_call<'a>(
1196 parser: &mut Parser<'a, '_>,
1197 func: Function<'a>,
1198 function_span: Span,
1199) -> Result<Expression<'a>, ParseError> {
1200 parser.consume_token(Token::LParen)?;
1201 let mut args = Vec::new();
1202 if !matches!(parser.token, Token::RParen) {
1203 loop {
1204 parser.recovered(
1205 "')' or ','",
1206 &|t| matches!(t, Token::RParen | Token::Comma),
1207 |parser| {
1208 args.push(parse_expression_outer(parser)?);
1209 Ok(())
1210 },
1211 )?;
1212 if parser.skip_token(Token::Comma).is_none() {
1213 break;
1214 }
1215 }
1216 }
1217 parser.consume_token(Token::RParen)?;
1218 if let Some(over) = parse_over_clause(parser)? {
1219 Ok(Expression::WindowFunction(Box::new(
1220 WindowFunctionCallExpression {
1221 function: func,
1222 args,
1223 function_span,
1224 over,
1225 },
1226 )))
1227 } else {
1228 Ok(Expression::Function(Box::new(FunctionCallExpression {
1229 function: func,
1230 args,
1231 function_span,
1232 })))
1233 }
1234}
1235
1236#[cfg(test)]
1237mod tests {
1238 use core::ops::Deref;
1239
1240 use alloc::string::{String, ToString};
1241
1242 use crate::{
1243 Function, FunctionCallExpression, ParseOptions, SQLDialect,
1244 expression::{Expression, PRIORITY_MAX},
1245 issue::Issues,
1246 parser::Parser,
1247 };
1248
1249 use super::parse_expression_unreserved;
1250
1251 fn test_expr(src: &'static str, f: impl FnOnce(&Expression<'_>) -> Result<(), String>) {
1252 let mut issues = Issues::new(src);
1253 let options = ParseOptions::new().dialect(SQLDialect::MariaDB);
1254 let mut parser = Parser::new(src, &mut issues, &options);
1255 let res = parse_expression_unreserved(&mut parser, PRIORITY_MAX)
1256 .expect("Expression in test expr");
1257 if let Err(e) = f(&res) {
1258 panic!("Error parsing {}: {}\nGot {:#?}", src, e, res);
1259 }
1260 }
1261
1262 #[test]
1263 fn mariadb_datetime_functions() {
1264 fn test_func(src: &'static str, f: Function, cnt: usize) {
1265 let mut issues = Issues::new(src);
1266 let options = ParseOptions::new().dialect(SQLDialect::MariaDB);
1267 let mut parser = Parser::new(src, &mut issues, &options);
1268 let res = match parse_expression_unreserved(&mut parser, PRIORITY_MAX) {
1269 Ok(res) => res,
1270 Err(e) => panic!("Unable to parse {}: {:?}", src, e),
1271 };
1272 let Expression::Function(r) = res else {
1273 panic!("Should be parsed as function {}", src);
1274 };
1275 let FunctionCallExpression {
1276 function: pf, args, ..
1277 } = r.deref();
1278 assert_eq!(pf, &f, "Failure en expr {}", src);
1279 assert_eq!(args.len(), cnt, "Failure en expr {}", src);
1280 }
1281 test_func("ADD_MONTHS('2012-01-31', 2)", Function::AddMonths, 2);
1282 test_func(
1283 "ADDTIME('2007-12-31 23:59:59.999999', '1 1:1:1.000002')",
1284 Function::AddTime,
1285 2,
1286 );
1287 test_func(
1288 "DATE_ADD('2008-01-02', INTERVAL 31 DAY)",
1289 Function::AddDate,
1290 2,
1291 );
1292 test_func(
1293 "ADDDATE('2008-01-02', INTERVAL 31 DAY)",
1294 Function::AddDate,
1295 2,
1296 );
1297 test_func("ADDDATE('2008-01-02', 31)", Function::AddDate, 2);
1298 test_func(
1299 "CONVERT_TZ('2016-01-01 12:00:00','+00:00','+10:00')",
1300 Function::ConvertTz,
1301 3,
1302 );
1303 test_func("CURDATE()", Function::CurDate, 0);
1304 test_func("CURRENT_DATE", Function::CurDate, 0);
1305 test_func("CURRENT_DATE()", Function::CurDate, 0);
1306 test_func("CURRENT_TIME", Function::CurTime, 0);
1307 test_func("CURRENT_TIME()", Function::CurTime, 0);
1308 test_func("CURTIME()", Function::CurTime, 0);
1309 test_func("CURTIME(2)", Function::CurTime, 1);
1310 test_func("CURRENT_DATE", Function::CurDate, 0);
1311 test_func("CURRENT_DATE()", Function::CurDate, 0);
1312 test_func("CURDATE()", Function::CurDate, 0);
1313 test_func("CURRENT_TIMESTAMP", Function::CurrentTimestamp, 0);
1314 test_func("CURRENT_TIMESTAMP()", Function::CurrentTimestamp, 0);
1315 test_func("CURRENT_TIMESTAMP(10)", Function::CurrentTimestamp, 1);
1316 test_func("LOCALTIME", Function::Now, 0);
1317 test_func("LOCALTIME()", Function::Now, 0);
1318 test_func("LOCALTIME(10)", Function::Now, 1);
1319 test_func("LOCALTIMESTAMP", Function::Now, 0);
1320 test_func("LOCALTIMESTAMP()", Function::Now, 0);
1321 test_func("LOCALTIMESTAMP(10)", Function::Now, 1);
1322 test_func("DATE('2013-07-18 12:21:32')", Function::Date, 1);
1323 test_func(
1324 "DATE_FORMAT('2009-10-04 22:23:00', '%W %M %Y')",
1325 Function::DateFormat,
1326 2,
1327 );
1328 test_func(
1329 "DATE_SUB('1998-01-02', INTERVAL 31 DAY)",
1330 Function::DateSub,
1331 2,
1332 );
1333 test_func("DAY('2007-02-03')", Function::DayOfMonth, 1);
1334 test_func("DAYOFMONTH('2007-02-03')", Function::DayOfMonth, 1);
1335 test_func(
1336 "DATEDIFF('2007-12-31 23:59:59','2007-12-30')",
1337 Function::DateDiff,
1338 2,
1339 );
1340 test_func("DAYNAME('2007-02-03')", Function::DayName, 1);
1341 test_func("DAYOFYEAR('2018-02-16')", Function::DayOfYear, 1);
1342 test_func("DAYOFWEEK('2007-02-03')", Function::DayOfWeek, 1);
1343 test_expr("EXTRACT(YEAR_MONTH FROM '2009-07-02 01:02:03')", |e| {
1344 let Expression::Extract { .. } = e else {
1345 return Err("Wrong type".to_string());
1346 };
1347 Ok(())
1348 });
1349 test_func("FROM_DAYS(730669)", Function::FromDays, 1);
1351 test_func("FROM_UNIXTIME(1196440219)", Function::FromUnixTime, 1);
1352 test_func(
1353 "FROM_UNIXTIME(UNIX_TIMESTAMP(), '%Y %D %M %h:%i:%s %x')",
1354 Function::FromUnixTime,
1355 2,
1356 );
1357 test_func("HOUR('10:05:03')", Function::Hour, 1);
1359 test_func("LAST_DAY('2004-01-01 01:01:01')", Function::LastDay, 1);
1360 test_func("MAKEDATE(2011,31)", Function::MakeDate, 2);
1361 test_func("MAKETIME(-13,57,33)", Function::MakeTime, 3);
1362 test_func("MICROSECOND('12:00:00.123456')", Function::MicroSecond, 1);
1363 test_func("MINUTE('2013-08-03 11:04:03')", Function::Minute, 1);
1364 test_func("MONTH('2019-01-03')", Function::Month, 1);
1365 test_func("MONTHNAME('2019-02-03')", Function::MonthName, 1);
1366 test_func("PERIOD_ADD(200801,2)", Function::PeriodAdd, 2);
1367 test_func("PERIOD_DIFF(200802,200703)", Function::PeriodDiff, 2);
1368 test_func("QUARTER('2008-04-01')", Function::Quarter, 1);
1369 test_func("SEC_TO_TIME(12414)", Function::SecToTime, 1);
1370 test_func("SECOND('10:05:03')", Function::Second, 1);
1371 test_func(
1372 "STR_TO_DATE('Wednesday, June 2, 2014', '%W, %M %e, %Y')",
1373 Function::StrToDate,
1374 2,
1375 );
1376 test_func(
1377 "DATE_SUB('2008-01-02', INTERVAL 31 DAY)",
1378 Function::DateSub,
1379 2,
1380 );
1381 test_func("SUBDATE('2008-01-02 12:00:00', 31)", Function::DateSub, 2);
1382 test_func(
1383 "SUBDATE('2008-01-02', INTERVAL 31 DAY)",
1384 Function::DateSub,
1385 2,
1386 );
1387 test_func(
1388 "SUBTIME('2007-12-31 23:59:59.999999','1 1:1:1.000002')",
1389 Function::SubTime,
1390 2,
1391 );
1392 test_func("SYSDATE()", Function::SysDate, 0);
1393 test_func("SYSDATE(4)", Function::SysDate, 1);
1394 test_func("TIME('2003-12-31 01:02:03')", Function::Time, 1);
1395 test_func(
1396 "TIME_FORMAT('100:00:00', '%H %k %h %I %l')",
1397 Function::TimeFormat,
1398 2,
1399 );
1400 test_func("TIME_TO_SEC('22:23:00')", Function::TimeToSec, 1);
1401 test_func(
1402 "TIMEDIFF('2008-12-31 23:59:59.000001', '2008-12-30 01:01:01.000002')",
1403 Function::TimeDiff,
1404 2,
1405 );
1406 test_func("TIMESTAMP('2003-12-31')", Function::Timestamp, 1);
1407 test_func(
1408 "TIMESTAMP('2003-12-31 12:00:00','6:30:00')",
1409 Function::Timestamp,
1410 2,
1411 );
1412 test_expr("TIMESTAMPADD(MINUTE,1,'2003-01-02')", |e| {
1413 let Expression::TimestampAdd { .. } = e else {
1414 return Err("Wrong type".to_string());
1415 };
1416 Ok(())
1417 });
1418 test_expr("TIMESTAMPDIFF(MONTH,'2003-02-01','2003-05-01');", |e| {
1419 let Expression::TimestampDiff { .. } = e else {
1420 return Err("Wrong type".to_string());
1421 };
1422 Ok(())
1423 });
1424 test_func("TO_DAYS('2007-10-07')", Function::ToDays, 1);
1425 test_func("UNIX_TIMESTAMP()", Function::UnixTimestamp, 0);
1426 test_func(
1427 "UNIX_TIMESTAMP('2007-11-30 10:30:19')",
1428 Function::UnixTimestamp,
1429 1,
1430 );
1431 test_func("UTC_DATE", Function::UtcDate, 0);
1432 test_func("UTC_DATE()", Function::UtcDate, 0);
1433 test_func("UTC_TIME", Function::UtcTime, 0);
1434 test_func("UTC_TIME()", Function::UtcTime, 0);
1435 test_func("UTC_TIME(5)", Function::UtcTime, 1);
1436 test_func("UTC_TIMESTAMP", Function::UtcTimeStamp, 0);
1437 test_func("UTC_TIMESTAMP()", Function::UtcTimeStamp, 0);
1438 test_func("UTC_TIMESTAMP(4)", Function::UtcTimeStamp, 1);
1439 test_func("WEEK('2008-02-20')", Function::Week, 1);
1440 test_func("WEEK('2008-02-20',0)", Function::Week, 2);
1441 test_func("WEEKDAY('2008-02-03 22:23:00')", Function::Weekday, 1);
1442 test_func("WEEKOFYEAR('2008-02-20')", Function::WeekOfYear, 1);
1443 test_func("YEAR('1987-01-01')", Function::Year, 1);
1444 test_func("YEARWEEK('1987-01-01')", Function::YearWeek, 1);
1445 test_func("YEARWEEK('1987-01-01',0)", Function::YearWeek, 2);
1446 }
1447}