@@ -4276,17 +4276,32 @@ impl<'a> Parser<'a> {
42764276 /// not be efficient as it does a loop on the tokens with `peek_nth_token`
42774277 /// each time.
42784278 pub fn parse_keyword_with_tokens(&mut self, expected: Keyword, tokens: &[Token]) -> bool {
4279+ self.keyword_with_tokens(expected, tokens, true)
4280+ }
4281+
4282+ /// Peeks to see if the current token is the `expected` keyword followed by specified tokens
4283+ /// without consuming them.
4284+ ///
4285+ /// See [Self::parse_keyword_with_tokens] for details.
4286+ pub(crate) fn peek_keyword_with_tokens(&mut self, expected: Keyword, tokens: &[Token]) -> bool {
4287+ self.keyword_with_tokens(expected, tokens, false)
4288+ }
4289+
4290+ fn keyword_with_tokens(&mut self, expected: Keyword, tokens: &[Token], consume: bool) -> bool {
42794291 match &self.peek_token_ref().token {
42804292 Token::Word(w) if expected == w.keyword => {
42814293 for (idx, token) in tokens.iter().enumerate() {
42824294 if self.peek_nth_token_ref(idx + 1).token != *token {
42834295 return false;
42844296 }
42854297 }
4286- // consume all tokens
4287- for _ in 0..(tokens.len() + 1) {
4288- self.advance_token();
4298+
4299+ if consume {
4300+ for _ in 0..(tokens.len() + 1) {
4301+ self.advance_token();
4302+ }
42894303 }
4304+
42904305 true
42914306 }
42924307 _ => false,
@@ -13428,6 +13443,7 @@ impl<'a> Parser<'a> {
1342813443 | TableFactor::Pivot { alias, .. }
1342913444 | TableFactor::Unpivot { alias, .. }
1343013445 | TableFactor::MatchRecognize { alias, .. }
13446+ | TableFactor::SemanticView { alias, .. }
1343113447 | TableFactor::NestedJoin { alias, .. }
1343213448 | TableFactor::PassThroughQuery { alias, .. } => {
1343313449 // but not `FROM (mytable AS alias1) AS alias2`.
@@ -13543,6 +13559,10 @@ impl<'a> Parser<'a> {
1354313559 } else if self.parse_keyword_with_tokens(Keyword::XMLTABLE, &[Token::LParen]) {
1354413560 self.prev_token();
1354513561 self.parse_xml_table_factor()
13562+ } else if self.dialect.supports_semantic_view_table_factor()
13563+ && self.peek_keyword_with_tokens(Keyword::SEMANTIC_VIEW, &[Token::LParen])
13564+ {
13565+ self.parse_semantic_view_table_factor()
1354613566 } else {
1354713567 let name = self.parse_object_name(true)?;
1354813568
@@ -13874,6 +13894,70 @@ impl<'a> Parser<'a> {
1387413894 Ok(XmlPassingClause { arguments })
1387513895 }
1387613896
13897+ /// Parse a [TableFactor::SemanticView]
13898+ fn parse_semantic_view_table_factor(&mut self) -> Result<TableFactor, ParserError> {
13899+ self.expect_keyword(Keyword::SEMANTIC_VIEW)?;
13900+ self.expect_token(&Token::LParen)?;
13901+
13902+ let name = self.parse_object_name(true)?;
13903+
13904+ // Parse DIMENSIONS, METRICS, FACTS and WHERE clauses in flexible order
13905+ let mut dimensions = Vec::new();
13906+ let mut metrics = Vec::new();
13907+ let mut facts = Vec::new();
13908+ let mut where_clause = None;
13909+
13910+ while self.peek_token().token != Token::RParen {
13911+ if self.parse_keyword(Keyword::DIMENSIONS) {
13912+ if !dimensions.is_empty() {
13913+ return Err(ParserError::ParserError(
13914+ "DIMENSIONS clause can only be specified once".to_string(),
13915+ ));
13916+ }
13917+ dimensions = self.parse_comma_separated(Parser::parse_expr)?;
13918+ } else if self.parse_keyword(Keyword::METRICS) {
13919+ if !metrics.is_empty() {
13920+ return Err(ParserError::ParserError(
13921+ "METRICS clause can only be specified once".to_string(),
13922+ ));
13923+ }
13924+ metrics = self.parse_comma_separated(|parser| parser.parse_object_name(true))?;
13925+ } else if self.parse_keyword(Keyword::FACTS) {
13926+ if !facts.is_empty() {
13927+ return Err(ParserError::ParserError(
13928+ "FACTS clause can only be specified once".to_string(),
13929+ ));
13930+ }
13931+ facts = self.parse_comma_separated(Parser::parse_expr)?;
13932+ } else if self.parse_keyword(Keyword::WHERE) {
13933+ if where_clause.is_some() {
13934+ return Err(ParserError::ParserError(
13935+ "WHERE clause can only be specified once".to_string(),
13936+ ));
13937+ }
13938+ where_clause = Some(self.parse_expr()?);
13939+ } else {
13940+ return parser_err!(
13941+ "Expected one of DIMENSIONS, METRICS, FACTS or WHERE",
13942+ self.peek_token().span.start
13943+ )?;
13944+ }
13945+ }
13946+
13947+ self.expect_token(&Token::RParen)?;
13948+
13949+ let alias = self.maybe_parse_table_alias()?;
13950+
13951+ Ok(TableFactor::SemanticView {
13952+ name,
13953+ dimensions,
13954+ metrics,
13955+ facts,
13956+ where_clause,
13957+ alias,
13958+ })
13959+ }
13960+
1387713961 fn parse_match_recognize(&mut self, table: TableFactor) -> Result<TableFactor, ParserError> {
1387813962 self.expect_token(&Token::LParen)?;
1387913963
0 commit comments