@@ -4245,17 +4245,32 @@ impl<'a> Parser<'a> {
4245
4245
/// not be efficient as it does a loop on the tokens with `peek_nth_token`
4246
4246
/// each time.
4247
4247
pub fn parse_keyword_with_tokens(&mut self, expected: Keyword, tokens: &[Token]) -> bool {
4248
+ self.keyword_with_tokens(expected, tokens, true)
4249
+ }
4250
+
4251
+ /// Peeks to see if the current token is the `expected` keyword followed by specified tokens
4252
+ /// without consuming them.
4253
+ ///
4254
+ /// See [Self::parse_keyword_with_tokens] for details.
4255
+ pub(crate) fn peek_keyword_with_tokens(&mut self, expected: Keyword, tokens: &[Token]) -> bool {
4256
+ self.keyword_with_tokens(expected, tokens, false)
4257
+ }
4258
+
4259
+ fn keyword_with_tokens(&mut self, expected: Keyword, tokens: &[Token], consume: bool) -> bool {
4248
4260
match &self.peek_token_ref().token {
4249
4261
Token::Word(w) if expected == w.keyword => {
4250
4262
for (idx, token) in tokens.iter().enumerate() {
4251
4263
if self.peek_nth_token_ref(idx + 1).token != *token {
4252
4264
return false;
4253
4265
}
4254
4266
}
4255
- // consume all tokens
4256
- for _ in 0..(tokens.len() + 1) {
4257
- self.advance_token();
4267
+
4268
+ if consume {
4269
+ for _ in 0..(tokens.len() + 1) {
4270
+ self.advance_token();
4271
+ }
4258
4272
}
4273
+
4259
4274
true
4260
4275
}
4261
4276
_ => false,
@@ -13397,6 +13412,7 @@ impl<'a> Parser<'a> {
13397
13412
| TableFactor::Pivot { alias, .. }
13398
13413
| TableFactor::Unpivot { alias, .. }
13399
13414
| TableFactor::MatchRecognize { alias, .. }
13415
+ | TableFactor::SemanticView { alias, .. }
13400
13416
| TableFactor::NestedJoin { alias, .. } => {
13401
13417
// but not `FROM (mytable AS alias1) AS alias2`.
13402
13418
if let Some(inner_alias) = alias {
@@ -13511,6 +13527,10 @@ impl<'a> Parser<'a> {
13511
13527
} else if self.parse_keyword_with_tokens(Keyword::XMLTABLE, &[Token::LParen]) {
13512
13528
self.prev_token();
13513
13529
self.parse_xml_table_factor()
13530
+ } else if self.dialect.supports_semantic_view_table_factor()
13531
+ && self.peek_keyword_with_tokens(Keyword::SEMANTIC_VIEW, &[Token::LParen])
13532
+ {
13533
+ self.parse_semantic_view_table_factor()
13514
13534
} else {
13515
13535
let name = self.parse_object_name(true)?;
13516
13536
@@ -13842,6 +13862,70 @@ impl<'a> Parser<'a> {
13842
13862
Ok(XmlPassingClause { arguments })
13843
13863
}
13844
13864
13865
+ /// Parse a [TableFactor::SemanticView]
13866
+ fn parse_semantic_view_table_factor(&mut self) -> Result<TableFactor, ParserError> {
13867
+ self.expect_keyword(Keyword::SEMANTIC_VIEW)?;
13868
+ self.expect_token(&Token::LParen)?;
13869
+
13870
+ let name = self.parse_object_name(true)?;
13871
+
13872
+ // Parse DIMENSIONS, METRICS, FACTS and WHERE clauses in flexible order
13873
+ let mut dimensions = Vec::new();
13874
+ let mut metrics = Vec::new();
13875
+ let mut facts = Vec::new();
13876
+ let mut where_clause = None;
13877
+
13878
+ while self.peek_token().token != Token::RParen {
13879
+ if self.parse_keyword(Keyword::DIMENSIONS) {
13880
+ if !dimensions.is_empty() {
13881
+ return Err(ParserError::ParserError(
13882
+ "DIMENSIONS clause can only be specified once".to_string(),
13883
+ ));
13884
+ }
13885
+ dimensions = self.parse_comma_separated(Parser::parse_expr)?;
13886
+ } else if self.parse_keyword(Keyword::METRICS) {
13887
+ if !metrics.is_empty() {
13888
+ return Err(ParserError::ParserError(
13889
+ "METRICS clause can only be specified once".to_string(),
13890
+ ));
13891
+ }
13892
+ metrics = self.parse_comma_separated(|parser| parser.parse_object_name(true))?;
13893
+ } else if self.parse_keyword(Keyword::FACTS) {
13894
+ if !facts.is_empty() {
13895
+ return Err(ParserError::ParserError(
13896
+ "FACTS clause can only be specified once".to_string(),
13897
+ ));
13898
+ }
13899
+ facts = self.parse_comma_separated(Parser::parse_expr)?;
13900
+ } else if self.parse_keyword(Keyword::WHERE) {
13901
+ if where_clause.is_some() {
13902
+ return Err(ParserError::ParserError(
13903
+ "WHERE clause can only be specified once".to_string(),
13904
+ ));
13905
+ }
13906
+ where_clause = Some(self.parse_expr()?);
13907
+ } else {
13908
+ return parser_err!(
13909
+ "Expected one of DIMENSIONS, METRICS, FACTS or WHERE",
13910
+ self.peek_token().span.start
13911
+ )?;
13912
+ }
13913
+ }
13914
+
13915
+ self.expect_token(&Token::RParen)?;
13916
+
13917
+ let alias = self.maybe_parse_table_alias()?;
13918
+
13919
+ Ok(TableFactor::SemanticView {
13920
+ name,
13921
+ dimensions,
13922
+ metrics,
13923
+ facts,
13924
+ where_clause,
13925
+ alias,
13926
+ })
13927
+ }
13928
+
13845
13929
fn parse_match_recognize(&mut self, table: TableFactor) -> Result<TableFactor, ParserError> {
13846
13930
self.expect_token(&Token::LParen)?;
13847
13931
0 commit comments