Skip to content

Commit 81f406f

Browse files
committed
Make SEMANTIC_VIEW parse method work on full expression
1 parent 3e34999 commit 81f406f

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
@@ -4241,17 +4241,33 @@ impl<'a> Parser<'a> {
42414241
/// not be efficient as it does a loop on the tokens with `peek_nth_token`
42424242
/// each time.
42434243
pub fn parse_keyword_with_tokens(&mut self, expected: Keyword, tokens: &[Token]) -> bool {
4244+
self.keyword_with_tokens(expected, tokens, true)
4245+
}
4246+
4247+
/// Peeks to see if the current token is the `expected` keyword followed by specified tokens
4248+
/// without consuming them.
4249+
///
4250+
/// Note that if the length of `tokens` is too long, this function will not be efficient as it
4251+
/// does a loop on the tokens with `peek_nth_token` each time.
4252+
pub fn peek_keyword_with_tokens(&mut self, expected: Keyword, tokens: &[Token]) -> bool {
4253+
self.keyword_with_tokens(expected, tokens, false)
4254+
}
4255+
4256+
fn keyword_with_tokens(&mut self, expected: Keyword, tokens: &[Token], consume: bool) -> bool {
42444257
match &self.peek_token_ref().token {
42454258
Token::Word(w) if expected == w.keyword => {
42464259
for (idx, token) in tokens.iter().enumerate() {
42474260
if self.peek_nth_token_ref(idx + 1).token != *token {
42484261
return false;
42494262
}
42504263
}
4251-
// consume all tokens
4252-
for _ in 0..(tokens.len() + 1) {
4253-
self.advance_token();
4264+
4265+
if consume {
4266+
for _ in 0..(tokens.len() + 1) {
4267+
self.advance_token();
4268+
}
42544269
}
4270+
42554271
true
42564272
}
42574273
_ => false,
@@ -13440,7 +13456,7 @@ impl<'a> Parser<'a> {
1344013456
self.prev_token();
1344113457
self.parse_xml_table_factor()
1344213458
} else if self.dialect.supports_semantic_view()
13443-
&& self.parse_keyword_with_tokens(Keyword::SEMANTIC_VIEW, &[Token::LParen])
13459+
&& self.peek_keyword_with_tokens(Keyword::SEMANTIC_VIEW, &[Token::LParen])
1344413460
{
1344513461
self.parse_semantic_view_table_factor()
1344613462
} else {
@@ -13776,6 +13792,9 @@ impl<'a> Parser<'a> {
1377613792

1377713793
/// Parse a [TableFactor::SemanticView]
1377813794
fn parse_semantic_view_table_factor(&mut self) -> Result<TableFactor, ParserError> {
13795+
self.expect_keyword(Keyword::SEMANTIC_VIEW)?;
13796+
self.expect_token(&Token::LParen)?;
13797+
1377913798
let name = self.parse_object_name(true)?;
1378013799

1378113800
// Parse DIMENSIONS, METRICS, FACTS and WHERE clauses in flexible order
@@ -17935,4 +17954,18 @@ mod tests {
1793517954
assert!(Parser::parse_sql(&GenericDialect, &sql).is_err());
1793617955
}
1793717956
}
17957+
17958+
#[test]
17959+
fn test_parse_semantic_view() {
17960+
let sql = r#"SEMANTIC_VIEW(model DIMENSIONS a.b METRICS c.d WHERE x > 0) AS sm"#;
17961+
let mut parser = Parser::new(&GenericDialect {})
17962+
.try_with_sql(sql)
17963+
.expect("failed to create parser");
17964+
17965+
let ast = parser
17966+
.parse_semantic_view_table_factor()
17967+
.expect("should parse SEMANTIC_VIEW");
17968+
17969+
assert!(matches!(ast, TableFactor::SemanticView { .. }));
17970+
}
1793817971
}

0 commit comments

Comments
 (0)