aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/SqlParser.scala24
-rw-r--r--unsafe/src/main/java/org/apache/spark/unsafe/types/Interval.java42
-rw-r--r--unsafe/src/test/java/org/apache/spark/unsafe/types/IntervalSuite.java59
3 files changed, 119 insertions, 6 deletions
diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/SqlParser.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/SqlParser.scala
index dedd8c8fa3..d4ef04c229 100644
--- a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/SqlParser.scala
+++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/SqlParser.scala
@@ -353,22 +353,34 @@ class SqlParser extends AbstractSparkSQLParser with DataTypeParser {
integral <~ intervalUnit("microsecond") ^^ { case num => num.toLong }
protected lazy val millisecond: Parser[Long] =
- integral <~ intervalUnit("millisecond") ^^ { case num => num.toLong * 1000 }
+ integral <~ intervalUnit("millisecond") ^^ {
+ case num => num.toLong * Interval.MICROS_PER_MILLI
+ }
protected lazy val second: Parser[Long] =
- integral <~ intervalUnit("second") ^^ { case num => num.toLong * 1000 * 1000 }
+ integral <~ intervalUnit("second") ^^ {
+ case num => num.toLong * Interval.MICROS_PER_SECOND
+ }
protected lazy val minute: Parser[Long] =
- integral <~ intervalUnit("minute") ^^ { case num => num.toLong * 1000 * 1000 * 60 }
+ integral <~ intervalUnit("minute") ^^ {
+ case num => num.toLong * Interval.MICROS_PER_MINUTE
+ }
protected lazy val hour: Parser[Long] =
- integral <~ intervalUnit("hour") ^^ { case num => num.toLong * 1000 * 1000 * 3600 }
+ integral <~ intervalUnit("hour") ^^ {
+ case num => num.toLong * Interval.MICROS_PER_HOUR
+ }
protected lazy val day: Parser[Long] =
- integral <~ intervalUnit("day") ^^ { case num => num.toLong * 1000 * 1000 * 3600 * 24 }
+ integral <~ intervalUnit("day") ^^ {
+ case num => num.toLong * Interval.MICROS_PER_DAY
+ }
protected lazy val week: Parser[Long] =
- integral <~ intervalUnit("week") ^^ { case num => num.toLong * 1000 * 1000 * 3600 * 24 * 7 }
+ integral <~ intervalUnit("week") ^^ {
+ case num => num.toLong * Interval.MICROS_PER_WEEK
+ }
protected lazy val intervalLiteral: Parser[Literal] =
INTERVAL ~> year.? ~ month.? ~ week.? ~ day.? ~ hour.? ~ minute.? ~ second.? ~
diff --git a/unsafe/src/main/java/org/apache/spark/unsafe/types/Interval.java b/unsafe/src/main/java/org/apache/spark/unsafe/types/Interval.java
index 3eb67ede06..0af982d484 100644
--- a/unsafe/src/main/java/org/apache/spark/unsafe/types/Interval.java
+++ b/unsafe/src/main/java/org/apache/spark/unsafe/types/Interval.java
@@ -23,6 +23,13 @@ import java.io.Serializable;
* The internal representation of interval type.
*/
public final class Interval implements Serializable {
+ public static final long MICROS_PER_MILLI = 1000L;
+ public static final long MICROS_PER_SECOND = MICROS_PER_MILLI * 1000;
+ public static final long MICROS_PER_MINUTE = MICROS_PER_SECOND * 60;
+ public static final long MICROS_PER_HOUR = MICROS_PER_MINUTE * 60;
+ public static final long MICROS_PER_DAY = MICROS_PER_HOUR * 24;
+ public static final long MICROS_PER_WEEK = MICROS_PER_DAY * 7;
+
public final int months;
public final long microseconds;
@@ -44,4 +51,39 @@ public final class Interval implements Serializable {
public int hashCode() {
return 31 * months + (int) microseconds;
}
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder("interval");
+
+ if (months != 0) {
+ appendUnit(sb, months / 12, "year");
+ appendUnit(sb, months % 12, "month");
+ }
+
+ if (microseconds != 0) {
+ long rest = microseconds;
+ appendUnit(sb, rest / MICROS_PER_WEEK, "week");
+ rest %= MICROS_PER_WEEK;
+ appendUnit(sb, rest / MICROS_PER_DAY, "day");
+ rest %= MICROS_PER_DAY;
+ appendUnit(sb, rest / MICROS_PER_HOUR, "hour");
+ rest %= MICROS_PER_HOUR;
+ appendUnit(sb, rest / MICROS_PER_MINUTE, "minute");
+ rest %= MICROS_PER_MINUTE;
+ appendUnit(sb, rest / MICROS_PER_SECOND, "second");
+ rest %= MICROS_PER_SECOND;
+ appendUnit(sb, rest / MICROS_PER_MILLI, "millisecond");
+ rest %= MICROS_PER_MILLI;
+ appendUnit(sb, rest, "microsecond");
+ }
+
+ return sb.toString();
+ }
+
+ private void appendUnit(StringBuilder sb, long value, String unit) {
+ if (value != 0) {
+ sb.append(" " + value + " " + unit + "s");
+ }
+ }
}
diff --git a/unsafe/src/test/java/org/apache/spark/unsafe/types/IntervalSuite.java b/unsafe/src/test/java/org/apache/spark/unsafe/types/IntervalSuite.java
new file mode 100644
index 0000000000..0f4f38b2b0
--- /dev/null
+++ b/unsafe/src/test/java/org/apache/spark/unsafe/types/IntervalSuite.java
@@ -0,0 +1,59 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+package org.apache.spark.unsafe.types;
+
+import org.junit.Test;
+
+import static junit.framework.Assert.*;
+import static org.apache.spark.unsafe.types.Interval.*;
+
+public class IntervalSuite {
+
+ @Test
+ public void equalsTest() {
+ Interval i1 = new Interval(3, 123);
+ Interval i2 = new Interval(3, 321);
+ Interval i3 = new Interval(1, 123);
+ Interval i4 = new Interval(3, 123);
+
+ assertNotSame(i1, i2);
+ assertNotSame(i1, i3);
+ assertNotSame(i2, i3);
+ assertEquals(i1, i4);
+ }
+
+ @Test
+ public void toStringTest() {
+ Interval i;
+
+ i = new Interval(34, 0);
+ assertEquals(i.toString(), "interval 2 years 10 months");
+
+ i = new Interval(-34, 0);
+ assertEquals(i.toString(), "interval -2 years -10 months");
+
+ i = new Interval(0, 3 * MICROS_PER_WEEK + 13 * MICROS_PER_HOUR + 123);
+ assertEquals(i.toString(), "interval 3 weeks 13 hours 123 microseconds");
+
+ i = new Interval(0, -3 * MICROS_PER_WEEK - 13 * MICROS_PER_HOUR - 123);
+ assertEquals(i.toString(), "interval -3 weeks -13 hours -123 microseconds");
+
+ i = new Interval(34, 3 * MICROS_PER_WEEK + 13 * MICROS_PER_HOUR + 123);
+ assertEquals(i.toString(), "interval 2 years 10 months 3 weeks 13 hours 123 microseconds");
+ }
+}