Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ private static String unitRegex(String unit) {
private static Pattern yearMonthPattern =
Pattern.compile("^(?:['|\"])?([+|-])?(\\d+)-(\\d+)(?:['|\"])?$");

private static Pattern dayTimePattern =
Pattern.compile("^(?:['|\"])?([+|-])?((\\d+) )?(\\d+):(\\d+):(\\d+)(\\.(\\d+))?(?:['|\"])?$");
private static Pattern dayTimePattern = Pattern.compile(
"^(?:['|\"])?([+|-])?((\\d+) )?(\\d+):(\\d+)(:(\\d+))?(\\.(\\d+))?(?:['|\"])?$");

private static Pattern quoteTrimPattern = Pattern.compile("^(?:['|\"])?(.*?)(?:['|\"])?$");

Expand Down Expand Up @@ -159,8 +159,13 @@ public static CalendarInterval fromYearMonthString(String s) throws IllegalArgum
*
* adapted from HiveIntervalDayTime.valueOf
*/
public static CalendarInterval fromDayTimeString(String s) throws IllegalArgumentException {
CalendarInterval result = null;
public static CalendarInterval fromDayTimeString(String s) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We still need throws IllegalArgumentException here.

return fromDayTimeString(s, "day", "second");
}

public static CalendarInterval fromDayTimeString(String s, String from, String to)
throws IllegalArgumentException {
CalendarInterval result;
if (s == null) {
throw new IllegalArgumentException("Interval day-time string was null");
}
Expand All @@ -174,11 +179,41 @@ public static CalendarInterval fromDayTimeString(String s) throws IllegalArgumen
int sign = m.group(1) != null && m.group(1).equals("-") ? -1 : 1;
long days = m.group(2) == null ? 0 : toLongWithRange("day", m.group(3),
0, Integer.MAX_VALUE);
long hours = toLongWithRange("hour", m.group(4), 0, 23);
long minutes = toLongWithRange("minute", m.group(5), 0, 59);
long seconds = toLongWithRange("second", m.group(6), 0, 59);
long hours;
long minutes;
long seconds;
switch (from) {
case "minute":
hours = m.group(6) == null ? 0 : toLongWithRange("hour", m.group(4), 0, 23);
minutes = m.group(6) == null ? toLongWithRange("minute", m.group(4), 0, 59)
: toLongWithRange("minute", m.group(5), 0, 59);
seconds = m.group(6) == null ? toLongWithRange("minute", m.group(5), 0, 59)
: toLongWithRange("second", m.group(7), 0, 59);
break;
default:
Copy link
Member

@dongjoon-hyun dongjoon-hyun Jul 3, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we have only two cases, shall we use if ... else instead of switch?

if(m.group(8) != null && m.group(6) == null) {
hours = 0;
minutes = toLongWithRange("minute", m.group(4), 0, 59);
seconds = toLongWithRange("second", m.group(5), 0, 59);
} else {
hours = toLongWithRange("hour", m.group(4), 0, 23);
minutes = toLongWithRange("minute", m.group(5), 0, 59);
seconds = toLongWithRange("second", m.group(7), 0, 59);
}
}
// Hive allow nanosecond precision interval
long nanos = toLongWithRange("nanosecond", m.group(8), 0L, 999999999L);
long nanos = toLongWithRange("nanosecond", m.group(9), 0L, 999999999L);
switch (to) {
case "minute":
seconds = 0;
nanos = 0;
break;
case "hour":
minutes = 0;
seconds = 0;
nanos = 0;
break;
}
result = new CalendarInterval(0, sign * (
days * MICROS_PER_DAY + hours * MICROS_PER_HOUR + minutes * MICROS_PER_MINUTE +
seconds * MICROS_PER_SECOND + nanos / 1000L));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1836,7 +1836,8 @@ class AstBuilder(conf: SQLConf) extends SqlBaseBaseVisitor[AnyRef] with Logging
* Create a [[CalendarInterval]] for a unit value pair. Two unit configuration types are
* supported:
* - Single unit.
* - From-To unit (only 'YEAR TO MONTH' and 'DAY TO SECOND' and 'HOUR to SECOND' are supported).
* - From-To unit ('YEAR TO MONTH' and 'DAY TO HOUR' and 'DAY TO MINUTE' and 'DAY TO SECOND'
* - and 'HOUR to MINUTE' and 'HOUR to SECOND' and 'MINUTE to SECOND' are supported).
*/
override def visitIntervalField(ctx: IntervalFieldContext): CalendarInterval = withOrigin(ctx) {
import ctx._
Expand All @@ -1851,10 +1852,18 @@ class AstBuilder(conf: SQLConf) extends SqlBaseBaseVisitor[AnyRef] with Logging
CalendarInterval.fromSingleUnitString(u, s)
case ("year", Some("month")) =>
CalendarInterval.fromYearMonthString(s)
case ("day", Some("hour")) =>
CalendarInterval.fromDayTimeString(s, "day", "hour")
case ("day", Some("minute")) =>
CalendarInterval.fromDayTimeString(s, "day", "minute")
case ("day", Some("second")) =>
CalendarInterval.fromDayTimeString(s)
CalendarInterval.fromDayTimeString(s, "day", "second")
case ("hour", Some("minute")) =>
CalendarInterval.fromDayTimeString(s, "hour", "minute")
case ("hour", Some("second")) =>
CalendarInterval.fromDayTimeString(s)
CalendarInterval.fromDayTimeString(s, "hour", "second")
case ("minute", Some("second")) =>
CalendarInterval.fromDayTimeString(s, "minute", "second")
case (from, Some(t)) =>
throw new ParseException(s"Intervals FROM $from TO $t are not supported.", ctx)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1180,12 +1180,34 @@ class SQLQuerySuite extends QueryTest with SQLTestUtils with TestHiveSingleton {
test("Convert hive interval term into Literal of CalendarIntervalType") {
checkAnswer(sql("select interval '10-9' year to month"),
Row(CalendarInterval.fromString("interval 10 years 9 months")))
checkAnswer(sql("select interval '20 15:40:32.99899999' day to hour"),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All these test cases are positive ones. Could you add the negative cases too? Do they throw an exception? Exception messages make sense?

Row(CalendarInterval.fromString("interval 2 weeks 6 days 15 hours")))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

indentation?

checkAnswer(sql("select interval '20 15:40:32.99899999' day to minute"),
Row(CalendarInterval.fromString("interval 2 weeks 6 days 15 hours 40 minutes")))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

indentation?

checkAnswer(sql("select interval '20 15:40:32.99899999' day to second"),
Row(CalendarInterval.fromString("interval 2 weeks 6 days 15 hours 40 minutes " +
"32 seconds 99 milliseconds 899 microseconds")))
checkAnswer(sql("select interval '15:40:32.99899999' hour to minute"),
Row(CalendarInterval.fromString("interval 15 hours 40 minutes")))
checkAnswer(sql("select interval '15:40.99899999' hour to second"),
Row(CalendarInterval.fromString("interval 15 minutes 40 seconds 99 milliseconds " +
"899 microseconds")))
checkAnswer(sql("select interval '15:40' hour to second"),
Row(CalendarInterval.fromString("interval 15 hours 40 minutes")))
checkAnswer(sql("select interval '15:40:32.99899999' hour to second"),
Row(CalendarInterval.fromString("interval 15 hours 40 minutes 32 seconds 99 milliseconds " +
"899 microseconds")))
checkAnswer(sql("select interval '20 40:32.99899999' minute to second"),
Row(CalendarInterval.fromString("interval 2 weeks 6 days 40 minutes 32 seconds " +
"99 milliseconds 899 microseconds")))
checkAnswer(sql("select interval '40:32.99899999' minute to second"),
Row(CalendarInterval.fromString("interval 40 minutes 32 seconds 99 milliseconds " +
"899 microseconds")))
checkAnswer(sql("select interval '40:32.99899999' minute to second"),
Row(CalendarInterval.fromString("interval 40 minutes 32 seconds 99 milliseconds " +
"899 microseconds")))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line 1203 ~ 1205 are the same with line 1206 ~ 1208.

checkAnswer(sql("select interval '40:32' minute to second"),
Row(CalendarInterval.fromString("interval 40 minutes 32 seconds")))
checkAnswer(sql("select interval '30' year"),
Row(CalendarInterval.fromString("interval 30 years")))
checkAnswer(sql("select interval '25' month"),
Expand Down