Repository: tobymao/sqlglot

Issue:
Type error when converting datediff from redshift to trino 
```
sql = "select datediff(week,'2009-01-01','2009-12-31')"
converted_sql = sqlglot.transpile(sql, read="redshift", write="trino")[0]
print(converted_sql)
SELECT DATE_DIFF('week', '2009-01-01', '2009-12-31')
```

Trino error: `Unexpected parameters (varchar(4), varchar(10), varchar(10)) for function date_diff. Expected: date_diff(varchar(x), date, date), date_diff(varchar(x), timestamp(p), timestamp(p)), date_diff(varchar(x), timestamp(p) with time zone, timestamp(p) with time zone), date_diff(varchar(x), time(p), time(p)), date_diff(varchar(x), time(p) with time zone, time(p) with time zone)'
`

Changing the SQL to `SELECT DATE_DIFF('week', DATE'2009-01-01', DATE'2009-12-31')` works in Trino

https://trino.io/docs/current/functions/datetime.html

Comments:

Patch:
diff --git a/sqlglot/dialects/redshift.py b/sqlglot/dialects/redshift.py
index afed1d1e..b0a67749 100644
--- a/sqlglot/dialects/redshift.py
+++ b/sqlglot/dialects/redshift.py
@@ -25,13 +25,13 @@ class Redshift(Postgres):
         FUNCTIONS = {
             **Postgres.Parser.FUNCTIONS,
             "DATEADD": lambda args: exp.DateAdd(
-                this=seq_get(args, 2),
+                this=exp.TsOrDsToDate(this=seq_get(args, 2)),
                 expression=seq_get(args, 1),
                 unit=seq_get(args, 0),
             ),
             "DATEDIFF": lambda args: exp.DateDiff(
-                this=seq_get(args, 2),
-                expression=seq_get(args, 1),
+                this=exp.TsOrDsToDate(this=seq_get(args, 2)),
+                expression=exp.TsOrDsToDate(this=seq_get(args, 1)),
                 unit=seq_get(args, 0),
             ),
             "NVL": exp.Coalesce.from_arg_list,
@@ -103,11 +103,12 @@ class Redshift(Postgres):
             ),
             exp.DistKeyProperty: lambda self, e: f"DISTKEY({e.name})",
             exp.DistStyleProperty: lambda self, e: self.naked_property(e),
+            exp.FromBase: rename_func("STRTOL"),
             exp.JSONExtract: _json_sql,
             exp.JSONExtractScalar: _json_sql,
             exp.Select: transforms.preprocess([transforms.eliminate_distinct_on]),
             exp.SortKeyProperty: lambda self, e: f"{'COMPOUND ' if e.args['compound'] else ''}SORTKEY({self.format_args(*e.this)})",
-            exp.FromBase: rename_func("STRTOL"),
+            exp.TsOrDsToDate: lambda self, e: self.sql(e.this),
         }
 
         # Postgres maps exp.Pivot to no_pivot_sql, but Redshift support pivots


Test patch:
diff --git a/tests/dialects/test_presto.py b/tests/dialects/test_presto.py
index 0504576d..e3d09ef0 100644
--- a/tests/dialects/test_presto.py
+++ b/tests/dialects/test_presto.py
@@ -6,6 +6,14 @@ class TestPresto(Validator):
     dialect = "presto"
 
     def test_cast(self):
+        self.validate_all(
+            "SELECT DATE_DIFF('week', CAST(SUBSTR(CAST('2009-01-01' AS VARCHAR), 1, 10) AS DATE), CAST(SUBSTR(CAST('2009-12-31' AS VARCHAR), 1, 10) AS DATE))",
+            read={"redshift": "SELECT DATEDIFF(week, '2009-01-01', '2009-12-31')"},
+        )
+        self.validate_all(
+            "SELECT DATE_ADD('month', 18, CAST(SUBSTR(CAST('2008-02-28' AS VARCHAR), 1, 10) AS DATE))",
+            read={"redshift": "SELECT DATEADD(month, 18, '2008-02-28')"},
+        )
         self.validate_all(
             "SELECT TRY_CAST('1970-01-01 00:00:00' AS TIMESTAMP)",
             read={"postgres": "SELECT 'epoch'::TIMESTAMP"},
diff --git a/tests/dialects/test_redshift.py b/tests/dialects/test_redshift.py
index db5d72a9..f4efe24f 100644
--- a/tests/dialects/test_redshift.py
+++ b/tests/dialects/test_redshift.py
@@ -180,7 +180,7 @@ class TestRedshift(Validator):
             "DATEDIFF('day', a, b)",
             write={
                 "redshift": "DATEDIFF(day, a, b)",
-                "presto": "DATE_DIFF('day', a, b)",
+                "presto": "DATE_DIFF('day', CAST(SUBSTR(CAST(a AS VARCHAR), 1, 10) AS DATE), CAST(SUBSTR(CAST(b AS VARCHAR), 1, 10) AS DATE))",
             },
         )
         self.validate_all(