diff options
Diffstat (limited to 'sqlglot/dialects')
-rw-r--r-- | sqlglot/dialects/bigquery.py | 2 | ||||
-rw-r--r-- | sqlglot/dialects/dialect.py | 15 | ||||
-rw-r--r-- | sqlglot/dialects/drill.py | 3 | ||||
-rw-r--r-- | sqlglot/dialects/duckdb.py | 19 | ||||
-rw-r--r-- | sqlglot/dialects/snowflake.py | 2 |
5 files changed, 26 insertions, 15 deletions
diff --git a/sqlglot/dialects/bigquery.py b/sqlglot/dialects/bigquery.py index 7fd9e35..a75e802 100644 --- a/sqlglot/dialects/bigquery.py +++ b/sqlglot/dialects/bigquery.py @@ -13,6 +13,7 @@ from sqlglot.dialects.dialect import ( no_ilike_sql, rename_func, timestrtotime_sql, + ts_or_ds_to_date_sql, ) from sqlglot.helper import seq_get from sqlglot.tokens import TokenType @@ -233,6 +234,7 @@ class BigQuery(Dialect): exp.TimestampAdd: _date_add_sql("TIMESTAMP", "ADD"), exp.TimestampSub: _date_add_sql("TIMESTAMP", "SUB"), exp.TimeStrToTime: timestrtotime_sql, + exp.TsOrDsToDate: ts_or_ds_to_date_sql("bigquery"), exp.PartitionedByProperty: lambda self, e: f"PARTITION BY {self.sql(e, 'this')}", exp.VariancePop: rename_func("VAR_POP"), exp.Values: _derived_table_values_to_unnest, diff --git a/sqlglot/dialects/dialect.py b/sqlglot/dialects/dialect.py index f4e8fd4..af36256 100644 --- a/sqlglot/dialects/dialect.py +++ b/sqlglot/dialects/dialect.py @@ -423,3 +423,18 @@ def trim_sql(self: Generator, expression: exp.Trim) -> str: from_part = "FROM " if trim_type or remove_chars else "" collation = f" COLLATE {collation}" if collation else "" return f"TRIM({trim_type}{remove_chars}{from_part}{target}{collation})" + + +def str_to_time_sql(self, expression: exp.Expression) -> str: + return self.func("STRPTIME", expression.this, self.format_time(expression)) + + +def ts_or_ds_to_date_sql(dialect: str) -> t.Callable: + def _ts_or_ds_to_date_sql(self: Generator, expression: exp.TsOrDsToDate) -> str: + _dialect = Dialect.get_or_raise(dialect) + time_format = self.format_time(expression) + if time_format and time_format not in (_dialect.time_format, _dialect.date_format): + return f"CAST({str_to_time_sql(self, expression)} AS DATE)" + return f"CAST({self.sql(expression, 'this')} AS DATE)" + + return _ts_or_ds_to_date_sql diff --git a/sqlglot/dialects/drill.py b/sqlglot/dialects/drill.py index e9c42e1..afcf4d0 100644 --- a/sqlglot/dialects/drill.py +++ b/sqlglot/dialects/drill.py @@ -14,6 +14,7 @@ from sqlglot.dialects.dialect import ( rename_func, str_position_sql, timestrtotime_sql, + ts_or_ds_to_date_sql, ) @@ -147,7 +148,7 @@ class Drill(Dialect): exp.TimeToUnix: rename_func("UNIX_TIMESTAMP"), exp.TryCast: no_trycast_sql, exp.TsOrDsAdd: lambda self, e: f"DATE_ADD(CAST({self.sql(e, 'this')} AS DATE), {self.sql(exp.Interval(this=e.expression, unit=exp.Var(this='DAY')))})", - exp.TsOrDsToDate: _ts_or_ds_to_date_sql, + exp.TsOrDsToDate: ts_or_ds_to_date_sql("drill"), exp.TsOrDiToDi: lambda self, e: f"CAST(SUBSTR(REPLACE(CAST({self.sql(e, 'this')} AS VARCHAR), '-', ''), 1, 8) AS INT)", } diff --git a/sqlglot/dialects/duckdb.py b/sqlglot/dialects/duckdb.py index cfec9a4..6144101 100644 --- a/sqlglot/dialects/duckdb.py +++ b/sqlglot/dialects/duckdb.py @@ -14,29 +14,20 @@ from sqlglot.dialects.dialect import ( no_tablesample_sql, rename_func, str_position_sql, + str_to_time_sql, timestrtotime_sql, + ts_or_ds_to_date_sql, ) from sqlglot.helper import seq_get from sqlglot.tokens import TokenType -def _str_to_time_sql(self, expression): - return f"STRPTIME({self.sql(expression, 'this')}, {self.format_time(expression)})" - - def _ts_or_ds_add(self, expression): this = expression.args.get("this") unit = self.sql(expression, "unit").strip("'") or "DAY" return f"CAST({this} AS DATE) + {self.sql(exp.Interval(this=expression.expression, unit=unit))}" -def _ts_or_ds_to_date_sql(self, expression): - time_format = self.format_time(expression) - if time_format and time_format not in (DuckDB.time_format, DuckDB.date_format): - return f"CAST({_str_to_time_sql(self, expression)} AS DATE)" - return f"CAST({self.sql(expression, 'this')} AS DATE)" - - def _date_add(self, expression): this = self.sql(expression, "this") unit = self.sql(expression, "unit").strip("'") or "DAY" @@ -159,8 +150,8 @@ class DuckDB(Dialect): exp.Split: rename_func("STR_SPLIT"), exp.SortArray: _sort_array_sql, exp.StrPosition: str_position_sql, - exp.StrToDate: lambda self, e: f"CAST({_str_to_time_sql(self, e)} AS DATE)", - exp.StrToTime: _str_to_time_sql, + exp.StrToDate: lambda self, e: f"CAST({str_to_time_sql(self, e)} AS DATE)", + exp.StrToTime: str_to_time_sql, exp.StrToUnix: lambda self, e: f"EPOCH(STRPTIME({self.sql(e, 'this')}, {self.format_time(e)}))", exp.Struct: _struct_sql, exp.TableSample: no_tablesample_sql, @@ -171,7 +162,7 @@ class DuckDB(Dialect): exp.TimeToUnix: rename_func("EPOCH"), exp.TsOrDiToDi: lambda self, e: f"CAST(SUBSTR(REPLACE(CAST({self.sql(e, 'this')} AS TEXT), '-', ''), 1, 8) AS INT)", exp.TsOrDsAdd: _ts_or_ds_add, - exp.TsOrDsToDate: _ts_or_ds_to_date_sql, + exp.TsOrDsToDate: ts_or_ds_to_date_sql("duckdb"), exp.UnixToStr: lambda self, e: f"STRFTIME(TO_TIMESTAMP({self.sql(e, 'this')}), {self.format_time(e)})", exp.UnixToTime: rename_func("TO_TIMESTAMP"), exp.UnixToTimeStr: lambda self, e: f"CAST(TO_TIMESTAMP({self.sql(e, 'this')}) AS TEXT)", diff --git a/sqlglot/dialects/snowflake.py b/sqlglot/dialects/snowflake.py index bb46135..9342865 100644 --- a/sqlglot/dialects/snowflake.py +++ b/sqlglot/dialects/snowflake.py @@ -8,6 +8,7 @@ from sqlglot.dialects.dialect import ( inline_array_sql, rename_func, timestrtotime_sql, + ts_or_ds_to_date_sql, var_map_sql, ) from sqlglot.expressions import Literal @@ -236,6 +237,7 @@ class Snowflake(Dialect): exp.TimeStrToTime: timestrtotime_sql, exp.TimeToUnix: lambda self, e: f"EXTRACT(epoch_second FROM {self.sql(e, 'this')})", exp.Trim: lambda self, e: self.func("TRIM", e.this, e.expression), + exp.TsOrDsToDate: ts_or_ds_to_date_sql("snowflake"), exp.UnixToTime: _unix_to_time_sql, exp.DayOfWeek: rename_func("DAYOFWEEK"), } |