|
12 | 12 | rename_func, |
13 | 13 | strposition_sql, |
14 | 14 | timestrtotime_sql, |
15 | | - unit_to_str, |
16 | 15 | timestamptrunc_sql, |
17 | 16 | build_date_delta, |
18 | 17 | ) |
@@ -107,6 +106,27 @@ def prefix_local(node): |
107 | 106 | return expression |
108 | 107 |
|
109 | 108 |
|
| 109 | +def _trunc_sql(self: Exasol.Generator, kind: str, expression: exp.DateTrunc) -> str: |
| 110 | + unit = expression.text("unit") |
| 111 | + node = expression.this.this if isinstance(expression.this, exp.Cast) else expression.this |
| 112 | + expr_sql = self.sql(node) |
| 113 | + if isinstance(node, exp.Literal) and node.is_string: |
| 114 | + expr_sql = ( |
| 115 | + f"{kind} '{node.this.replace('T', ' ')}'" |
| 116 | + if kind == "TIMESTAMP" |
| 117 | + else f"DATE '{node.this}'" |
| 118 | + ) |
| 119 | + return f"DATE_TRUNC('{unit}', {expr_sql})" |
| 120 | + |
| 121 | + |
| 122 | +def _date_trunc_sql(self: Exasol.Generator, expression: exp.DateTrunc) -> str: |
| 123 | + return _trunc_sql(self, "DATE", expression) |
| 124 | + |
| 125 | + |
| 126 | +def _timestamp_trunc_sql(self: Exasol.Generator, expression: exp.DateTrunc) -> str: |
| 127 | + return _trunc_sql(self, "TIMESTAMP", expression) |
| 128 | + |
| 129 | + |
110 | 130 | DATE_UNITS = {"DAY", "WEEK", "MONTH", "YEAR", "HOUR", "MINUTE", "SECOND"} |
111 | 131 |
|
112 | 132 |
|
@@ -308,7 +328,7 @@ def datatype_sql(self, expression: exp.DataType) -> str: |
308 | 328 | # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/div.htm#DIV |
309 | 329 | exp.IntDiv: rename_func("DIV"), |
310 | 330 | exp.TsOrDsDiff: _date_diff_sql, |
311 | | - exp.DateTrunc: lambda self, e: self.func("TRUNC", e.this, unit_to_str(e)), |
| 331 | + exp.DateTrunc: _date_trunc_sql, |
312 | 332 | exp.DayOfWeek: lambda self, e: f"CAST(TO_CHAR({self.sql(e, 'this')}, 'D') AS INTEGER)", |
313 | 333 | exp.DatetimeTrunc: timestamptrunc_sql(), |
314 | 334 | exp.GroupConcat: lambda self, e: groupconcat_sql( |
@@ -338,7 +358,7 @@ def datatype_sql(self, expression: exp.DataType) -> str: |
338 | 358 | exp.TsOrDsToDate: lambda self, e: self.func("TO_DATE", e.this, self.format_time(e)), |
339 | 359 | exp.TimeToStr: lambda self, e: self.func("TO_CHAR", e.this, self.format_time(e)), |
340 | 360 | exp.TimeStrToTime: timestrtotime_sql, |
341 | | - exp.TimestampTrunc: timestamptrunc_sql(), |
| 361 | + exp.TimestampTrunc: _timestamp_trunc_sql, |
342 | 362 | exp.StrToTime: lambda self, e: self.func("TO_DATE", e.this, self.format_time(e)), |
343 | 363 | exp.CurrentUser: lambda *_: "CURRENT_USER", |
344 | 364 | exp.AtTimeZone: lambda self, e: self.func( |
@@ -373,6 +393,7 @@ def datatype_sql(self, expression: exp.DataType) -> str: |
373 | 393 | exp.Date: rename_func("TO_DATE"), |
374 | 394 | # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/to_timestamp.htm |
375 | 395 | exp.Timestamp: rename_func("TO_TIMESTAMP"), |
| 396 | + exp.Quarter: lambda self, e: f"CEIL(MONTH(TO_DATE({self.sql(e, 'this')}))/3)", |
376 | 397 | } |
377 | 398 |
|
378 | 399 | def converttimezone_sql(self, expression: exp.ConvertTimezone) -> str: |
|
0 commit comments