Skip to content

Commit 321051a

Browse files
authored
feat(presto, trino): Add support for exp.TimestampAdd (#3765)
1 parent 5df3f52 commit 321051a

File tree

3 files changed

+30
-12
lines changed

3 files changed

+30
-12
lines changed

sqlglot/dialects/presto.py

+20-12
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@
3535
from sqlglot.tokens import TokenType
3636
from sqlglot.transforms import unqualify_columns
3737

38+
DATE_ADD_OR_SUB = t.Union[exp.DateAdd, exp.TimestampAdd, exp.DateSub]
39+
3840

3941
def _explode_to_unnest_sql(self: Presto.Generator, expression: exp.Lateral) -> str:
4042
if isinstance(expression.this, exp.Explode):
@@ -223,6 +225,21 @@ def _build_to_char(args: t.List) -> exp.TimeToStr:
223225
return build_formatted_time(exp.TimeToStr, "teradata")(args)
224226

225227

228+
def _date_delta_sql(
229+
name: str, negate_interval: bool = False
230+
) -> t.Callable[[Presto.Generator, DATE_ADD_OR_SUB], str]:
231+
def _delta_sql(self: Presto.Generator, expression: DATE_ADD_OR_SUB) -> str:
232+
interval = _to_int(expression.expression)
233+
return self.func(
234+
name,
235+
unit_to_str(expression),
236+
interval * (-1) if negate_interval else interval,
237+
expression.this,
238+
)
239+
240+
return _delta_sql
241+
242+
226243
class Presto(Dialect):
227244
INDEX_OFFSET = 1
228245
NULL_ORDERING = "nulls_are_last"
@@ -385,24 +402,14 @@ class Generator(generator.Generator):
385402
exp.BitwiseXor: lambda self, e: self.func("BITWISE_XOR", e.this, e.expression),
386403
exp.Cast: transforms.preprocess([transforms.epoch_cast_to_ts]),
387404
exp.CurrentTimestamp: lambda *_: "CURRENT_TIMESTAMP",
388-
exp.DateAdd: lambda self, e: self.func(
389-
"DATE_ADD",
390-
unit_to_str(e),
391-
_to_int(e.expression),
392-
e.this,
393-
),
405+
exp.DateAdd: _date_delta_sql("DATE_ADD"),
394406
exp.DateDiff: lambda self, e: self.func(
395407
"DATE_DIFF", unit_to_str(e), e.expression, e.this
396408
),
397409
exp.DateStrToDate: datestrtodate_sql,
398410
exp.DateToDi: lambda self,
399411
e: f"CAST(DATE_FORMAT({self.sql(e, 'this')}, {Presto.DATEINT_FORMAT}) AS INT)",
400-
exp.DateSub: lambda self, e: self.func(
401-
"DATE_ADD",
402-
unit_to_str(e),
403-
_to_int(e.expression * -1),
404-
e.this,
405-
),
412+
exp.DateSub: _date_delta_sql("DATE_ADD", negate_interval=True),
406413
exp.Decode: lambda self, e: encode_decode_sql(self, e, "FROM_UTF8"),
407414
exp.DiToDate: lambda self,
408415
e: f"CAST(DATE_PARSE(CAST({self.sql(e, 'this')} AS VARCHAR), {Presto.DATEINT_FORMAT}) AS DATE)",
@@ -451,6 +458,7 @@ class Generator(generator.Generator):
451458
exp.StructExtract: struct_extract_sql,
452459
exp.Table: transforms.preprocess([_unnest_sequence]),
453460
exp.Timestamp: no_timestamp_sql,
461+
exp.TimestampAdd: _date_delta_sql("DATE_ADD"),
454462
exp.TimestampTrunc: timestamptrunc_sql(),
455463
exp.TimeStrToDate: timestrtotime_sql,
456464
exp.TimeStrToTime: timestrtotime_sql,

tests/dialects/test_presto.py

+8
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,14 @@ def test_time(self):
405405
)
406406
self.validate_identity("DATE_ADD('DAY', 1, y)")
407407

408+
self.validate_all(
409+
"SELECT DATE_ADD('MINUTE', 30, col)",
410+
write={
411+
"presto": "SELECT DATE_ADD('MINUTE', 30, col)",
412+
"trino": "SELECT DATE_ADD('MINUTE', 30, col)",
413+
},
414+
)
415+
408416
def test_ddl(self):
409417
self.validate_all(
410418
"CREATE TABLE test WITH (FORMAT = 'PARQUET') AS SELECT 1",

tests/dialects/test_spark.py

+2
Original file line numberDiff line numberDiff line change
@@ -684,6 +684,8 @@ def test_spark(self):
684684
write={
685685
"spark": "SELECT DATE_ADD(MONTH, 20, col)",
686686
"databricks": "SELECT DATE_ADD(MONTH, 20, col)",
687+
"presto": "SELECT DATE_ADD('MONTH', 20, col)",
688+
"trino": "SELECT DATE_ADD('MONTH', 20, col)",
687689
},
688690
)
689691

0 commit comments

Comments
 (0)