summaryrefslogtreecommitdiffstats
path: root/sqlglot/dialects/snowflake.py
diff options
context:
space:
mode:
Diffstat (limited to 'sqlglot/dialects/snowflake.py')
-rw-r--r--sqlglot/dialects/snowflake.py33
1 files changed, 32 insertions, 1 deletions
diff --git a/sqlglot/dialects/snowflake.py b/sqlglot/dialects/snowflake.py
index 19a427c..627258f 100644
--- a/sqlglot/dialects/snowflake.py
+++ b/sqlglot/dialects/snowflake.py
@@ -69,6 +69,35 @@ def _unix_to_time(self, expression):
raise ValueError("Improper scale for timestamp")
+# https://docs.snowflake.com/en/sql-reference/functions/date_part.html
+# https://docs.snowflake.com/en/sql-reference/functions-date-time.html#label-supported-date-time-parts
+def _parse_date_part(self):
+ this = self._parse_var() or self._parse_type()
+ self._match(TokenType.COMMA)
+ expression = self._parse_bitwise()
+
+ name = this.name.upper()
+ if name.startswith("EPOCH"):
+ if name.startswith("EPOCH_MILLISECOND"):
+ scale = 10**3
+ elif name.startswith("EPOCH_MICROSECOND"):
+ scale = 10**6
+ elif name.startswith("EPOCH_NANOSECOND"):
+ scale = 10**9
+ else:
+ scale = None
+
+ ts = self.expression(exp.Cast, this=expression, to=exp.DataType.build("TIMESTAMP"))
+ to_unix = self.expression(exp.TimeToUnix, this=ts)
+
+ if scale:
+ to_unix = exp.Mul(this=to_unix, expression=exp.Literal.number(scale))
+
+ return to_unix
+
+ return self.expression(exp.Extract, this=this, expression=expression)
+
+
class Snowflake(Dialect):
null_ordering = "nulls_are_large"
time_format = "'yyyy-mm-dd hh24:mi:ss'"
@@ -115,7 +144,7 @@ class Snowflake(Dialect):
FUNCTION_PARSERS = {
**Parser.FUNCTION_PARSERS,
- "DATE_PART": lambda self: self._parse_extract(),
+ "DATE_PART": _parse_date_part,
}
FUNC_TOKENS = {
@@ -161,9 +190,11 @@ class Snowflake(Dialect):
class Generator(Generator):
TRANSFORMS = {
**Generator.TRANSFORMS,
+ exp.ArrayConcat: rename_func("ARRAY_CAT"),
exp.If: rename_func("IFF"),
exp.StrToTime: lambda self, e: f"TO_TIMESTAMP({self.sql(e, 'this')}, {self.format_time(e)})",
exp.UnixToTime: _unix_to_time,
+ exp.TimeToUnix: lambda self, e: f"EXTRACT(epoch_second FROM {self.sql(e, 'this')})",
exp.Array: inline_array_sql,
exp.StrPosition: rename_func("POSITION"),
exp.Parameter: lambda self, e: f"${self.sql(e, 'this')}",