Skip to content

Commit 96e810e

Browse files
committed
fix(dialect): support newer SQLGlot parser signatures
Signed-off-by: dvasdekis <dimitri.vasdekis@detsi.qld.gov.au>
1 parent 187a701 commit 96e810e

2 files changed

Lines changed: 40 additions & 6 deletions

File tree

sqlmesh/core/dialect.py

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -315,16 +315,26 @@ def _parse_with(self: Parser, skip_with_token: bool = False) -> t.Optional[exp.E
315315

316316

317317
def _parse_join(
318-
self: Parser, skip_join_token: bool = False, parse_bracket: bool = False
318+
self: Parser,
319+
skip_join_token: bool = False,
320+
parse_bracket: bool = False,
321+
alias_tokens: t.Optional[t.Collection[TokenType]] = None,
319322
) -> t.Optional[exp.Expr]:
320323
index = self._index
321324
method, side, kind = self._parse_join_parts()
322325
macro = _parse_matching_macro(self, "JOIN")
323326
if not macro:
324327
self._retreat(index)
325-
return self.__parse_join(skip_join_token=skip_join_token, parse_bracket=parse_bracket) # type: ignore
328+
parse_join = self.__parse_join # type: ignore
329+
if "alias_tokens" in parse_join.__code__.co_varnames:
330+
return parse_join(
331+
skip_join_token=skip_join_token,
332+
parse_bracket=parse_bracket,
333+
alias_tokens=alias_tokens,
334+
)
335+
return parse_join(skip_join_token=skip_join_token, parse_bracket=parse_bracket)
326336

327-
join = self.__parse_join(skip_join_token=True) # type: ignore
337+
join = self.__parse_join(skip_join_token=True, alias_tokens=alias_tokens) # type: ignore
328338
if method:
329339
join.set("method", method.text)
330340
if side:
@@ -575,7 +585,11 @@ def altercolumn_sql(self: Generator, expression: exp.AlterColumn) -> str:
575585
# sqlglot's generator returns as soon as it renders the type, so the nullability parsed
576586
# above has to be appended here
577587
allow_null = expression.args.get("allow_null")
578-
if expression.args.get("dtype") and allow_null is not None:
588+
if (
589+
expression.args.get("dtype")
590+
and allow_null is not None
591+
and not hasattr(self, "_alter_column_null_constraint_sql")
592+
):
579593
sql = f"{sql} NULL" if allow_null else f"{sql} NOT NULL"
580594

581595
return sql
@@ -800,8 +814,14 @@ def _whens_sql(self: Generator, expression: exp.Whens) -> str:
800814
return self.wrap(self.expressions(expression, sep=" ", indent=False))
801815

802816

803-
def _parse_interval_span(self: Parser, this: exp.Expr) -> exp.Interval:
804-
interval = self.__parse_interval_span(this) # type: ignore
817+
def _parse_interval_span(
818+
self: Parser, this: exp.Expr, parse_function_unit: bool = True
819+
) -> exp.Interval:
820+
parse_interval_span = self.__parse_interval_span # type: ignore
821+
if "parse_function_unit" in parse_interval_span.__code__.co_varnames:
822+
interval = parse_interval_span(this, parse_function_unit=parse_function_unit)
823+
else:
824+
interval = parse_interval_span(this)
805825
# Without this, @unit in `INTERVAL @value @unit` is misread as an alias.
806826
if not interval.args.get("unit") and self._match(TokenType.PARAMETER):
807827
macro = _parse_macro(self)

tests/core/test_dialect.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1027,6 +1027,20 @@ def test_tsql_alter_column_nullability():
10271027
)
10281028

10291029

1030+
def test_sqlglot_parser_signature_compatibility():
1031+
# SQLGlot passes UPDATE-specific alias tokens to _parse_join. The SQLMesh
1032+
# override must preserve those tokens when delegating to SQLGlot.
1033+
assert (
1034+
parse_one("UPDATE target JOIN source SET target.x = source.x", read="tsql").sql(
1035+
dialect="tsql"
1036+
)
1037+
== "UPDATE target, source SET target.x = source.x"
1038+
)
1039+
1040+
# SQLGlot 30.17 passes parse_function_unit to _parse_interval_span.
1041+
assert parse_one("INTERVAL '1' DAY").sql() == "INTERVAL '1' DAY"
1042+
1043+
10301044
def test_model_name_cannot_be_string():
10311045
with pytest.raises(ParseError) as parse_error:
10321046
parse(

0 commit comments

Comments
 (0)