(
context: &mut ParserContext,
tokens: &[Token],
position: &mut usize,
)
| 641 | } |
| 642 | |
| 643 | fn parse_select_distinct_option( |
| 644 | context: &mut ParserContext, |
| 645 | tokens: &[Token], |
| 646 | position: &mut usize, |
| 647 | ) -> Result<Distinct, Box<Diagnostic>> { |
| 648 | if is_current_token(tokens, position, TokenKind::Distinct) { |
| 649 | // Consume `DISTINCT` keyword |
| 650 | *position += 1; |
| 651 | |
| 652 | if is_current_token(tokens, position, TokenKind::On) { |
| 653 | // Consume `ON` keyword |
| 654 | *position += 1; |
| 655 | |
| 656 | if !is_current_token(tokens, position, TokenKind::LeftParen) { |
| 657 | return Err(Diagnostic::error("Expect `(` after `DISTINCT ON`") |
| 658 | .add_help("Try to add `(` after ON and before fields") |
| 659 | .with_location(calculate_safe_location(tokens, *position)) |
| 660 | .as_boxed()); |
| 661 | } |
| 662 | |
| 663 | // Consume `(` Left Parenthesis |
| 664 | *position += 1; |
| 665 | |
| 666 | let mut distinct_fields: Vec<String> = vec![]; |
| 667 | while !is_current_token(tokens, position, TokenKind::RightParen) { |
| 668 | let field_token = &tokens[*position]; |
| 669 | let literal = &field_token.to_string(); |
| 670 | let location = field_token.location; |
| 671 | |
| 672 | distinct_fields.push(literal.to_string()); |
| 673 | |
| 674 | context.hidden_selections.push(literal.to_string()); |
| 675 | context.projection_names.push(literal.to_string()); |
| 676 | context.projection_locations.push(location); |
| 677 | |
| 678 | // Consume field name |
| 679 | *position += 1; |
| 680 | |
| 681 | if is_current_token(tokens, position, TokenKind::Comma) { |
| 682 | // Consume `,` |
| 683 | *position += 1; |
| 684 | } else { |
| 685 | break; |
| 686 | } |
| 687 | } |
| 688 | |
| 689 | // Consume `)` Right Parenthesis |
| 690 | consume_token_or_error( |
| 691 | tokens, |
| 692 | position, |
| 693 | TokenKind::RightParen, |
| 694 | "Expect `)` after `DISTINCT ON fields`", |
| 695 | )?; |
| 696 | |
| 697 | // Prevent passing empty fields |
| 698 | if distinct_fields.is_empty() { |
| 699 | return Err(Diagnostic::error( |
| 700 | "DISTINCT ON(...) must be used with one of more column", |
no test coverage detected
searching dependent graphs…