Skip to content

Commit 02e7563

Browse files
committed
Make SEMANTIC_VIEW parse method work on full expression
1 parent 4dd2f0c commit 02e7563

File tree

1 file changed

+37
-4
lines changed

1 file changed

+37
-4
lines changed

src/parser/mod.rs

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4245,17 +4245,33 @@ impl<'a> Parser<'a> {
42454245
/// not be efficient as it does a loop on the tokens with `peek_nth_token`
42464246
/// each time.
42474247
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+
/// Note that if the length of `tokens` is too long, this function will not be efficient as it
4255+
/// does a loop on the tokens with `peek_nth_token` each time.
4256+
pub fn peek_keyword_with_tokens(&mut self, expected: Keyword, tokens: &[Token]) -> bool {
4257+
self.keyword_with_tokens(expected, tokens, false)
4258+
}
4259+
4260+
fn keyword_with_tokens(&mut self, expected: Keyword, tokens: &[Token], consume: bool) -> bool {
42484261
match &self.peek_token_ref().token {
42494262
Token::Word(w) if expected == w.keyword => {
42504263
for (idx, token) in tokens.iter().enumerate() {
42514264
if self.peek_nth_token_ref(idx + 1).token != *token {
42524265
return false;
42534266
}
42544267
}
4255-
// consume all tokens
4256-
for _ in 0..(tokens.len() + 1) {
4257-
self.advance_token();
4268+
4269+
if consume {
4270+
for _ in 0..(tokens.len() + 1) {
4271+
self.advance_token();
4272+
}
42584273
}
4274+
42594275
true
42604276
}
42614277
_ => false,
@@ -13513,7 +13529,7 @@ impl<'a> Parser<'a> {
1351313529
self.prev_token();
1351413530
self.parse_xml_table_factor()
1351513531
} else if self.dialect.supports_semantic_view()
13516-
&& self.parse_keyword_with_tokens(Keyword::SEMANTIC_VIEW, &[Token::LParen])
13532+
&& self.peek_keyword_with_tokens(Keyword::SEMANTIC_VIEW, &[Token::LParen])
1351713533
{
1351813534
self.parse_semantic_view_table_factor()
1351913535
} else {
@@ -13849,6 +13865,9 @@ impl<'a> Parser<'a> {
1384913865

1385013866
/// Parse a [TableFactor::SemanticView]
1385113867
fn parse_semantic_view_table_factor(&mut self) -> Result<TableFactor, ParserError> {
13868+
self.expect_keyword(Keyword::SEMANTIC_VIEW)?;
13869+
self.expect_token(&Token::LParen)?;
13870+
1385213871
let name = self.parse_object_name(true)?;
1385313872

1385413873
// Parse DIMENSIONS, METRICS, FACTS and WHERE clauses in flexible order
@@ -18048,4 +18067,18 @@ mod tests {
1804818067
assert!(Parser::parse_sql(&GenericDialect, &sql).is_err());
1804918068
}
1805018069
}
18070+
18071+
#[test]
18072+
fn test_parse_semantic_view() {
18073+
let sql = r#"SEMANTIC_VIEW(model DIMENSIONS a.b METRICS c.d WHERE x > 0) AS sm"#;
18074+
let mut parser = Parser::new(&GenericDialect {})
18075+
.try_with_sql(sql)
18076+
.expect("failed to create parser");
18077+
18078+
let ast = parser
18079+
.parse_semantic_view_table_factor()
18080+
.expect("should parse SEMANTIC_VIEW");
18081+
18082+
assert!(matches!(ast, TableFactor::SemanticView { .. }));
18083+
}
1805118084
}

0 commit comments

Comments
 (0)