Skip to content

Commit

Permalink
address comments
Browse files Browse the repository at this point in the history
  • Loading branch information
cloud-fan committed Jul 11, 2015
1 parent ac1f3d1 commit 0fbbe19
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,10 @@ case class Cast(child: Expression, dataType: DataType) extends UnaryExpression w
case (_, StringType) =>
defineCodeGen(ctx, ev, c => s"${ctx.stringType}.fromString(String.valueOf($c))")

case (StringType, IntervalType) =>
defineCodeGen(ctx, ev, c =>
s"org.apache.spark.unsafe.types.Interval.fromString($c.toString)")

// fallback for DecimalType, this must be before other numeric types
case (_, dt: DecimalType) =>
super.genCode(ctx, ev)
Expand Down
10 changes: 10 additions & 0 deletions unsafe/src/main/java/org/apache/spark/unsafe/types/Interval.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,16 @@ public final class Interval implements Serializable {
public static final long MICROS_PER_DAY = MICROS_PER_HOUR * 24;
public static final long MICROS_PER_WEEK = MICROS_PER_DAY * 7;

/**
* A function to generate regex which matches interval string's unit part like "3 years".
*
* First, we can leave out some units in interval string, and we only care about the value of
* unit, so here we use non-capturing group to wrap the actual regex.
* At the beginning of the actual regex, we should match spaces before the unit part.
* Next is the number part, starts with an optional "-" to represent negative value. We use
* capturing group to wrap this part as we need the value later.
* Finally is the unit name, ends with an optional "s".
*/
private static String unitRegex(String unit) {
return "(?:\\s+(-?\\d+)\\s+" + unit + "s?)?";
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,31 +59,50 @@ public void toStringTest() {

@Test
public void fromStringTest() {
testSingleUnit("year", 3, 36, 0);
testSingleUnit("month", 3, 3, 0);
testSingleUnit("week", 3, 0, 3 * MICROS_PER_WEEK);
testSingleUnit("day", 3, 0, 3 * MICROS_PER_DAY);
testSingleUnit("hour", 3, 0, 3 * MICROS_PER_HOUR);
testSingleUnit("minute", 3, 0, 3 * MICROS_PER_MINUTE);
testSingleUnit("second", 3, 0, 3 * MICROS_PER_SECOND);
testSingleUnit("millisecond", 3, 0, 3 * MICROS_PER_MILLI);
testSingleUnit("microsecond", 3, 0, 3);

String s;
Interval i;

s = "interval 2 weeks -6 minute";
i = new Interval(0, 2 * MICROS_PER_WEEK - 6 * MICROS_PER_MINUTE);
assertEquals(Interval.fromString(s), i);

s = "interval -5 years 23 month";
s = "interval -5 years 23 month";
i = new Interval(-5 * 12 + 23, 0);
assertEquals(Interval.fromString(s), i);

s = "interval 3month 1 hour";
// Error cases
i = null;

s = "interval 3month 1 hour";
assertEquals(Interval.fromString(s), i);

s = "interval 3 moth 1 hour";
i = null;
assertEquals(Interval.fromString(s), i);

s = "interval";
i = null;
assertEquals(Interval.fromString(s), i);

s = "int";
assertEquals(Interval.fromString(s), i);

s = "";
assertEquals(Interval.fromString(s), i);

s = null;
i = null;
assertEquals(Interval.fromString(s), i);
}

private void testSingleUnit(String unit, int number, int months, long microseconds) {
String s1 = "interval " + number + " " + unit;
String s2 = "interval " + number + " " + unit + "s";
Interval i = new Interval(months, microseconds);
assertEquals(Interval.fromString(s1), i);
assertEquals(Interval.fromString(s2), i);
}
}

0 comments on commit 0fbbe19

Please sign in to comment.