From 6aa85a017a0d9dce3342b4665d39027f64765e51 Mon Sep 17 00:00:00 2001 From: "navis.ryu" Date: Fri, 27 Mar 2015 11:37:16 +0900 Subject: [PATCH] TAJO-1454 Comparing two date or two timestamp need not normalizing --- .../java/org/apache/tajo/datum/DateDatum.java | 79 +++++++++---------- .../org/apache/tajo/datum/Float4Datum.java | 4 +- .../org/apache/tajo/datum/Float8Datum.java | 4 +- .../java/org/apache/tajo/datum/Int2Datum.java | 4 +- .../java/org/apache/tajo/datum/Int4Datum.java | 4 +- .../java/org/apache/tajo/datum/Int8Datum.java | 4 +- .../org/apache/tajo/datum/IntervalDatum.java | 57 +++++-------- .../java/org/apache/tajo/datum/TimeDatum.java | 26 +++--- .../org/apache/tajo/datum/TimestampDatum.java | 36 ++------- .../tajo/util/datetime/DateTimeUtil.java | 14 +++- .../apache/tajo/util/datetime/TimeMeta.java | 9 +++ .../tajo/engine/function/datetime/ToDate.java | 2 +- .../org/apache/tajo/plan/ExprAnnotator.java | 2 +- 13 files changed, 110 insertions(+), 135 deletions(-) diff --git a/tajo-common/src/main/java/org/apache/tajo/datum/DateDatum.java b/tajo-common/src/main/java/org/apache/tajo/datum/DateDatum.java index 188d226ac7..65342e8df0 100644 --- a/tajo-common/src/main/java/org/apache/tajo/datum/DateDatum.java +++ b/tajo-common/src/main/java/org/apache/tajo/datum/DateDatum.java @@ -18,13 +18,13 @@ package org.apache.tajo.datum; +import com.google.common.primitives.Ints; import org.apache.tajo.common.TajoDataTypes; import org.apache.tajo.common.TajoDataTypes.Type; import org.apache.tajo.exception.InvalidCastException; import org.apache.tajo.exception.InvalidOperationException; import org.apache.tajo.util.Bytes; import org.apache.tajo.util.datetime.DateTimeConstants.DateStyle; -import org.apache.tajo.util.datetime.DateTimeFormat; import org.apache.tajo.util.datetime.DateTimeUtil; import org.apache.tajo.util.datetime.TimeMeta; @@ -32,15 +32,16 @@ public class DateDatum extends Datum { public static final int SIZE = 4; // Dates are stored in UTC. - private int year; - private int monthOfYear; - private int dayOfMonth; + final int year; + final int monthOfYear; + final int dayOfMonth; public DateDatum(int value) { - super(TajoDataTypes.Type.DATE); - TimeMeta tm = new TimeMeta(); - DateTimeUtil.j2date(value, tm); + this(DateTimeUtil.j2date(value)); + } + public DateDatum(TimeMeta tm) { + super(TajoDataTypes.Type.DATE); year = tm.years; monthOfYear = tm.monthOfYear; dayOfMonth = tm.dayOfMonth; @@ -48,7 +49,9 @@ public DateDatum(int value) { public TimeMeta toTimeMeta() { TimeMeta tm = new TimeMeta(); - DateTimeUtil.j2date(DateTimeUtil.date2j(year, monthOfYear, dayOfMonth), tm); + tm.years = year; + tm.monthOfYear = monthOfYear; + tm.dayOfMonth = dayOfMonth; return tm; } @@ -58,8 +61,7 @@ public int getCenturyOfEra() { } public int getYear() { - TimeMeta tm = toTimeMeta(); - return tm.years; + return year; } public int getWeekyear() { @@ -68,8 +70,7 @@ public int getWeekyear() { } public int getMonthOfYear() { - TimeMeta tm = toTimeMeta(); - return tm.monthOfYear; + return monthOfYear; } public int getDayOfYear() { @@ -93,15 +94,15 @@ public int getWeekOfYear() { } public int getDayOfMonth() { - TimeMeta tm = toTimeMeta(); - return tm.dayOfMonth; + return dayOfMonth; } - + @Override public String toString() { return asChars(); } + @Override public Datum plus(Datum datum) { switch(datum.type()) { case INT2: @@ -111,17 +112,13 @@ public Datum plus(Datum datum) { case FLOAT8: { TimeMeta tm = toTimeMeta(); tm.plusDays(datum.asInt4()); - return new DateDatum(DateTimeUtil.date2j(tm.years, tm.monthOfYear, tm.dayOfMonth)); + return new DateDatum(tm); } - case INTERVAL: { + case INTERVAL: IntervalDatum interval = (IntervalDatum) datum; TimeMeta tm = toTimeMeta(); - tm.plusMillis(interval.getMilliSeconds()); - if (interval.getMonths() > 0) { - tm.plusMonths(interval.getMonths()); - } + tm.plusInterval(interval.months, interval.milliseconds); return new TimestampDatum(DateTimeUtil.toJulianTimestamp(tm)); - } case TIME: { TimeMeta tm1 = toTimeMeta(); TimeMeta tm2 = ((TimeDatum)datum).toTimeMeta(); @@ -133,6 +130,7 @@ public Datum plus(Datum datum) { } } + @Override public Datum minus(Datum datum) { switch(datum.type()) { case INT2: @@ -142,15 +140,12 @@ public Datum minus(Datum datum) { case FLOAT8: { TimeMeta tm = toTimeMeta(); tm.plusDays(0 - datum.asInt4()); - return new DateDatum(DateTimeUtil.date2j(tm.years, tm.monthOfYear, tm.dayOfMonth)); + return new DateDatum(tm); } case INTERVAL: { IntervalDatum interval = (IntervalDatum) datum; TimeMeta tm = toTimeMeta(); - if (interval.getMonths() > 0) { - tm.plusMonths(0 - interval.getMonths()); - } - tm.plusMillis(0 - interval.getMilliSeconds()); + tm.plusInterval(-interval.months, -interval.milliseconds); return new TimestampDatum(DateTimeUtil.toJulianTimestamp(tm)); } case TIME: { @@ -160,11 +155,9 @@ public Datum minus(Datum datum) { return new TimestampDatum(DateTimeUtil.toJulianTimestamp(tm1)); } case DATE: { - TimeMeta tm1 = toTimeMeta(); - TimeMeta tm2 = ((DateDatum) datum).toTimeMeta(); - - int day1 = DateTimeUtil.date2j(tm1.years, tm1.monthOfYear, tm1.dayOfMonth); - int day2 = DateTimeUtil.date2j(tm2.years, tm2.monthOfYear, tm2.dayOfMonth); + DateDatum d = (DateDatum) datum; + int day1 = DateTimeUtil.date2j(year, monthOfYear, dayOfMonth); + int day2 = DateTimeUtil.date2j(d.year, d.monthOfYear, d.dayOfMonth); return new Int4Datum(day1 - day2); } default: @@ -198,13 +191,7 @@ public double asFloat8() { @Override public String asChars() { - TimeMeta tm = toTimeMeta(); - return DateTimeUtil.encodeDate(tm, DateStyle.ISO_DATES); - } - - public String toChars(String format) { - TimeMeta tm = toTimeMeta(); - return DateTimeFormat.to_char(tm, format); + return DateTimeUtil.encodeDate(year, monthOfYear, dayOfMonth, DateStyle.ISO_DATES); } @Override @@ -232,10 +219,15 @@ public Datum equalsTo(Datum datum) { public int compareTo(Datum datum) { if (datum.type() == TajoDataTypes.Type.DATE) { DateDatum another = (DateDatum) datum; - TimeMeta myMeta, otherMeta; - myMeta = toTimeMeta(); - otherMeta = another.toTimeMeta(); - return myMeta.compareTo(otherMeta); + int compare = Ints.compare(year, another.year); + if (compare != 0) { + return compare; + } + compare = Ints.compare(monthOfYear, another.monthOfYear); + if (compare != 0) { + return compare; + } + return Ints.compare(dayOfMonth, another.dayOfMonth); } else if (datum.type() == TajoDataTypes.Type.TIMESTAMP) { TimestampDatum another = (TimestampDatum) datum; TimeMeta myMeta, otherMeta; @@ -249,6 +241,7 @@ public int compareTo(Datum datum) { } } + @Override public boolean equals(Object obj) { if (obj instanceof DateDatum) { DateDatum another = (DateDatum) obj; diff --git a/tajo-common/src/main/java/org/apache/tajo/datum/Float4Datum.java b/tajo-common/src/main/java/org/apache/tajo/datum/Float4Datum.java index 8b16528a65..e71a20189b 100644 --- a/tajo-common/src/main/java/org/apache/tajo/datum/Float4Datum.java +++ b/tajo-common/src/main/java/org/apache/tajo/datum/Float4Datum.java @@ -217,7 +217,7 @@ public Datum plus(Datum datum) { DateDatum dateDatum = (DateDatum)datum; TimeMeta tm = dateDatum.toTimeMeta(); tm.plusDays(asInt4()); - return new DateDatum(DateTimeUtil.date2j(tm.years, tm.monthOfYear, tm.dayOfMonth)); + return new DateDatum(tm); case NULL_TYPE: return datum; default: @@ -242,7 +242,7 @@ public Datum minus(Datum datum) { DateDatum dateDatum = (DateDatum)datum; TimeMeta tm = dateDatum.toTimeMeta(); tm.plusDays(0 - asInt4()); - return new DateDatum(DateTimeUtil.date2j(tm.years, tm.monthOfYear, tm.dayOfMonth)); + return new DateDatum(tm); case NULL_TYPE: return datum; default: diff --git a/tajo-common/src/main/java/org/apache/tajo/datum/Float8Datum.java b/tajo-common/src/main/java/org/apache/tajo/datum/Float8Datum.java index d41af2d73e..a0298f2a15 100644 --- a/tajo-common/src/main/java/org/apache/tajo/datum/Float8Datum.java +++ b/tajo-common/src/main/java/org/apache/tajo/datum/Float8Datum.java @@ -206,7 +206,7 @@ public Datum plus(Datum datum) { DateDatum dateDatum = (DateDatum)datum; TimeMeta tm = dateDatum.toTimeMeta(); tm.plusDays(asInt4()); - return new DateDatum(DateTimeUtil.date2j(tm.years, tm.monthOfYear, tm.dayOfMonth)); + return new DateDatum(tm); case NULL_TYPE: return datum; default: @@ -231,7 +231,7 @@ public Datum minus(Datum datum) { DateDatum dateDatum = (DateDatum)datum; TimeMeta tm = dateDatum.toTimeMeta(); tm.plusDays(0 - asInt4()); - return new DateDatum(DateTimeUtil.date2j(tm.years, tm.monthOfYear, tm.dayOfMonth)); + return new DateDatum(tm); case NULL_TYPE: return datum; default: diff --git a/tajo-common/src/main/java/org/apache/tajo/datum/Int2Datum.java b/tajo-common/src/main/java/org/apache/tajo/datum/Int2Datum.java index 2a6c691cbf..f11a5c5d3b 100644 --- a/tajo-common/src/main/java/org/apache/tajo/datum/Int2Datum.java +++ b/tajo-common/src/main/java/org/apache/tajo/datum/Int2Datum.java @@ -208,7 +208,7 @@ public Datum plus(Datum datum) { DateDatum dateDatum = (DateDatum)datum; TimeMeta tm = dateDatum.toTimeMeta(); tm.plusDays(asInt2()); - return new DateDatum(DateTimeUtil.date2j(tm.years, tm.monthOfYear, tm.dayOfMonth)); + return new DateDatum(tm); case NULL_TYPE: return datum; default: @@ -233,7 +233,7 @@ public Datum minus(Datum datum) { DateDatum dateDatum = (DateDatum)datum; TimeMeta tm = dateDatum.toTimeMeta(); tm.plusDays(0 - asInt2()); - return new DateDatum(DateTimeUtil.date2j(tm.years, tm.monthOfYear, tm.dayOfMonth)); + return new DateDatum(tm); case NULL_TYPE: return datum; default: diff --git a/tajo-common/src/main/java/org/apache/tajo/datum/Int4Datum.java b/tajo-common/src/main/java/org/apache/tajo/datum/Int4Datum.java index 26201fbe7f..ea531b9a7d 100644 --- a/tajo-common/src/main/java/org/apache/tajo/datum/Int4Datum.java +++ b/tajo-common/src/main/java/org/apache/tajo/datum/Int4Datum.java @@ -212,7 +212,7 @@ public Datum plus(Datum datum) { DateDatum dateDatum = (DateDatum)datum; TimeMeta tm = dateDatum.toTimeMeta(); tm.plusDays(asInt4()); - return new DateDatum(DateTimeUtil.date2j(tm.years, tm.monthOfYear, tm.dayOfMonth)); + return new DateDatum(tm); case NULL_TYPE: return datum; default: @@ -237,7 +237,7 @@ public Datum minus(Datum datum) { DateDatum dateDatum = (DateDatum)datum; TimeMeta tm = dateDatum.toTimeMeta(); tm.plusDays(0 - asInt4()); - return new DateDatum(DateTimeUtil.date2j(tm.years, tm.monthOfYear, tm.dayOfMonth)); + return new DateDatum(tm); case NULL_TYPE: return datum; default: diff --git a/tajo-common/src/main/java/org/apache/tajo/datum/Int8Datum.java b/tajo-common/src/main/java/org/apache/tajo/datum/Int8Datum.java index 9fa41d15ef..cd448e3a73 100644 --- a/tajo-common/src/main/java/org/apache/tajo/datum/Int8Datum.java +++ b/tajo-common/src/main/java/org/apache/tajo/datum/Int8Datum.java @@ -220,7 +220,7 @@ public Datum plus(Datum datum) { DateDatum dateDatum = (DateDatum)datum; TimeMeta tm = dateDatum.toTimeMeta(); tm.plusDays(asInt4()); - return new DateDatum(DateTimeUtil.date2j(tm.years, tm.monthOfYear, tm.dayOfMonth)); + return new DateDatum(tm); case NULL_TYPE: return datum; default: @@ -245,7 +245,7 @@ public Datum minus(Datum datum) { DateDatum dateDatum = (DateDatum)datum; TimeMeta tm = dateDatum.toTimeMeta(); tm.plusDays(0 - asInt4()); - return new DateDatum(DateTimeUtil.date2j(tm.years, tm.monthOfYear, tm.dayOfMonth)); + return new DateDatum(tm); case NULL_TYPE: return datum; default: diff --git a/tajo-common/src/main/java/org/apache/tajo/datum/IntervalDatum.java b/tajo-common/src/main/java/org/apache/tajo/datum/IntervalDatum.java index 6207891861..e8d439df2e 100644 --- a/tajo-common/src/main/java/org/apache/tajo/datum/IntervalDatum.java +++ b/tajo-common/src/main/java/org/apache/tajo/datum/IntervalDatum.java @@ -18,7 +18,7 @@ package org.apache.tajo.datum; -import com.google.common.base.Objects; +import com.google.common.primitives.Longs; import org.apache.tajo.common.TajoDataTypes; import org.apache.tajo.exception.InvalidOperationException; import org.apache.tajo.util.datetime.DateTimeUtil; @@ -62,8 +62,8 @@ static enum DATE_UNIT { } } - private int months; - private long millieconds; + final int months; + final long milliseconds; public IntervalDatum(long milliseconds) { this(0, milliseconds); @@ -72,7 +72,7 @@ public IntervalDatum(long milliseconds) { public IntervalDatum(int months, long milliseconds) { super(TajoDataTypes.Type.INTERVAL); this.months = months; - this.millieconds = milliseconds; + this.milliseconds = milliseconds; } public IntervalDatum(String intervalStr) { @@ -162,7 +162,7 @@ public IntervalDatum(String intervalStr) { throw new InvalidOperationException("invalid input syntax for type interval: " + intervalStr); } - this.millieconds = time + day * DAY_MILLIS + hour * HOUR_MILLIS + minute * 60 * 1000L + second * 1000L + + this.milliseconds = time + day * DAY_MILLIS + hour * HOUR_MILLIS + minute * 60 * 1000L + second * 1000L + microsecond * 100L + millisecond; this.months = year * 12 + month; } catch (InvalidOperationException e) { @@ -220,7 +220,7 @@ public int getMonths() { } public long getMilliSeconds() { - return millieconds; + return milliseconds; } @Override @@ -228,30 +228,22 @@ public Datum plus(Datum datum) { switch(datum.type()) { case INTERVAL: IntervalDatum other = (IntervalDatum) datum; - return new IntervalDatum(months + other.months, millieconds + other.millieconds); + return new IntervalDatum(months + other.months, milliseconds + other.milliseconds); case DATE: { DateDatum dateDatum = (DateDatum) datum; TimeMeta tm = dateDatum.toTimeMeta(); - tm.plusMillis(getMilliSeconds()); - if (getMonths() > 0) { - tm.plusMonths(getMonths()); - } + tm.plusInterval(months, milliseconds); return new TimestampDatum(DateTimeUtil.toJulianTimestamp(tm)); } case TIME: { TimeMeta tm = ((TimeDatum) datum).toTimeMeta(); - tm.plusMillis(millieconds); + tm.plusInterval(months, milliseconds); return new TimeDatum(DateTimeUtil.toTime(tm)); } case TIMESTAMP: { TimeMeta tm = new TimeMeta(); - DateTimeUtil.toJulianTimeMeta(((TimestampDatum) datum).asInt8(), tm); - if (months > 0) { - tm.plusMonths(months); - } - if (millieconds > 0) { - tm.plusMillis(millieconds); - } + DateTimeUtil.toJulianTimeMeta(datum.asInt8(), tm); + tm.plusInterval(months, milliseconds); return new TimestampDatum(DateTimeUtil.toJulianTimestamp(tm)); } default: @@ -263,7 +255,7 @@ public Datum plus(Datum datum) { public Datum minus(Datum datum) { if (datum.type() == TajoDataTypes.Type.INTERVAL) { IntervalDatum other = (IntervalDatum) datum; - return new IntervalDatum(months - other.months, millieconds - other.millieconds); + return new IntervalDatum(months - other.months, milliseconds - other.milliseconds); } else { throw new InvalidOperationException(datum.type()); } @@ -276,11 +268,11 @@ public Datum multiply(Datum datum) { case INT4: case INT8: long int8Val = datum.asInt8(); - return createIntervalDatum((double)months * int8Val, (double) millieconds * int8Val); + return createIntervalDatum((double)months * int8Val, (double) milliseconds * int8Val); case FLOAT4: case FLOAT8: double float8Val = datum.asFloat8(); - return createIntervalDatum((double)months * float8Val, (double) millieconds * float8Val); + return createIntervalDatum((double)months * float8Val, (double) milliseconds * float8Val); default: throw new InvalidOperationException(datum.type()); } @@ -296,14 +288,14 @@ public Datum divide(Datum datum) { if (!validateDivideZero(paramValueI8)) { return NullDatum.get(); } - return createIntervalDatum((double) months / paramValueI8, (double) millieconds / paramValueI8); + return createIntervalDatum((double) months / paramValueI8, (double) milliseconds / paramValueI8); case FLOAT4: case FLOAT8: double paramValueF8 = datum.asFloat8(); if (!validateDivideZero(paramValueF8)) { return NullDatum.get(); } - return createIntervalDatum((double) months / paramValueF8, (double) millieconds / paramValueF8); + return createIntervalDatum((double) months / paramValueF8, (double) milliseconds / paramValueF8); default: throw new InvalidOperationException(datum.type()); } @@ -316,9 +308,10 @@ private IntervalDatum createIntervalDatum(double monthValue, double millisValue) @Override public long asInt8() { - return (months * 30) * DAY_MILLIS + millieconds; + return (months * 30) * DAY_MILLIS + milliseconds; } + @Override public String toString() { return asChars(); } @@ -346,7 +339,7 @@ public String asChars() { prefix = " "; } - formatMillis(sb, prefix, millieconds); + formatMillis(sb, prefix, milliseconds); return sb.toString(); } catch (Exception e) { return ""; @@ -398,15 +391,7 @@ public int size() { @Override public int compareTo(Datum datum) { if (datum.type() == TajoDataTypes.Type.INTERVAL) { - long val = asInt8(); - long another = datum.asInt8(); - if (val < another) { - return -1; - } else if (val > another) { - return 1; - } else { - return 0; - } + return Longs.compare(asInt8(), datum.asInt8()); } else if (datum instanceof NullDatum || datum.isNull()) { return -1; } else { @@ -436,6 +421,6 @@ public boolean equals(Object obj) { @Override public int hashCode(){ - return Objects.hashCode(asInt8()); + return Longs.hashCode(asInt8()); } } diff --git a/tajo-common/src/main/java/org/apache/tajo/datum/TimeDatum.java b/tajo-common/src/main/java/org/apache/tajo/datum/TimeDatum.java index 6cac586f2e..04cce54bcc 100644 --- a/tajo-common/src/main/java/org/apache/tajo/datum/TimeDatum.java +++ b/tajo-common/src/main/java/org/apache/tajo/datum/TimeDatum.java @@ -18,6 +18,7 @@ package org.apache.tajo.datum; +import com.google.common.primitives.Longs; import org.apache.tajo.common.TajoDataTypes; import org.apache.tajo.exception.InvalidCastException; import org.apache.tajo.exception.InvalidOperationException; @@ -118,19 +119,18 @@ public int size() { return Bytes.toBytes(asInt8()); } + @Override public Datum plus(Datum datum) { switch(datum.type()) { - case INTERVAL: { + case INTERVAL: IntervalDatum interval = ((IntervalDatum)datum); TimeMeta tm = toTimeMeta(); - tm.plusMillis(interval.getMilliSeconds()); + tm.plusInterval(interval.months, interval.milliseconds); return new TimeDatum(DateTimeUtil.toTime(tm)); - } case DATE: { - TimeMeta tm = toTimeMeta(); DateDatum dateDatum = (DateDatum) datum; TimeMeta dateTm = dateDatum.toTimeMeta(); - dateTm.plusTime(DateTimeUtil.toTime(tm)); + dateTm.plusTime(time); return new TimestampDatum(DateTimeUtil.toJulianTimestamp(dateTm)); } default: @@ -138,19 +138,16 @@ public Datum plus(Datum datum) { } } + @Override public Datum minus(Datum datum) { switch(datum.type()) { - case INTERVAL: { + case INTERVAL: IntervalDatum interval = ((IntervalDatum)datum); TimeMeta tm = toTimeMeta(); - tm.plusMillis(0 - interval.getMilliSeconds()); + tm.plusInterval(-interval.months, -interval.milliseconds); return new TimeDatum(DateTimeUtil.toTime(tm)); - } case TIME: - TimeMeta tm1 = toTimeMeta(); - TimeMeta tm2 = ((TimeDatum)datum).toTimeMeta(); - - return new IntervalDatum((DateTimeUtil.toTime(tm1) - DateTimeUtil.toTime(tm2))/1000); + return new IntervalDatum((time - ((TimeDatum)datum).time)/1000); default: throw new InvalidOperationException(datum.type()); } @@ -171,7 +168,7 @@ public Datum equalsTo(Datum datum) { public int compareTo(Datum datum) { if (datum.type() == TajoDataTypes.Type.TIME) { TimeDatum another = (TimeDatum)datum; - return (time < another.time) ? -1 : ((time == another.time) ? 0 : 1); + return Longs.compare(time, another.time); } else if (datum instanceof NullDatum || datum.isNull()) { return -1; } else { @@ -179,6 +176,7 @@ public int compareTo(Datum datum) { } } + @Override public boolean equals(Object obj) { if (obj instanceof TimeDatum) { TimeDatum another = (TimeDatum) obj; @@ -190,7 +188,7 @@ public boolean equals(Object obj) { @Override public int hashCode() { - return (int)(time ^ (time >>> 32)); + return Longs.hashCode(time); } } diff --git a/tajo-common/src/main/java/org/apache/tajo/datum/TimestampDatum.java b/tajo-common/src/main/java/org/apache/tajo/datum/TimestampDatum.java index 9ad5f2b2aa..ad73c749ba 100644 --- a/tajo-common/src/main/java/org/apache/tajo/datum/TimestampDatum.java +++ b/tajo-common/src/main/java/org/apache/tajo/datum/TimestampDatum.java @@ -18,7 +18,7 @@ package org.apache.tajo.datum; -import com.google.common.base.Objects; +import com.google.common.primitives.Longs; import org.apache.tajo.common.TajoDataTypes; import org.apache.tajo.exception.InvalidOperationException; import org.apache.tajo.util.Bytes; @@ -178,10 +178,7 @@ public Datum equalsTo(Datum datum) { public int compareTo(Datum datum) { if (datum.type() == TajoDataTypes.Type.TIMESTAMP) { TimestampDatum another = (TimestampDatum) datum; - TimeMeta myMeta, otherMeta; - myMeta = toTimeMeta(); - otherMeta = another.toTimeMeta(); - return myMeta.compareTo(otherMeta); + return Longs.compare(timestamp, another.timestamp); } else if (datum.type() == TajoDataTypes.Type.DATE) { DateDatum another = (DateDatum) datum; TimeMeta myMeta, otherMeta; @@ -195,6 +192,7 @@ public int compareTo(Datum datum) { } } + @Override public boolean equals(Object obj) { if (obj instanceof TimestampDatum) { TimestampDatum another = (TimestampDatum) obj; @@ -208,19 +206,9 @@ public boolean equals(Object obj) { public Datum plus(Datum datum) { if (datum.type() == TajoDataTypes.Type.INTERVAL) { IntervalDatum interval = (IntervalDatum)datum; - - TimeMeta tm = new TimeMeta(); - DateTimeUtil.toJulianTimeMeta(timestamp, tm); - - if (interval.getMonths() > 0) { - tm.plusMonths(interval.getMonths()); - } - if (interval.getMilliSeconds() > 0) { - tm.plusMillis(interval.getMilliSeconds()); - } - + TimeMeta tm = toTimeMeta(); + tm.plusInterval(interval.months, interval.milliseconds); return new TimestampDatum(DateTimeUtil.toJulianTimestamp(tm)); - } else { throw new InvalidOperationException(datum.type()); } @@ -231,16 +219,8 @@ public Datum minus(Datum datum) { switch(datum.type()) { case INTERVAL: IntervalDatum interval = (IntervalDatum)datum; - - TimeMeta tm = new TimeMeta(); - DateTimeUtil.toJulianTimeMeta(timestamp, tm); - - if (interval.getMonths() > 0) { - tm.plusMonths(0 - interval.getMonths()); - } - if (interval.getMilliSeconds() > 0) { - tm.plusMillis(0 - interval.getMilliSeconds()); - } + TimeMeta tm = toTimeMeta(); + tm.plusInterval(-interval.months, -interval.milliseconds); return new TimestampDatum(DateTimeUtil.toJulianTimestamp(tm)); case TIMESTAMP: return new IntervalDatum((timestamp - ((TimestampDatum)datum).timestamp) / 1000); @@ -251,7 +231,7 @@ public Datum minus(Datum datum) { @Override public int hashCode(){ - return Objects.hashCode(timestamp); + return Longs.hashCode(timestamp); } public TimeMeta toTimeMeta() { diff --git a/tajo-common/src/main/java/org/apache/tajo/util/datetime/DateTimeUtil.java b/tajo-common/src/main/java/org/apache/tajo/util/datetime/DateTimeUtil.java index f1c7970d6a..15b423667a 100644 --- a/tajo-common/src/main/java/org/apache/tajo/util/datetime/DateTimeUtil.java +++ b/tajo-common/src/main/java/org/apache/tajo/util/datetime/DateTimeUtil.java @@ -126,6 +126,12 @@ public static int date2j(int year, int month, int day) { return julian; } + public static TimeMeta j2date(int julianDate) { + TimeMeta tm = new TimeMeta(); + j2date(julianDate, tm); + return tm; + } + /** * Set TimeMeta's date fields. * @param julianDate @@ -1899,6 +1905,10 @@ public static String encodeDateTime(TimeMeta tm, DateStyle style) { } public static String encodeDate(TimeMeta tm, DateStyle style) { + return encodeDate(tm.years, tm.monthOfYear, tm.dayOfMonth, style); + } + + public static String encodeDate(int years, int monthOfYear, int dayOfMonth, DateStyle style) { StringBuilder sb = new StringBuilder(); switch (style) { case ISO_DATES: @@ -1907,8 +1917,8 @@ public static String encodeDate(TimeMeta tm, DateStyle style) { // Compatible with Oracle/Ingres date formats default: sb.append(String.format("%04d-%02d-%02d", - (tm.years > 0) ? tm.years : -(tm.years - 1), - tm.monthOfYear, tm.dayOfMonth)); + (years > 0) ? years : -(years - 1), + monthOfYear, dayOfMonth)); } return sb.toString(); diff --git a/tajo-common/src/main/java/org/apache/tajo/util/datetime/TimeMeta.java b/tajo-common/src/main/java/org/apache/tajo/util/datetime/TimeMeta.java index 30d4ce1d45..3349f4357d 100644 --- a/tajo-common/src/main/java/org/apache/tajo/util/datetime/TimeMeta.java +++ b/tajo-common/src/main/java/org/apache/tajo/util/datetime/TimeMeta.java @@ -136,6 +136,15 @@ public void plusTime(long time) { DateTimeUtil.toJulianTimeMeta(timestamp, this); } + public void plusInterval(int months, long milliseconds) { + if (months != 0) { + plusMonths(months); + } + if (milliseconds != 0) { + plusMillis(milliseconds); + } + } + public int getCenturyOfEra() { return DateTimeUtil.getCenturyOfEra(years); } diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/function/datetime/ToDate.java b/tajo-core/src/main/java/org/apache/tajo/engine/function/datetime/ToDate.java index 727b78a172..9575e12a88 100644 --- a/tajo-core/src/main/java/org/apache/tajo/engine/function/datetime/ToDate.java +++ b/tajo-core/src/main/java/org/apache/tajo/engine/function/datetime/ToDate.java @@ -57,6 +57,6 @@ public Datum eval(Tuple params) { TimeMeta tm = DateTimeFormat.parseDateTime(value, pattern); - return new DateDatum(DateTimeUtil.date2j(tm.years, tm.monthOfYear, tm.dayOfMonth)); + return new DateDatum(tm); } } diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/ExprAnnotator.java b/tajo-plan/src/main/java/org/apache/tajo/plan/ExprAnnotator.java index 127d5bd232..42a7380645 100644 --- a/tajo-plan/src/main/java/org/apache/tajo/plan/ExprAnnotator.java +++ b/tajo-plan/src/main/java/org/apache/tajo/plan/ExprAnnotator.java @@ -836,7 +836,7 @@ public EvalNode visitDateLiteral(Context context, Stack stack, DateLiteral DateTimeUtil.j2date(DateTimeUtil.date2j(dates[0], dates[1], dates[2]), tm); - return new ConstEval(new DateDatum(DateTimeUtil.date2j(tm.years, tm.monthOfYear, tm.dayOfMonth))); + return new ConstEval(new DateDatum(tm)); } @Override