Skip to content

Commit 479b5ba

Browse files
authored
fix: Swap parser override order for macro IF under T-SQL (Issue #5823) (#5828)
Signed-off-by: Jagan Nalla <jagannalla1@gmail.com>
1 parent 9ba6a58 commit 479b5ba

2 files changed

Lines changed: 19 additions & 1 deletion

File tree

sqlmesh/core/dialect.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -556,6 +556,10 @@ def _parse_if(self: Parser) -> t.Optional[exp.Expr]:
556556
# to parse a statement / command to support the macro @IF(condition, statement)
557557
index = self._index
558558
try:
559+
if self.dialect == "tsql":
560+
if not (self._index >= 2 and self._tokens[self._index - 2].text == "@"):
561+
return self.__parse_if() # type: ignore
562+
return Parser.__parse_if(self) # type: ignore
559563
return self.__parse_if() # type: ignore
560564
except ParseError:
561565
self._retreat(index)
@@ -1133,8 +1137,8 @@ def extend_sqlglot() -> None:
11331137
_override(Parser, _parse_value)
11341138
_override(Parser, _parse_lambda)
11351139
_override(Parser, _parse_types)
1136-
_override(TSQL.Parser, Parser._parse_if)
11371140
_override(Parser, _parse_if)
1141+
_override(TSQL.Parser, Parser._parse_if)
11381142
_override(Parser, _parse_id_var)
11391143
_override(Parser, _parse_interval_span)
11401144
_override(Parser, _warn_unsupported)

tests/core/test_dialect.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -709,6 +709,20 @@ def test_conditional_statement():
709709
q = parse_one("@IF(cond, VACUUM ANALYZE);", read="postgres")
710710
assert q.sql(dialect="postgres") == "@IF(cond, VACUUM ANALYZE)"
711711

712+
# Verify that the original error case from issue #5823 (Required keyword: 'true' missing) is resolved.
713+
# It must be parsed as a macro function containing an Anonymous expression rather than exp.If.
714+
q = parse_one("@IF(1 = 1, ALTER TABLE x ADD y INT);", read="tsql")
715+
assert q.sql(dialect="tsql") == "@IF(1 = 1, ALTER TABLE x ADD y INTEGER)"
716+
assert isinstance(q.this, exp.Anonymous)
717+
assert q.this.name == "IF"
718+
719+
# Note: SQLGlot's fallback Command parser strips quotes from string literal tokens when parsing unparsed commands
720+
q = parse_one("@IF(cond, PRINT 'hello');", read="tsql")
721+
assert q.sql(dialect="tsql") == "@IF(cond, PRINT hello)"
722+
723+
q = parse_one("@IF(@runtime_stage = 'evaluating', SELECT 1);", read="tsql")
724+
assert q.sql(dialect="tsql") == "@IF(@runtime_stage = 'evaluating', SELECT 1)"
725+
712726

713727
def test_model_name_cannot_be_string():
714728
with pytest.raises(ParseError) as parse_error:

0 commit comments

Comments
 (0)