1use ethnum::i256;
16use itertools::Itertools;
17use nom::Parser;
18use nom::combinator::consumed;
19use nom::combinator::verify;
20use nom::error::context;
21use nom_rule::rule;
22use pratt::Affix;
23use pratt::Associativity;
24use pratt::PrattParser;
25use pratt::Precedence;
26
27use crate::Span;
28use crate::ast::quote::AtString;
29use crate::ast::*;
30use crate::parser::Error;
31use crate::parser::ErrorKind;
32use crate::parser::common::*;
33use crate::parser::input::Input;
34use crate::parser::input::WithSpan;
35use crate::parser::query::*;
36use crate::parser::token::*;
37use crate::span::merge_span;
38
39macro_rules! with_span {
40 ($parser:expr_2021) => {
41 map(consumed($parser), |(span, elem)| WithSpan { span, elem })
42 };
43}
44
45pub fn expr(i: Input) -> IResult<Expr> {
46 context("expression", subexpr(0)).parse(i)
47}
48
49pub fn values(i: Input) -> IResult<Vec<Expr>> {
50 let values = comma_separated_list0(expr);
51 map(rule! { ( "(" ~ #values ~ ")" ) }, |(_, v, _)| v).parse(i)
52}
53
54pub fn subexpr(min_precedence: u32) -> impl FnMut(Input) -> IResult<Expr> {
55 move |i| {
56 let higher_prec_expr_element = |i| {
57 expr_element(i).and_then(|(rest, elem)| match elem.elem.affix() {
58 Affix::Infix(prec, _) | Affix::Prefix(prec) | Affix::Postfix(prec)
59 if prec <= Precedence(min_precedence) =>
60 {
61 Err(nom::Err::Error(Error::from_error_kind(
62 i,
63 ErrorKind::Other("expected more tokens for expression"),
64 )))
65 }
66 _ => Ok((rest, elem)),
67 })
68 };
69
70 let (rest, mut expr_elements) = rule! { #higher_prec_expr_element+ }.parse(i)?;
71
72 for (prev, curr) in (-1..(expr_elements.len() as isize)).tuple_windows() {
73 if prev == -1
75 || matches!(
76 expr_elements[prev as usize].elem.affix(),
77 Affix::Prefix(_) | Affix::Infix(_, _)
78 )
79 {
80 let span = expr_elements[curr as usize].span;
81 let elem = &mut expr_elements[curr as usize].elem;
82 match elem {
83 ExprElement::MapAccess {
85 accessor: MapAccessor::Bracket { key },
86 } => {
87 *elem = ExprElement::Array {
88 exprs: vec![(**key).clone()],
89 };
90 }
91 ExprElement::BinaryOp {
93 op: BinaryOperator::Plus,
94 } => {
95 *elem = ExprElement::UnaryOp {
96 op: UnaryOperator::Plus,
97 };
98 }
99 ExprElement::BinaryOp {
100 op: BinaryOperator::Minus,
101 } => {
102 *elem = ExprElement::UnaryOp {
103 op: UnaryOperator::Minus,
104 };
105 }
106 ExprElement::MapAccess {
108 accessor: MapAccessor::Colon { key },
109 } => {
110 if !key.is_quoted() && !key.is_hole() {
111 *elem = ExprElement::Hole {
112 name: key.to_string(),
113 };
114 }
115 }
116 ExprElement::MapAccess {
118 accessor: MapAccessor::DotNumber { .. },
119 } => {
120 *elem = ExprElement::Literal {
121 value: literal(span)?.1,
122 };
123 }
124 ExprElement::JsonOp { op } => {
126 if *op == JsonOperator::Question {
127 *elem = ExprElement::Placeholder;
128 }
129 }
130 _ => {}
131 }
132 }
133 }
134
135 run_pratt_parser(ExprParser, expr_elements, rest, i)
136 }
137}
138
139#[derive(Debug, Clone, PartialEq)]
149#[allow(clippy::large_enum_variant)]
150pub enum ExprElement {
151 ColumnRef {
153 column: ColumnRef,
154 },
155 DotAccess {
157 key: ColumnID,
158 },
159 IsNull {
161 not: bool,
162 },
163 IsDistinctFrom {
165 not: bool,
166 },
167 InList {
169 list: Vec<Expr>,
170 not: bool,
171 },
172 InSubquery {
174 subquery: Box<Query>,
175 not: bool,
176 },
177 LikeSubquery {
179 modifier: SubqueryModifier,
180 subquery: Box<Query>,
181 escape: Option<String>,
182 },
183 Escape {
185 escape: String,
186 },
187 Between {
189 low: Box<Expr>,
190 high: Box<Expr>,
191 not: bool,
192 },
193 BinaryOp {
195 op: BinaryOperator,
196 },
197 JsonOp {
199 op: JsonOperator,
200 },
201 UnaryOp {
203 op: UnaryOperator,
204 },
205 VariableAccess(String),
206 Cast {
208 expr: Box<Expr>,
209 target_type: TypeName,
210 },
211 TryCast {
213 expr: Box<Expr>,
214 target_type: TypeName,
215 },
216 PgCast {
218 target_type: TypeName,
219 },
220 Extract {
222 field: IntervalKind,
223 expr: Box<Expr>,
224 },
225 DatePart {
227 field: IntervalKind,
228 expr: Box<Expr>,
229 },
230 Position {
232 substr_expr: Box<Expr>,
233 str_expr: Box<Expr>,
234 },
235 SubString {
237 expr: Box<Expr>,
238 substring_from: Box<Expr>,
239 substring_for: Option<Box<Expr>>,
240 },
241 Trim {
245 expr: Box<Expr>,
246 trim_where: Option<(TrimWhere, Box<Expr>)>,
248 },
249 Literal {
251 value: Literal,
252 },
253 CountAll {
255 qualified: QualifiedName,
256 window: Option<Window>,
257 },
258 Tuple {
260 exprs: Vec<Expr>,
261 },
262 FunctionCall {
264 func: FunctionCall,
265 },
266 Case {
268 operand: Option<Box<Expr>>,
269 conditions: Vec<Expr>,
270 results: Vec<Expr>,
271 else_result: Option<Box<Expr>>,
272 },
273 Exists {
275 subquery: Query,
276 not: bool,
277 },
278 Subquery {
280 modifier: Option<SubqueryModifier>,
281 subquery: Query,
282 },
283 MapAccess {
285 accessor: MapAccessor,
286 },
287 ChainFunctionCall {
289 name: Identifier,
290 args: Vec<Expr>,
291 lambda: Option<Lambda>,
292 },
293 ListComprehension {
295 source: Expr,
296 param: Identifier,
297 filter: Option<Expr>,
298 result: Expr,
299 },
300 Group(Expr),
302 Array {
304 exprs: Vec<Expr>,
305 },
306 Map {
308 kvs: Vec<(Literal, Expr)>,
309 },
310 Interval {
311 expr: Expr,
312 unit: IntervalKind,
313 },
314 DateAdd {
315 unit: IntervalKind,
316 interval: Expr,
317 date: Expr,
318 },
319 DateDiff {
320 unit: IntervalKind,
321 date_start: Expr,
322 date_end: Expr,
323 },
324 DateBetween {
325 unit: IntervalKind,
326 date_start: Expr,
327 date_end: Expr,
328 },
329 DateSub {
330 unit: IntervalKind,
331 interval: Expr,
332 date: Expr,
333 },
334 DateTrunc {
335 unit: IntervalKind,
336 date: Expr,
337 },
338 TimeSlice {
339 unit: IntervalKind,
340 date: Expr,
341 slice_length: u64,
342 start_or_end: Option<String>,
343 },
344 LastDay {
345 unit: IntervalKind,
346 date: Expr,
347 },
348 PreviousDay {
349 unit: Weekday,
350 date: Expr,
351 },
352 NextDay {
353 unit: Weekday,
354 date: Expr,
355 },
356 Hole {
357 name: String,
358 },
359 Placeholder,
360 StageLocation {
361 location: String,
362 },
363}
364
365pub const BETWEEN_PREC: u32 = 20;
366pub const NOT_PREC: u32 = 15;
367const CHAIN_FUNCTION_AFFIX: Affix = Affix::Postfix(Precedence(61));
368const DOT_ACCESS_AFFIX: Affix = Affix::Postfix(Precedence(60));
369const MAP_ACCESS_AFFIX: Affix = Affix::Postfix(Precedence(60));
370const IS_NULL_AFFIX: Affix = Affix::Postfix(Precedence(17));
371const BETWEEN_AFFIX: Affix = Affix::Postfix(Precedence(BETWEEN_PREC));
372const IS_DISTINCT_FROM_AFFIX: Affix = Affix::Infix(Precedence(BETWEEN_PREC), Associativity::Left);
373const IN_LIST_AFFIX: Affix = Affix::Postfix(Precedence(BETWEEN_PREC));
374const IN_SUBQUERY_AFFIX: Affix = Affix::Postfix(Precedence(BETWEEN_PREC));
375const LIKE_SUBQUERY_AFFIX: Affix = Affix::Postfix(Precedence(BETWEEN_PREC));
376const LIKE_ANY_WITH_ESCAPE_AFFIX: Affix = Affix::Postfix(Precedence(BETWEEN_PREC));
377const LIKE_WITH_ESCAPE_AFFIX: Affix = Affix::Postfix(Precedence(BETWEEN_PREC));
378const ESCAPE_AFFIX: Affix = Affix::Postfix(Precedence(BETWEEN_PREC));
379const JSON_OP_AFFIX: Affix = Affix::Infix(Precedence(40), Associativity::Left);
380const PG_CAST_AFFIX: Affix = Affix::Postfix(Precedence(60));
381
382const fn unary_affix(op: &UnaryOperator) -> Affix {
383 match op {
384 UnaryOperator::Not => Affix::Prefix(Precedence(NOT_PREC)),
385 UnaryOperator::Plus => Affix::Prefix(Precedence(50)),
386 UnaryOperator::Minus => Affix::Prefix(Precedence(50)),
387 UnaryOperator::BitwiseNot => Affix::Prefix(Precedence(50)),
388 UnaryOperator::SquareRoot => Affix::Prefix(Precedence(60)),
389 UnaryOperator::CubeRoot => Affix::Prefix(Precedence(60)),
390 UnaryOperator::Abs => Affix::Prefix(Precedence(60)),
391 UnaryOperator::Factorial => Affix::Postfix(Precedence(60)),
392 }
393}
394
395const fn binary_affix(op: &BinaryOperator) -> Affix {
396 match op {
397 BinaryOperator::Or => Affix::Infix(Precedence(5), Associativity::Left),
398 BinaryOperator::And => Affix::Infix(Precedence(10), Associativity::Left),
399 BinaryOperator::Eq => Affix::Infix(Precedence(20), Associativity::Left),
400 BinaryOperator::NotEq => Affix::Infix(Precedence(20), Associativity::Left),
401 BinaryOperator::Gt => Affix::Infix(Precedence(20), Associativity::Left),
402 BinaryOperator::Lt => Affix::Infix(Precedence(20), Associativity::Left),
403 BinaryOperator::Gte => Affix::Infix(Precedence(20), Associativity::Left),
404 BinaryOperator::Lte => Affix::Infix(Precedence(20), Associativity::Left),
405 BinaryOperator::Like(_) => Affix::Infix(Precedence(20), Associativity::Left),
406 BinaryOperator::LikeAny(_) => Affix::Infix(Precedence(20), Associativity::Left),
407 BinaryOperator::NotLike(_) => Affix::Infix(Precedence(20), Associativity::Left),
408 BinaryOperator::Regexp => Affix::Infix(Precedence(20), Associativity::Left),
409 BinaryOperator::NotRegexp => Affix::Infix(Precedence(20), Associativity::Left),
410 BinaryOperator::RLike => Affix::Infix(Precedence(20), Associativity::Left),
411 BinaryOperator::NotRLike => Affix::Infix(Precedence(20), Associativity::Left),
412 BinaryOperator::SoundsLike => Affix::Infix(Precedence(20), Associativity::Left),
413 BinaryOperator::BitwiseOr => Affix::Infix(Precedence(22), Associativity::Left),
414 BinaryOperator::BitwiseAnd => Affix::Infix(Precedence(22), Associativity::Left),
415 BinaryOperator::BitwiseXor => Affix::Infix(Precedence(22), Associativity::Left),
416 BinaryOperator::CosineDistance => Affix::Infix(Precedence(22), Associativity::Left),
417 BinaryOperator::L1Distance => Affix::Infix(Precedence(22), Associativity::Left),
418 BinaryOperator::L2Distance => Affix::Infix(Precedence(22), Associativity::Left),
419 BinaryOperator::BitwiseShiftLeft => Affix::Infix(Precedence(23), Associativity::Left),
420 BinaryOperator::BitwiseShiftRight => Affix::Infix(Precedence(23), Associativity::Left),
421 BinaryOperator::Xor => Affix::Infix(Precedence(24), Associativity::Left),
422 BinaryOperator::Plus => Affix::Infix(Precedence(30), Associativity::Left),
423 BinaryOperator::Minus => Affix::Infix(Precedence(30), Associativity::Left),
424 BinaryOperator::Multiply => Affix::Infix(Precedence(40), Associativity::Left),
425 BinaryOperator::Div => Affix::Infix(Precedence(40), Associativity::Left),
426 BinaryOperator::Divide => Affix::Infix(Precedence(40), Associativity::Left),
427 BinaryOperator::IntDiv => Affix::Infix(Precedence(40), Associativity::Left),
428 BinaryOperator::Modulo => Affix::Infix(Precedence(40), Associativity::Left),
429 BinaryOperator::StringConcat => Affix::Infix(Precedence(40), Associativity::Left),
430 BinaryOperator::Caret => Affix::Infix(Precedence(40), Associativity::Right),
431 }
432}
433
434impl ExprElement {
435 pub fn affix(&self) -> Affix {
436 match &self {
437 ExprElement::ChainFunctionCall { .. } => CHAIN_FUNCTION_AFFIX,
438 ExprElement::DotAccess { .. } => DOT_ACCESS_AFFIX,
439 ExprElement::MapAccess { .. } => MAP_ACCESS_AFFIX,
440 ExprElement::IsNull { .. } => IS_NULL_AFFIX,
441 ExprElement::Between { .. } => BETWEEN_AFFIX,
442 ExprElement::IsDistinctFrom { .. } => IS_DISTINCT_FROM_AFFIX,
443 ExprElement::InList { .. } => IN_LIST_AFFIX,
444 ExprElement::InSubquery { .. } => IN_SUBQUERY_AFFIX,
445 ExprElement::LikeSubquery { .. } => LIKE_SUBQUERY_AFFIX,
446 ExprElement::Escape { .. } => ESCAPE_AFFIX,
447 ExprElement::UnaryOp { op } => unary_affix(op),
448 ExprElement::BinaryOp { op } => binary_affix(op),
449 ExprElement::JsonOp { .. } => JSON_OP_AFFIX,
450 ExprElement::PgCast { .. } => PG_CAST_AFFIX,
451 ExprElement::ColumnRef { .. } => Affix::Nilfix,
452 ExprElement::Cast { .. } => Affix::Nilfix,
453 ExprElement::TryCast { .. } => Affix::Nilfix,
454 ExprElement::Extract { .. } => Affix::Nilfix,
455 ExprElement::DatePart { .. } => Affix::Nilfix,
456 ExprElement::Position { .. } => Affix::Nilfix,
457 ExprElement::SubString { .. } => Affix::Nilfix,
458 ExprElement::Trim { .. } => Affix::Nilfix,
459 ExprElement::Literal { .. } => Affix::Nilfix,
460 ExprElement::CountAll { .. } => Affix::Nilfix,
461 ExprElement::Tuple { .. } => Affix::Nilfix,
462 ExprElement::FunctionCall { .. } => Affix::Nilfix,
463 ExprElement::Case { .. } => Affix::Nilfix,
464 ExprElement::Exists { .. } => Affix::Nilfix,
465 ExprElement::Subquery { .. } => Affix::Nilfix,
466 ExprElement::ListComprehension { .. } => Affix::Nilfix,
467 ExprElement::Group(_) => Affix::Nilfix,
468 ExprElement::Array { .. } => Affix::Nilfix,
469 ExprElement::Map { .. } => Affix::Nilfix,
470 ExprElement::Interval { .. } => Affix::Nilfix,
471 ExprElement::DateAdd { .. } => Affix::Nilfix,
472 ExprElement::DateDiff { .. } => Affix::Nilfix,
473 ExprElement::DateBetween { .. } => Affix::Nilfix,
474 ExprElement::DateSub { .. } => Affix::Nilfix,
475 ExprElement::DateTrunc { .. } => Affix::Nilfix,
476 ExprElement::TimeSlice { .. } => Affix::Nilfix,
477 ExprElement::LastDay { .. } => Affix::Nilfix,
478 ExprElement::PreviousDay { .. } => Affix::Nilfix,
479 ExprElement::NextDay { .. } => Affix::Nilfix,
480 ExprElement::Hole { .. } => Affix::Nilfix,
481 ExprElement::Placeholder => Affix::Nilfix,
482 ExprElement::VariableAccess { .. } => Affix::Nilfix,
483 ExprElement::StageLocation { .. } => Affix::Nilfix,
484 }
485 }
486}
487
488impl Expr {
489 pub fn affix(&self) -> Affix {
490 match self {
491 Expr::MapAccess { .. } => MAP_ACCESS_AFFIX,
492 Expr::IsNull { .. } => IS_NULL_AFFIX,
493 Expr::Between { .. } => BETWEEN_AFFIX,
494 Expr::IsDistinctFrom { .. } => Affix::Nilfix,
495 Expr::InList { .. } => IN_LIST_AFFIX,
496 Expr::InSubquery { .. } => IN_SUBQUERY_AFFIX,
497 Expr::LikeSubquery { .. } => LIKE_SUBQUERY_AFFIX,
498 Expr::LikeAnyWithEscape { .. } => LIKE_ANY_WITH_ESCAPE_AFFIX,
499 Expr::LikeWithEscape { .. } => LIKE_WITH_ESCAPE_AFFIX,
500 Expr::UnaryOp { op, .. } => unary_affix(op),
501 Expr::BinaryOp { op, .. } => binary_affix(op),
502 Expr::JsonOp { .. } => JSON_OP_AFFIX,
503 Expr::Cast { pg_style: true, .. } => PG_CAST_AFFIX,
504 Expr::Cast {
505 pg_style: false, ..
506 } => Affix::Nilfix,
507 Expr::TryCast { .. } => Affix::Nilfix,
508 Expr::Extract { .. } => Affix::Nilfix,
509 Expr::DatePart { .. } => Affix::Nilfix,
510 Expr::Position { .. } => Affix::Nilfix,
511 Expr::Substring { .. } => Affix::Nilfix,
512 Expr::ColumnRef { .. } => Affix::Nilfix,
513 Expr::Trim { .. } => Affix::Nilfix,
514 Expr::Literal { .. } => Affix::Nilfix,
515 Expr::CountAll { .. } => Affix::Nilfix,
516 Expr::Tuple { .. } => Affix::Nilfix,
517 Expr::FunctionCall { .. } => Affix::Nilfix,
518 Expr::Case { .. } => Affix::Nilfix,
519 Expr::Exists { .. } => Affix::Nilfix,
520 Expr::Subquery { .. } => Affix::Nilfix,
521 Expr::Array { .. } => Affix::Nilfix,
522 Expr::Map { .. } => Affix::Nilfix,
523 Expr::Interval { .. } => Affix::Nilfix,
524 Expr::DateAdd { .. } => Affix::Nilfix,
525 Expr::DateDiff { .. } => Affix::Nilfix,
526 Expr::DateBetween { .. } => Affix::Nilfix,
527 Expr::DateSub { .. } => Affix::Nilfix,
528 Expr::DateTrunc { .. } => Affix::Nilfix,
529 Expr::TimeSlice { .. } => Affix::Nilfix,
530 Expr::LastDay { .. } => Affix::Nilfix,
531 Expr::PreviousDay { .. } => Affix::Nilfix,
532 Expr::NextDay { .. } => Affix::Nilfix,
533 Expr::Hole { .. } => Affix::Nilfix,
534 Expr::Placeholder { .. } => Affix::Nilfix,
535 Expr::StageLocation { .. } => Affix::Nilfix,
536 }
537 }
538}
539
540struct ExprParser;
541
542impl<'a, I: Iterator<Item = WithSpan<'a, ExprElement>>> PrattParser<I> for ExprParser {
543 type Error = &'static str;
544 type Input = WithSpan<'a, ExprElement>;
545 type Output = Expr;
546
547 fn query(&mut self, elem: &WithSpan<ExprElement>) -> Result<Affix, &'static str> {
548 Ok(elem.elem.affix())
549 }
550
551 fn primary(&mut self, elem: WithSpan<'a, ExprElement>) -> Result<Expr, &'static str> {
552 let expr = match elem.elem {
553 ExprElement::ColumnRef { column } => Expr::ColumnRef {
554 span: transform_span(elem.span.tokens),
555 column,
556 },
557 ExprElement::Cast { expr, target_type } => Expr::Cast {
558 span: transform_span(elem.span.tokens),
559 expr,
560 target_type,
561 pg_style: false,
562 },
563 ExprElement::TryCast { expr, target_type } => Expr::TryCast {
564 span: transform_span(elem.span.tokens),
565 expr,
566 target_type,
567 },
568 ExprElement::Extract { field, expr } => Expr::Extract {
569 span: transform_span(elem.span.tokens),
570 kind: field,
571 expr,
572 },
573 ExprElement::DatePart { field, expr } => Expr::DatePart {
574 span: transform_span(elem.span.tokens),
575 kind: field,
576 expr,
577 },
578 ExprElement::Position {
579 substr_expr,
580 str_expr,
581 } => Expr::Position {
582 span: transform_span(elem.span.tokens),
583 substr_expr,
584 str_expr,
585 },
586 ExprElement::SubString {
587 expr,
588 substring_from,
589 substring_for,
590 } => Expr::Substring {
591 span: transform_span(elem.span.tokens),
592 expr,
593 substring_from,
594 substring_for,
595 },
596 ExprElement::Trim { expr, trim_where } => Expr::Trim {
597 span: transform_span(elem.span.tokens),
598 expr,
599 trim_where,
600 },
601 ExprElement::Literal { value } => Expr::Literal {
602 span: transform_span(elem.span.tokens),
603 value,
604 },
605 ExprElement::CountAll { qualified, window } => Expr::CountAll {
606 span: transform_span(elem.span.tokens),
607 qualified,
608 window,
609 },
610 ExprElement::Tuple { exprs } => Expr::Tuple {
611 span: transform_span(elem.span.tokens),
612 exprs,
613 },
614 ExprElement::FunctionCall { func } => Expr::FunctionCall {
615 span: transform_span(elem.span.tokens),
616 func,
617 },
618 ExprElement::Case {
619 operand,
620 conditions,
621 results,
622 else_result,
623 } => Expr::Case {
624 span: transform_span(elem.span.tokens),
625 operand,
626 conditions,
627 results,
628 else_result,
629 },
630 ExprElement::Exists { subquery, not } => Expr::Exists {
631 span: transform_span(elem.span.tokens),
632 not,
633 subquery: Box::new(subquery),
634 },
635 ExprElement::Subquery { subquery, modifier } => Expr::Subquery {
636 span: transform_span(elem.span.tokens),
637 modifier,
638 subquery: Box::new(subquery),
639 },
640 ExprElement::Group(expr) => expr,
641 ExprElement::Array { exprs } => Expr::Array {
642 span: transform_span(elem.span.tokens),
643 exprs,
644 },
645 ExprElement::ListComprehension {
646 source,
647 param,
648 filter,
649 result,
650 } => {
651 let span = transform_span(elem.span.tokens);
652 let mut source = source;
653
654 if let Some(filter) = filter {
656 source = Expr::FunctionCall {
657 span,
658 func: FunctionCall {
659 distinct: false,
660 name: Identifier::from_name(
661 transform_span(elem.span.tokens),
662 "array_filter",
663 ),
664 args: vec![source],
665 params: vec![],
666 order_by: vec![],
667 window: None,
668 lambda: Some(Lambda {
669 params: vec![param.clone()],
670 expr: Box::new(filter),
671 }),
672 },
673 };
674 }
675 Expr::FunctionCall {
677 span,
678 func: FunctionCall {
679 distinct: false,
680 name: Identifier::from_name(transform_span(elem.span.tokens), "array_map"),
681 args: vec![source],
682 params: vec![],
683 order_by: vec![],
684 window: None,
685 lambda: Some(Lambda {
686 params: vec![param.clone()],
687 expr: Box::new(result),
688 }),
689 },
690 }
691 }
692 ExprElement::Map { kvs } => Expr::Map {
693 span: transform_span(elem.span.tokens),
694 kvs,
695 },
696 ExprElement::Interval { expr, unit } => Expr::Interval {
697 span: transform_span(elem.span.tokens),
698 expr: Box::new(expr),
699 unit,
700 },
701 ExprElement::DateAdd {
702 unit,
703 interval,
704 date,
705 } => Expr::DateAdd {
706 span: transform_span(elem.span.tokens),
707 unit,
708 interval: Box::new(interval),
709 date: Box::new(date),
710 },
711 ExprElement::DateDiff {
712 unit,
713 date_start,
714 date_end,
715 } => Expr::DateDiff {
716 span: transform_span(elem.span.tokens),
717 unit,
718 date_start: Box::new(date_start),
719 date_end: Box::new(date_end),
720 },
721 ExprElement::DateBetween {
722 unit,
723 date_start,
724 date_end,
725 } => Expr::DateBetween {
726 span: transform_span(elem.span.tokens),
727 unit,
728 date_start: Box::new(date_start),
729 date_end: Box::new(date_end),
730 },
731 ExprElement::DateSub {
732 unit,
733 interval,
734 date,
735 } => Expr::DateSub {
736 span: transform_span(elem.span.tokens),
737 unit,
738 interval: Box::new(interval),
739 date: Box::new(date),
740 },
741 ExprElement::DateTrunc { unit, date } => Expr::DateTrunc {
742 span: transform_span(elem.span.tokens),
743 unit,
744 date: Box::new(date),
745 },
746 ExprElement::TimeSlice {
747 unit,
748 date,
749 slice_length,
750 start_or_end,
751 } => Expr::TimeSlice {
752 span: transform_span(elem.span.tokens),
753 unit,
754 date: Box::new(date),
755 slice_length,
756 start_or_end: start_or_end.unwrap_or("start".to_string()),
757 },
758 ExprElement::LastDay { unit, date } => Expr::LastDay {
759 span: transform_span(elem.span.tokens),
760 unit,
761 date: Box::new(date),
762 },
763 ExprElement::PreviousDay { unit, date } => Expr::PreviousDay {
764 span: transform_span(elem.span.tokens),
765 unit,
766 date: Box::new(date),
767 },
768 ExprElement::NextDay { unit, date } => Expr::NextDay {
769 span: transform_span(elem.span.tokens),
770 unit,
771 date: Box::new(date),
772 },
773 ExprElement::Hole { name } => Expr::Hole {
774 span: transform_span(elem.span.tokens),
775 name,
776 },
777 ExprElement::Placeholder => Expr::Placeholder {
778 span: transform_span(elem.span.tokens),
779 },
780 ExprElement::VariableAccess(name) => {
781 let span = transform_span(elem.span.tokens);
782 make_func_get_variable(span, name)
783 }
784 ExprElement::StageLocation { location } => Expr::StageLocation {
785 span: transform_span(elem.span.tokens),
786 location,
787 },
788 _ => unreachable!(),
789 };
790 Ok(expr)
791 }
792
793 fn infix(
794 &mut self,
795 lhs: Expr,
796 elem: WithSpan<'a, ExprElement>,
797 rhs: Expr,
798 ) -> Result<Expr, &'static str> {
799 let expr = match elem.elem {
800 ExprElement::BinaryOp { op } => Expr::BinaryOp {
801 span: transform_span(elem.span.tokens),
802 left: Box::new(lhs),
803 right: Box::new(rhs),
804 op,
805 },
806 ExprElement::IsDistinctFrom { not } => Expr::IsDistinctFrom {
807 span: transform_span(elem.span.tokens),
808 left: Box::new(lhs),
809 right: Box::new(rhs),
810 not,
811 },
812 ExprElement::JsonOp { op } => Expr::JsonOp {
813 span: transform_span(elem.span.tokens),
814 left: Box::new(lhs),
815 right: Box::new(rhs),
816 op,
817 },
818 _ => unreachable!(),
819 };
820 Ok(expr)
821 }
822
823 fn prefix(&mut self, elem: WithSpan<'a, ExprElement>, rhs: Expr) -> Result<Expr, &'static str> {
824 match elem.elem {
825 ExprElement::UnaryOp { op } => {
826 let op_span = transform_span(elem.span.tokens);
827 match (op, rhs) {
828 (
829 UnaryOperator::Minus,
830 Expr::Literal {
831 span: rhs_span,
832 value,
833 },
834 ) => {
835 if let Some(value) = try_negate_literal(&value) {
836 Ok(Expr::Literal {
837 span: merge_span(op_span, rhs_span),
838 value,
839 })
840 } else {
841 Ok(Expr::UnaryOp {
842 span: op_span,
843 op: UnaryOperator::Minus,
844 expr: Box::new(Expr::Literal {
845 span: rhs_span,
846 value,
847 }),
848 })
849 }
850 }
851 (op, rhs_expr) => Ok(Expr::UnaryOp {
852 span: op_span,
853 op,
854 expr: Box::new(rhs_expr),
855 }),
856 }
857 }
858 _ => unreachable!(),
859 }
860 }
861
862 fn postfix(
863 &mut self,
864 mut lhs: Expr,
865 elem: WithSpan<'a, ExprElement>,
866 ) -> Result<Expr, &'static str> {
867 let expr = match elem.elem {
868 ExprElement::MapAccess { accessor } => Expr::MapAccess {
869 span: transform_span(elem.span.tokens),
870 expr: Box::new(lhs),
871 accessor,
872 },
873 ExprElement::DotAccess { key } => {
874 if let Expr::ColumnRef { column, .. } = &mut lhs
877 && let ColumnID::Name(name) = &column.column
878 {
879 column.database = column.table.take();
880 column.table = Some(name.clone());
881 column.column = key.clone();
882 return Ok(lhs);
883 }
884
885 match key {
886 ColumnID::Name(id) => Expr::MapAccess {
887 span: transform_span(elem.span.tokens),
888 expr: Box::new(lhs),
889 accessor: MapAccessor::Colon { key: id },
890 },
891 _ => {
892 return Err("dot access position must be after ident");
893 }
894 }
895 }
896 ExprElement::ChainFunctionCall { name, args, lambda } => Expr::FunctionCall {
897 span: transform_span(elem.span.tokens),
898 func: FunctionCall {
899 distinct: false,
900 name,
901 args: [vec![lhs], args].concat(),
902 params: vec![],
903 order_by: vec![],
904 window: None,
905 lambda,
906 },
907 },
908 ExprElement::IsNull { not } => Expr::IsNull {
909 span: transform_span(elem.span.tokens),
910 expr: Box::new(lhs),
911 not,
912 },
913 ExprElement::InList { list, not } => Expr::InList {
914 span: transform_span(elem.span.tokens),
915 expr: Box::new(lhs),
916 list,
917 not,
918 },
919 ExprElement::InSubquery { subquery, not } => Expr::InSubquery {
920 span: transform_span(elem.span.tokens),
921 expr: Box::new(lhs),
922 subquery,
923 not,
924 },
925 ExprElement::LikeSubquery {
926 subquery,
927 modifier,
928 escape,
929 } => Expr::LikeSubquery {
930 span: transform_span(elem.span.tokens),
931 expr: Box::new(lhs),
932 subquery,
933 modifier,
934 escape,
935 },
936 ExprElement::Escape { escape } => match lhs {
937 Expr::BinaryOp {
938 span,
939 op: BinaryOperator::Like(_),
940 left,
941 right,
942 } => Expr::LikeWithEscape {
943 span,
944 left,
945 right,
946 is_not: false,
947 escape,
948 },
949 Expr::BinaryOp {
950 span,
951 op: BinaryOperator::NotLike(_),
952 left,
953 right,
954 } => Expr::LikeWithEscape {
955 span,
956 left,
957 right,
958 is_not: true,
959 escape,
960 },
961 Expr::BinaryOp {
962 span,
963 op: BinaryOperator::LikeAny(_),
964 left,
965 right,
966 } => Expr::LikeAnyWithEscape {
967 span,
968 left,
969 right,
970 escape,
971 },
972 _ => return Err("escape clause must be after LIKE/NOT LIKE/LIKE ANY binary expr"),
973 },
974 ExprElement::Between { low, high, not } => Expr::Between {
975 span: transform_span(elem.span.tokens),
976 expr: Box::new(lhs),
977 low,
978 high,
979 not,
980 },
981 ExprElement::PgCast { target_type } => Expr::Cast {
982 span: transform_span(elem.span.tokens),
983 expr: Box::new(lhs),
984 target_type,
985 pg_style: true,
986 },
987 ExprElement::UnaryOp { op } => Expr::UnaryOp {
988 span: transform_span(elem.span.tokens),
989 op,
990 expr: Box::new(lhs),
991 },
992 _ => unreachable!(),
993 };
994 Ok(expr)
995 }
996}
997#[allow(unreachable_code)]
998pub fn expr_element(i: Input) -> IResult<WithSpan<ExprElement>> {
999 let column_ref = map(column_id, |column| ExprElement::ColumnRef {
1000 column: ColumnRef {
1001 database: None,
1002 table: None,
1003 column,
1004 },
1005 });
1006 let is_null = map(
1007 rule! {
1008 IS ~ NOT? ~ NULL
1009 },
1010 |(_, opt_not, _)| ExprElement::IsNull {
1011 not: opt_not.is_some(),
1012 },
1013 );
1014 let in_list = map(
1015 rule! {
1016 NOT? ~ IN ~ "(" ~ #comma_separated_list1(subexpr(0)) ~ ^")"
1017 },
1018 |(opt_not, _, _, list, _)| ExprElement::InList {
1019 list,
1020 not: opt_not.is_some(),
1021 },
1022 );
1023 let in_subquery = map(
1024 rule! {
1025 NOT? ~ IN ~ "(" ~ #query ~ ^")"
1026 },
1027 |(opt_not, _, _, subquery, _)| ExprElement::InSubquery {
1028 subquery: Box::new(subquery),
1029 not: opt_not.is_some(),
1030 },
1031 );
1032 let like_subquery = map(
1033 rule! {
1034 LIKE ~ ( ANY | SOME | ALL ) ~ "(" ~ #query ~ ^")" ~ (ESCAPE ~ ^#literal_string)?
1035 },
1036 |(_, m, _, subquery, _, option_escape)| {
1037 let modifier = match m.kind {
1038 ALL => SubqueryModifier::All,
1039 ANY => SubqueryModifier::Any,
1040 SOME => SubqueryModifier::Some,
1041 _ => unreachable!(),
1042 };
1043 ExprElement::LikeSubquery {
1044 modifier,
1045 subquery: Box::new(subquery),
1046 escape: option_escape.map(|(_, escape)| escape),
1047 }
1048 },
1049 );
1050 let escape = map(
1051 rule! {
1052 ESCAPE ~ ^#literal_string
1053 },
1054 |(_, escape)| ExprElement::Escape { escape },
1055 );
1056 let between = map(
1057 rule! {
1058 NOT? ~ BETWEEN ~ ^#subexpr(BETWEEN_PREC) ~ ^AND ~ ^#subexpr(BETWEEN_PREC)
1059 },
1060 |(opt_not, _, low, _, high)| ExprElement::Between {
1061 low: Box::new(low),
1062 high: Box::new(high),
1063 not: opt_not.is_some(),
1064 },
1065 );
1066 let cast = map(
1067 rule! {
1068 ( CAST | TRY_CAST )
1069 ~ "("
1070 ~ ^#subexpr(0)
1071 ~ ^( AS | "," )
1072 ~ ^#type_name
1073 ~ ^")"
1074 },
1075 |(cast, _, expr, _, target_type, _)| {
1076 if cast.kind == CAST {
1077 ExprElement::Cast {
1078 expr: Box::new(expr),
1079 target_type,
1080 }
1081 } else {
1082 ExprElement::TryCast {
1083 expr: Box::new(expr),
1084 target_type,
1085 }
1086 }
1087 },
1088 );
1089 let pg_cast = map(
1090 rule! {
1091 "::" ~ ^#type_name
1092 },
1093 |(_, target_type)| ExprElement::PgCast { target_type },
1094 );
1095 let date_part = map(
1096 rule! {
1097 (DATE_PART | DATEPART) ~ "(" ~ ^#interval_kind ~ "," ~ ^#subexpr(0) ~ ^")"
1098 },
1099 |(_, _, field, _, expr, _)| ExprElement::DatePart {
1100 field,
1101 expr: Box::new(expr),
1102 },
1103 );
1104 let extract = map(
1105 rule! {
1106 EXTRACT ~ "(" ~ ^#interval_kind ~ ^FROM ~ ^#subexpr(0) ~ ^")"
1107 },
1108 |(_, _, field, _, expr, _)| ExprElement::Extract {
1109 field,
1110 expr: Box::new(expr),
1111 },
1112 );
1113 let position = map(
1114 rule! {
1115 POSITION
1116 ~ "("
1117 ~ ^#subexpr(BETWEEN_PREC)
1118 ~ ^IN
1119 ~ ^#subexpr(0)
1120 ~ ^")"
1121 },
1122 |(_, _, substr_expr, _, str_expr, _)| ExprElement::Position {
1123 substr_expr: Box::new(substr_expr),
1124 str_expr: Box::new(str_expr),
1125 },
1126 );
1127 let substring = map(
1128 rule! {
1129 ( SUBSTRING | SUBSTR )
1130 ~ "("
1131 ~ ^#subexpr(0)
1132 ~ ( FROM | "," )
1133 ~ ^#subexpr(0)
1134 ~ ( ( FOR | "," ) ~ ^#subexpr(0) )?
1135 ~ ^")"
1136 },
1137 |(_, _, expr, _, substring_from, opt_substring_for, _)| ExprElement::SubString {
1138 expr: Box::new(expr),
1139 substring_from: Box::new(substring_from),
1140 substring_for: opt_substring_for.map(|(_, expr)| Box::new(expr)),
1141 },
1142 );
1143 let trim_where = alt((
1144 value(TrimWhere::Both, rule! { BOTH }),
1145 value(TrimWhere::Leading, rule! { LEADING }),
1146 value(TrimWhere::Trailing, rule! { TRAILING }),
1147 ));
1148 let trim_from = map(
1149 rule! {
1150 TRIM
1151 ~ "("
1152 ~ #trim_where
1153 ~ ^#subexpr(0)
1154 ~ ^FROM
1155 ~ ^#subexpr(0)
1156 ~ ^")"
1157 },
1158 |(_, _, trim_where, trim_str, _, expr, _)| ExprElement::Trim {
1159 expr: Box::new(expr),
1160 trim_where: Some((trim_where, Box::new(trim_str))),
1161 },
1162 );
1163
1164 let count_all_with_window = map(
1165 rule! {
1166 COUNT ~ "(" ~ ( #ident ~ "." ~ ( #ident ~ "." )? )? ~ "*" ~ ")" ~ ( OVER ~ #window_spec_ident )?
1167 },
1168 |(_, _, res, star, _, window)| match res {
1169 Some((fst, _, Some((snd, _)))) => ExprElement::CountAll {
1170 qualified: vec![
1171 Indirection::Identifier(fst),
1172 Indirection::Identifier(snd),
1173 Indirection::Star(Some(star.span)),
1174 ],
1175 window: window.map(|w| w.1),
1176 },
1177 Some((fst, _, None)) => ExprElement::CountAll {
1178 qualified: vec![
1179 Indirection::Identifier(fst),
1180 Indirection::Star(Some(star.span)),
1181 ],
1182 window: window.map(|w| w.1),
1183 },
1184 None => ExprElement::CountAll {
1185 qualified: vec![Indirection::Star(Some(star.span))],
1186 window: window.map(|w| w.1),
1187 },
1188 },
1189 );
1190
1191 let tuple = map(
1192 rule! {
1193 "(" ~ #comma_separated_list1_ignore_trailing(subexpr(0)) ~ ","? ~ ^")"
1194 },
1195 |(_, mut exprs, opt_trail, _)| {
1196 if exprs.len() == 1 && opt_trail.is_none() {
1197 ExprElement::Group(exprs.remove(0))
1198 } else {
1199 ExprElement::Tuple { exprs }
1200 }
1201 },
1202 );
1203 let subquery = map(
1204 rule! {
1205 ( ANY | SOME | ALL )? ~ "(" ~ #query ~ ^")"
1206 },
1207 |(modifier, _, subquery, _)| {
1208 let modifier = modifier.map(|m| match m.kind {
1209 ALL => SubqueryModifier::All,
1210 ANY => SubqueryModifier::Any,
1211 SOME => SubqueryModifier::Some,
1212 _ => unreachable!(),
1213 });
1214 ExprElement::Subquery { modifier, subquery }
1215 },
1216 );
1217
1218 let case = map(
1219 rule! {
1220 CASE ~ #subexpr(0)?
1221 ~ ( WHEN ~ ^#subexpr(0) ~ ^THEN ~ ^#subexpr(0) )+
1222 ~ ( ELSE ~ ^#subexpr(0) )? ~ ^END
1223 },
1224 |(_, operand, branches, else_result, _)| {
1225 let (conditions, results) = branches
1226 .into_iter()
1227 .map(|(_, cond, _, result)| (cond, result))
1228 .unzip();
1229 let else_result = else_result.map(|(_, result)| result);
1230 ExprElement::Case {
1231 operand: operand.map(Box::new),
1232 conditions,
1233 results,
1234 else_result: else_result.map(Box::new),
1235 }
1236 },
1237 );
1238 let exists = map(
1239 rule! {
1240 NOT? ~ EXISTS ~ "(" ~ ^#query ~ ^")"
1241 },
1242 |(opt_not, _, _, subquery, _)| ExprElement::Exists {
1243 subquery,
1244 not: opt_not.is_some(),
1245 },
1246 );
1247 let binary_op = map(binary_op, |op| ExprElement::BinaryOp { op });
1248 let json_op = map(json_op, |op| ExprElement::JsonOp { op });
1249 let variable_access = map(variable_ident, ExprElement::VariableAccess);
1250
1251 let unary_op = map(unary_op, |op| ExprElement::UnaryOp { op });
1252 let dot_number_map_access = map(map_access_dot_number, |accessor| ExprElement::MapAccess {
1253 accessor,
1254 });
1255 let colon_map_access = map(map_access_colon, |accessor| ExprElement::MapAccess {
1256 accessor,
1257 });
1258 let dot_access = map(
1259 rule! {
1260 "." ~ #column_id
1261 },
1262 |(_, column)| ExprElement::DotAccess { key: column },
1263 );
1264
1265 let chain_function_call = check_experimental_chain_function(
1266 true,
1267 alt((
1268 map(
1269 rule! {
1270 "." ~ #function_name
1271 ~ "(" ~ #ident ~ "->" ~ #subexpr(0) ~ ")"
1272 },
1273 |(_, name, _, param, _, expr, _)| ExprElement::ChainFunctionCall {
1274 name,
1275 args: vec![],
1276 lambda: Some(Lambda {
1277 params: vec![param],
1278 expr: Box::new(expr),
1279 }),
1280 },
1281 ),
1282 map(
1283 rule! {
1284 "." ~ #function_name ~ "(" ~ #comma_separated_list0(subexpr(0)) ~ ^")"
1285 },
1286 |(_, name, _, args, _)| ExprElement::ChainFunctionCall {
1287 name,
1288 args,
1289 lambda: None,
1290 },
1291 ),
1292 )),
1293 );
1294
1295 let list_comprehensions = check_experimental_list_comprehension(
1299 true,
1300 map(
1301 rule! {
1302 "[" ~ #subexpr(0) ~ FOR ~ #ident ~ IN
1303 ~ #subexpr(0) ~ (IF ~ #subexpr(2))? ~ "]"
1304 },
1305 |(_, result, _, param, _, source, opt_filter, _)| {
1306 let filter = opt_filter.map(|(_, filter)| filter);
1307 ExprElement::ListComprehension {
1308 source,
1309 param,
1310 filter,
1311 result,
1312 }
1313 },
1314 ),
1315 );
1316
1317 let literal = map(literal, |value| ExprElement::Literal { value });
1321 let array = map(
1322 rule! {
1326 "[" ~ #comma_separated_list0_ignore_trailing(subexpr(0))? ~ ","? ~ ^"]"
1327 },
1328 |(_, opt_args, _, _)| {
1329 let mut exprs = opt_args.unwrap_or_default();
1330
1331 if exprs.len() == 1 {
1332 let expr = exprs.pop().unwrap();
1333 return ExprElement::MapAccess {
1334 accessor: MapAccessor::Bracket {
1335 key: Box::new(expr),
1336 },
1337 };
1338 }
1339 ExprElement::Array { exprs }
1340 },
1341 );
1342
1343 let map_expr = map(
1344 rule! { "{" ~ #comma_separated_list0(map_element) ~ "}" },
1345 |(_, kvs, _)| ExprElement::Map { kvs },
1346 );
1347
1348 let date_add = map(
1349 rule! {
1350 (DATEADD | DATE_ADD) ~ "(" ~ #interval_kind ~ "," ~ #subexpr(0) ~ "," ~ #subexpr(0) ~ ")"
1351 },
1352 |(_, _, unit, _, interval, _, date, _)| ExprElement::DateAdd {
1353 unit,
1354 interval,
1355 date,
1356 },
1357 );
1358
1359 let date_diff = map(
1360 rule! {
1361 (DATE_DIFF | DATEDIFF) ~ "(" ~ #interval_kind ~ "," ~ #subexpr(0) ~ "," ~ #subexpr(0) ~ ")"
1362 },
1363 |(_, _, unit, _, date_start, _, date_end, _)| ExprElement::DateDiff {
1364 unit,
1365 date_start,
1366 date_end,
1367 },
1368 );
1369
1370 let date_sub = map(
1371 rule! {
1372 (DATESUB | DATE_SUB) ~ "(" ~ #interval_kind ~ "," ~ #subexpr(0) ~ "," ~ #subexpr(0) ~ ")"
1373 },
1374 |(_, _, unit, _, interval, _, date, _)| ExprElement::DateSub {
1375 unit,
1376 interval,
1377 date,
1378 },
1379 );
1380
1381 let date_between = map(
1382 rule! {
1383 (DATEBETWEEN | DATE_BETWEEN) ~ "(" ~ #interval_kind ~ "," ~ #subexpr(0) ~ "," ~ #subexpr(0) ~ ")"
1384 },
1385 |(_, _, unit, _, date_start, _, date_end, _)| ExprElement::DateBetween {
1386 unit,
1387 date_start,
1388 date_end,
1389 },
1390 );
1391
1392 let interval = map(
1393 rule! {
1394 INTERVAL ~ ^#subexpr(0) ~ #interval_kind?
1395 },
1396 |(_, expr, unit)| match unit {
1397 None => ExprElement::Cast {
1398 expr: Box::new(expr),
1399 target_type: TypeName::Interval,
1400 },
1401 Some(unit) => ExprElement::Interval { expr, unit },
1402 },
1403 );
1404
1405 let date_trunc = map(
1406 rule! {
1407 DATE_TRUNC ~ "(" ~ #interval_kind ~ "," ~ #subexpr(0) ~ ")"
1408 },
1409 |(_, _, unit, _, date, _)| ExprElement::DateTrunc { unit, date },
1410 );
1411
1412 let time_slice = map(
1413 rule! {
1414 TIME_SLICE ~ "(" ~ #subexpr(0) ~ "," ~ ^#literal_u64 ~ "," ~ #interval_kind ~ ("," ~ ^#literal_string)? ~ ")"
1415 },
1416 |(_, _, date, _, slice_length, _, unit, opt_start_or_end, _)| ExprElement::TimeSlice {
1417 unit,
1418 date,
1419 slice_length,
1420 start_or_end: opt_start_or_end.map(|(_, start_or_end)| start_or_end),
1421 },
1422 );
1423
1424 let trunc = map(
1425 rule! {
1426 TRUNC ~ "(" ~ (#subexpr(0) ~ "," ~ #interval_kind)? ~ (#subexpr(0) ~ ("," ~ #subexpr(0))?)? ~ ")"
1427 },
1428 |(s, _, opt_date, opt_numeric, _)| match (opt_date, opt_numeric) {
1429 (Some((date, _, unit)), None) => ExprElement::DateTrunc { unit, date },
1430 (None, Some((expr, opt_expr2))) => {
1431 if let Some((_, expr2)) = opt_expr2 {
1432 ExprElement::FunctionCall {
1433 func: FunctionCall {
1434 distinct: false,
1435 name: Identifier::from_name(Some(s.span), "TRUNCATE"),
1436 args: vec![expr, expr2],
1437 ..Default::default()
1438 },
1439 }
1440 } else {
1441 ExprElement::FunctionCall {
1442 func: FunctionCall {
1443 distinct: false,
1444 name: Identifier::from_name(Some(s.span), "TRUNCATE"),
1445 args: vec![expr],
1446 ..Default::default()
1447 },
1448 }
1449 }
1450 }
1451 _ => ExprElement::DateTrunc {
1452 unit: IntervalKind::UnknownIntervalKind,
1453 date: Expr::Literal {
1454 span: None,
1455 value: Literal::Null,
1456 },
1457 },
1458 },
1459 );
1460
1461 let last_day = map(
1462 rule! {
1463 LAST_DAY ~ "(" ~ #subexpr(0) ~ ("," ~ #interval_kind)? ~ ")"
1464 },
1465 |(_, _, date, opt_unit, _)| {
1466 if let Some((_, unit)) = opt_unit {
1467 ExprElement::LastDay { unit, date }
1468 } else {
1469 ExprElement::LastDay {
1470 unit: IntervalKind::Month,
1471 date,
1472 }
1473 }
1474 },
1475 );
1476
1477 let previous_day = map(
1478 rule! {
1479 PREVIOUS_DAY ~ "(" ~ #subexpr(0) ~ "," ~ #weekday ~ ")"
1480 },
1481 |(_, _, date, _, unit, _)| ExprElement::PreviousDay { unit, date },
1482 );
1483
1484 let next_day = map(
1485 rule! {
1486 NEXT_DAY ~ "(" ~ #subexpr(0) ~ "," ~ #weekday ~ ")"
1487 },
1488 |(_, _, date, _, unit, _)| ExprElement::NextDay { unit, date },
1489 );
1490
1491 let date_expr = map(
1492 rule! {
1493 DATE ~ #consumed(literal_string)
1494 },
1495 |(_, (span, date))| ExprElement::Cast {
1496 expr: Box::new(Expr::Literal {
1497 span: transform_span(span.tokens),
1498 value: Literal::String(date),
1499 }),
1500 target_type: TypeName::Date,
1501 },
1502 );
1503
1504 let timestamp_expr = map(
1505 rule! {
1506 TIMESTAMP ~ #consumed(literal_string)
1507 },
1508 |(_, (span, date))| ExprElement::Cast {
1509 expr: Box::new(Expr::Literal {
1510 span: transform_span(span.tokens),
1511 value: Literal::String(date),
1512 }),
1513 target_type: TypeName::Timestamp,
1514 },
1515 );
1516
1517 let timestamp_tz_expr = map(
1518 rule! {
1519 TIMESTAMP_TZ ~ #consumed(literal_string)
1520 },
1521 |(_, (span, date))| ExprElement::Cast {
1522 expr: Box::new(Expr::Literal {
1523 span: transform_span(span.tokens),
1524 value: Literal::String(date),
1525 }),
1526 target_type: TypeName::TimestampTz,
1527 },
1528 );
1529
1530 let is_distinct_from = map(
1531 rule! {
1532 IS ~ NOT? ~ DISTINCT ~ FROM
1533 },
1534 |(_, not, _, _)| ExprElement::IsDistinctFrom { not: not.is_some() },
1535 );
1536
1537 let current_date = map(consumed(rule! { CURRENT_DATE }), |(span, _)| {
1538 ExprElement::FunctionCall {
1539 func: FunctionCall {
1540 distinct: false,
1541 name: Identifier::from_name(transform_span(span.tokens), "current_date"),
1542 args: vec![],
1543 params: vec![],
1544 order_by: vec![],
1545 window: None,
1546 lambda: None,
1547 },
1548 }
1549 });
1550
1551 let current_time = map(consumed(rule! { CURRENT_TIME }), |(span, _)| {
1552 ExprElement::FunctionCall {
1553 func: FunctionCall {
1554 distinct: false,
1555 name: Identifier::from_name(transform_span(span.tokens), "current_time"),
1556 args: vec![],
1557 params: vec![],
1558 order_by: vec![],
1559 window: None,
1560 lambda: None,
1561 },
1562 }
1563 });
1564
1565 let current_timestamp = map(consumed(rule! { CURRENT_TIMESTAMP }), |(span, _)| {
1566 ExprElement::FunctionCall {
1567 func: FunctionCall {
1568 distinct: false,
1569 name: Identifier::from_name(transform_span(span.tokens), "current_timestamp"),
1570 args: vec![],
1571 params: vec![],
1572 order_by: vec![],
1573 window: None,
1574 lambda: None,
1575 },
1576 }
1577 });
1578
1579 let stage_location = map(rule! { #at_string }, |location| {
1580 ExprElement::StageLocation { location }
1581 });
1582 let string = map(literal_string, |literal| ExprElement::Literal {
1583 value: Literal::String(literal),
1584 });
1585 let code_string = map(code_string, |literal| ExprElement::Literal {
1586 value: Literal::String(literal),
1587 });
1588 let boolean = map(literal_bool, |literal| ExprElement::Literal {
1589 value: Literal::Boolean(literal),
1590 });
1591 let null = value(
1592 ExprElement::Literal {
1593 value: Literal::Null,
1594 },
1595 rule! { NULL },
1596 );
1597 let decimal_uint = map_res(
1598 rule! {
1599 LiteralInteger
1600 },
1601 |token| {
1602 Ok(ExprElement::Literal {
1603 value: parse_uint(token.text(), 10).map_err(nom::Err::Failure)?,
1604 })
1605 },
1606 );
1607 let hex_uint = map_res(literal_hex_str, |str| {
1608 Ok(ExprElement::Literal {
1609 value: parse_uint(str, 16).map_err(nom::Err::Failure)?,
1610 })
1611 });
1612 let decimal_float = map_res(
1613 verify(
1614 rule! {
1615 LiteralFloat
1616 },
1617 |token: &Token| !token.text().starts_with('.'),
1618 ),
1619 |token| {
1620 Ok(ExprElement::Literal {
1621 value: parse_float(token.text()).map_err(nom::Err::Failure)?,
1622 })
1623 },
1624 );
1625 let column_position = map(column_position, |column| ExprElement::ColumnRef {
1626 column: ColumnRef {
1627 database: None,
1628 table: None,
1629 column,
1630 },
1631 });
1632 let column_row = map(column_row, |column| ExprElement::ColumnRef {
1633 column: ColumnRef {
1634 database: None,
1635 table: None,
1636 column,
1637 },
1638 });
1639 let column_ident = map(column_ident, |column| ExprElement::ColumnRef {
1640 column: ColumnRef {
1641 database: None,
1642 table: None,
1643 column,
1644 },
1645 });
1646
1647 if i.tokens.first().map(|token| token.kind) == Some(ColumnPosition) {
1648 return with_span!(column_position).parse(i);
1649 }
1650
1651 try_dispatch!(i, true,
1652 IS => with_span!(rule!(#is_null | #is_distinct_from)).parse(i),
1653 NOT => with_span!(rule!(
1654 #in_list
1655 | #in_subquery
1656 | #exists
1657 | #between
1658 | #binary_op
1659 | #unary_op
1660 ))
1661 .parse(i),
1662 IN => with_span!(rule!(#in_list | #in_subquery)).parse(i),
1663 LIKE => with_span!(rule!(#like_subquery | #binary_op)).parse(i),
1664 EXISTS => with_span!(exists).parse(i),
1665 BETWEEN => with_span!(between).parse(i),
1666 CAST | TRY_CAST => with_span!(cast).parse(i),
1667 DoubleColon => with_span!(pg_cast).parse(i),
1668 POSITION => with_span!(position).parse(i),
1669 IDENTIFIER => {
1670 return with_span!(column_ref).parse(i);
1671 },
1672 IdentVariable => with_span!(variable_access).parse(i),
1673 ESCAPE => with_span!(escape).parse(i),
1674 COUNT => with_span!(rule!{ #count_all_with_window | #function_call}).parse(i),
1675 SUBSTRING | SUBSTR => with_span!(substring).parse(i),
1676 TRIM => with_span!(trim_from).parse(i),
1677 CASE => with_span!(case).parse(i),
1678 LParen => with_span!(rule!(#tuple | #subquery)).parse(i),
1679 ANY | SOME | ALL => with_span!(subquery).parse(i),
1680 Dot => {
1681 return with_span!(rule!(#chain_function_call | #dot_access | #dot_number_map_access))
1682 .parse(i);
1683 },
1684 Colon => {
1685 return with_span!(colon_map_access).parse(i);
1686 },
1687 LBracket => {
1688 return with_span!(rule!(
1689 #list_comprehensions | #array
1690 ))
1691 .parse(i);
1692 },
1693 LBrace => with_span!(map_expr).parse(i),
1694 LiteralAtString => with_span!(stage_location).parse(i),
1695 DATEADD | DATE_ADD => with_span!(date_add).parse(i),
1696 DATE_DIFF | DATEDIFF => with_span!(date_diff).parse(i),
1697 DATESUB | DATE_SUB => with_span!(date_sub).parse(i),
1698 DATEBETWEEN | DATE_BETWEEN => with_span!(date_between).parse(i),
1699 DATE_TRUNC => with_span!(date_trunc).parse(i),
1700 TIME_SLICE => with_span!(time_slice).parse(i),
1701 TRUNC => with_span!(trunc).parse(i),
1702 LAST_DAY => with_span!(last_day).parse(i),
1703 PREVIOUS_DAY => with_span!(previous_day).parse(i),
1704 NEXT_DAY => with_span!(next_day).parse(i),
1705 DATE => with_span!(date_expr).parse(i),
1706 TIMESTAMP => with_span!(timestamp_expr).parse(i),
1707 TIMESTAMP_TZ => with_span!(timestamp_tz_expr).parse(i),
1708 INTERVAL => with_span!(interval).parse(i),
1709 DATE_PART | DATEPART => with_span!(date_part).parse(i),
1710 EXTRACT => with_span!(extract).parse(i),
1711 CURRENT_DATE => with_span!(rule!{ #function_call | #current_date }).parse(i),
1712 CURRENT_TIME => with_span!(rule!{ #function_call | #current_time }).parse(i),
1713 CURRENT_TIMESTAMP => with_span!(rule!{ #function_call | #current_timestamp }).parse(i),
1714 Plus
1715 | Minus
1716 | Multiply
1717 | Divide
1718 | IntDiv
1719 | DIV
1720 | Modulo
1721 | StringConcat
1722 | Spaceship
1723 | L1DISTANCE
1724 | L2DISTANCE
1725 | Gt
1726 | Lt
1727 | Gte
1728 | Lte
1729 | Eq
1730 | NotEq
1731 | Caret
1732 | AND
1733 | OR
1734 | XOR
1735 | REGEXP
1736 | RLIKE
1737 | BitWiseOr
1738 | BitWiseAnd
1739 | BitWiseXor
1740 | ShiftLeft
1741 | ShiftRight
1742 | SOUNDS => with_span!(rule!{ #binary_op | #unary_op }).parse(i),
1743 RArrow
1744 | LongRArrow
1745 | HashRArrow
1746 | HashLongRArrow
1747 | Placeholder
1748 | QuestionOr
1749 | QuestionAnd
1750 | AtArrow
1751 | ArrowAt
1752 | AtQuestion
1753 | AtAt
1754 | HashMinus => with_span!(json_op).parse(i),
1755 Factorial | SquareRoot | BitWiseNot | CubeRoot | Abs => with_span!(unary_op).parse(i),
1756 LiteralString => with_span!(string).parse(i),
1757 LiteralCodeString => with_span!(code_string).parse(i),
1758 LiteralInteger => with_span!(decimal_uint).parse(i),
1759 LiteralFloat => with_span!(rule!{ #decimal_float | #dot_number_map_access }).parse(i),
1760 MySQLLiteralHex | PGLiteralHex => with_span!(hex_uint).parse(i),
1761 TRUE | FALSE => with_span!(boolean).parse(i),
1762 NULL => with_span!(null).parse(i),
1763 ROW => with_span!(column_row).parse(i),
1764 );
1765
1766 if i.tokens
1769 .get(1)
1770 .map(|token| token.kind == LParen)
1771 .unwrap_or(false)
1772 {
1773 return with_span!(function_call).parse(i);
1774 }
1775
1776 with_span!(alt((rule!(
1777 #column_ident : "<column>"
1778 | #literal : "<literal>"
1779 ),)))
1780 .parse(i)
1781}
1782
1783#[inline]
1784fn return_op<T>(i: Input, start: usize, op: T) -> IResult<T> {
1785 Ok((i.slice(start..), op))
1786}
1787
1788macro_rules! op_branch {
1789 ($i:ident, $token_0:ident, $($kind:ident => $op:expr_2021),+ $(,)?) => {
1790 match $token_0.kind {
1791 $(
1792 TokenKind::$kind => return return_op($i, 1, $op),
1793 )+
1794 _ => (),
1795 }
1796 };
1797}
1798
1799pub fn unary_op(i: Input) -> IResult<UnaryOperator> {
1800 if let Some(token_0) = i.tokens.first() {
1802 op_branch!(
1803 i, token_0,
1804 NOT => UnaryOperator::Not,
1805 Factorial => UnaryOperator::Factorial,
1806 SquareRoot => UnaryOperator::SquareRoot,
1807 BitWiseNot => UnaryOperator::BitwiseNot,
1808 CubeRoot => UnaryOperator::CubeRoot,
1809 Abs => UnaryOperator::Abs,
1810 );
1811 }
1812 Err(nom::Err::Error(Error::from_error_kind(
1813 i,
1814 ErrorKind::Other("expecting `NOT`, '!', '|/', '~', '||/', '@', or more ..."),
1815 )))
1816}
1817
1818pub fn binary_op(i: Input) -> IResult<BinaryOperator> {
1819 if let Some(token_0) = i.tokens.first() {
1820 op_branch!(
1821 i, token_0,
1822 Plus => BinaryOperator::Plus,
1823 Minus => BinaryOperator::Minus,
1824 Multiply => BinaryOperator::Multiply,
1825 Divide => BinaryOperator::Divide,
1826 IntDiv => BinaryOperator::IntDiv,
1827 DIV => BinaryOperator::Div,
1828 Modulo => BinaryOperator::Modulo,
1829 StringConcat => BinaryOperator::StringConcat,
1830 Spaceship => BinaryOperator::CosineDistance,
1831 L1DISTANCE => BinaryOperator::L1Distance,
1832 L2DISTANCE => BinaryOperator::L2Distance,
1833 Gt => BinaryOperator::Gt,
1834 Lt => BinaryOperator::Lt,
1835 Gte => BinaryOperator::Gte,
1836 Lte => BinaryOperator::Lte,
1837 Eq => BinaryOperator::Eq,
1838 NotEq => BinaryOperator::NotEq,
1839 Caret => BinaryOperator::Caret,
1840 AND => BinaryOperator::And,
1841 OR => BinaryOperator::Or,
1842 XOR => BinaryOperator::Xor,
1843 REGEXP => BinaryOperator::Regexp,
1844 RLIKE => BinaryOperator::RLike,
1845 BitWiseOr => BinaryOperator::BitwiseOr,
1846 BitWiseAnd => BinaryOperator::BitwiseAnd,
1847 BitWiseXor => BinaryOperator::BitwiseXor,
1848 ShiftLeft => BinaryOperator::BitwiseShiftLeft,
1849 ShiftRight => BinaryOperator::BitwiseShiftRight,
1850 );
1851 match token_0.kind {
1852 LIKE => {
1853 return if matches!(i.tokens.get(1).map(|first| first.kind == ANY), Some(true)) {
1854 return_op(i, 2, BinaryOperator::LikeAny(None))
1855 } else {
1856 return_op(i, 1, BinaryOperator::Like(None))
1857 };
1858 }
1859 NOT => match i.tokens.get(1).map(|first| first.kind) {
1860 Some(LIKE) => {
1861 return return_op(i, 2, BinaryOperator::NotLike(None));
1862 }
1863 Some(REGEXP) => {
1864 return return_op(i, 2, BinaryOperator::NotRegexp);
1865 }
1866 Some(RLIKE) => {
1867 return return_op(i, 2, BinaryOperator::NotRLike);
1868 }
1869 _ => (),
1870 },
1871 SOUNDS => {
1872 if let Some(LIKE) = i.tokens.get(1).map(|first| first.kind) {
1873 return return_op(i, 2, BinaryOperator::SoundsLike);
1874 }
1875 }
1876 _ => (),
1877 }
1878 }
1879 Err(nom::Err::Error(Error::from_error_kind(
1880 i,
1881 ErrorKind::Other(
1882 "expecting `IS`, `IN`, `LIKE`, `EXISTS`, `BETWEEN`, `+`, `-`, `*`, `/`, `//`, `DIV`, `%`, `||`, `<=>`, `<+>`, `<->`, `>`, `<`, `>=`, `<=`, `=`, `<>`, `!=`, `^`, `AND`, `OR`, `XOR`, `NOT`, `REGEXP`, `RLIKE`, `SOUNDS`, or more ...",
1883 ),
1884 )))
1885}
1886
1887pub fn json_op(i: Input) -> IResult<JsonOperator> {
1888 if let Some(token_0) = i.tokens.first() {
1889 op_branch!(
1890 i, token_0,
1891 RArrow => JsonOperator::Arrow,
1892 LongRArrow => JsonOperator::LongArrow,
1893 HashRArrow => JsonOperator::HashArrow,
1894 HashLongRArrow => JsonOperator::HashLongArrow,
1895 Placeholder => JsonOperator::Question,
1896 QuestionOr => JsonOperator::QuestionOr,
1897 QuestionAnd => JsonOperator::QuestionAnd,
1898 AtArrow => JsonOperator::AtArrow,
1899 ArrowAt => JsonOperator::ArrowAt,
1900 AtQuestion => JsonOperator::AtQuestion,
1901 AtAt => JsonOperator::AtAt,
1902 HashMinus => JsonOperator::HashMinus,
1903 );
1904 }
1905 Err(nom::Err::Error(Error::from_error_kind(
1906 i,
1907 ErrorKind::Other(
1908 "expecting `->`, '->>', '#>', '#>>', '?', '?|', '?&', '@>', '<@', '@?', '@@', '#-', or more ...",
1909 ),
1910 )))
1911}
1912
1913pub fn literal(i: Input) -> IResult<Literal> {
1914 let mut string = map(literal_string, Literal::String);
1915 let mut code_string = map(code_string, Literal::String);
1916 let mut boolean = map(literal_bool, Literal::Boolean);
1917 let mut null = value(Literal::Null, rule! { NULL });
1918 let mut decimal_uint = map_res(
1919 rule! {
1920 LiteralInteger
1921 },
1922 |token| parse_uint(token.text(), 10).map_err(nom::Err::Failure),
1923 );
1924 let mut hex_uint = map_res(literal_hex_str, |str| {
1925 parse_uint(str, 16).map_err(nom::Err::Failure)
1926 });
1927 let mut decimal_float = map_res(
1928 rule! {
1929 LiteralFloat
1930 },
1931 |token| parse_float(token.text()).map_err(nom::Err::Failure),
1932 );
1933
1934 try_dispatch!(i, true,
1935 LiteralString => string.parse(i),
1936 LiteralCodeString => code_string.parse(i),
1937 LiteralInteger => decimal_uint.parse(i),
1938 LiteralFloat => decimal_float.parse(i),
1939 MySQLLiteralHex | PGLiteralHex => hex_uint(i),
1940 TRUE | FALSE => boolean.parse(i),
1941 NULL => null.parse(i),
1942 );
1943
1944 Err(nom::Err::Error(Error::from_error_kind(
1945 i,
1946 ErrorKind::Other(
1947 "expecting `<LiteralString>`, '<LiteralCodeString>', '<LiteralInteger>', '<LiteralFloat>', 'TRUE', 'FALSE', or more ...",
1948 ),
1949 )))
1950}
1951
1952pub fn literal_hex_str(i: Input<'_>) -> IResult<'_, &str> {
1953 let mysql_hex = map(
1955 rule! {
1956 MySQLLiteralHex
1957 },
1958 |token| &token.text()[2..],
1959 );
1960 let pg_hex = map(
1962 rule! {
1963 PGLiteralHex
1964 },
1965 |token| &token.text()[2..token.text().len() - 1],
1966 );
1967
1968 rule!(
1969 #mysql_hex
1970 | #pg_hex
1971 )
1972 .parse(i)
1973}
1974
1975#[allow(clippy::from_str_radix_10)]
1976pub fn literal_u64(i: Input) -> IResult<u64> {
1977 let decimal = map_res(
1978 rule! {
1979 LiteralInteger
1980 },
1981 |token| u64::from_str_radix(token.text(), 10).map_err(|e| nom::Err::Failure(e.into())),
1982 );
1983 let hex = map_res(literal_hex_str, |lit| {
1984 u64::from_str_radix(lit, 16).map_err(|e| nom::Err::Failure(e.into()))
1985 });
1986
1987 rule!(
1988 #decimal
1989 | #hex
1990 )
1991 .parse(i)
1992}
1993
1994#[allow(clippy::from_str_radix_10)]
1995pub fn literal_i64(i: Input) -> IResult<i64> {
1996 let decimal = map_res(
1997 rule! {
1998 LiteralInteger
1999 },
2000 |token| i64::from_str_radix(token.text(), 10).map_err(|e| nom::Err::Failure(e.into())),
2001 );
2002 let hex = map_res(literal_hex_str, |lit| {
2003 i64::from_str_radix(lit, 16).map_err(|e| nom::Err::Failure(e.into()))
2004 });
2005
2006 rule!(
2007 #decimal
2008 | #hex
2009 )
2010 .parse(i)
2011}
2012
2013pub fn literal_bool(i: Input) -> IResult<bool> {
2014 alt((value(true, rule! { TRUE }), value(false, rule! { FALSE }))).parse(i)
2015}
2016
2017pub fn literal_string(i: Input) -> IResult<String> {
2018 map_res(
2019 rule! {
2020 LiteralString
2021 },
2022 |token| {
2023 let quote::QuotedString(s, quote) = token
2024 .text()
2025 .parse()
2026 .map_err(|_| nom::Err::Failure(ErrorKind::Other("invalid escape or unicode")))?;
2027
2028 if !i.dialect.is_string_quote(quote) {
2029 return Err(nom::Err::Error(ErrorKind::ExpectToken(LiteralString)));
2030 }
2031
2032 Ok(s)
2033 },
2034 )(i)
2035}
2036
2037pub fn literal_string_eq_ignore_case(s: &str) -> impl FnMut(Input) -> IResult<()> + '_ {
2038 move |i| {
2039 map_res(rule! { LiteralString }, |token| {
2040 if token.text()[1..token.text().len() - 1].eq_ignore_ascii_case(s) {
2041 Ok(())
2042 } else {
2043 Err(nom::Err::Error(ErrorKind::ExpectToken(LiteralString)))
2044 }
2045 })(i)
2046 }
2047}
2048
2049pub fn at_string(i: Input) -> IResult<String> {
2050 map_res(rule! { LiteralAtString }, |token| {
2051 let AtString(s) = token
2052 .text()
2053 .parse()
2054 .map_err(|_| nom::Err::Failure(ErrorKind::Other("invalid at string")))?;
2055 Ok(s)
2056 })(i)
2057}
2058
2059pub fn code_string(i: Input) -> IResult<String> {
2060 map_res(rule! { LiteralCodeString }, |token| {
2061 let content = &token.text()[2..token.text().len() - 2];
2062 let trimmed = unindent::unindent(content).trim().to_string();
2063 Ok(trimmed)
2064 })(i)
2065}
2066
2067pub fn nullable(i: Input) -> IResult<bool> {
2068 alt((
2069 value(true, rule! { NULL }),
2070 value(false, rule! { NOT ~ NULL }),
2071 ))
2072 .parse(i)
2073}
2074
2075pub fn type_name(i: Input) -> IResult<TypeName> {
2076 let ty_boolean = value(TypeName::Boolean, rule! { BOOLEAN | BOOL });
2077 let ty_uint8 = value(TypeName::UInt8, rule! { (
2078 #map(rule! { UINT8 ~ ( "(" ~ ^#literal_u64 ~ ^")" )? }, |(t, _)| t) |
2079 #map(rule! { TINYINT ~ ( "(" ~ ^#literal_u64 ~ ^")" )? ~ UNSIGNED }, |(t, _, _)| t)
2080 )
2081 });
2082 let ty_uint16 = value(TypeName::UInt16, rule! { (
2083 #map(rule! { UINT16 ~ ( "(" ~ ^#literal_u64 ~ ^")" )? }, |(t, _)| t) |
2084 #map(rule! { SMALLINT ~ ( "(" ~ ^#literal_u64 ~ ^")" )? ~ UNSIGNED }, |(t, _, _)| t)
2085 )
2086 });
2087 let ty_uint32 = value(TypeName::UInt32, rule! { (
2088 #map(rule! { UINT32 ~ ( "(" ~ ^#literal_u64 ~ ^")" )? }, |(t, _)| t) |
2089 #map(rule! { ( INT | INTEGER ) ~ ( "(" ~ ^#literal_u64 ~ ^")" )? ~ UNSIGNED }, |(t, _, _)| t)
2090 )
2091 });
2092 let ty_uint64 = value(TypeName::UInt64, rule! { (
2093 #map(rule! { ( UINT64 | UNSIGNED) ~ ( "(" ~ ^#literal_u64 ~ ^")" )? }, |(t, _)| t) |
2094 #map(rule! { BIGINT ~ ( "(" ~ ^#literal_u64 ~ ^")" )? ~ UNSIGNED }, |(t, _, _)| t)
2095 )
2096 });
2097 let ty_int8 = value(
2098 TypeName::Int8,
2099 rule! { ( INT8 | TINYINT ) ~ ( "(" ~ ^#literal_u64 ~ ^")" )? },
2100 );
2101 let ty_int16 = value(
2102 TypeName::Int16,
2103 rule! { ( INT16 | SMALLINT ) ~ ( "(" ~ ^#literal_u64 ~ ^")" )? },
2104 );
2105 let ty_int32 = value(
2106 TypeName::Int32,
2107 rule! { ( INT32 | INT | INTEGER ) ~ ( "(" ~ ^#literal_u64 ~ ^")" )? },
2108 );
2109 let ty_int64 = value(
2110 TypeName::Int64,
2111 rule! { ( INT64 | SIGNED | BIGINT ) ~ ( "(" ~ ^#literal_u64 ~ ^")" )? },
2112 );
2113 let ty_float32 = value(TypeName::Float32, rule! { FLOAT32 | FLOAT | REAL });
2114 let ty_float64 = value(
2115 TypeName::Float64,
2116 rule! { (FLOAT64 | DOUBLE) ~ PRECISION? },
2117 );
2118 let ty_decimal = map_res(
2119 rule! { DECIMAL ~ ( "(" ~ #literal_u64 ~ ( "," ~ ^#literal_u64 )? ~ ")" )? },
2120 |(_, opt_precision)| {
2121 let (precision, scale) = match opt_precision {
2122 Some((_, precision, scale, _)) => {
2123 (precision, scale.map(|(_, scale)| scale).unwrap_or(0))
2124 }
2125 None => (18, 3),
2126 };
2127
2128 Ok(TypeName::Decimal {
2129 precision: precision
2130 .try_into()
2131 .map_err(|_| nom::Err::Failure(ErrorKind::Other("precision is too large")))?,
2132 scale: scale
2133 .try_into()
2134 .map_err(|_| nom::Err::Failure(ErrorKind::Other("scale is too large")))?,
2135 })
2136 },
2137 );
2138 let ty_numeric = value(
2139 TypeName::Decimal {
2140 precision: 18,
2141 scale: 3,
2142 },
2143 rule! { NUMERIC },
2144 );
2145
2146 let ty_array = map(
2147 rule! { ARRAY ~ "(" ~ #type_name ~ ")" },
2148 |(_, _, item_type, _)| TypeName::Array(Box::new(item_type)),
2149 );
2150 let ty_map = map(
2151 rule! { MAP ~ "(" ~ #type_name ~ "," ~ #type_name ~ ")" },
2152 |(_, _, key_type, _, val_type, _)| TypeName::Map {
2153 key_type: Box::new(key_type),
2154 val_type: Box::new(val_type),
2155 },
2156 );
2157 let ty_bitmap = value(TypeName::Bitmap, rule! { BITMAP });
2158 let ty_nullable = map(
2159 rule! { NULLABLE ~ ( "(" ~ #type_name ~ ")" ) },
2160 |(_, item_type)| TypeName::Nullable(Box::new(item_type.1)),
2161 );
2162 let ty_tuple = map(
2163 rule! { TUPLE ~ "(" ~ #comma_separated_list1(type_name) ~ ")" },
2164 |(_, _, fields_type, _)| TypeName::Tuple {
2165 fields_name: None,
2166 fields_type,
2167 },
2168 );
2169 let ty_named_tuple = map_res(
2170 rule! { TUPLE ~ "(" ~ #comma_separated_list1(rule! { #ident ~ #type_name }) ~ ")" },
2171 |(_, _, fields, _)| {
2172 let (fields_name, fields_type): (Vec<Identifier>, Vec<TypeName>) =
2173 fields.into_iter().unzip();
2174 Ok(TypeName::Tuple {
2175 fields_name: Some(fields_name),
2176 fields_type,
2177 })
2178 },
2179 );
2180 let ty_date = value(TypeName::Date, rule! { DATE });
2181 let ty_interval = value(TypeName::Interval, rule! { INTERVAL });
2182 let ty_datetime = map(
2183 rule! { ( DATETIME | TIMESTAMP ) ~ ( "(" ~ ^#literal_u64 ~ ^")" )? },
2184 |(_, _)| TypeName::Timestamp,
2185 );
2186 let ty_binary = value(
2187 TypeName::Binary,
2188 rule! { ( BINARY | VARBINARY | LONGBLOB | MEDIUMBLOB | TINYBLOB | BLOB ) ~ ( "(" ~ ^#literal_u64 ~ ^")" )? },
2189 );
2190 let ty_string = value(
2191 TypeName::String,
2192 rule! { ( STRING | VARCHAR | CHAR | CHARACTER | TEXT ) ~ ( "(" ~ ^#literal_u64 ~ ^")" )? },
2193 );
2194 let ty_variant = value(TypeName::Variant, rule! { VARIANT | JSON });
2195 let ty_geometry = value(TypeName::Geometry, rule! { GEOMETRY });
2196 let ty_geography = value(TypeName::Geography, rule! { GEOGRAPHY });
2197 let ty_vector = map(
2198 rule! { VECTOR ~ ^"(" ~ ^#literal_u64 ~ ^")" },
2199 |(_, _, dimension, _)| TypeName::Vector(dimension),
2200 );
2201 let ty_stage_location = value(TypeName::StageLocation, rule! { STAGE_LOCATION });
2202 let ty_timestamp_tz = value(
2203 TypeName::TimestampTz,
2204 rule! { TIMESTAMP ~ WITH ~ TIME ~ ZONE },
2205 );
2206 let ty_timestamp_tz_simply = value(TypeName::TimestampTz, rule! { TIMESTAMP_TZ });
2207 map_res(
2208 alt((
2209 rule! {
2210 ( #ty_boolean
2211 | #ty_uint8
2212 | #ty_uint16
2213 | #ty_uint32
2214 | #ty_uint64
2215 | #ty_int8
2216 | #ty_int16
2217 | #ty_int32
2218 | #ty_int64
2219 | #ty_float32
2220 | #ty_float64
2221 | #ty_decimal
2222 | #ty_array
2223 | #ty_map
2224 | #ty_bitmap
2225 | #ty_tuple : "TUPLE(<type>, ...)"
2226 | #ty_named_tuple : "TUPLE(<name> <type>, ...)"
2227 ) ~ #nullable? : "type name"
2228 },
2229 rule! {
2230 ( #ty_date
2231 | #ty_timestamp_tz
2232 | #ty_timestamp_tz_simply
2233 | #ty_datetime
2234 | #ty_interval
2235 | #ty_numeric
2236 | #ty_binary
2237 | #ty_string
2238 | #ty_variant
2239 | #ty_geometry
2240 | #ty_geography
2241 | #ty_nullable
2242 | #ty_vector
2243 | #ty_stage_location
2244 ) ~ #nullable? : "type name" },
2245 )),
2246 |(ty, opt_nullable)| match opt_nullable {
2247 Some(true) => Ok(ty.wrap_nullable()),
2248 Some(false) => {
2249 if matches!(ty, TypeName::Nullable(_)) {
2250 Err(nom::Err::Failure(ErrorKind::Other(
2251 "ambiguous NOT NULL constraint",
2252 )))
2253 } else {
2254 Ok(ty.wrap_not_null())
2255 }
2256 }
2257 None => Ok(ty),
2258 },
2259 )(i)
2260}
2261
2262pub fn weekday(i: Input) -> IResult<Weekday> {
2263 alt((
2264 value(Weekday::Sunday, rule! { SUNDAY }),
2265 value(Weekday::Monday, rule! { MONDAY }),
2266 value(Weekday::Tuesday, rule! { TUESDAY }),
2267 value(Weekday::Wednesday, rule! { WEDNESDAY }),
2268 value(Weekday::Thursday, rule! { THURSDAY }),
2269 value(Weekday::Friday, rule! { FRIDAY }),
2270 value(Weekday::Saturday, rule! { SATURDAY }),
2271 value(
2272 Weekday::Sunday,
2273 rule! { #literal_string_eq_ignore_case("SUNDAY") },
2274 ),
2275 value(
2276 Weekday::Monday,
2277 rule! { #literal_string_eq_ignore_case("MONDAY") },
2278 ),
2279 value(
2280 Weekday::Tuesday,
2281 rule! { #literal_string_eq_ignore_case("TUESDAY") },
2282 ),
2283 value(
2284 Weekday::Wednesday,
2285 rule! { #literal_string_eq_ignore_case("WEDNESDAY") },
2286 ),
2287 value(
2288 Weekday::Thursday,
2289 rule! { #literal_string_eq_ignore_case("THURSDAY") },
2290 ),
2291 value(
2292 Weekday::Friday,
2293 rule! { #literal_string_eq_ignore_case("FRIDAY") },
2294 ),
2295 value(
2296 Weekday::Saturday,
2297 rule! { #literal_string_eq_ignore_case("SATURDAY") },
2298 ),
2299 ))
2300 .parse(i)
2301}
2302
2303pub fn interval_kind(i: Input) -> IResult<IntervalKind> {
2304 let iso_year = value(IntervalKind::ISOYear, rule! { ISOYEAR });
2305 let year = value(IntervalKind::Year, rule! { YEAR });
2306 let quarter = value(IntervalKind::Quarter, rule! { QUARTER });
2307 let month = value(IntervalKind::Month, rule! { MONTH });
2308 let day = value(IntervalKind::Day, rule! { DAY });
2309 let hour = value(IntervalKind::Hour, rule! { HOUR });
2310 let minute = value(IntervalKind::Minute, rule! { MINUTE });
2311 let second = value(IntervalKind::Second, rule! { SECOND });
2312 let doy = value(IntervalKind::Doy, rule! { DOY });
2313 let dow = value(IntervalKind::Dow, rule! { DOW });
2314 let isodow = value(IntervalKind::ISODow, rule! { ISODOW });
2315 let isoweek = value(IntervalKind::ISOWeek, rule! { ISOWEEK });
2316 let week = value(IntervalKind::Week, rule! { WEEK });
2317 let epoch = value(IntervalKind::Epoch, rule! { EPOCH });
2318 let microsecond = value(IntervalKind::MicroSecond, rule! { MICROSECOND });
2319 let millennium = value(IntervalKind::Millennium, rule! { MILLENNIUM });
2320 let yearweek = value(IntervalKind::YearWeek, rule! { YEARWEEK });
2321
2322 let iso_year_str = value(
2323 IntervalKind::ISOYear,
2324 rule! { #literal_string_eq_ignore_case("ISOYEAR") },
2325 );
2326
2327 let year_str = value(
2328 IntervalKind::Year,
2329 rule! { #literal_string_eq_ignore_case("YEAR")
2330 | #literal_string_eq_ignore_case("Y")
2331 | #literal_string_eq_ignore_case("YY")
2332 | #literal_string_eq_ignore_case("YYY")
2333 | #literal_string_eq_ignore_case("YYYY")
2334 | #literal_string_eq_ignore_case("YR")
2335 | #literal_string_eq_ignore_case("YEARS")
2336 | #literal_string_eq_ignore_case("YRS")
2337 },
2338 );
2339
2340 let quarter_str = value(
2341 IntervalKind::Quarter,
2342 rule! { #literal_string_eq_ignore_case("QUARTER")
2343 | #literal_string_eq_ignore_case("Q")
2344 | #literal_string_eq_ignore_case("QTR")
2345 | #literal_string_eq_ignore_case("QTRS")
2346 | #literal_string_eq_ignore_case("QUARTERS")
2347 },
2348 );
2349
2350 let month_str = value(
2351 IntervalKind::Month,
2352 rule! { #literal_string_eq_ignore_case("MONTH")
2353 | #literal_string_eq_ignore_case("MM")
2354 | #literal_string_eq_ignore_case("MON")
2355 | #literal_string_eq_ignore_case("MONS")
2356 | #literal_string_eq_ignore_case("MONTHS")
2357 },
2358 );
2359
2360 let day_str = value(
2361 IntervalKind::Day,
2362 rule! { #literal_string_eq_ignore_case("DAY")
2363 | #literal_string_eq_ignore_case("D")
2364 | #literal_string_eq_ignore_case("DD")
2365 | #literal_string_eq_ignore_case("DAYS")
2366 | #literal_string_eq_ignore_case("DAYOFMONTH")
2367 },
2368 );
2369
2370 let hour_str = value(
2371 IntervalKind::Hour,
2372 rule! { #literal_string_eq_ignore_case("HOUR")
2373 | #literal_string_eq_ignore_case("H")
2374 | #literal_string_eq_ignore_case("HH")
2375 | #literal_string_eq_ignore_case("HH24")
2376 | #literal_string_eq_ignore_case("HR")
2377 | #literal_string_eq_ignore_case("HOURS")
2378 | #literal_string_eq_ignore_case("HRS")
2379 },
2380 );
2381
2382 let minute_str = value(
2383 IntervalKind::Minute,
2384 rule! { #literal_string_eq_ignore_case("MINUTE")
2385 | #literal_string_eq_ignore_case("M")
2386 | #literal_string_eq_ignore_case("MI")
2387 | #literal_string_eq_ignore_case("MIN")
2388 | #literal_string_eq_ignore_case("MINUTES")
2389 | #literal_string_eq_ignore_case("MINS")
2390 },
2391 );
2392
2393 let second_str = value(
2394 IntervalKind::Second,
2395 rule! { #literal_string_eq_ignore_case("SECOND")
2396 | #literal_string_eq_ignore_case("S")
2397 | #literal_string_eq_ignore_case("SEC")
2398 | #literal_string_eq_ignore_case("SECONDS")
2399 | #literal_string_eq_ignore_case("SECS")
2400 },
2401 );
2402
2403 let doy_str = value(
2404 IntervalKind::Doy,
2405 rule! { #literal_string_eq_ignore_case("DOY")
2406 | #literal_string_eq_ignore_case("DAYOFYEAR")
2407 | #literal_string_eq_ignore_case("YEARDAY")
2408 | #literal_string_eq_ignore_case("DY")
2409 },
2410 );
2411
2412 let dow_str = value(
2413 IntervalKind::Dow,
2414 rule! { (#literal_string_eq_ignore_case("DOW")
2415 | #literal_string_eq_ignore_case("WEEKDAY")
2416 | #literal_string_eq_ignore_case("DW")
2417 | #literal_string_eq_ignore_case("DAYOFWEEK"))
2418 },
2419 );
2420
2421 let isodow_str = value(
2422 IntervalKind::ISODow,
2423 rule! { #literal_string_eq_ignore_case("ISODOW")
2424 | #literal_string_eq_ignore_case("DAYOFWEEK_ISO")
2425 | #literal_string_eq_ignore_case("DAYOFWEEKISO")
2426 | #literal_string_eq_ignore_case("WEEKDAY_ISO")
2427 | #literal_string_eq_ignore_case("DOW_ISO")
2428 | #literal_string_eq_ignore_case("DW_ISO")
2429 },
2430 );
2431
2432 let week_str = value(
2433 IntervalKind::Week,
2434 rule! { (#literal_string_eq_ignore_case("WEEK") | #literal_string_eq_ignore_case("WEEKS") | #literal_string_eq_ignore_case("W"))
2435 | #literal_string_eq_ignore_case("WK")
2436 | #literal_string_eq_ignore_case("WEEKOFYEAR")
2437 | #literal_string_eq_ignore_case("WOY")
2438 | #literal_string_eq_ignore_case("WY")
2439 },
2440 );
2441
2442 let isoweek_str = value(
2443 IntervalKind::ISOWeek,
2444 rule! { #literal_string_eq_ignore_case("IW") },
2445 );
2446
2447 let epoch_str = value(
2448 IntervalKind::Epoch,
2449 rule! { #literal_string_eq_ignore_case("EPOCH")
2450 | #literal_string_eq_ignore_case("EPOCH_SECOND")
2451 | #literal_string_eq_ignore_case("EPOCH")
2452 | #literal_string_eq_ignore_case("EPOCH_SECONDS")
2453 },
2454 );
2455
2456 let microsecond_str = value(
2457 IntervalKind::MicroSecond,
2458 rule! { #literal_string_eq_ignore_case("MICROSECOND")
2459 | #literal_string_eq_ignore_case("MICROSECONDS")
2460 | #literal_string_eq_ignore_case("US")
2461 | #literal_string_eq_ignore_case("USEC")
2462 },
2463 );
2464
2465 let yearweek_str = value(
2466 IntervalKind::YearWeek,
2467 rule! { #literal_string_eq_ignore_case("YEARWEEK")
2468 | #literal_string_eq_ignore_case("YEAROFWEEK")
2469 },
2470 );
2471
2472 let millennium_str = value(
2473 IntervalKind::Millennium,
2474 rule! { #literal_string_eq_ignore_case("MILLENNIUM") },
2475 );
2476
2477 alt((
2478 rule!(
2479 #year
2480 | #iso_year
2481 | #quarter
2482 | #month
2483 | #day
2484 | #hour
2485 | #minute
2486 | #second
2487 | #doy
2488 | #dow
2489 | #week
2490 | #epoch
2491 | #microsecond
2492 | #isodow
2493 | #isoweek
2494 | #millennium
2495 | #yearweek
2496 ),
2497 rule!(
2498 #year_str
2499 | #iso_year_str
2500 | #quarter_str
2501 | #month_str
2502 | #day_str
2503 | #hour_str
2504 | #minute_str
2505 | #second_str
2506 | #doy_str
2507 | #dow_str
2508 | #week_str
2509 | #epoch_str
2510 | #microsecond_str
2511 | #isodow_str
2512 | #isoweek_str
2513 | #yearweek_str
2514 | #millennium_str
2515 ),
2516 ))
2517 .parse(i)
2518}
2519
2520fn map_access_dot_number(i: Input) -> IResult<MapAccessor> {
2521 map_res(rule! { LiteralFloat }, |key| {
2522 if key.text().starts_with('.')
2523 && let Ok(key) = (key.text()[1..]).parse::<u64>()
2524 {
2525 return Ok(MapAccessor::DotNumber { key });
2526 }
2527 Err(nom::Err::Error(ErrorKind::ExpectText(".")))
2528 })
2529 .parse(i)
2530}
2531
2532fn map_access_colon(i: Input) -> IResult<MapAccessor> {
2533 map(
2534 rule! {
2535 ":" ~ #ident
2536 },
2537 |(_, key)| MapAccessor::Colon { key },
2538 )
2539 .parse(i)
2540}
2541
2542pub fn map_element(i: Input) -> IResult<(Literal, Expr)> {
2543 map(
2544 rule! {
2545 #literal ~ ":" ~ #subexpr(0)
2546 },
2547 |(key, _, value)| (key, value),
2548 )
2549 .parse(i)
2550}
2551
2552pub fn function_call(i: Input) -> IResult<ExprElement> {
2553 enum FunctionCallSuffix {
2554 Simple {
2555 distinct: bool,
2556 args: Vec<Expr>,
2557 },
2558 Lambda {
2559 arg: Expr,
2560 params: Vec<Identifier>,
2561 expr: Box<Expr>,
2562 },
2563 Window {
2564 distinct: bool,
2565 args: Vec<Expr>,
2566 window: WindowDesc,
2567 },
2568 WithInGroupWindow {
2569 distinct: bool,
2570 args: Vec<Expr>,
2571 order_by: Vec<OrderByExpr>,
2572 window: Option<WindowDesc>,
2573 },
2574 ParamsWindow {
2575 distinct: bool,
2576 params: Vec<Expr>,
2577 args: Vec<Expr>,
2578 window: Option<WindowDesc>,
2579 },
2580 }
2581 let function_call_body = map_res(
2582 rule! {
2583 "(" ~ DISTINCT? ~ #subexpr(0)? ~ ","? ~ (#lambda_params ~ "->" ~ #subexpr(0))? ~ #comma_separated_list1(subexpr(0))? ~ ")"
2584 ~ ("(" ~ DISTINCT? ~ #comma_separated_list0(subexpr(0))? ~ ")")?
2585 ~ #within_group?
2586 ~ #window_function?
2587 },
2588 |(
2589 _,
2590 opt_distinct_0,
2591 first_param,
2592 _,
2593 opt_lambda,
2594 params_0,
2595 _,
2596 params_1,
2597 order_by,
2598 window,
2599 )| {
2600 match (
2601 first_param,
2602 opt_lambda,
2603 opt_distinct_0,
2604 params_0,
2605 params_1,
2606 order_by,
2607 window,
2608 ) {
2609 (
2610 Some(first_param),
2611 Some((lambda_params, _, arg_1)),
2612 None,
2613 None,
2614 None,
2615 None,
2616 None,
2617 ) => Ok(FunctionCallSuffix::Lambda {
2618 arg: first_param,
2619 params: lambda_params,
2620 expr: Box::new(arg_1),
2621 }),
2622 (
2623 Some(first_param),
2624 None,
2625 None,
2626 params_0,
2627 Some((_, opt_distinct_1, params_1, _)),
2628 None,
2629 window,
2630 ) => {
2631 let params = params_0
2632 .map(|mut params| {
2633 params.insert(0, first_param.clone());
2634 params
2635 })
2636 .unwrap_or_else(|| vec![first_param]);
2637
2638 Ok(FunctionCallSuffix::ParamsWindow {
2639 distinct: opt_distinct_1.is_some(),
2640 params,
2641 args: params_1.unwrap_or_default(),
2642 window,
2643 })
2644 }
2645 (first_param, None, opt_distinct, params, None, Some(order_by), window) => {
2646 let mut args = params.unwrap_or_default();
2647 if let Some(first_param) = first_param {
2648 args.insert(0, first_param)
2649 }
2650
2651 Ok(FunctionCallSuffix::WithInGroupWindow {
2652 distinct: opt_distinct.is_some(),
2653 args,
2654 order_by,
2655 window,
2656 })
2657 }
2658 (first_param, None, opt_distinct, params, None, None, Some(window)) => {
2659 let mut args = params.unwrap_or_default();
2660 if let Some(first_param) = first_param {
2661 args.insert(0, first_param)
2662 }
2663
2664 Ok(FunctionCallSuffix::Window {
2665 distinct: opt_distinct.is_some(),
2666 args,
2667 window,
2668 })
2669 }
2670 (first_param, None, opt_distinct, params, None, None, None) => {
2671 let mut args = params.unwrap_or_default();
2672 if let Some(first_param) = first_param {
2673 args.insert(0, first_param)
2674 }
2675
2676 Ok(FunctionCallSuffix::Simple {
2677 distinct: opt_distinct.is_some(),
2678 args,
2679 })
2680 }
2681 _ => Err(nom::Err::Error(ErrorKind::Other(
2682 "Unsupported function format",
2683 ))),
2684 }
2685 },
2686 );
2687
2688 map(
2689 rule!(
2690 #function_name
2691 ~ #function_call_body : "`function(... [ , x -> ... ] ) [ (...) ] [ WITHIN GROUP ( ORDER BY <expr>, ... ) ] [ OVER ([ PARTITION BY <expr>, ... ] [ ORDER BY <expr>, ... ] [ <window frame> ]) ]`"
2692 ),
2693 |(name, suffix)| match suffix {
2694 FunctionCallSuffix::Simple { distinct, args } => ExprElement::FunctionCall {
2695 func: FunctionCall {
2696 distinct,
2697 name,
2698 args,
2699 params: vec![],
2700 order_by: vec![],
2701 window: None,
2702 lambda: None,
2703 },
2704 },
2705 FunctionCallSuffix::Lambda { arg, params, expr } => ExprElement::FunctionCall {
2706 func: FunctionCall {
2707 distinct: false,
2708 name,
2709 args: vec![arg],
2710 params: vec![],
2711 order_by: vec![],
2712 window: None,
2713 lambda: Some(Lambda { params, expr }),
2714 },
2715 },
2716 FunctionCallSuffix::Window {
2717 distinct,
2718 args,
2719 window,
2720 } => ExprElement::FunctionCall {
2721 func: FunctionCall {
2722 distinct,
2723 name,
2724 args,
2725 params: vec![],
2726 order_by: vec![],
2727 window: Some(window),
2728 lambda: None,
2729 },
2730 },
2731 FunctionCallSuffix::WithInGroupWindow {
2732 distinct,
2733 args,
2734 order_by,
2735 window,
2736 } => ExprElement::FunctionCall {
2737 func: FunctionCall {
2738 distinct,
2739 name,
2740 args,
2741 params: vec![],
2742 order_by,
2743 window,
2744 lambda: None,
2745 },
2746 },
2747 FunctionCallSuffix::ParamsWindow {
2748 distinct,
2749 params,
2750 args,
2751 window,
2752 } => ExprElement::FunctionCall {
2753 func: FunctionCall {
2754 distinct,
2755 name,
2756 args,
2757 params,
2758 order_by: vec![],
2759 window,
2760 lambda: None,
2761 },
2762 },
2763 },
2764 ).parse(i)
2765}
2766
2767pub fn parse_float(text: &str) -> Result<Literal, ErrorKind> {
2768 let text = text.trim_start_matches('0');
2769 let point_pos = text.find('.');
2770 let e_pos = text.find(['e', 'E']);
2771 let (i_part, f_part, e_part) = match (point_pos, e_pos) {
2772 (Some(p1), Some(p2)) => (&text[..p1], &text[(p1 + 1)..p2], Some(&text[(p2 + 1)..])),
2773 (Some(p), None) => (&text[..p], &text[(p + 1)..], None),
2774 (None, Some(p)) => (&text[..p], "", Some(&text[(p + 1)..])),
2775 _ => unreachable!(),
2776 };
2777 let exp = match e_part {
2778 Some(s) => match s.parse::<i32>() {
2779 Ok(i) => i,
2780 Err(_) => return Ok(Literal::Float64(fast_float2::parse(text)?)),
2781 },
2782 None => 0,
2783 };
2784
2785 let i_part_len = i_part.len() as i32;
2786 let f_part_len = f_part.len() as i32;
2787 let mut precision = i_part_len + f_part_len;
2788 if exp > f_part_len {
2789 precision += exp - f_part_len;
2790 } else if i_part_len + exp < 0 {
2791 precision -= i_part_len + exp;
2792 }
2793
2794 if precision > 76 {
2795 Ok(Literal::Float64(fast_float2::parse(text)?))
2796 } else {
2797 let mut digits = String::with_capacity(precision as usize);
2798 digits.push_str(i_part);
2799 digits.push_str(f_part);
2800 if digits.is_empty() {
2801 digits.push('0')
2802 }
2803 let mut scale = f_part_len - exp;
2804 if scale < 0 {
2805 for _ in 0..(-scale) {
2807 digits.push('0')
2808 }
2809 scale = 0;
2810 };
2811 Ok(Literal::Decimal256 {
2812 value: i256::from_str_radix(&digits, 10)?,
2813 precision: 76,
2814 scale: scale as u8,
2815 })
2816 }
2817}
2818
2819pub fn parse_uint(text: &str, radix: u32) -> Result<Literal, ErrorKind> {
2820 let text = text.trim_start_matches('0');
2821 let contains_underscore = text.contains('_');
2822 if contains_underscore {
2823 let text = text.replace('_', "");
2824 return parse_uint(&text, radix);
2825 }
2826
2827 if text.is_empty() {
2828 return Ok(Literal::UInt64(0));
2829 } else if text.len() > 76 {
2830 return Ok(Literal::Float64(fast_float2::parse(text)?));
2831 }
2832
2833 let value = i256::from_str_radix(text, radix)?;
2834 if value <= i256::from(u64::MAX) {
2835 Ok(Literal::UInt64(value.as_u64()))
2836 } else {
2837 Ok(Literal::Decimal256 {
2838 value,
2839 precision: 76,
2840 scale: 0,
2841 })
2842 }
2843}
2844
2845fn try_negate_literal(literal: &Literal) -> Option<Literal> {
2846 match literal {
2847 Literal::UInt64(value) => Some(Literal::Decimal256 {
2848 value: -i256::from(*value),
2849 precision: 76,
2850 scale: 0,
2851 }),
2852 Literal::Decimal256 {
2853 value,
2854 precision,
2855 scale,
2856 } => Some(Literal::Decimal256 {
2857 value: -*value,
2858 precision: *precision,
2859 scale: *scale,
2860 }),
2861 Literal::Float64(value) => Some(Literal::Float64(-value)),
2862 _ => None,
2863 }
2864}
2865
2866pub(crate) fn make_func_get_variable(span: Span, name: String) -> Expr {
2867 Expr::FunctionCall {
2868 span,
2869 func: FunctionCall {
2870 distinct: false,
2871 name: Identifier::from_name(span, "getvariable"),
2872 args: vec![Expr::Literal {
2873 span,
2874 value: Literal::String(name),
2875 }],
2876 params: vec![],
2877 order_by: vec![],
2878 window: None,
2879 lambda: None,
2880 },
2881 }
2882}