MCPcopy Create free account
hub / github.com/MaterializeInc/materialize / parse_select

Method parse_select

src/sql-parser/src/parser.rs:7813–7913  ·  view source on GitHub ↗

Parse a restricted `SELECT` statement (no CTEs / `UNION` / `ORDER BY`), assuming the initial `SELECT` was already consumed

(&mut self)

Source from the content-addressed store, hash-verified

7811 /// Parse a restricted `SELECT` statement (no CTEs / `UNION` / `ORDER BY`),
7812 /// assuming the initial `SELECT` was already consumed
7813 fn parse_select(&mut self) -> Result<Select<Raw>, ParserError> {
7814 let all = self.parse_keyword(ALL);
7815 let distinct = self.parse_keyword(DISTINCT);
7816 if all && distinct {
7817 return parser_err!(
7818 self,
7819 self.peek_prev_pos(),
7820 "Cannot specify both ALL and DISTINCT in SELECT"
7821 );
7822 }
7823 let distinct = if distinct && self.parse_keyword(ON) {
7824 self.expect_token(&Token::LParen)?;
7825 let exprs = self.parse_comma_separated(Parser::parse_expr)?;
7826 self.expect_token(&Token::RParen)?;
7827 Some(Distinct::On(exprs))
7828 } else if distinct {
7829 Some(Distinct::EntireRow)
7830 } else {
7831 None
7832 };
7833
7834 let projection = match self.peek_token() {
7835 // An empty target list is permissible to match PostgreSQL, which
7836 // permits these for symmetry with zero column tables. We need
7837 // to sniff out `AS` here specially to support `SELECT AS OF ...`.
7838 Some(Token::Keyword(kw)) if kw.is_always_reserved() || kw == AS => vec![],
7839 Some(Token::Semicolon) | Some(Token::RParen) | None => vec![],
7840 _ => {
7841 let mut projection = vec![];
7842 loop {
7843 projection.push(self.parse_select_item()?);
7844 if !self.consume_token(&Token::Comma) {
7845 break;
7846 }
7847 if self.peek_keyword(FROM) {
7848 return parser_err!(
7849 self,
7850 self.peek_prev_pos(),
7851 "invalid trailing comma in SELECT list",
7852 );
7853 }
7854 }
7855 projection
7856 }
7857 };
7858
7859 // Note that for keywords to be properly handled here, they need to be
7860 // added to `RESERVED_FOR_COLUMN_ALIAS` / `RESERVED_FOR_TABLE_ALIAS`,
7861 // otherwise they may be parsed as an alias as part of the `projection`
7862 // or `from`.
7863
7864 let from = if self.parse_keyword(FROM) {
7865 self.parse_comma_separated(Parser::parse_table_and_joins)?
7866 } else {
7867 vec![]
7868 };
7869
7870 let selection = if self.parse_keyword(WHERE) {

Callers 1

parse_query_bodyMethod · 0.80

Calls 11

parse_keywordMethod · 0.80
expect_tokenMethod · 0.80
parse_comma_separatedMethod · 0.80
peek_tokenMethod · 0.80
is_always_reservedMethod · 0.80
parse_select_itemMethod · 0.80
consume_tokenMethod · 0.80
peek_keywordMethod · 0.80
parse_exprMethod · 0.80
parse_keywordsMethod · 0.80
pushMethod · 0.45

Tested by

no test coverage detected