Skip to content

Commit

Permalink
Fix!: stop normalizing qualified anonymous functions (#3969)
Browse files Browse the repository at this point in the history
  • Loading branch information
georgesittas committed Aug 26, 2024
1 parent 48b214d commit 22bb9a0
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 7 deletions.
5 changes: 3 additions & 2 deletions sqlglot/dialects/tsql.py
Original file line number Diff line number Diff line change
Expand Up @@ -351,12 +351,13 @@ def _timestrtotime_sql(self: TSQL.Generator, expression: exp.TimeStrToTime):


class TSQL(Dialect):
NORMALIZATION_STRATEGY = NormalizationStrategy.CASE_INSENSITIVE
TIME_FORMAT = "'yyyy-mm-dd hh:mm:ss'"
SUPPORTS_SEMI_ANTI_JOIN = False
LOG_BASE_FIRST = False
TYPED_DIVISION = True
CONCAT_COALESCE = True
NORMALIZATION_STRATEGY = NormalizationStrategy.CASE_INSENSITIVE

TIME_FORMAT = "'yyyy-mm-dd hh:mm:ss'"

TIME_MAPPING = {
"year": "%Y",
Expand Down
11 changes: 9 additions & 2 deletions sqlglot/generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -2888,7 +2888,12 @@ def reference_sql(self, expression: exp.Reference) -> str:
return f"REFERENCES {this}{expressions}{options}"

def anonymous_sql(self, expression: exp.Anonymous) -> str:
return self.func(self.sql(expression, "this"), *expression.expressions)
# We don't normalize qualified functions such as a.b.foo(), because they can be case-sensitive
parent = expression.parent
is_qualified = isinstance(parent, exp.Dot) and expression is parent.expression
return self.func(
self.sql(expression, "this"), *expression.expressions, normalize=not is_qualified
)

def paren_sql(self, expression: exp.Paren) -> str:
sql = self.seg(self.indent(self.sql(expression, "this")), sep="")
Expand Down Expand Up @@ -3397,8 +3402,10 @@ def func(
*args: t.Optional[exp.Expression | str],
prefix: str = "(",
suffix: str = ")",
normalize: bool = True,
) -> str:
return f"{self.normalize_func(name)}{prefix}{self.format_args(*args)}{suffix}"
name = self.normalize_func(name) if normalize else name
return f"{name}{prefix}{self.format_args(*args)}{suffix}"

def format_args(self, *args: t.Optional[str | exp.Expression]) -> str:
arg_sqls = tuple(
Expand Down
2 changes: 1 addition & 1 deletion tests/dialects/test_oracle.py
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,7 @@ def test_xml_table(self):
FROM XMLTABLE(
'ROWSET/ROW'
PASSING
dbms_xmlgen.GETXMLTYPE('SELECT table_name, column_name, data_default FROM user_tab_columns')
dbms_xmlgen.getxmltype('SELECT table_name, column_name, data_default FROM user_tab_columns')
COLUMNS
table_name VARCHAR2(128) PATH '*[1]',
column_name VARCHAR2(128) PATH '*[2]',
Expand Down
7 changes: 5 additions & 2 deletions tests/dialects/test_tsql.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ def test_tsql(self):
self.validate_identity("1 AND true", "1 <> 0 AND (1 = 1)")
self.validate_identity("CAST(x AS int) OR y", "CAST(x AS INTEGER) <> 0 OR y <> 0")
self.validate_identity("TRUNCATE TABLE t1 WITH (PARTITIONS(1, 2 TO 5, 10 TO 20, 84))")
self.validate_identity(
"SELECT TOP 10 s.RECORDID, n.c.value('(/*:FORM_ROOT/*:SOME_TAG)[1]', 'float') AS SOME_TAG_VALUE FROM source_table.dbo.source_data AS s(nolock) CROSS APPLY FormContent.nodes('/*:FORM_ROOT') AS N(C)"
)
self.validate_identity(
"CREATE CLUSTERED INDEX [IX_OfficeTagDetail_TagDetailID] ON [dbo].[OfficeTagDetail]([TagDetailID] ASC)"
)
Expand Down Expand Up @@ -1577,8 +1580,8 @@ def test_lateral_table_valued_function(self):
self.validate_all(
"SELECT t.x, y.z FROM x OUTER APPLY a.b.tvfTest(t.x)y(z)",
write={
"spark": "SELECT t.x, y.z FROM x LEFT JOIN LATERAL a.b.TVFTEST(t.x) AS y(z)",
"tsql": "SELECT t.x, y.z FROM x OUTER APPLY a.b.TVFTEST(t.x) AS y(z)",
"spark": "SELECT t.x, y.z FROM x LEFT JOIN LATERAL a.b.tvfTest(t.x) AS y(z)",
"tsql": "SELECT t.x, y.z FROM x OUTER APPLY a.b.tvfTest(t.x) AS y(z)",
},
)

Expand Down

0 comments on commit 22bb9a0

Please sign in to comment.