Skip to content

Commit

Permalink
feat: Support for MySQL & Redshift UnixTotime (#3223)
Browse files Browse the repository at this point in the history
* feat: Support for MySQL & Redshift UnixTotime

* First iteration
  • Loading branch information
VaggelisD committed Mar 26, 2024
1 parent e7c9158 commit b50dc5e
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 3 deletions.
2 changes: 2 additions & 0 deletions sqlglot/dialects/mysql.py
Expand Up @@ -291,6 +291,7 @@ class Parser(parser.Parser):
"DAYOFWEEK": lambda args: exp.DayOfWeek(this=exp.TsOrDsToDate(this=seq_get(args, 0))),
"DAYOFYEAR": lambda args: exp.DayOfYear(this=exp.TsOrDsToDate(this=seq_get(args, 0))),
"INSTR": lambda args: exp.StrPosition(substr=seq_get(args, 1), this=seq_get(args, 0)),
"FROM_UNIXTIME": build_formatted_time(exp.UnixToTime, "mysql"),
"ISNULL": isnull_to_is_null,
"LOCATE": locate_to_strposition,
"MAKETIME": exp.TimeFromParts.from_arg_list,
Expand Down Expand Up @@ -720,6 +721,7 @@ class Generator(generator.Generator):
exp.TsOrDsAdd: _date_add_sql("ADD"),
exp.TsOrDsDiff: lambda self, e: self.func("DATEDIFF", e.this, e.expression),
exp.TsOrDsToDate: _ts_or_ds_to_date_sql,
exp.UnixToTime: lambda self, e: self.func("FROM_UNIXTIME", e.this, self.format_time(e)),
exp.Week: _remove_ts_or_ds_to_date(),
exp.WeekOfYear: _remove_ts_or_ds_to_date(rename_func("WEEKOFYEAR")),
exp.Year: _remove_ts_or_ds_to_date(),
Expand Down
2 changes: 2 additions & 0 deletions sqlglot/dialects/redshift.py
Expand Up @@ -176,6 +176,8 @@ class Generator(Postgres.Generator):
exp.TableSample: no_tablesample_sql,
exp.TsOrDsAdd: date_delta_sql("DATEADD"),
exp.TsOrDsDiff: date_delta_sql("DATEDIFF"),
exp.UnixToTime: lambda self,
e: f"(TIMESTAMP 'epoch' + {self.sql(e.this)} * INTERVAL '1 SECOND')",
}

# Postgres maps exp.Pivot to no_pivot_sql, but Redshift support pivots
Expand Down
9 changes: 8 additions & 1 deletion sqlglot/expressions.py
Expand Up @@ -5707,7 +5707,14 @@ class UnixToStr(Func):
# https://prestodb.io/docs/current/functions/datetime.html
# presto has weird zone/hours/minutes
class UnixToTime(Func):
arg_types = {"this": True, "scale": False, "zone": False, "hours": False, "minutes": False}
arg_types = {
"this": True,
"scale": False,
"zone": False,
"hours": False,
"minutes": False,
"format": False,
}

SECONDS = Literal.number(0)
DECIS = Literal.number(1)
Expand Down
14 changes: 12 additions & 2 deletions tests/dialects/test_mysql.py
Expand Up @@ -513,9 +513,8 @@ def test_date_format(self):
)

def test_mysql_time(self):
self.validate_identity("FROM_UNIXTIME(a, b)")
self.validate_identity("FROM_UNIXTIME(a, b, c)")
self.validate_identity("TIME_STR_TO_UNIX(x)", "UNIX_TIMESTAMP(x)")
self.validate_identity("SELECT FROM_UNIXTIME(1711366265, '%Y %D %M')")
self.validate_all(
"SELECT TO_DAYS(x)",
write={
Expand Down Expand Up @@ -581,6 +580,17 @@ def test_mysql_time(self):
self.validate_all(
"STR_TO_DATE(x, '%Y-%m-%dT%T')", write={"presto": "DATE_PARSE(x, '%Y-%m-%dT%T')"}
)
self.validate_all(
"SELECT FROM_UNIXTIME(col)",
read={
"postgres": "SELECT TO_TIMESTAMP(col)",
},
write={
"mysql": "SELECT FROM_UNIXTIME(col)",
"postgres": "SELECT TO_TIMESTAMP(col)",
"redshift": "SELECT (TIMESTAMP 'epoch' + col * INTERVAL '1 SECOND')",
},
)

def test_mysql(self):
self.validate_all(
Expand Down

0 comments on commit b50dc5e

Please sign in to comment.