Repository: hive Updated Branches: refs/heads/master f6726f84e -> 7a88ffbed
HIVE-20385 : Date: date + int fails to add days (Bruno Pusztahazi via Ashutosh Chauhan) Signed-off-by: Ashutosh Chauhan <hashut...@apache.org> Project: http://git-wip-us.apache.org/repos/asf/hive/repo Commit: http://git-wip-us.apache.org/repos/asf/hive/commit/7a88ffbe Tree: http://git-wip-us.apache.org/repos/asf/hive/tree/7a88ffbe Diff: http://git-wip-us.apache.org/repos/asf/hive/diff/7a88ffbe Branch: refs/heads/master Commit: 7a88ffbedadd18baf42fe9ffafe1af5933303d3f Parents: f6726f8 Author: Bruno Pusztahazi <bpusztah...@hortonworks.com> Authored: Thu Sep 13 01:34:00 2018 -0700 Committer: Ashutosh Chauhan <hashut...@apache.org> Committed: Sat Oct 13 09:31:31 2018 -0700 ---------------------------------------------------------------------- .../ql/udf/generic/GenericUDFOPDTIMinus.java | 110 +++++++++++-------- .../ql/udf/generic/GenericUDFOPDTIPlus.java | 94 +++++++++------- .../hadoop/hive/ql/util/DateTimeMath.java | 18 ++- .../clientpositive/date_int_operation_test.q | 5 + .../date_int_operation_test.q.out | 18 +++ 5 files changed, 158 insertions(+), 87 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/hive/blob/7a88ffbe/ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFOPDTIMinus.java ---------------------------------------------------------------------- diff --git a/ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFOPDTIMinus.java b/ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFOPDTIMinus.java index 076ca51..9e56d3c 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFOPDTIMinus.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFOPDTIMinus.java @@ -71,7 +71,8 @@ public class GenericUDFOPDTIMinus extends GenericUDFBaseDTI { TIMESTAMP_MINUS_INTERVALYM, INTERVALDT_MINUS_INTERVALDT, TIMESTAMP_MINUS_INTERVALDT, - TIMESTAMP_MINUS_TIMESTAMP + TIMESTAMP_MINUS_TIMESTAMP, + DATE_MINUS_INT }; public GenericUDFOPDTIMinus() { @@ -101,8 +102,8 @@ public class GenericUDFOPDTIMinus extends GenericUDFBaseDTI { } inputOIs = new PrimitiveObjectInspector[] { - (PrimitiveObjectInspector) arguments[0], - (PrimitiveObjectInspector) arguments[1] + (PrimitiveObjectInspector) arguments[0], + (PrimitiveObjectInspector) arguments[1] }; PrimitiveObjectInspector leftOI = inputOIs[0]; PrimitiveObjectInspector rightOI = inputOIs[1]; @@ -117,6 +118,7 @@ public class GenericUDFOPDTIMinus extends GenericUDFBaseDTI { // Timestamp - Timestamp = IntervalDayTime // Date - Date = IntervalDayTime // Timestamp - Date = IntervalDayTime (operands reversible) + // Date - Int = Date if (checkArgs(PrimitiveCategory.INTERVAL_YEAR_MONTH, PrimitiveCategory.INTERVAL_YEAR_MONTH)) { minusOpType = OperationType.INTERVALYM_MINUS_INTERVALYM; intervalArg1Idx = 0; @@ -161,6 +163,13 @@ public class GenericUDFOPDTIMinus extends GenericUDFBaseDTI { TypeInfoFactory.intervalDayTimeTypeInfo); dt1Converter = ObjectInspectorConverters.getConverter(leftOI, resultOI); dt2Converter = ObjectInspectorConverters.getConverter(leftOI, resultOI); + } else if (checkArgs(PrimitiveCategory.DATE, PrimitiveCategory.INT)) { + minusOpType = OperationType.DATE_MINUS_INT; + intervalArg1Idx = 1; + dtArg1Idx = 0; + resultOI = PrimitiveObjectInspectorFactory.getPrimitiveWritableObjectInspector( + TypeInfoFactory.dateTypeInfo); + dt1Converter = ObjectInspectorConverters.getConverter(leftOI, resultOI); } else { // Unsupported types - error List<TypeInfo> argTypeInfos = new ArrayList<TypeInfo>(2); @@ -175,50 +184,57 @@ public class GenericUDFOPDTIMinus extends GenericUDFBaseDTI { @Override public Object evaluate(DeferredObject[] arguments) throws HiveException { switch (minusOpType) { - case INTERVALYM_MINUS_INTERVALYM: { - HiveIntervalYearMonth iym1 = PrimitiveObjectInspectorUtils.getHiveIntervalYearMonth( - arguments[intervalArg1Idx].get(), inputOIs[intervalArg1Idx]); - HiveIntervalYearMonth iym2 = PrimitiveObjectInspectorUtils.getHiveIntervalYearMonth( - arguments[intervalArg2Idx].get(), inputOIs[intervalArg2Idx]); - return handleIntervalYearMonthResult(dtm.subtract(iym1, iym2)); - } - case DATE_MINUS_INTERVALYM: { - HiveIntervalYearMonth iym1 = PrimitiveObjectInspectorUtils.getHiveIntervalYearMonth( - arguments[intervalArg1Idx].get(), inputOIs[intervalArg1Idx]); - Date dt1 = PrimitiveObjectInspectorUtils.getDate( - arguments[dtArg1Idx].get(), inputOIs[dtArg1Idx]); - return handleDateResult(dtm.subtract(dt1, iym1)); - } - case TIMESTAMP_MINUS_INTERVALYM: { - HiveIntervalYearMonth iym1 = PrimitiveObjectInspectorUtils.getHiveIntervalYearMonth( - arguments[intervalArg1Idx].get(), inputOIs[intervalArg1Idx]); - Timestamp ts1 = PrimitiveObjectInspectorUtils.getTimestamp( - arguments[dtArg1Idx].get(), inputOIs[dtArg1Idx]); - return handleTimestampResult(dtm.subtract(ts1, iym1)); - } - case INTERVALDT_MINUS_INTERVALDT: { - HiveIntervalDayTime idt1 = PrimitiveObjectInspectorUtils.getHiveIntervalDayTime( - arguments[intervalArg1Idx].get(), inputOIs[intervalArg1Idx]); - HiveIntervalDayTime idt2 = PrimitiveObjectInspectorUtils.getHiveIntervalDayTime( - arguments[intervalArg2Idx].get(), inputOIs[intervalArg2Idx]); - return handleIntervalDayTimeResult(dtm.subtract(idt1, idt2)); - } - case TIMESTAMP_MINUS_INTERVALDT: { - HiveIntervalDayTime idt1 = PrimitiveObjectInspectorUtils.getHiveIntervalDayTime( - arguments[intervalArg1Idx].get(), inputOIs[intervalArg1Idx]); - Timestamp ts1 = PrimitiveObjectInspectorUtils.getTimestamp( - arguments[dtArg1Idx].get(), inputOIs[dtArg1Idx]); - return handleTimestampResult(dtm.subtract(ts1, idt1)); - } - case TIMESTAMP_MINUS_TIMESTAMP: { - Timestamp ts1 = PrimitiveObjectInspectorUtils.getTimestamp( - arguments[dtArg1Idx].get(), inputOIs[dtArg1Idx]); - Timestamp ts2 = PrimitiveObjectInspectorUtils.getTimestamp( - arguments[dtArg2Idx].get(), inputOIs[dtArg2Idx]); - return handleIntervalDayTimeResult(dtm.subtract(ts1, ts2)); - } - default: - throw new HiveException("Unknown PlusOpType " + minusOpType); + case INTERVALYM_MINUS_INTERVALYM: { + HiveIntervalYearMonth iym1 = PrimitiveObjectInspectorUtils.getHiveIntervalYearMonth( + arguments[intervalArg1Idx].get(), inputOIs[intervalArg1Idx]); + HiveIntervalYearMonth iym2 = PrimitiveObjectInspectorUtils.getHiveIntervalYearMonth( + arguments[intervalArg2Idx].get(), inputOIs[intervalArg2Idx]); + return handleIntervalYearMonthResult(dtm.subtract(iym1, iym2)); + } + case DATE_MINUS_INTERVALYM: { + HiveIntervalYearMonth iym1 = PrimitiveObjectInspectorUtils.getHiveIntervalYearMonth( + arguments[intervalArg1Idx].get(), inputOIs[intervalArg1Idx]); + Date dt1 = PrimitiveObjectInspectorUtils.getDate( + arguments[dtArg1Idx].get(), inputOIs[dtArg1Idx]); + return handleDateResult(dtm.subtract(dt1, iym1)); + } + case TIMESTAMP_MINUS_INTERVALYM: { + HiveIntervalYearMonth iym1 = PrimitiveObjectInspectorUtils.getHiveIntervalYearMonth( + arguments[intervalArg1Idx].get(), inputOIs[intervalArg1Idx]); + Timestamp ts1 = PrimitiveObjectInspectorUtils.getTimestamp( + arguments[dtArg1Idx].get(), inputOIs[dtArg1Idx]); + return handleTimestampResult(dtm.subtract(ts1, iym1)); + } + case INTERVALDT_MINUS_INTERVALDT: { + HiveIntervalDayTime idt1 = PrimitiveObjectInspectorUtils.getHiveIntervalDayTime( + arguments[intervalArg1Idx].get(), inputOIs[intervalArg1Idx]); + HiveIntervalDayTime idt2 = PrimitiveObjectInspectorUtils.getHiveIntervalDayTime( + arguments[intervalArg2Idx].get(), inputOIs[intervalArg2Idx]); + return handleIntervalDayTimeResult(dtm.subtract(idt1, idt2)); + } + case TIMESTAMP_MINUS_INTERVALDT: { + HiveIntervalDayTime idt1 = PrimitiveObjectInspectorUtils.getHiveIntervalDayTime( + arguments[intervalArg1Idx].get(), inputOIs[intervalArg1Idx]); + Timestamp ts1 = PrimitiveObjectInspectorUtils.getTimestamp( + arguments[dtArg1Idx].get(), inputOIs[dtArg1Idx]); + return handleTimestampResult(dtm.subtract(ts1, idt1)); + } + case TIMESTAMP_MINUS_TIMESTAMP: { + Timestamp ts1 = PrimitiveObjectInspectorUtils.getTimestamp( + arguments[dtArg1Idx].get(), inputOIs[dtArg1Idx]); + Timestamp ts2 = PrimitiveObjectInspectorUtils.getTimestamp( + arguments[dtArg2Idx].get(), inputOIs[dtArg2Idx]); + return handleIntervalDayTimeResult(dtm.subtract(ts1, ts2)); + } + case DATE_MINUS_INT: { + int intVal = PrimitiveObjectInspectorUtils.getInt(arguments[intervalArg1Idx].get(), + inputOIs[intervalArg1Idx]); + Date dt1 = PrimitiveObjectInspectorUtils.getDate( + arguments[dtArg1Idx].get(), inputOIs[dtArg1Idx]); + return handleDateResult(dtm.add(dt1, -intVal)); + } + default: + throw new HiveException("Unknown MinusOpType " + minusOpType); } } http://git-wip-us.apache.org/repos/asf/hive/blob/7a88ffbe/ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFOPDTIPlus.java ---------------------------------------------------------------------- diff --git a/ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFOPDTIPlus.java b/ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFOPDTIPlus.java index 9295c8f..da480a4 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFOPDTIPlus.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFOPDTIPlus.java @@ -69,6 +69,7 @@ public class GenericUDFOPDTIPlus extends GenericUDFBaseDTI { INTERVALYM_PLUS_TIMESTAMP, INTERVALDT_PLUS_INTERVALDT, INTERVALDT_PLUS_TIMESTAMP, + DATE_PLUS_INT, }; public GenericUDFOPDTIPlus() { @@ -98,8 +99,8 @@ public class GenericUDFOPDTIPlus extends GenericUDFBaseDTI { } inputOIs = new PrimitiveObjectInspector[] { - (PrimitiveObjectInspector) arguments[0], - (PrimitiveObjectInspector) arguments[1] + (PrimitiveObjectInspector) arguments[0], + (PrimitiveObjectInspector) arguments[1] }; PrimitiveObjectInspector leftOI = inputOIs[0]; PrimitiveObjectInspector rightOI = inputOIs[1]; @@ -111,6 +112,7 @@ public class GenericUDFOPDTIPlus extends GenericUDFBaseDTI { // IntervalDayTime + IntervalDayTime = IntervalDayTime // IntervalDayTime + Date = Timestamp (operands reversible) // IntervalDayTime + Timestamp = Timestamp (operands reversible) + // Date + Int = Date if (checkArgs(PrimitiveCategory.INTERVAL_YEAR_MONTH, PrimitiveCategory.INTERVAL_YEAR_MONTH)) { plusOpType = OperationType.INTERVALYM_PLUS_INTERVALYM; intervalArg1Idx = 0; @@ -163,6 +165,13 @@ public class GenericUDFOPDTIPlus extends GenericUDFBaseDTI { resultOI = PrimitiveObjectInspectorFactory.getPrimitiveWritableObjectInspector( TypeInfoFactory.timestampTypeInfo); dtConverter = ObjectInspectorConverters.getConverter(leftOI, resultOI); + } else if (checkArgs(PrimitiveCategory.DATE, PrimitiveCategory.INT)) { + plusOpType = OperationType.DATE_PLUS_INT; + intervalArg1Idx = 1; + dtArgIdx = 0; + resultOI = PrimitiveObjectInspectorFactory.getPrimitiveWritableObjectInspector( + TypeInfoFactory.dateTypeInfo); + dtConverter = ObjectInspectorConverters.getConverter(leftOI, resultOI); } else { // Unsupported types - error List<TypeInfo> argTypeInfos = new ArrayList<TypeInfo>(2); @@ -177,43 +186,50 @@ public class GenericUDFOPDTIPlus extends GenericUDFBaseDTI { @Override public Object evaluate(DeferredObject[] arguments) throws HiveException { switch (plusOpType) { - case INTERVALYM_PLUS_INTERVALYM: { - HiveIntervalYearMonth iym1 = PrimitiveObjectInspectorUtils.getHiveIntervalYearMonth( - arguments[intervalArg1Idx].get(), inputOIs[intervalArg1Idx]); - HiveIntervalYearMonth iym2 = PrimitiveObjectInspectorUtils.getHiveIntervalYearMonth( - arguments[intervalArg2Idx].get(), inputOIs[intervalArg2Idx]); - return handleIntervalYearMonthResult(dtm.add(iym1, iym2)); - } - case INTERVALYM_PLUS_DATE: { - HiveIntervalYearMonth iym1 = PrimitiveObjectInspectorUtils.getHiveIntervalYearMonth( - arguments[intervalArg1Idx].get(), inputOIs[intervalArg1Idx]); - Date dt1 = PrimitiveObjectInspectorUtils.getDate( - arguments[dtArgIdx].get(), inputOIs[dtArgIdx]); - return handleDateResult(dtm.add(dt1, iym1)); - } - case INTERVALYM_PLUS_TIMESTAMP: { - HiveIntervalYearMonth iym1 = PrimitiveObjectInspectorUtils.getHiveIntervalYearMonth( - arguments[intervalArg1Idx].get(), inputOIs[intervalArg1Idx]); - Timestamp ts1 = PrimitiveObjectInspectorUtils.getTimestamp( - arguments[dtArgIdx].get(), inputOIs[dtArgIdx]); - return handleTimestampResult(dtm.add(ts1, iym1)); - } - case INTERVALDT_PLUS_INTERVALDT: { - HiveIntervalDayTime idt1 = PrimitiveObjectInspectorUtils.getHiveIntervalDayTime( - arguments[intervalArg1Idx].get(), inputOIs[intervalArg1Idx]); - HiveIntervalDayTime idt2 = PrimitiveObjectInspectorUtils.getHiveIntervalDayTime( - arguments[intervalArg2Idx].get(), inputOIs[intervalArg2Idx]); - return handleIntervalDayTimeResult(dtm.add(idt1, idt2)); - } - case INTERVALDT_PLUS_TIMESTAMP: { - HiveIntervalDayTime idt1 = PrimitiveObjectInspectorUtils.getHiveIntervalDayTime( - arguments[intervalArg1Idx].get(), inputOIs[intervalArg1Idx]); - Timestamp ts1 = PrimitiveObjectInspectorUtils.getTimestamp( - arguments[dtArgIdx].get(), inputOIs[dtArgIdx]); - return handleTimestampResult(dtm.add(ts1, idt1)); - } - default: - throw new HiveException("Unknown PlusOpType " + plusOpType); + case INTERVALYM_PLUS_INTERVALYM: { + HiveIntervalYearMonth iym1 = PrimitiveObjectInspectorUtils.getHiveIntervalYearMonth( + arguments[intervalArg1Idx].get(), inputOIs[intervalArg1Idx]); + HiveIntervalYearMonth iym2 = PrimitiveObjectInspectorUtils.getHiveIntervalYearMonth( + arguments[intervalArg2Idx].get(), inputOIs[intervalArg2Idx]); + return handleIntervalYearMonthResult(dtm.add(iym1, iym2)); + } + case INTERVALYM_PLUS_DATE: { + HiveIntervalYearMonth iym1 = PrimitiveObjectInspectorUtils.getHiveIntervalYearMonth( + arguments[intervalArg1Idx].get(), inputOIs[intervalArg1Idx]); + Date dt1 = PrimitiveObjectInspectorUtils.getDate( + arguments[dtArgIdx].get(), inputOIs[dtArgIdx]); + return handleDateResult(dtm.add(dt1, iym1)); + } + case INTERVALYM_PLUS_TIMESTAMP: { + HiveIntervalYearMonth iym1 = PrimitiveObjectInspectorUtils.getHiveIntervalYearMonth( + arguments[intervalArg1Idx].get(), inputOIs[intervalArg1Idx]); + Timestamp ts1 = PrimitiveObjectInspectorUtils.getTimestamp( + arguments[dtArgIdx].get(), inputOIs[dtArgIdx]); + return handleTimestampResult(dtm.add(ts1, iym1)); + } + case INTERVALDT_PLUS_INTERVALDT: { + HiveIntervalDayTime idt1 = PrimitiveObjectInspectorUtils.getHiveIntervalDayTime( + arguments[intervalArg1Idx].get(), inputOIs[intervalArg1Idx]); + HiveIntervalDayTime idt2 = PrimitiveObjectInspectorUtils.getHiveIntervalDayTime( + arguments[intervalArg2Idx].get(), inputOIs[intervalArg2Idx]); + return handleIntervalDayTimeResult(dtm.add(idt1, idt2)); + } + case INTERVALDT_PLUS_TIMESTAMP: { + HiveIntervalDayTime idt1 = PrimitiveObjectInspectorUtils.getHiveIntervalDayTime( + arguments[intervalArg1Idx].get(), inputOIs[intervalArg1Idx]); + Timestamp ts1 = PrimitiveObjectInspectorUtils.getTimestamp( + arguments[dtArgIdx].get(), inputOIs[dtArgIdx]); + return handleTimestampResult(dtm.add(ts1, idt1)); + } + case DATE_PLUS_INT: { + int intVal = PrimitiveObjectInspectorUtils.getInt(arguments[intervalArg1Idx].get(), + inputOIs[intervalArg1Idx]); + Date dt1 = PrimitiveObjectInspectorUtils.getDate( + arguments[dtArgIdx].get(), inputOIs[dtArgIdx]); + return handleDateResult(dtm.add(dt1, intVal)); + } + default: + throw new HiveException("Unknown PlusOpType " + plusOpType); } } http://git-wip-us.apache.org/repos/asf/hive/blob/7a88ffbe/ql/src/java/org/apache/hadoop/hive/ql/util/DateTimeMath.java ---------------------------------------------------------------------- diff --git a/ql/src/java/org/apache/hadoop/hive/ql/util/DateTimeMath.java b/ql/src/java/org/apache/hadoop/hive/ql/util/DateTimeMath.java index 16babbf..20acfa2 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/util/DateTimeMath.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/util/DateTimeMath.java @@ -230,6 +230,22 @@ public class DateTimeMath { return dtResult; } + /** + * Perform date + int operation . + * @param dt the date + * @param interval the int (days) + * @return the resulting date + */ + public Date add(Date dt, int interval) { + if (dt == null) { + return null; + } + + Date dtResult = new Date(); + dtResult.setTimeInDays(dt.toEpochDay() + interval); + return dtResult; + } + @Deprecated public java.sql.Date add(HiveIntervalYearMonth interval, java.sql.Date dt) { if (dt == null || interval == null) { @@ -471,7 +487,7 @@ public class DateTimeMath { HiveIntervalDayTime result = new HiveIntervalDayTime(); add(left, right, result); - + return result; } http://git-wip-us.apache.org/repos/asf/hive/blob/7a88ffbe/ql/src/test/queries/clientpositive/date_int_operation_test.q ---------------------------------------------------------------------- diff --git a/ql/src/test/queries/clientpositive/date_int_operation_test.q b/ql/src/test/queries/clientpositive/date_int_operation_test.q new file mode 100644 index 0000000..05d97d7 --- /dev/null +++ b/ql/src/test/queries/clientpositive/date_int_operation_test.q @@ -0,0 +1,5 @@ +--! qt:dataset:srcpart +--! qt:dataset:src +--! qt:dataset:alltypesorc +select date('2001-01-28') + 3; +select date('2001-01-28') - 3; http://git-wip-us.apache.org/repos/asf/hive/blob/7a88ffbe/ql/src/test/results/clientpositive/date_int_operation_test.q.out ---------------------------------------------------------------------- diff --git a/ql/src/test/results/clientpositive/date_int_operation_test.q.out b/ql/src/test/results/clientpositive/date_int_operation_test.q.out new file mode 100644 index 0000000..ab7f7b4 --- /dev/null +++ b/ql/src/test/results/clientpositive/date_int_operation_test.q.out @@ -0,0 +1,18 @@ +PREHOOK: query: select date('2001-01-28') + 3 +PREHOOK: type: QUERY +PREHOOK: Input: _dummy_database@_dummy_table +#### A masked pattern was here #### +POSTHOOK: query: select date('2001-01-28') + 3 +POSTHOOK: type: QUERY +POSTHOOK: Input: _dummy_database@_dummy_table +#### A masked pattern was here #### +2001-01-31 +PREHOOK: query: select date('2001-01-28') - 3 +PREHOOK: type: QUERY +PREHOOK: Input: _dummy_database@_dummy_table +#### A masked pattern was here #### +POSTHOOK: query: select date('2001-01-28') - 3 +POSTHOOK: type: QUERY +POSTHOOK: Input: _dummy_database@_dummy_table +#### A masked pattern was here #### +2001-01-25