From 8e2e806973471e45dd9a3e82c8d73ec795daec80 Mon Sep 17 00:00:00 2001 From: tkaunlaky-e6 Date: Wed, 4 Mar 2026 16:44:37 +0530 Subject: [PATCH] Fix UNIX_TIMESTAMP transpilation: add CAST(... AS TIMESTAMP) and remove FLOOR E6's TO_UNIX_TIMESTAMP only accepts TIMESTAMP/DATE types, not integers or strings. This wraps the argument in CAST(... AS TIMESTAMP) for the no-format branch. Also removes the redundant FLOOR wrapper since E6 returns milliseconds as a long and integer division by 1000 already truncates. Before: FLOOR(TO_UNIX_TIMESTAMP(column) / 1000) After: TO_UNIX_TIMESTAMP(CAST(column AS TIMESTAMP)) / 1000 --- sqlglot/dialects/e6.py | 24 ++++++++++-------------- tests/dialects/test_e6.py | 16 ++++++++-------- 2 files changed, 18 insertions(+), 22 deletions(-) diff --git a/sqlglot/dialects/e6.py b/sqlglot/dialects/e6.py index 3e1ab6b2a8..65832dc0fe 100644 --- a/sqlglot/dialects/e6.py +++ b/sqlglot/dialects/e6.py @@ -2460,24 +2460,20 @@ def to_unix_timestamp_sql( this="TO_UNIX_TIMESTAMP", expressions=[parse_datetime_expr] ) div_expr = exp.Div(this=to_unix_expr, expression=exp.Literal.number("1000")) + return self.sql(div_expr) - if isinstance(expression.parent, (exp.UnixToTime, exp.UnixToStr)): - return self.sql(div_expr) - - # Wrap in FLOOR using exp.Floor - floor_expr = exp.Floor(this=div_expr) - return self.sql(floor_expr) + # Wrap argument in CAST(... AS TIMESTAMP) since E6's TO_UNIX_TIMESTAMP + # only accepts TIMESTAMP/DATE types, not integers or strings + if not ( + isinstance(time_expr, exp.Cast) + and time_expr.to.is_type(exp.DataType.Type.TIMESTAMP) + ): + time_expr = exp.Cast(this=time_expr, to=exp.DataType.build("TIMESTAMP")) - # Build expression tree for TO_UNIX_TIMESTAMP(...) / 1000 + # Build expression tree for TO_UNIX_TIMESTAMP(CAST(... AS TIMESTAMP)) / 1000 to_unix_expr = exp.Anonymous(this="TO_UNIX_TIMESTAMP", expressions=[time_expr]) div_expr = exp.Div(this=to_unix_expr, expression=exp.Literal.number("1000")) - - if isinstance(expression.parent, (exp.UnixToTime, exp.UnixToStr)): - return self.sql(div_expr) - - # For direct column/expression without format, wrap in FLOOR using exp.Floor - floor_expr = exp.Floor(this=div_expr) - return self.sql(floor_expr) + return self.sql(div_expr) def lateral_sql(self, expression: exp.Lateral) -> str: expression.set("view", True) diff --git a/tests/dialects/test_e6.py b/tests/dialects/test_e6.py index 4d2f94fb25..1525aae7be 100644 --- a/tests/dialects/test_e6.py +++ b/tests/dialects/test_e6.py @@ -2277,38 +2277,38 @@ def test_unixtime_functions(self): ) self.validate_all( - "SELECT FLOOR(TO_UNIX_TIMESTAMP(PARSE_DATETIME('%Y-%m-%d', '2016-04-08')) / 1000)", + "SELECT TO_UNIX_TIMESTAMP(PARSE_DATETIME('%Y-%m-%d', '2016-04-08')) / 1000", read={"databricks": "SELECT unix_timestamp('2016-04-08', 'yyyy-MM-dd')"}, ) self.validate_all( - "SELECT FLOOR(TO_UNIX_TIMESTAMP('2016-04-08') / 1000)", + "SELECT TO_UNIX_TIMESTAMP(CAST('2016-04-08' AS TIMESTAMP)) / 1000", read={"databricks": "SELECT to_unix_timestamp('2016-04-08')"}, ) self.validate_all( - "SELECT FLOOR(TO_UNIX_TIMESTAMP(A) / 1000)", + "SELECT TO_UNIX_TIMESTAMP(CAST(A AS TIMESTAMP)) / 1000", read={"databricks": "SELECT UNIX_TIMESTAMP(A)", "trino": "SELECT TO_UNIXTIME(A)"}, write={ - "databricks": "SELECT TO_UNIX_TIMESTAMP(A) / 1000", - "snowflake": "SELECT EXTRACT(epoch_second FROM A) / 1000", + "databricks": "SELECT TO_UNIX_TIMESTAMP(CAST(A AS TIMESTAMP)) / 1000", + "snowflake": "SELECT EXTRACT(epoch_second FROM CAST(A AS TIMESTAMP)) / 1000", }, ) self.validate_all( - "SELECT FLOOR(TO_UNIX_TIMESTAMP(CURRENT_TIMESTAMP) / 1000)", + "SELECT TO_UNIX_TIMESTAMP(CAST(CURRENT_TIMESTAMP AS TIMESTAMP)) / 1000", read={"databricks": "SELECT UNIX_TIMESTAMP()"}, ) self.validate_all( - "SELECT * FROM events WHERE event_time >= FLOOR(TO_UNIX_TIMESTAMP(PARSE_DATETIME('%Y-%m-%d', '2023-01-01')) / 1000) AND event_time < FLOOR(TO_UNIX_TIMESTAMP(PARSE_DATETIME('%Y-%m-%d', '2023-02-01')) / 1000)", + "SELECT * FROM events WHERE event_time >= TO_UNIX_TIMESTAMP(PARSE_DATETIME('%Y-%m-%d', '2023-01-01')) / 1000 AND event_time < TO_UNIX_TIMESTAMP(PARSE_DATETIME('%Y-%m-%d', '2023-02-01')) / 1000", read={ "databricks": "SELECT * FROM events WHERE event_time >= unix_timestamp('2023-01-01', 'yyyy-MM-dd') AND event_time < unix_timestamp('2023-02-01', 'yyyy-MM-dd')" }, ) self.validate_all( - "SELECT FLOOR(TO_UNIX_TIMESTAMP(PARSE_DATETIME('%Y-%m-%d %h:%i:%S', '2016-04-08 12:10:15')) / 1000)", + "SELECT TO_UNIX_TIMESTAMP(PARSE_DATETIME('%Y-%m-%d %h:%i:%S', '2016-04-08 12:10:15')) / 1000", read={ "databricks": "SELECT to_unix_timestamp('2016-04-08 12:10:15', 'yyyy-LL-dd hh:mm:ss')" },