Skip to content

Commit a37c193

Browse files
committed
Reduce duplication in parse_cte
1 parent e2a82e5 commit a37c193

File tree

1 file changed

+57
-80
lines changed

1 file changed

+57
-80
lines changed

src/parser/mod.rs

Lines changed: 57 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -14064,93 +14064,70 @@ impl<'a> Parser<'a> {
1406414064
pub fn parse_cte(&mut self) -> Result<Cte, ParserError> {
1406514065
let name = self.parse_identifier()?;
1406614066

14067-
let mut cte = if self.parse_keyword(Keyword::AS) {
14068-
let mut is_materialized = None;
14069-
if dialect_of!(self is PostgreSqlDialect) {
14070-
if self.parse_keyword(Keyword::MATERIALIZED) {
14071-
is_materialized = Some(CteAsMaterialized::Materialized);
14072-
} else if self.parse_keywords(&[Keyword::NOT, Keyword::MATERIALIZED]) {
14073-
is_materialized = Some(CteAsMaterialized::NotMaterialized);
14074-
}
14075-
}
14076-
self.expect_token(&Token::LParen)?;
14077-
14078-
let query = self.parse_query()?;
14079-
let closing_paren_token = self.expect_token(&Token::RParen)?;
14080-
14081-
let alias = TableAlias {
14082-
explicit: false,
14083-
name,
14084-
columns: vec![],
14085-
};
14086-
Cte {
14087-
alias,
14088-
query,
14089-
from: None,
14090-
materialized: is_materialized,
14091-
closing_paren_token: closing_paren_token.into(),
14092-
}
14093-
} else {
14094-
let as_optional = self.dialect.supports_cte_without_as();
14095-
let opt_query = if as_optional {
14096-
self.maybe_parse(|p| {
14097-
p.expect_token(&Token::LParen)?;
14098-
let query = p.parse_query()?;
14099-
let closing_paren_token = p.expect_token(&Token::RParen)?;
14100-
Ok((query, closing_paren_token))
14101-
})?
14102-
} else {
14103-
None
14104-
};
14105-
match opt_query {
14106-
Some((query, closing_paren_token)) => {
14107-
let alias = TableAlias {
14067+
let as_optional = self.dialect.supports_cte_without_as();
14068+
14069+
// If AS is optional, first try to parse `name (query)` directly
14070+
if as_optional && !self.peek_keyword(Keyword::AS) {
14071+
if let Some((query, closing_paren_token)) = self.maybe_parse(|p| {
14072+
p.expect_token(&Token::LParen)?;
14073+
let query = p.parse_query()?;
14074+
let closing_paren_token = p.expect_token(&Token::RParen)?;
14075+
Ok((query, closing_paren_token))
14076+
})? {
14077+
let mut cte = Cte {
14078+
alias: TableAlias {
1410814079
explicit: false,
1410914080
name,
1411014081
columns: vec![],
14111-
};
14112-
Cte {
14113-
alias,
14114-
query,
14115-
from: None,
14116-
materialized: None,
14117-
closing_paren_token: closing_paren_token.into(),
14118-
}
14082+
},
14083+
query,
14084+
from: None,
14085+
materialized: None,
14086+
closing_paren_token: closing_paren_token.into(),
14087+
};
14088+
if self.parse_keyword(Keyword::FROM) {
14089+
cte.from = Some(self.parse_identifier()?);
1411914090
}
14120-
None => {
14121-
let columns = self.parse_table_alias_column_defs()?;
14122-
if as_optional {
14123-
let _ = self.parse_keyword(Keyword::AS);
14124-
} else {
14125-
self.expect_keyword_is(Keyword::AS)?;
14126-
}
14127-
let mut is_materialized = None;
14128-
if dialect_of!(self is PostgreSqlDialect) {
14129-
if self.parse_keyword(Keyword::MATERIALIZED) {
14130-
is_materialized = Some(CteAsMaterialized::Materialized);
14131-
} else if self.parse_keywords(&[Keyword::NOT, Keyword::MATERIALIZED]) {
14132-
is_materialized = Some(CteAsMaterialized::NotMaterialized);
14133-
}
14134-
}
14135-
self.expect_token(&Token::LParen)?;
14091+
return Ok(cte);
14092+
}
14093+
}
1413614094

14137-
let query = self.parse_query()?;
14138-
let closing_paren_token = self.expect_token(&Token::RParen)?;
14095+
// Determine column definitions and consume AS
14096+
let columns = if self.parse_keyword(Keyword::AS) {
14097+
vec![]
14098+
} else {
14099+
let columns = self.parse_table_alias_column_defs()?;
14100+
if as_optional {
14101+
let _ = self.parse_keyword(Keyword::AS);
14102+
} else {
14103+
self.expect_keyword_is(Keyword::AS)?;
14104+
}
14105+
columns
14106+
};
1413914107

14140-
let alias = TableAlias {
14141-
explicit: false,
14142-
name,
14143-
columns,
14144-
};
14145-
Cte {
14146-
alias,
14147-
query,
14148-
from: None,
14149-
materialized: is_materialized,
14150-
closing_paren_token: closing_paren_token.into(),
14151-
}
14152-
}
14108+
let mut is_materialized = None;
14109+
if dialect_of!(self is PostgreSqlDialect) {
14110+
if self.parse_keyword(Keyword::MATERIALIZED) {
14111+
is_materialized = Some(CteAsMaterialized::Materialized);
14112+
} else if self.parse_keywords(&[Keyword::NOT, Keyword::MATERIALIZED]) {
14113+
is_materialized = Some(CteAsMaterialized::NotMaterialized);
1415314114
}
14115+
}
14116+
14117+
self.expect_token(&Token::LParen)?;
14118+
let query = self.parse_query()?;
14119+
let closing_paren_token = self.expect_token(&Token::RParen)?;
14120+
14121+
let mut cte = Cte {
14122+
alias: TableAlias {
14123+
explicit: false,
14124+
name,
14125+
columns,
14126+
},
14127+
query,
14128+
from: None,
14129+
materialized: is_materialized,
14130+
closing_paren_token: closing_paren_token.into(),
1415414131
};
1415514132
if self.parse_keyword(Keyword::FROM) {
1415614133
cte.from = Some(self.parse_identifier()?);

0 commit comments

Comments
 (0)