From a5ed2c68c25cf0893882fd92bfc3735683837430 Mon Sep 17 00:00:00 2001 From: Tanay Kulkarni Date: Thu, 31 Jul 2025 17:43:45 +0530 Subject: [PATCH] feat: Add TIMESTAMP_MILLIS and TIMESTAMP_MICROS support - Add TIMESTAMP_MILLIS and TIMESTAMP_MICROS functions to Spark parser (Spark 3.1+) - Add TIMESTAMP_MILLIS and TIMESTAMP_MICROS functions to Databricks parser - Convert microseconds to milliseconds by dividing by 1000 in E6 dialect - Use proper UnixToTime scale constants for consistency across dialects --- sqlglot/dialects/databricks.py | 6 ++++++ sqlglot/dialects/e6.py | 7 ++++++- sqlglot/dialects/spark.py | 6 ++++++ 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/sqlglot/dialects/databricks.py b/sqlglot/dialects/databricks.py index ebefaa1664..278ea203ed 100644 --- a/sqlglot/dialects/databricks.py +++ b/sqlglot/dialects/databricks.py @@ -116,6 +116,12 @@ class Parser(Spark.Parser): "TIMEDIFF": lambda args: exp.TimestampDiff( unit=seq_get(args, 0), this=seq_get(args, 1), expression=seq_get(args, 2) ), + "TIMESTAMP_MILLIS": lambda args: exp.UnixToTime( + this=seq_get(args, 0), scale=exp.UnixToTime.MILLIS + ), + "TIMESTAMP_MICROS": lambda args: exp.UnixToTime( + this=seq_get(args, 0), scale=exp.UnixToTime.MICROS + ), "TIMESTAMP_SECONDS": lambda args: exp.UnixToTime( this=seq_get(args, 0), scale=exp.Literal.string("seconds") ), diff --git a/sqlglot/dialects/e6.py b/sqlglot/dialects/e6.py index f5c0082dce..97106487ed 100644 --- a/sqlglot/dialects/e6.py +++ b/sqlglot/dialects/e6.py @@ -2121,6 +2121,11 @@ def from_unixtime_sql( # If scale is milliseconds, use FROM_UNIXTIME_WITHUNIT if scale_expr and scale_expr.this == "milliseconds": return self.func("FROM_UNIXTIME_WITHUNIT", unix_expr, scale_expr) + if scale_expr and scale_expr.this == "microseconds": + # Convert microseconds to milliseconds by dividing by 1000 + unix_expr_div = exp.Div(this=unix_expr, expression=exp.Literal.number(1000)) + scale_expr = exp.Literal.string("milliseconds") + return self.func("FROM_UNIXTIME_WITHUNIT", unix_expr_div, scale_expr) if not format_expr: return self.func("FROM_UNIXTIME", unix_expr) @@ -2445,7 +2450,7 @@ def split_sql(self, expression: exp.Split | exp.RegexpSplit): "thursday", "friday", "saturday", - "variant" + "variant", } UNSIGNED_TYPE_MAPPING = { diff --git a/sqlglot/dialects/spark.py b/sqlglot/dialects/spark.py index 0bddcfddaf..509f6a9e5a 100644 --- a/sqlglot/dialects/spark.py +++ b/sqlglot/dialects/spark.py @@ -123,6 +123,12 @@ class Parser(Spark2.Parser): "TYPEOF": lambda args: exp.TypeOf(this=seq_get(args, 0)), "TIMESTAMP_LTZ": _build_as_cast("TIMESTAMP_LTZ"), "TIMESTAMP_NTZ": _build_as_cast("TIMESTAMP_NTZ"), + "TIMESTAMP_MILLIS": lambda args: exp.UnixToTime( + this=seq_get(args, 0), scale=exp.UnixToTime.MILLIS + ), + "TIMESTAMP_MICROS": lambda args: exp.UnixToTime( + this=seq_get(args, 0), scale=exp.UnixToTime.MICROS + ), "TIMESTAMP_SECONDS": lambda args: exp.UnixToTime( this=seq_get(args, 0), scale=exp.Literal.string("seconds") ),