(
context: &mut ParserContext,
env: &mut Environment,
tokens: &[Token],
position: &mut usize,
)
| 534 | } |
| 535 | |
| 536 | fn parse_select_statement( |
| 537 | context: &mut ParserContext, |
| 538 | env: &mut Environment, |
| 539 | tokens: &[Token], |
| 540 | position: &mut usize, |
| 541 | ) -> Result<Statement, Box<Diagnostic>> { |
| 542 | // Consume `SELECT` keyword |
| 543 | *position += 1; |
| 544 | |
| 545 | if *position >= tokens.len() { |
| 546 | return Err(Diagnostic::error("Incomplete input for select statement") |
| 547 | .add_help("Try select one or more values in the `SELECT` statement") |
| 548 | .add_note("Select statements requires at least selecting one value") |
| 549 | .with_location(calculate_safe_location(tokens, *position - 1)) |
| 550 | .as_boxed()); |
| 551 | } |
| 552 | |
| 553 | // Parse `DISTINCT` or `DISTINCT ON(...)` |
| 554 | let distinct = parse_select_distinct_option(context, tokens, position)?; |
| 555 | |
| 556 | // Parse `*` or `expressions` |
| 557 | let mut fields_names: Vec<String> = vec![]; |
| 558 | let mut selected_expr_titles: Vec<String> = vec![]; |
| 559 | let mut selected_expr: Vec<Box<dyn Expr>> = vec![]; |
| 560 | let mut is_select_all = false; |
| 561 | |
| 562 | context.inside_selections = true; |
| 563 | parse_select_all_or_expressions( |
| 564 | context, |
| 565 | env, |
| 566 | tokens, |
| 567 | position, |
| 568 | &mut fields_names, |
| 569 | &mut selected_expr_titles, |
| 570 | &mut selected_expr, |
| 571 | &mut is_select_all, |
| 572 | )?; |
| 573 | context.inside_selections = false; |
| 574 | |
| 575 | // Parse optional `FROM` with one or more tables and joins |
| 576 | let mut joins: Vec<Join> = vec![]; |
| 577 | let mut tables_to_select_from: Vec<String> = vec![]; |
| 578 | parse_from_option( |
| 579 | context, |
| 580 | env, |
| 581 | &mut tables_to_select_from, |
| 582 | &mut joins, |
| 583 | tokens, |
| 584 | position, |
| 585 | )?; |
| 586 | |
| 587 | // Make sure Aggregated functions are used with tables only |
| 588 | if tables_to_select_from.is_empty() && !context.aggregations.is_empty() { |
| 589 | return Err( |
| 590 | Diagnostic::error("Aggregations functions should be used only with tables") |
| 591 | .add_note("Try to select from one of the available tables in current schema") |
| 592 | .with_location(calculate_safe_location(tokens, *position)) |
| 593 | .as_boxed(), |
no test coverage detected
searching dependent graphs…