Parses a `SELECT` statement.
(&mut self, select_pos: LineCol)
| 1682 | |
| 1683 | /// Parses a `SELECT` statement. |
| 1684 | fn parse_select(&mut self, select_pos: LineCol) -> Result<Statement> { |
| 1685 | self.expect_and_consume(Token::Case, "Expecting CASE after SELECT")?; |
| 1686 | |
| 1687 | let expr = self.parse_required_expr("No expression in SELECT CASE statement")?; |
| 1688 | self.expect_and_consume(Token::Eol, "Expecting newline after SELECT CASE")?; |
| 1689 | |
| 1690 | let mut cases = vec![]; |
| 1691 | |
| 1692 | let mut i = 0; |
| 1693 | let mut last = false; |
| 1694 | let end_pos; |
| 1695 | loop { |
| 1696 | let peeked = self.lexer.peek()?; |
| 1697 | match peeked.token { |
| 1698 | Token::Eof => { |
| 1699 | end_pos = peeked.pos; |
| 1700 | break; |
| 1701 | } |
| 1702 | |
| 1703 | Token::Eol => { |
| 1704 | self.lexer.consume_peeked(); |
| 1705 | } |
| 1706 | |
| 1707 | Token::Case => { |
| 1708 | let peeked = self.lexer.consume_peeked(); |
| 1709 | let guards = self.parse_case_guards()?; |
| 1710 | self.expect_and_consume(Token::Eol, "Expecting newline after CASE")?; |
| 1711 | |
| 1712 | let is_last = guards.is_empty(); |
| 1713 | if last { |
| 1714 | if is_last { |
| 1715 | return Err(Error::Bad( |
| 1716 | peeked.pos, |
| 1717 | "CASE ELSE must be unique".to_owned(), |
| 1718 | )); |
| 1719 | } else { |
| 1720 | return Err(Error::Bad(peeked.pos, "CASE ELSE is not last".to_owned())); |
| 1721 | } |
| 1722 | } |
| 1723 | last |= is_last; |
| 1724 | |
| 1725 | cases.push(CaseSpan { guards, body: vec![] }); |
| 1726 | if cases.len() > 1 { |
| 1727 | i += 1; |
| 1728 | } |
| 1729 | } |
| 1730 | |
| 1731 | Token::End => { |
| 1732 | let end_span = self.lexer.consume_peeked(); |
| 1733 | match self.maybe_parse_end(end_span.pos)? { |
| 1734 | Ok(stmt) => { |
| 1735 | if cases.is_empty() { |
| 1736 | return Err(Error::Bad( |
| 1737 | end_span.pos, |
| 1738 | "Expected CASE after SELECT CASE before any statement" |
| 1739 | .to_owned(), |
| 1740 | )); |
| 1741 | } |
no test coverage detected