Repository: tobymao/sqlglot

Issue:
cannot correctly convert syntax "timestamp 'epoch'" from redshift to presto/trino
```
sql = """

select CAST(
    DATE_TRUNC( 
    'day', 
    timestamp 'epoch' + creation_time * interval '1 second' 
    ) AS DATE
) AS dt

"""
sqlglot.transpile(sql, read="redshift", write="trino")[0]
```

the output is:
`"SELECT TRY_CAST(DATE_TRUNC('day', CAST('epoch' AS TIMESTAMP) + creation_time * INTERVAL '1' second) AS DATE) AS dt"`

trino would throw the error when executing the above sql: `Value cannot be cast to timestamp: epoch`



Discussion:
spark and postgres both support cast('epoch' as timestamp/date)

Resolving patch:
diff --git a/sqlglot/dialects/presto.py b/sqlglot/dialects/presto.py
--- a/sqlglot/dialects/presto.py
+++ b/sqlglot/dialects/presto.py
@@ -272,6 +272,7 @@ class Generator(generator.Generator):
             exp.BitwiseOr: lambda self, e: f"BITWISE_OR({self.sql(e, 'this')}, {self.sql(e, 'expression')})",
             exp.BitwiseRightShift: lambda self, e: f"BITWISE_ARITHMETIC_SHIFT_RIGHT({self.sql(e, 'this')}, {self.sql(e, 'expression')})",
             exp.BitwiseXor: lambda self, e: f"BITWISE_XOR({self.sql(e, 'this')}, {self.sql(e, 'expression')})",
+            exp.Cast: transforms.preprocess([transforms.epoch_cast_to_ts]),
             exp.CurrentTimestamp: lambda *_: "CURRENT_TIMESTAMP",
             exp.DataType: _datatype_sql,
             exp.DateAdd: lambda self, e: self.func(
@@ -319,6 +320,7 @@ class Generator(generator.Generator):
             exp.TimeStrToUnix: lambda self, e: f"TO_UNIXTIME(DATE_PARSE({self.sql(e, 'this')}, {Presto.time_format}))",
             exp.TimeToStr: lambda self, e: f"DATE_FORMAT({self.sql(e, 'this')}, {self.format_time(e)})",
             exp.TimeToUnix: rename_func("TO_UNIXTIME"),
+            exp.TryCast: transforms.preprocess([transforms.epoch_cast_to_ts]),
             exp.TsOrDiToDi: lambda self, e: f"CAST(SUBSTR(REPLACE(CAST({self.sql(e, 'this')} AS VARCHAR), '-', ''), 1, 8) AS INT)",
             exp.TsOrDsAdd: _ts_or_ds_add_sql,
             exp.TsOrDsToDate: _ts_or_ds_to_date_sql,
diff --git a/sqlglot/transforms.py b/sqlglot/transforms.py
--- a/sqlglot/transforms.py
+++ b/sqlglot/transforms.py
@@ -268,6 +268,17 @@ def add_recursive_cte_column_names(expression: exp.Expression) -> exp.Expression
     return expression
 
 
+def epoch_cast_to_ts(expression: exp.Expression) -> exp.Expression:
+    if (
+        isinstance(expression, (exp.Cast, exp.TryCast))
+        and expression.name.lower() == "epoch"
+        and expression.to.this in exp.DataType.TEMPORAL_TYPES
+    ):
+        expression.this.replace(exp.Literal.string("1970-01-01 00:00:00"))
+
+    return expression
+
+
 def preprocess(
     transforms: t.List[t.Callable[[exp.Expression], exp.Expression]],
 ) -> t.Callable[[Generator, exp.Expression], str]:


Test patch:
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
@@ -6,6 +6,10 @@ class TestPresto(Validator):
     dialect = "presto"
 
     def test_cast(self):
+        self.validate_all(
+            "SELECT TRY_CAST('1970-01-01 00:00:00' AS TIMESTAMP)",
+            read={"postgres": "SELECT 'epoch'::TIMESTAMP"},
+        )
         self.validate_all(
             "FROM_BASE64(x)",
             read={