Skip to content

Commit

Permalink
Fix!: improve support for interval spans like HOUR TO SECOND (#2167)
Browse files Browse the repository at this point in the history
  • Loading branch information
georgesittas authored Sep 6, 2023
1 parent 5dd0fda commit 3fc2eb5
Show file tree
Hide file tree
Showing 4 changed files with 15 additions and 16 deletions.
11 changes: 3 additions & 8 deletions sqlglot/expressions.py
Original file line number Diff line number Diff line change
Expand Up @@ -3992,16 +3992,11 @@ def __init__(self, **args):
super().__init__(**args)


# https://www.oracletutorial.com/oracle-basics/oracle-interval/
# https://trino.io/docs/current/language/types.html#interval-year-to-month
class IntervalYearToMonthSpan(Expression):
arg_types = {}


# https://www.oracletutorial.com/oracle-basics/oracle-interval/
# https://trino.io/docs/current/language/types.html#interval-day-to-second
class IntervalDayToSecondSpan(Expression):
arg_types = {}
# https://docs.databricks.com/en/sql/language-manual/data-types/interval-type.html
class IntervalSpan(Expression):
arg_types = {"this": True, "expression": True}


class Interval(TimeUnit):
Expand Down
3 changes: 1 addition & 2 deletions sqlglot/generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,7 @@ class Generator:
exp.ExternalProperty: lambda self, e: "EXTERNAL",
exp.HeapProperty: lambda self, e: "HEAP",
exp.InlineLengthColumnConstraint: lambda self, e: f"INLINE LENGTH {self.sql(e, 'this')}",
exp.IntervalDayToSecondSpan: "DAY TO SECOND",
exp.IntervalYearToMonthSpan: "YEAR TO MONTH",
exp.IntervalSpan: lambda self, e: f"{self.sql(e, 'this')} TO {self.sql(e, 'expression')}",
exp.LanguageProperty: lambda self, e: self.naked_property(e),
exp.LocationProperty: lambda self, e: self.naked_property(e),
exp.LogProperty: lambda self, e: f"{'NO ' if e.args.get('no') else ''}LOG",
Expand Down
11 changes: 5 additions & 6 deletions sqlglot/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -3325,15 +3325,14 @@ def _parse_types(
elif self._match_text_seq("WITHOUT", "TIME", "ZONE"):
maybe_func = False
elif type_token == TokenType.INTERVAL:
if self._match_text_seq("YEAR", "TO", "MONTH"):
span: t.Optional[t.List[exp.Expression]] = [exp.IntervalYearToMonthSpan()]
elif self._match_text_seq("DAY", "TO", "SECOND"):
span = [exp.IntervalDayToSecondSpan()]
unit = self._parse_var()

if self._match_text_seq("TO"):
span = [exp.IntervalSpan(this=unit, expression=self._parse_var())]
else:
span = None

unit = not span and self._parse_var()
if not unit:
if span or not unit:
this = self.expression(
exp.DataType, this=exp.DataType.Type.INTERVAL, expressions=span
)
Expand Down
6 changes: 6 additions & 0 deletions tests/dialects/test_databricks.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ class TestDatabricks(Validator):
dialect = "databricks"

def test_databricks(self):
self.validate_identity("SELECT CAST('11 23:4:0' AS INTERVAL DAY TO HOUR)")
self.validate_identity("SELECT CAST('11 23:4:0' AS INTERVAL DAY TO MINUTE)")
self.validate_identity("SELECT CAST('11 23:4:0' AS INTERVAL DAY TO SECOND)")
self.validate_identity("SELECT CAST('23:00:00' AS INTERVAL HOUR TO MINUTE)")
self.validate_identity("SELECT CAST('23:00:00' AS INTERVAL HOUR TO SECOND)")
self.validate_identity("SELECT CAST('23:00:00' AS INTERVAL MINUTE TO SECOND)")
self.validate_identity("CREATE TABLE target SHALLOW CLONE source")
self.validate_identity("INSERT INTO a REPLACE WHERE cond VALUES (1), (2)")
self.validate_identity("SELECT c1 : price")
Expand Down

0 comments on commit 3fc2eb5

Please sign in to comment.