diff --git ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/VectorUDFDateDiffColScalar.java ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/VectorUDFDateDiffColScalar.java index 71b3887..a58949a 100644 --- ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/VectorUDFDateDiffColScalar.java +++ ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/VectorUDFDateDiffColScalar.java @@ -18,7 +18,6 @@ package org.apache.hadoop.hive.ql.exec.vector.expressions; -import org.apache.hadoop.hive.metastore.parser.ExpressionTree.Operator; import org.apache.hadoop.hive.ql.exec.vector.BytesColumnVector; import org.apache.hadoop.hive.ql.exec.vector.ColumnVector; import org.apache.hadoop.hive.ql.exec.vector.LongColumnVector; @@ -28,6 +27,8 @@ import org.apache.hadoop.hive.serde2.io.DateWritable; import org.apache.hadoop.io.Text; +import com.google.common.base.Preconditions; + import java.sql.Date; import java.sql.Timestamp; import java.text.ParseException; @@ -44,6 +45,7 @@ private transient SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd"); private transient final Text text = new Text(); private int baseDate; + private boolean isNull = false; private transient Date date = new Date(0); public VectorUDFDateDiffColScalar(int colNum, Object object, int outputColumn) { @@ -52,11 +54,14 @@ public VectorUDFDateDiffColScalar(int colNum, Object object, int outputColumn) { this.outputColumn = outputColumn; if (object instanceof Long) { - this.longValue = (Long) object; + setLongValue((Long) object); } else if (object instanceof Timestamp) { - this.timestampValue = (Timestamp) object; + setTimeStampValue((Timestamp) object); } else if (object instanceof byte []) { - this.stringValue = (byte []) object; + setStringValue((byte []) object); + } else { + assert object == null; + isNull = true; } } @@ -71,6 +76,17 @@ public void evaluate(VectorizedRowBatch batch) { super.evaluateChildren(batch); } + switch (inputTypes[1]) { + case DATE: + case TIMESTAMP: + case STRING: + case CHAR: + case VARCHAR: + break; + default: + throw new Error("Invalid input type #1: " + inputTypes[1].name()); + } + LongColumnVector outV = (LongColumnVector) batch.cols[outputColumn]; ColumnVector inputCol = batch.cols[this.colNum]; /* every line below this is identical for evaluateLong & evaluateString */ @@ -86,39 +102,20 @@ public void evaluate(VectorizedRowBatch batch) { /* true for all algebraic UDFs with no state */ outV.isRepeating = inputCol.isRepeating; - switch (inputTypes[1]) { - case DATE: - baseDate = (int) longValue; - break; - - case TIMESTAMP: - date.setTime(timestampValue.getTime()); - baseDate = DateWritable.dateToDays(date); - break; - - case STRING: - case CHAR: - case VARCHAR: - try { - date.setTime(formatter.parse(new String(stringValue, "UTF-8")).getTime()); - baseDate = DateWritable.dateToDays(date); - break; - } catch (Exception e) { - outV.noNulls = false; - if (selectedInUse) { - for(int j=0; j < n; j++) { - int i = sel[j]; - outV.isNull[i] = true; - } - } else { - for(int i = 0; i < n; i++) { - outV.isNull[i] = true; - } - } - return; + if (isNull) { + // rhs is null + outV.noNulls = false; + if (selectedInUse) { + for(int j=0; j < n; j++) { + int i = sel[j]; + outV.isNull[i] = true; } - default: - throw new Error("Invalid input type #1: " + inputTypes[1].name()); + } else { + for(int i = 0; i < n; i++) { + outV.isNull[i] = true; + } + } + return; } switch (inputTypes[0]) { @@ -284,8 +281,10 @@ public long getLongValue() { return longValue; } - public void setLongValue(int longValue) { + public void setLongValue(long longValue) { this.longValue = longValue; + Preconditions.checkArgument(longValue <= Integer.MAX_VALUE); + baseDate = (int) longValue; } public byte[] getStringValue() { @@ -294,8 +293,25 @@ public void setLongValue(int longValue) { public void setStringValue(byte[] stringValue) { this.stringValue = stringValue; + try { + date.setTime(formatter.parse(new String(stringValue, "UTF-8")).getTime()); + baseDate = DateWritable.dateToDays(date); + } catch (Exception e) { + isNull = true; + } + } + + public Timestamp getTimestampValue() { + return this.timestampValue; + } + + public void setTimeStampValue(Timestamp timestampValue) { + this.timestampValue = timestampValue; + date.setTime(timestampValue.getTime()); + baseDate = DateWritable.dateToDays(date); } + @Override public VectorExpressionDescriptor.Descriptor getDescriptor() { VectorExpressionDescriptor.Builder b = new VectorExpressionDescriptor.Builder(); diff --git ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/VectorUDFDateDiffScalarCol.java ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/VectorUDFDateDiffScalarCol.java index c733bc9..3022b8e 100644 --- ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/VectorUDFDateDiffScalarCol.java +++ ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/VectorUDFDateDiffScalarCol.java @@ -27,6 +27,8 @@ import org.apache.hadoop.hive.serde2.io.DateWritable; import org.apache.hadoop.io.Text; +import com.google.common.base.Preconditions; + import java.sql.Date; import java.sql.Timestamp; import java.text.ParseException; @@ -43,6 +45,7 @@ private transient SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd"); private transient final Text text = new Text(); private int baseDate; + private boolean isNull = false; private transient Date date = new Date(0); public VectorUDFDateDiffScalarCol(Object object, int colNum, int outputColumn) { @@ -51,11 +54,14 @@ public VectorUDFDateDiffScalarCol(Object object, int colNum, int outputColumn) { this.outputColumn = outputColumn; if (object instanceof Long) { - this.longValue = (Long) object; + setLongValue((Long) object); } else if (object instanceof Timestamp) { - this.timestampValue = (Timestamp) object; + setTimeStampValue((Timestamp) object); } else if (object instanceof byte []) { - this.stringValue = (byte[]) object; + setStringValue((byte []) object); + } else { + assert object == null; + isNull = true; } } @@ -70,6 +76,17 @@ public void evaluate(VectorizedRowBatch batch) { super.evaluateChildren(batch); } + switch (inputTypes[0]) { + case DATE: + case TIMESTAMP: + case STRING: + case CHAR: + case VARCHAR: + break; + default: + throw new Error("Unsupported input type " + inputTypes[0].name()); + } + LongColumnVector outV = (LongColumnVector) batch.cols[outputColumn]; ColumnVector inputCol = batch.cols[this.colNum]; /* every line below this is identical for evaluateLong & evaluateString */ @@ -85,39 +102,20 @@ public void evaluate(VectorizedRowBatch batch) { /* true for all algebraic UDFs with no state */ outV.isRepeating = inputCol.isRepeating; - switch (inputTypes[0]) { - case DATE: - baseDate = (int) longValue; - break; - - case TIMESTAMP: - date.setTime(timestampValue.getTime()); - baseDate = DateWritable.dateToDays(date); - break; - - case STRING: - case CHAR: - case VARCHAR: - try { - date.setTime(formatter.parse(new String(stringValue, "UTF-8")).getTime()); - baseDate = DateWritable.dateToDays(date); - break; - } catch (Exception e) { - outV.noNulls = false; - if (selectedInUse) { - for(int j=0; j < n; j++) { - int i = sel[j]; - outV.isNull[i] = true; - } - } else { - for(int i = 0; i < n; i++) { - outV.isNull[i] = true; - } - } - return; + if (isNull) { + // rhs is null + outV.noNulls = false; + if (selectedInUse) { + for(int j=0; j < n; j++) { + int i = sel[j]; + outV.isNull[i] = true; } - default: - throw new Error("Unsupported input type " + inputTypes[0].name()); + } else { + for(int i = 0; i < n; i++) { + outV.isNull[i] = true; + } + } + return; } switch (inputTypes[1]) { @@ -257,6 +255,7 @@ protected void evaluateString(ColumnVector columnVector, LongColumnVector output output.isNull[i] = true; } } + @Override public int getOutputColumn() { return this.outputColumn; @@ -283,8 +282,10 @@ public long getLongValue() { return longValue; } - public void setLongValue(int longValue) { + public void setLongValue(long longValue) { this.longValue = longValue; + Preconditions.checkArgument(longValue <= Integer.MAX_VALUE); + baseDate = (int) longValue; } public byte[] getStringValue() { @@ -293,6 +294,22 @@ public void setLongValue(int longValue) { public void setStringValue(byte[] stringValue) { this.stringValue = stringValue; + try { + date.setTime(formatter.parse(new String(stringValue, "UTF-8")).getTime()); + baseDate = DateWritable.dateToDays(date); + } catch (Exception e) { + isNull = true; + } + } + + public Timestamp getTimestampValue() { + return this.timestampValue; + } + + public void setTimeStampValue(Timestamp timestampValue) { + this.timestampValue = timestampValue; + date.setTime(timestampValue.getTime()); + baseDate = DateWritable.dateToDays(date); } @Override