Skip to content

Commit cead7c3

Browse files
authored
Fix(parser)!: require AS token in CTEs for all dialects except spark, databricks (#4546)
1 parent 931eef6 commit cead7c3

File tree

4 files changed

+14
-3
lines changed

4 files changed

+14
-3
lines changed

sqlglot/dialects/clickhouse.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -633,7 +633,7 @@ def _parse_position(self, haystack_first: bool = False) -> exp.StrPosition:
633633
return super()._parse_position(haystack_first=True)
634634

635635
# https://clickhouse.com/docs/en/sql-reference/statements/select/with/
636-
def _parse_cte(self) -> exp.CTE:
636+
def _parse_cte(self) -> t.Optional[exp.CTE]:
637637
# WITH <identifier> AS <subquery expression>
638638
cte: t.Optional[exp.CTE] = self._try_parse(super()._parse_cte)
639639

sqlglot/dialects/spark.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,8 @@ class Tokenizer(Spark2.Tokenizer):
102102
]
103103

104104
class Parser(Spark2.Parser):
105+
OPTIONAL_ALIAS_TOKEN_CTE = True
106+
105107
FUNCTIONS = {
106108
**Spark2.Parser.FUNCTIONS,
107109
"ANY_VALUE": _build_with_ignore_nulls(exp.AnyValue),

sqlglot/parser.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1379,6 +1379,9 @@ class Parser(metaclass=_Parser):
13791379
# Whether the `name AS expr` schema/column constraint requires parentheses around `expr`
13801380
WRAPPED_TRANSFORM_COLUMN_CONSTRAINT = True
13811381

1382+
# Whether the 'AS' keyword is optional in the CTE definition syntax
1383+
OPTIONAL_ALIAS_TOKEN_CTE = False
1384+
13821385
__slots__ = (
13831386
"error_level",
13841387
"error_message_context",
@@ -3131,12 +3134,17 @@ def _parse_with(self, skip_with_token: bool = False) -> t.Optional[exp.With]:
31313134
exp.With, comments=comments, expressions=expressions, recursive=recursive
31323135
)
31333136

3134-
def _parse_cte(self) -> exp.CTE:
3137+
def _parse_cte(self) -> t.Optional[exp.CTE]:
3138+
index = self._index
3139+
31353140
alias = self._parse_table_alias(self.ID_VAR_TOKENS)
31363141
if not alias or not alias.this:
31373142
self.raise_error("Expected CTE to have alias")
31383143

3139-
self._match(TokenType.ALIAS)
3144+
if not self._match(TokenType.ALIAS) and not self.OPTIONAL_ALIAS_TOKEN_CTE:
3145+
self._retreat(index)
3146+
return None
3147+
31403148
comments = self._prev_comments
31413149

31423150
if self._match_text_seq("NOT", "MATERIALIZED"):

tests/dialects/test_clickhouse.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ def test_clickhouse(self):
2929
self.assertEqual(expr.sql(dialect="clickhouse"), "COUNT(x)")
3030
self.assertIsNone(expr._meta)
3131

32+
self.validate_identity("WITH arrayJoin([(1, [2, 3])]) AS arr SELECT arr")
3233
self.validate_identity("CAST(1 AS Bool)")
3334
self.validate_identity("SELECT toString(CHAR(104.1, 101, 108.9, 108.9, 111, 32))")
3435
self.validate_identity("@macro").assert_is(exp.Parameter).this.assert_is(exp.Var)

0 commit comments

Comments
 (0)