Repository: tobymao/sqlglot

Issue:
FROM_UNIXTIME has different types in Trino and SparkSQL
```FROM_UNIXTIME(`created`)``` in Trino SQL returns a datetime, but ```FROM_UNIXTIME(`created`)``` in SparkSQL returns a string, which can cause queries to fail.

I would expect:
```select FROM_UNIXTIME(`created`) from a``` # (read='trino') 
to convert to
```select CAST(FROM_UNIXTIME('created') as timestamp) from a``` # (write='spark')

https://docs.databricks.com/sql/language-manual/functions/from_unixtime.html
https://spark.apache.org/docs/3.0.0/api/sql/#from_unixtime



Discussion:

Resolving patch:
diff --git a/sqlglot/dialects/spark2.py b/sqlglot/dialects/spark2.py
--- a/sqlglot/dialects/spark2.py
+++ b/sqlglot/dialects/spark2.py
@@ -42,7 +42,7 @@ def _unix_to_time_sql(self: Hive.Generator, expression: exp.UnixToTime) -> str:
     scale = expression.args.get("scale")
     timestamp = self.sql(expression, "this")
     if scale is None:
-        return f"FROM_UNIXTIME({timestamp})"
+        return f"CAST(FROM_UNIXTIME({timestamp}) AS TIMESTAMP)"
     if scale == exp.UnixToTime.SECONDS:
         return f"TIMESTAMP_SECONDS({timestamp})"
     if scale == exp.UnixToTime.MILLIS:


Test patch:
diff --git a/tests/dialects/test_duckdb.py b/tests/dialects/test_duckdb.py
--- a/tests/dialects/test_duckdb.py
+++ b/tests/dialects/test_duckdb.py
@@ -24,7 +24,7 @@ def test_time(self):
                 "bigquery": "UNIX_TO_TIME(x / 1000)",
                 "duckdb": "TO_TIMESTAMP(x / 1000)",
                 "presto": "FROM_UNIXTIME(x / 1000)",
-                "spark": "FROM_UNIXTIME(x / 1000)",
+                "spark": "CAST(FROM_UNIXTIME(x / 1000) AS TIMESTAMP)",
             },
         )
         self.validate_all(
diff --git a/tests/dialects/test_presto.py b/tests/dialects/test_presto.py
--- a/tests/dialects/test_presto.py
+++ b/tests/dialects/test_presto.py
@@ -133,6 +133,14 @@ def test_time(self):
         self.validate_identity("TRIM(a, b)")
         self.validate_identity("VAR_POP(a)")
 
+        self.validate_all(
+            "SELECT FROM_UNIXTIME(col) FROM tbl",
+            write={
+                "presto": "SELECT FROM_UNIXTIME(col) FROM tbl",
+                "spark": "SELECT CAST(FROM_UNIXTIME(col) AS TIMESTAMP) FROM tbl",
+                "trino": "SELECT FROM_UNIXTIME(col) FROM tbl",
+            },
+        )
         self.validate_all(
             "DATE_FORMAT(x, '%Y-%m-%d %H:%i:%S')",
             write={
@@ -181,7 +189,7 @@ def test_time(self):
                 "duckdb": "TO_TIMESTAMP(x)",
                 "presto": "FROM_UNIXTIME(x)",
                 "hive": "FROM_UNIXTIME(x)",
-                "spark": "FROM_UNIXTIME(x)",
+                "spark": "CAST(FROM_UNIXTIME(x) AS TIMESTAMP)",
             },
         )
         self.validate_all(
diff --git a/tests/dialects/test_snowflake.py b/tests/dialects/test_snowflake.py
--- a/tests/dialects/test_snowflake.py
+++ b/tests/dialects/test_snowflake.py
@@ -227,7 +227,7 @@ def test_snowflake(self):
             write={
                 "bigquery": "SELECT UNIX_TO_TIME(1659981729)",
                 "snowflake": "SELECT TO_TIMESTAMP(1659981729)",
-                "spark": "SELECT FROM_UNIXTIME(1659981729)",
+                "spark": "SELECT CAST(FROM_UNIXTIME(1659981729) AS TIMESTAMP)",
             },
         )
         self.validate_all(
@@ -243,7 +243,7 @@ def test_snowflake(self):
             write={
                 "bigquery": "SELECT UNIX_TO_TIME('1659981729')",
                 "snowflake": "SELECT TO_TIMESTAMP('1659981729')",
-                "spark": "SELECT FROM_UNIXTIME('1659981729')",
+                "spark": "SELECT CAST(FROM_UNIXTIME('1659981729') AS TIMESTAMP)",
             },
         )
         self.validate_all(
diff --git a/tests/test_transpile.py b/tests/test_transpile.py
--- a/tests/test_transpile.py
+++ b/tests/test_transpile.py
@@ -479,7 +479,7 @@ def test_time(self):
         self.validate("UNIX_TO_STR(123, 'y')", "FROM_UNIXTIME(123, 'y')", write="spark")
         self.validate(
             "UNIX_TO_TIME(123)",
-            "FROM_UNIXTIME(123)",
+            "CAST(FROM_UNIXTIME(123) AS TIMESTAMP)",
             write="spark",
         )
         self.validate(