@@ -14060,7 +14060,7 @@ impl<'a> Parser<'a> {
1406014060 })
1406114061 }
1406214062
14063- /// Parse a CTE (`alias [( col1, col2, ... )] AS (subquery)`)
14063+ /// Parse a CTE (`alias [( col1, col2, ... )] [AS] (subquery)`)
1406414064 pub fn parse_cte(&mut self) -> Result<Cte, ParserError> {
1406514065 let name = self.parse_identifier()?;
1406614066
@@ -14090,9 +14090,33 @@ impl<'a> Parser<'a> {
1409014090 materialized: is_materialized,
1409114091 closing_paren_token: closing_paren_token.into(),
1409214092 }
14093+ } else if self.dialect.supports_cte_without_as()
14094+ && self.peek_token().token == Token::LParen
14095+ && self.is_query_start_token(&self.peek_nth_token(1))
14096+ {
14097+ self.expect_token(&Token::LParen)?;
14098+ let query = self.parse_query()?;
14099+ let closing_paren_token = self.expect_token(&Token::RParen)?;
14100+
14101+ let alias = TableAlias {
14102+ explicit: false,
14103+ name,
14104+ columns: vec![],
14105+ };
14106+ Cte {
14107+ alias,
14108+ query,
14109+ from: None,
14110+ materialized: None,
14111+ closing_paren_token: closing_paren_token.into(),
14112+ }
1409314113 } else {
1409414114 let columns = self.parse_table_alias_column_defs()?;
14095- self.expect_keyword_is(Keyword::AS)?;
14115+ if self.dialect.supports_cte_without_as() {
14116+ let _ = self.parse_keyword(Keyword::AS);
14117+ } else {
14118+ self.expect_keyword_is(Keyword::AS)?;
14119+ }
1409614120 let mut is_materialized = None;
1409714121 if dialect_of!(self is PostgreSqlDialect) {
1409814122 if self.parse_keyword(Keyword::MATERIALIZED) {
@@ -14125,6 +14149,23 @@ impl<'a> Parser<'a> {
1412514149 Ok(cte)
1412614150 }
1412714151
14152+ fn is_query_start_token(&self, token: &TokenWithSpan) -> bool {
14153+ match &token.token {
14154+ Token::Word(w) => {
14155+ matches!(
14156+ w.keyword,
14157+ Keyword::SELECT
14158+ | Keyword::WITH
14159+ | Keyword::VALUES
14160+ | Keyword::VALUE
14161+ | Keyword::TABLE
14162+ ) || (w.keyword == Keyword::FROM && self.dialect.supports_from_first_select())
14163+ }
14164+ Token::LParen => true,
14165+ _ => false,
14166+ }
14167+ }
14168+
1412814169 /// Parse a "query body", which is an expression with roughly the
1412914170 /// following grammar:
1413014171 /// ```sql
0 commit comments