Repository: tobymao/sqlglot

Issue:
SQLGlot Fails if T-SQL FORMAT used with Culture Parameter
Repo:

```python
import sqlglot

sqlglot.parse_one("SELECT FORMAT(TimeStart, 'dddd', 'de-CH') FROM TableName", read="tsql")

```

Docs:  https://learn.microsoft.com/en-us/sql/t-sql/functions/format-transact-sql?view=sql-server-ver16 

The problematic line is to be found here: https://github.com/tobymao/sqlglot/blob/0746b6f96d9b8fad0d8fbea3e23170e8d56eb3ee/sqlglot/dialects/tsql.py#L82 


Discussion:

Patch:
diff --git a/sqlglot/dialects/tsql.py b/sqlglot/dialects/tsql.py
index a5089a16..b3b95384 100644
--- a/sqlglot/dialects/tsql.py
+++ b/sqlglot/dialects/tsql.py
@@ -79,22 +79,23 @@ def _format_time_lambda(
 
 
 def _parse_format(args: t.List) -> exp.Expression:
-    assert len(args) == 2
+    this = seq_get(args, 0)
+    fmt = seq_get(args, 1)
+    culture = seq_get(args, 2)
 
-    fmt = args[1]
-    number_fmt = fmt.name in TRANSPILE_SAFE_NUMBER_FMT or not DATE_FMT_RE.search(fmt.name)
+    number_fmt = fmt and (fmt.name in TRANSPILE_SAFE_NUMBER_FMT or not DATE_FMT_RE.search(fmt.name))
 
     if number_fmt:
-        return exp.NumberToStr(this=args[0], format=fmt)
+        return exp.NumberToStr(this=this, format=fmt, culture=culture)
 
-    return exp.TimeToStr(
-        this=args[0],
-        format=exp.Literal.string(
+    if fmt:
+        fmt = exp.Literal.string(
             format_time(fmt.name, TSQL.FORMAT_TIME_MAPPING)
             if len(fmt.name) == 1
             else format_time(fmt.name, TSQL.TIME_MAPPING)
-        ),
-    )
+        )
+
+    return exp.TimeToStr(this=this, format=fmt, culture=culture)
 
 
 def _parse_eomonth(args: t.List) -> exp.Expression:
@@ -147,7 +148,7 @@ def _format_sql(self: generator.Generator, expression: exp.NumberToStr | exp.Tim
             )
         )
     )
-    return self.func("FORMAT", expression.this, fmt)
+    return self.func("FORMAT", expression.this, fmt, expression.args.get("culture"))
 
 
 def _string_agg_sql(self: generator.Generator, expression: exp.GroupConcat) -> str:
diff --git a/sqlglot/expressions.py b/sqlglot/expressions.py
index 57b8bfa7..fa37892d 100644
--- a/sqlglot/expressions.py
+++ b/sqlglot/expressions.py
@@ -4649,7 +4649,7 @@ class StrToUnix(Func):
 
 
 class NumberToStr(Func):
-    arg_types = {"this": True, "format": True}
+    arg_types = {"this": True, "format": True, "culture": False}
 
 
 class FromBase(Func):
@@ -4686,7 +4686,7 @@ class StddevSamp(AggFunc):
 
 
 class TimeToStr(Func):
-    arg_types = {"this": True, "format": True}
+    arg_types = {"this": True, "format": True, "culture": False}
 
 
 class TimeToTimeStr(Func):


Test patch:
diff --git a/tests/dialects/test_tsql.py b/tests/dialects/test_tsql.py
index 9decd354..8b919d48 100644
--- a/tests/dialects/test_tsql.py
+++ b/tests/dialects/test_tsql.py
@@ -971,9 +971,12 @@ WHERE
         )
 
     def test_format(self):
+        self.validate_identity("SELECT FORMAT(foo, 'dddd', 'de-CH')")
+        self.validate_identity("SELECT FORMAT(EndOfDayRate, 'N', 'en-us')")
         self.validate_identity("SELECT FORMAT('01-01-1991', 'd.mm.yyyy')")
         self.validate_identity("SELECT FORMAT(12345, '###.###.###')")
         self.validate_identity("SELECT FORMAT(1234567, 'f')")
+
         self.validate_all(
             "SELECT FORMAT(1000000.01,'###,###.###')",
             write={"spark": "SELECT FORMAT_NUMBER(1000000.01, '###,###.###')"},