diff --git itests/hive-jmh/src/main/java/org/apache/hive/benchmark/vectorization/AbstractExpression.java itests/hive-jmh/src/main/java/org/apache/hive/benchmark/vectorization/AbstractExpression.java index 94af3e0..0f6d943 100644 --- itests/hive-jmh/src/main/java/org/apache/hive/benchmark/vectorization/AbstractExpression.java +++ itests/hive-jmh/src/main/java/org/apache/hive/benchmark/vectorization/AbstractExpression.java @@ -37,7 +37,8 @@ @State(Scope.Thread) @OutputTimeUnit(TimeUnit.NANOSECONDS) public abstract class AbstractExpression { - private static final int DEFAULT_ITER_TIME = 1000000; + protected static final int DEFAULT_ITER_TIME = 1000000; + protected int iterTime = DEFAULT_ITER_TIME; protected VectorExpression expression; protected VectorizedRowBatch rowBatch; @@ -58,7 +59,7 @@ protected VectorizedRowBatch buildRowBatch(ColumnVector output, int colNum, Colu @Warmup(iterations = 2, time = 2, timeUnit = TimeUnit.MILLISECONDS) @Measurement(iterations = 2, time = 2, timeUnit = TimeUnit.MILLISECONDS) public void bench() { - for (int i = 0; i < DEFAULT_ITER_TIME; i++) { + for (int i = 0; i < iterTime; i++) { expression.evaluate(rowBatch); } } diff --git itests/hive-jmh/src/main/java/org/apache/hive/benchmark/vectorization/DecimalColAddDecimalColumnOld.java itests/hive-jmh/src/main/java/org/apache/hive/benchmark/vectorization/DecimalColAddDecimalColumnOld.java new file mode 100644 index 0000000..8cc332c --- /dev/null +++ itests/hive-jmh/src/main/java/org/apache/hive/benchmark/vectorization/DecimalColAddDecimalColumnOld.java @@ -0,0 +1,157 @@ +package org.apache.hive.benchmark.vectorization; + +import org.apache.hadoop.hive.ql.exec.vector.DecimalColumnVector; +import org.apache.hadoop.hive.ql.exec.vector.VectorExpressionDescriptor; +import org.apache.hadoop.hive.ql.exec.vector.VectorizedRowBatch; +import org.apache.hadoop.hive.ql.exec.vector.expressions.DecimalUtil; +import org.apache.hadoop.hive.ql.exec.vector.expressions.NullUtil; +import org.apache.hadoop.hive.ql.exec.vector.expressions.VectorExpression; + +public class DecimalColAddDecimalColumnOld extends VectorExpression { + + private static final long serialVersionUID = 1L; + + private int colNum1; + private int colNum2; + private int outputColumn; + + public DecimalColAddDecimalColumnOld(int colNum1, int colNum2, int outputColumn) { + this.colNum1 = colNum1; + this.colNum2 = colNum2; + this.outputColumn = outputColumn; + this.outputType = "decimal"; + } + + public DecimalColAddDecimalColumnOld() { + this.outputType = "decimal"; + } + + @Override + public void evaluate(VectorizedRowBatch batch) { + + if (childExpressions != null) { + super.evaluateChildren(batch); + } + + DecimalColumnVector inputColVector1 = (DecimalColumnVector) batch.cols[colNum1]; + DecimalColumnVector inputColVector2 = (DecimalColumnVector) batch.cols[colNum2]; + DecimalColumnVector outputColVector = (DecimalColumnVector) batch.cols[outputColumn]; + int[] sel = batch.selected; + int n = batch.size; + + // return immediately if batch is empty + if (n == 0) { + return; + } + + outputColVector.isRepeating = + inputColVector1.isRepeating && inputColVector2.isRepeating + || inputColVector1.isRepeating && !inputColVector1.noNulls && inputColVector1.isNull[0] + || inputColVector2.isRepeating && !inputColVector2.noNulls && inputColVector2.isNull[0]; + + if (inputColVector1.noNulls && inputColVector2.noNulls) { + + /* Initialize output vector NULL values to false. This is necessary + * since the decimal operation may produce a NULL result even for + * a non-null input vector value, and convert the output vector + * to have noNulls = false; + */ + NullUtil.initOutputNullsToFalse(outputColVector, + inputColVector1.isRepeating && inputColVector2.isRepeating, + batch.selectedInUse, sel, n); + } + + // Handle nulls first + NullUtil.propagateNullsColCol( + inputColVector1, inputColVector2, outputColVector, sel, n, batch.selectedInUse); + + /* Disregard nulls for processing. In other words, + * the arithmetic operation is performed even if one or + * more inputs are null. This is to improve speed by avoiding + * conditional checks in the inner loop. + */ + if (inputColVector1.isRepeating && inputColVector2.isRepeating) { + DecimalUtil.addChecked(0, inputColVector1.get(0), inputColVector2.get(0), outputColVector); + } else if (inputColVector1.isRepeating) { + if (batch.selectedInUse) { + for(int j = 0; j != n; j++) { + int i = sel[j]; + DecimalUtil.addChecked(i, inputColVector1.get(0), inputColVector2.get(i), outputColVector); + } + } else { + for(int i = 0; i != n; i++) { + DecimalUtil.addChecked(i, inputColVector1.get(0), inputColVector2.get(i), outputColVector); + } + } + } else if (inputColVector2.isRepeating) { + if (batch.selectedInUse) { + for(int j = 0; j != n; j++) { + int i = sel[j]; + DecimalUtil.addChecked(i, inputColVector1.get(i), inputColVector2.get(0), outputColVector); + } + } else { + for(int i = 0; i != n; i++) { + DecimalUtil.addChecked(i, inputColVector1.get(i), inputColVector2.get(0), outputColVector); + } + } + } else { + if (batch.selectedInUse) { + for(int j = 0; j != n; j++) { + int i = sel[j]; + DecimalUtil.addChecked(i, inputColVector1.get(i), inputColVector2.get(i), outputColVector); + } + } else { + for(int i = 0; i != n; i++) { + DecimalUtil.addChecked(i, inputColVector1.get(i), inputColVector2.get(i), outputColVector); + } + } + } + + /* For the case when the output can have null values, follow + * the convention that the data values must be set to a specific non-zero + * value. This is to prevent possible later zero-divide errors + * in complex arithmetic expressions like col2 / (col1 - 1) + * in the case when some col1 entries are null. + */ + NullUtil.setNullDataEntriesDecimal(outputColVector, batch.selectedInUse, sel, n); + } + + @Override + public int getOutputColumn() { + return outputColumn; + } + + public int getColNum1() { + return colNum1; + } + + public void setColNum1(int colNum1) { + this.colNum1 = colNum1; + } + + public int getColNum2() { + return colNum2; + } + + public void setColNum2(int colNum2) { + this.colNum2 = colNum2; + } + + public void setOutputColumn(int outputColumn) { + this.outputColumn = outputColumn; + } + + @Override + public VectorExpressionDescriptor.Descriptor getDescriptor() { + return (new VectorExpressionDescriptor.Builder()) + .setMode( + VectorExpressionDescriptor.Mode.PROJECTION) + .setNumArguments(2) + .setArgumentTypes( + VectorExpressionDescriptor.ArgumentType.getType("decimal"), + VectorExpressionDescriptor.ArgumentType.getType("decimal")) + .setInputExpressionTypes( + VectorExpressionDescriptor.InputExpressionType.COLUMN, + VectorExpressionDescriptor.InputExpressionType.COLUMN).build(); + } +} diff --git itests/hive-jmh/src/main/java/org/apache/hive/benchmark/vectorization/DecimalColDivideDecimalColumnOld.java itests/hive-jmh/src/main/java/org/apache/hive/benchmark/vectorization/DecimalColDivideDecimalColumnOld.java new file mode 100644 index 0000000..b6ee9b7 --- /dev/null +++ itests/hive-jmh/src/main/java/org/apache/hive/benchmark/vectorization/DecimalColDivideDecimalColumnOld.java @@ -0,0 +1,129 @@ +package org.apache.hive.benchmark.vectorization; + +import org.apache.hadoop.hive.ql.exec.vector.DecimalColumnVector; +import org.apache.hadoop.hive.ql.exec.vector.VectorExpressionDescriptor; +import org.apache.hadoop.hive.ql.exec.vector.VectorizedRowBatch; +import org.apache.hadoop.hive.ql.exec.vector.expressions.DecimalUtil; +import org.apache.hadoop.hive.ql.exec.vector.expressions.NullUtil; +import org.apache.hadoop.hive.ql.exec.vector.expressions.VectorExpression; + +public class DecimalColDivideDecimalColumnOld extends VectorExpression { + + private static final long serialVersionUID = 1L; + + private int colNum1; + private int colNum2; + private int outputColumn; + + public DecimalColDivideDecimalColumnOld(int colNum1, int colNum2, int outputColumn) { + this.colNum1 = colNum1; + this.colNum2 = colNum2; + this.outputColumn = outputColumn; + this.outputType = "decimal"; + } + + public DecimalColDivideDecimalColumnOld() { + this.outputType = "decimal"; + } + + @Override + public void evaluate(VectorizedRowBatch batch) { + + if (childExpressions != null) { + super.evaluateChildren(batch); + } + + DecimalColumnVector inputColVector1 = (DecimalColumnVector) batch.cols[colNum1]; + DecimalColumnVector inputColVector2 = (DecimalColumnVector) batch.cols[colNum2]; + DecimalColumnVector outputColVector = (DecimalColumnVector) batch.cols[outputColumn]; + int[] sel = batch.selected; + int n = batch.size; + + // return immediately if batch is empty + if (n == 0) { + return; + } + + outputColVector.isRepeating = + inputColVector1.isRepeating && inputColVector2.isRepeating + || inputColVector1.isRepeating && !inputColVector1.noNulls && inputColVector1.isNull[0] + || inputColVector2.isRepeating && !inputColVector2.noNulls && inputColVector2.isNull[0]; + + if (inputColVector1.noNulls && inputColVector2.noNulls) { + + /* Initialize output vector NULL values to false. This is necessary + * since the decimal operation may produce a NULL result even for + * a non-null input vector value, and convert the output vector + * to have noNulls = false; + */ + NullUtil.initOutputNullsToFalse(outputColVector, + inputColVector1.isRepeating && inputColVector2.isRepeating, + batch.selectedInUse, sel, n); + } + + // Handle nulls first + NullUtil.propagateNullsColCol( + inputColVector1, inputColVector2, outputColVector, sel, n, batch.selectedInUse); + + /* Disregard nulls for processing. In other words, + * the arithmetic operation is performed even if one or + * more inputs are null. This is to improve speed by avoiding + * conditional checks in the inner loop. + */ + if (inputColVector1.isRepeating && inputColVector2.isRepeating) { + DecimalUtil.divideChecked(0, inputColVector1.get(0), inputColVector2.get(0), outputColVector); + } else if (inputColVector1.isRepeating) { + if (batch.selectedInUse) { + for(int j = 0; j != n; j++) { + int i = sel[j]; + DecimalUtil.divideChecked(i, inputColVector1.get(0), inputColVector2.get(i), outputColVector); + } + } else { + for(int i = 0; i != n; i++) { + DecimalUtil.divideChecked(i, inputColVector1.get(0), inputColVector2.get(i), outputColVector); + } + } + } else if (inputColVector2.isRepeating) { + if (batch.selectedInUse) { + for(int j = 0; j != n; j++) { + int i = sel[j]; + DecimalUtil.divideChecked(i, inputColVector1.get(i), inputColVector2.get(0), outputColVector); + } + } else { + for(int i = 0; i != n; i++) { + DecimalUtil.divideChecked(i, inputColVector1.get(i), inputColVector2.get(0), outputColVector); + } + } + } else { + if (batch.selectedInUse) { + for(int j = 0; j != n; j++) { + int i = sel[j]; + DecimalUtil.divideChecked(i, inputColVector1.get(i), inputColVector2.get(i), outputColVector); + } + } else { + for(int i = 0; i != n; i++) { + DecimalUtil.divideChecked(i, inputColVector1.get(i), inputColVector2.get(i), outputColVector); + } + } + } + } + + @Override + public int getOutputColumn() { + return outputColumn; + } + + @Override + public VectorExpressionDescriptor.Descriptor getDescriptor() { + return (new VectorExpressionDescriptor.Builder()) + .setMode( + VectorExpressionDescriptor.Mode.PROJECTION) + .setNumArguments(2) + .setArgumentTypes( + VectorExpressionDescriptor.ArgumentType.getType("decimal"), + VectorExpressionDescriptor.ArgumentType.getType("decimal")) + .setInputExpressionTypes( + VectorExpressionDescriptor.InputExpressionType.COLUMN, + VectorExpressionDescriptor.InputExpressionType.COLUMN).build(); + } +} diff --git itests/hive-jmh/src/main/java/org/apache/hive/benchmark/vectorization/DecimalColMultiplyDecimalColumnOld.java itests/hive-jmh/src/main/java/org/apache/hive/benchmark/vectorization/DecimalColMultiplyDecimalColumnOld.java new file mode 100644 index 0000000..0e6a013 --- /dev/null +++ itests/hive-jmh/src/main/java/org/apache/hive/benchmark/vectorization/DecimalColMultiplyDecimalColumnOld.java @@ -0,0 +1,157 @@ +package org.apache.hive.benchmark.vectorization; + +import org.apache.hadoop.hive.ql.exec.vector.DecimalColumnVector; +import org.apache.hadoop.hive.ql.exec.vector.VectorExpressionDescriptor; +import org.apache.hadoop.hive.ql.exec.vector.VectorizedRowBatch; +import org.apache.hadoop.hive.ql.exec.vector.expressions.DecimalUtil; +import org.apache.hadoop.hive.ql.exec.vector.expressions.NullUtil; +import org.apache.hadoop.hive.ql.exec.vector.expressions.VectorExpression; + +public class DecimalColMultiplyDecimalColumnOld extends VectorExpression { + + private static final long serialVersionUID = 1L; + + private int colNum1; + private int colNum2; + private int outputColumn; + + public DecimalColMultiplyDecimalColumnOld(int colNum1, int colNum2, int outputColumn) { + this.colNum1 = colNum1; + this.colNum2 = colNum2; + this.outputColumn = outputColumn; + this.outputType = "decimal"; + } + + public DecimalColMultiplyDecimalColumnOld() { + this.outputType = "decimal"; + } + + @Override + public void evaluate(VectorizedRowBatch batch) { + + if (childExpressions != null) { + super.evaluateChildren(batch); + } + + DecimalColumnVector inputColVector1 = (DecimalColumnVector) batch.cols[colNum1]; + DecimalColumnVector inputColVector2 = (DecimalColumnVector) batch.cols[colNum2]; + DecimalColumnVector outputColVector = (DecimalColumnVector) batch.cols[outputColumn]; + int[] sel = batch.selected; + int n = batch.size; + + // return immediately if batch is empty + if (n == 0) { + return; + } + + outputColVector.isRepeating = + inputColVector1.isRepeating && inputColVector2.isRepeating + || inputColVector1.isRepeating && !inputColVector1.noNulls && inputColVector1.isNull[0] + || inputColVector2.isRepeating && !inputColVector2.noNulls && inputColVector2.isNull[0]; + + if (inputColVector1.noNulls && inputColVector2.noNulls) { + + /* Initialize output vector NULL values to false. This is necessary + * since the decimal operation may produce a NULL result even for + * a non-null input vector value, and convert the output vector + * to have noNulls = false; + */ + NullUtil.initOutputNullsToFalse(outputColVector, + inputColVector1.isRepeating && inputColVector2.isRepeating, + batch.selectedInUse, sel, n); + } + + // Handle nulls first + NullUtil.propagateNullsColCol( + inputColVector1, inputColVector2, outputColVector, sel, n, batch.selectedInUse); + + /* Disregard nulls for processing. In other words, + * the arithmetic operation is performed even if one or + * more inputs are null. This is to improve speed by avoiding + * conditional checks in the inner loop. + */ + if (inputColVector1.isRepeating && inputColVector2.isRepeating) { + DecimalUtil.multiplyChecked(0, inputColVector1.get(0), inputColVector2.get(0), outputColVector); + } else if (inputColVector1.isRepeating) { + if (batch.selectedInUse) { + for(int j = 0; j != n; j++) { + int i = sel[j]; + DecimalUtil.multiplyChecked(i, inputColVector1.get(0), inputColVector2.get(i), outputColVector); + } + } else { + for(int i = 0; i != n; i++) { + DecimalUtil.multiplyChecked(i, inputColVector1.get(0), inputColVector2.get(i), outputColVector); + } + } + } else if (inputColVector2.isRepeating) { + if (batch.selectedInUse) { + for(int j = 0; j != n; j++) { + int i = sel[j]; + DecimalUtil.multiplyChecked(i, inputColVector1.get(i), inputColVector2.get(0), outputColVector); + } + } else { + for(int i = 0; i != n; i++) { + DecimalUtil.multiplyChecked(i, inputColVector1.get(i), inputColVector2.get(0), outputColVector); + } + } + } else { + if (batch.selectedInUse) { + for(int j = 0; j != n; j++) { + int i = sel[j]; + DecimalUtil.multiplyChecked(i, inputColVector1.get(i), inputColVector2.get(i), outputColVector); + } + } else { + for(int i = 0; i != n; i++) { + DecimalUtil.multiplyChecked(i, inputColVector1.get(i), inputColVector2.get(i), outputColVector); + } + } + } + + /* For the case when the output can have null values, follow + * the convention that the data values must be set to a specific non-zero + * value. This is to prevent possible later zero-divide errors + * in complex arithmetic expressions like col2 / (col1 - 1) + * in the case when some col1 entries are null. + */ + NullUtil.setNullDataEntriesDecimal(outputColVector, batch.selectedInUse, sel, n); + } + + @Override + public int getOutputColumn() { + return outputColumn; + } + + public int getColNum1() { + return colNum1; + } + + public void setColNum1(int colNum1) { + this.colNum1 = colNum1; + } + + public int getColNum2() { + return colNum2; + } + + public void setColNum2(int colNum2) { + this.colNum2 = colNum2; + } + + public void setOutputColumn(int outputColumn) { + this.outputColumn = outputColumn; + } + + @Override + public VectorExpressionDescriptor.Descriptor getDescriptor() { + return (new VectorExpressionDescriptor.Builder()) + .setMode( + VectorExpressionDescriptor.Mode.PROJECTION) + .setNumArguments(2) + .setArgumentTypes( + VectorExpressionDescriptor.ArgumentType.getType("decimal"), + VectorExpressionDescriptor.ArgumentType.getType("decimal")) + .setInputExpressionTypes( + VectorExpressionDescriptor.InputExpressionType.COLUMN, + VectorExpressionDescriptor.InputExpressionType.COLUMN).build(); + } +} diff --git itests/hive-jmh/src/main/java/org/apache/hive/benchmark/vectorization/DecimalColSubtractDecimalColumnOld.java itests/hive-jmh/src/main/java/org/apache/hive/benchmark/vectorization/DecimalColSubtractDecimalColumnOld.java new file mode 100644 index 0000000..9006b3b --- /dev/null +++ itests/hive-jmh/src/main/java/org/apache/hive/benchmark/vectorization/DecimalColSubtractDecimalColumnOld.java @@ -0,0 +1,157 @@ +package org.apache.hive.benchmark.vectorization; + +import org.apache.hadoop.hive.ql.exec.vector.DecimalColumnVector; +import org.apache.hadoop.hive.ql.exec.vector.VectorExpressionDescriptor; +import org.apache.hadoop.hive.ql.exec.vector.VectorizedRowBatch; +import org.apache.hadoop.hive.ql.exec.vector.expressions.DecimalUtil; +import org.apache.hadoop.hive.ql.exec.vector.expressions.NullUtil; +import org.apache.hadoop.hive.ql.exec.vector.expressions.VectorExpression; + +public class DecimalColSubtractDecimalColumnOld extends VectorExpression { + + private static final long serialVersionUID = 1L; + + private int colNum1; + private int colNum2; + private int outputColumn; + + public DecimalColSubtractDecimalColumnOld(int colNum1, int colNum2, int outputColumn) { + this.colNum1 = colNum1; + this.colNum2 = colNum2; + this.outputColumn = outputColumn; + this.outputType = "decimal"; + } + + public DecimalColSubtractDecimalColumnOld() { + this.outputType = "decimal"; + } + + @Override + public void evaluate(VectorizedRowBatch batch) { + + if (childExpressions != null) { + super.evaluateChildren(batch); + } + + DecimalColumnVector inputColVector1 = (DecimalColumnVector) batch.cols[colNum1]; + DecimalColumnVector inputColVector2 = (DecimalColumnVector) batch.cols[colNum2]; + DecimalColumnVector outputColVector = (DecimalColumnVector) batch.cols[outputColumn]; + int[] sel = batch.selected; + int n = batch.size; + + // return immediately if batch is empty + if (n == 0) { + return; + } + + outputColVector.isRepeating = + inputColVector1.isRepeating && inputColVector2.isRepeating + || inputColVector1.isRepeating && !inputColVector1.noNulls && inputColVector1.isNull[0] + || inputColVector2.isRepeating && !inputColVector2.noNulls && inputColVector2.isNull[0]; + + if (inputColVector1.noNulls && inputColVector2.noNulls) { + + /* Initialize output vector NULL values to false. This is necessary + * since the decimal operation may produce a NULL result even for + * a non-null input vector value, and convert the output vector + * to have noNulls = false; + */ + NullUtil.initOutputNullsToFalse(outputColVector, + inputColVector1.isRepeating && inputColVector2.isRepeating, + batch.selectedInUse, sel, n); + } + + // Handle nulls first + NullUtil.propagateNullsColCol( + inputColVector1, inputColVector2, outputColVector, sel, n, batch.selectedInUse); + + /* Disregard nulls for processing. In other words, + * the arithmetic operation is performed even if one or + * more inputs are null. This is to improve speed by avoiding + * conditional checks in the inner loop. + */ + if (inputColVector1.isRepeating && inputColVector2.isRepeating) { + DecimalUtil.subtractChecked(0, inputColVector1.get(0), inputColVector2.get(0), outputColVector); + } else if (inputColVector1.isRepeating) { + if (batch.selectedInUse) { + for(int j = 0; j != n; j++) { + int i = sel[j]; + DecimalUtil.subtractChecked(i, inputColVector1.get(0), inputColVector2.get(i), outputColVector); + } + } else { + for(int i = 0; i != n; i++) { + DecimalUtil.subtractChecked(i, inputColVector1.get(0), inputColVector2.get(i), outputColVector); + } + } + } else if (inputColVector2.isRepeating) { + if (batch.selectedInUse) { + for(int j = 0; j != n; j++) { + int i = sel[j]; + DecimalUtil.subtractChecked(i, inputColVector1.get(i), inputColVector2.get(0), outputColVector); + } + } else { + for(int i = 0; i != n; i++) { + DecimalUtil.subtractChecked(i, inputColVector1.get(i), inputColVector2.get(0), outputColVector); + } + } + } else { + if (batch.selectedInUse) { + for(int j = 0; j != n; j++) { + int i = sel[j]; + DecimalUtil.subtractChecked(i, inputColVector1.get(i), inputColVector2.get(i), outputColVector); + } + } else { + for(int i = 0; i != n; i++) { + DecimalUtil.subtractChecked(i, inputColVector1.get(i), inputColVector2.get(i), outputColVector); + } + } + } + + /* For the case when the output can have null values, follow + * the convention that the data values must be set to a specific non-zero + * value. This is to prevent possible later zero-divide errors + * in complex arithmetic expressions like col2 / (col1 - 1) + * in the case when some col1 entries are null. + */ + NullUtil.setNullDataEntriesDecimal(outputColVector, batch.selectedInUse, sel, n); + } + + @Override + public int getOutputColumn() { + return outputColumn; + } + + public int getColNum1() { + return colNum1; + } + + public void setColNum1(int colNum1) { + this.colNum1 = colNum1; + } + + public int getColNum2() { + return colNum2; + } + + public void setColNum2(int colNum2) { + this.colNum2 = colNum2; + } + + public void setOutputColumn(int outputColumn) { + this.outputColumn = outputColumn; + } + + @Override + public VectorExpressionDescriptor.Descriptor getDescriptor() { + return (new VectorExpressionDescriptor.Builder()) + .setMode( + VectorExpressionDescriptor.Mode.PROJECTION) + .setNumArguments(2) + .setArgumentTypes( + VectorExpressionDescriptor.ArgumentType.getType("decimal"), + VectorExpressionDescriptor.ArgumentType.getType("decimal")) + .setInputExpressionTypes( + VectorExpressionDescriptor.InputExpressionType.COLUMN, + VectorExpressionDescriptor.InputExpressionType.COLUMN).build(); + } +} diff --git itests/hive-jmh/src/main/java/org/apache/hive/benchmark/vectorization/VectorizedDecimalBench.java itests/hive-jmh/src/main/java/org/apache/hive/benchmark/vectorization/VectorizedDecimalBench.java new file mode 100644 index 0000000..5cb99fc --- /dev/null +++ itests/hive-jmh/src/main/java/org/apache/hive/benchmark/vectorization/VectorizedDecimalBench.java @@ -0,0 +1,275 @@ +/** + * Licensed 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.hive.benchmark.vectorization; + +import org.apache.hadoop.hive.common.type.HiveDecimal; +import org.apache.hadoop.hive.ql.exec.vector.DecimalColumnVector; +import org.apache.hadoop.hive.ql.exec.vector.BytesColumnVector; +import org.apache.hadoop.hive.ql.exec.vector.VectorizedRowBatch; +import org.apache.hadoop.hive.ql.exec.vector.expressions.*; +import org.apache.hadoop.hive.ql.exec.vector.expressions.gen.DecimalColAddDecimalColumn; +import org.apache.hadoop.hive.ql.exec.vector.expressions.gen.DecimalColDivideDecimalColumn; +import org.apache.hadoop.hive.ql.exec.vector.expressions.gen.DecimalColMultiplyDecimalColumn; +import org.apache.hadoop.hive.ql.exec.vector.expressions.gen.DecimalColSubtractDecimalColumn; +import org.openjdk.jmh.annotations.*; +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.runner.RunnerException; +import org.openjdk.jmh.runner.options.Options; +import org.openjdk.jmh.runner.options.OptionsBuilder; + +import java.util.Random; +import java.util.concurrent.TimeUnit; + +/** + * This test measures the performance for vectorization. + *

+ * This test uses JMH framework for benchmarking. + * You may execute this benchmark tool using JMH command line in different ways: + *

+ * To use the settings shown in the main() function, use: + * $ java -cp target/benchmarks.jar org.apache.hive.benchmark.vectorization.VectorizedArithmeticBench + *

+ * To use the default settings used by JMH, use: + * $ java -jar target/benchmarks.jar org.apache.hive.benchmark.vectorization.VectorizedArithmeticBench + *

+ * To specify different parameters, use: + * - This command will use 10 warm-up iterations, 5 test iterations, and 2 forks. And it will + * display the Average Time (avgt) in Microseconds (us) + * - Benchmark mode. Available modes are: + * [Throughput/thrpt, AverageTime/avgt, SampleTime/sample, SingleShotTime/ss, All/all] + * - Output time unit. Available time units are: [m, s, ms, us, ns]. + *

+ * $ java -jar target/benchmarks.jar org.apache.hive.benchmark.vectorization.VectorizedDecimalBench + * -wi 10 -i 5 -f 2 -bm avgt -tu us + */ +@State(Scope.Benchmark) +public class VectorizedDecimalBench { + + @BenchmarkMode(Mode.AverageTime) + @Fork(1) + @State(Scope.Thread) + @OutputTimeUnit(TimeUnit.NANOSECONDS) + private static abstract class AbstractDecimalExpression extends AbstractExpression { + private boolean firstRun = true; + + @Override + @Measurement(iterations = 5, time = 5, timeUnit = TimeUnit.MILLISECONDS) + public void bench() { + if (firstRun) { + iterTime = DEFAULT_ITER_TIME; + rowBatch.size = 1; + rowBatch.ensureSize(1); + } else { + iterTime = 1; + rowBatch.size = VectorizedRowBatch.DEFAULT_SIZE; + rowBatch.ensureSize(VectorizedRowBatch.DEFAULT_SIZE); + } + firstRun = false; + super.bench(); + } + } + + private static DecimalColumnVector getDecimalColumnVector(int precision, int scale) { + DecimalColumnVector vector = new DecimalColumnVector(precision, scale); + StringBuilder builder = new StringBuilder(); + Random random = new Random(); + for (int i = 0; i < precision - scale; i++) { + builder.append(random.nextInt(10)); + } + String string = builder.toString(); + for (int i = 0; i < VectorizedRowBatch.DEFAULT_SIZE; i++) { + HiveDecimal hiveDecimal = HiveDecimal.create(string); + vector.set(i, hiveDecimal); + } + return vector; + } + + public static class DecimalColAdd64ColNewBench extends AbstractDecimalExpression { + @Override + public void setup() { + rowBatch = buildRowBatch(new DecimalColumnVector(11, 2), 2, + getDecimalColumnVector(10, 2), getDecimalColumnVector(10, 2)); + expression = new DecimalColAddDecimalColumn(0, 1, 2); + } + } + + public static class DecimalColAdd128ColNewBench extends AbstractDecimalExpression { + @Override + public void setup() { + rowBatch = buildRowBatch(new DecimalColumnVector(21, 2), 2, + getDecimalColumnVector(20, 2), getDecimalColumnVector(20, 2)); + expression = new DecimalColAddDecimalColumn(0, 1, 2); + } + } + + public static class DecimalColAdd64ColOldBench extends AbstractDecimalExpression { + @Override + public void setup() { + rowBatch = buildRowBatch(new DecimalColumnVector(11, 2), 2, + getDecimalColumnVector(10, 2), getDecimalColumnVector(10, 2)); + expression = new DecimalColAddDecimalColumnOld(0, 1, 2); + } + } + + public static class DecimalColAdd128ColOldBench extends AbstractDecimalExpression { + @Override + public void setup() { + rowBatch = buildRowBatch(new DecimalColumnVector(21, 2), 2, + getDecimalColumnVector(20, 2), getDecimalColumnVector(20, 2)); + expression = new DecimalColAddDecimalColumnOld(0, 1, 2); + } + } + + public static class DecimalColSub64ColNewBench extends AbstractDecimalExpression { + @Override + public void setup() { + rowBatch = buildRowBatch(new DecimalColumnVector(21, 2), 2, + getDecimalColumnVector(10, 2), getDecimalColumnVector(10, 2)); + expression = new DecimalColSubtractDecimalColumn(0, 1, 2); + } + } + + public static class DecimalColSub128ColNewBench extends AbstractDecimalExpression { + @Override + public void setup() { + rowBatch = buildRowBatch(new DecimalColumnVector(21, 2), 2, + getDecimalColumnVector(20, 2), getDecimalColumnVector(20, 2)); + expression = new DecimalColSubtractDecimalColumn(0, 1, 2); + } + } + + public static class DecimalColSub64ColOldBench extends AbstractDecimalExpression { + @Override + public void setup() { + rowBatch = buildRowBatch(new DecimalColumnVector(21, 2), 2, + getDecimalColumnVector(10, 2), getDecimalColumnVector(10, 2)); + expression = new DecimalColSubtractDecimalColumnOld(0, 1, 2); + } + } + + public static class DecimalColSub128ColOldBench extends AbstractDecimalExpression { + @Override + public void setup() { + rowBatch = buildRowBatch(new DecimalColumnVector(21, 2), 2, + getDecimalColumnVector(20, 2), getDecimalColumnVector(20, 2)); + expression = new DecimalColSubtractDecimalColumnOld(0, 1, 2); + } + } + + public static class DecimalColDiv64ColNewBench extends AbstractDecimalExpression { + @Override + public void setup() { + rowBatch = buildRowBatch(new DecimalColumnVector(20, 2), 2, + getDecimalColumnVector(4, 0), getDecimalColumnVector(2, 0)); + expression = new DecimalColDivideDecimalColumn(0, 1, 2); + } + } + + public static class DecimalColDiv128ColNewBench extends AbstractDecimalExpression { + @Override + public void setup() { + rowBatch = buildRowBatch(new DecimalColumnVector(20, 2), 2, + getDecimalColumnVector(20, 0), getDecimalColumnVector(10, 0)); + expression = new DecimalColDivideDecimalColumn(0, 1, 2); + } + } + + public static class DecimalColDiv128By16ColNewBench extends AbstractDecimalExpression { + @Override + public void setup() { + rowBatch = buildRowBatch(new DecimalColumnVector(20, 2), 2, + getDecimalColumnVector(20, 0), getDecimalColumnVector(4, 0)); + expression = new DecimalColDivideDecimalColumn(0, 1, 2); + } + } + + public static class DecimalColDiv64ColOldBench extends AbstractDecimalExpression { + @Override + public void setup() { + rowBatch = buildRowBatch(new DecimalColumnVector(20, 2), 2, + getDecimalColumnVector(4, 0), getDecimalColumnVector(2, 0)); + expression = new DecimalColDivideDecimalColumnOld(0, 1, 2); + } + } + + public static class DecimalColDiv128ColOldBench extends AbstractDecimalExpression { + @Override + public void setup() { + rowBatch = buildRowBatch(new DecimalColumnVector(20, 2), 2, + getDecimalColumnVector(20, 0), getDecimalColumnVector(10, 0)); + expression = new DecimalColDivideDecimalColumnOld(0, 1, 2); + } + } + + public static class DecimalColDiv128By16ColOldBench extends AbstractDecimalExpression { + @Override + public void setup() { + rowBatch = buildRowBatch(new DecimalColumnVector(20, 2), 2, + getDecimalColumnVector(20, 0), getDecimalColumnVector(4, 0)); + expression = new DecimalColDivideDecimalColumnOld(0, 1, 2); + } + } + + public static class DecimalColMul64ColNewBench extends AbstractDecimalExpression { + @Override + public void setup() { + rowBatch = buildRowBatch(new DecimalColumnVector(11, 4), 2, + getDecimalColumnVector(5, 2), getDecimalColumnVector(5, 2)); + expression = new DecimalColMultiplyDecimalColumn(0, 1, 2); + } + } + + public static class DecimalColMul128ColNewBench extends AbstractDecimalExpression { + @Override + public void setup() { + rowBatch = buildRowBatch(new DecimalColumnVector(31, 4), 2, + getDecimalColumnVector(15, 2), getDecimalColumnVector(15, 2)); + expression = new DecimalColMultiplyDecimalColumn(0, 1, 2); + } + } + + public static class DecimalColMul64ColOldBench extends AbstractDecimalExpression { + @Override + public void setup() { + rowBatch = buildRowBatch(new DecimalColumnVector(11, 4), 2, + getDecimalColumnVector(5, 2), getDecimalColumnVector(5, 2)); + expression = new DecimalColMultiplyDecimalColumnOld(0, 1, 2); + } + } + + public static class DecimalColMul128ColOldBench extends AbstractDecimalExpression { + @Override + public void setup() { + rowBatch = buildRowBatch(new DecimalColumnVector(31, 4), 2, + getDecimalColumnVector(15, 2), getDecimalColumnVector(15, 2)); + expression = new DecimalColMultiplyDecimalColumnOld(0, 1, 2); + } + } + + public static class DecimalToString128ColBench extends AbstractDecimalExpression { + @Override + public void setup() { + rowBatch = buildRowBatch(new BytesColumnVector(), 1, + getDecimalColumnVector(20, 2)); + expression = new CastDecimalToString(0, 1); + } + } + + public static void main(String[] args) throws RunnerException { + Options opt = new OptionsBuilder().include(".*" + VectorizedDecimalBench.class.getSimpleName() + + ".*").build(); + new Runner(opt).run(); + } +} diff --git orc/src/java/org/apache/orc/impl/ConvertTreeReaderFactory.java orc/src/java/org/apache/orc/impl/ConvertTreeReaderFactory.java index 5d5f991..e4348d8 100644 --- orc/src/java/org/apache/orc/impl/ConvertTreeReaderFactory.java +++ orc/src/java/org/apache/orc/impl/ConvertTreeReaderFactory.java @@ -613,7 +613,7 @@ public void nextVector(ColumnVector previousVector, @Override public void setConvertVectorElement(int elementNum) throws IOException { - HiveDecimal decimalValue = decimalColVector.vector[elementNum].getHiveDecimal(); + HiveDecimal decimalValue = decimalColVector.hiveDecimal(elementNum); if (decimalValue.compareTo(DECIMAL_MAX_LONG) > 0 || decimalValue.compareTo(DECIMAL_MIN_LONG) < 0) { longColVector.isNull[elementNum] = true; @@ -828,7 +828,7 @@ public void nextVector(ColumnVector previousVector, @Override public void setConvertVectorElement(int elementNum) throws IOException { doubleColVector.vector[elementNum] = - (float) decimalColVector.vector[elementNum].getHiveDecimal().doubleValue(); + (float) decimalColVector.hiveDecimal(elementNum).floatValue(); } @Override @@ -1034,7 +1034,7 @@ public void nextVector(ColumnVector previousVector, @Override public void setConvertVectorElement(int elementNum) throws IOException { doubleColVector.vector[elementNum] = - decimalColVector.vector[elementNum].getHiveDecimal().doubleValue(); + decimalColVector.hiveDecimal(elementNum).doubleValue(); } @Override @@ -1372,7 +1372,7 @@ public void nextVector(ColumnVector previousVector, public void setConvertVectorElement(int elementNum) throws IOException { HiveDecimalWritable valueWritable = HiveDecimalWritable.enforcePrecisionScale( - fileDecimalColVector.vector[elementNum], readerPrecision, readerScale); + fileDecimalColVector.get(elementNum), readerPrecision, readerScale); if (valueWritable != null) { decimalColVector.set(elementNum, valueWritable); } else { @@ -1553,7 +1553,7 @@ public void nextVector(ColumnVector previousVector, @Override public void setConvertVectorElement(int elementNum) { - String string = decimalColVector.vector[elementNum].getHiveDecimal().toString(); + String string = decimalColVector.hiveDecimal(elementNum).toString(); byte[] bytes = string.getBytes(); assignStringGroupVectorEntry(bytesColVector, elementNum, readerType, bytes); } @@ -1888,7 +1888,7 @@ public void nextVector(ColumnVector previousVector, public void setConvertVectorElement(int elementNum) { Timestamp timestampValue = TimestampUtils.decimalToTimestamp( - decimalColVector.vector[elementNum].getHiveDecimal()); + decimalColVector.hiveDecimal(elementNum)); // The TimestampColumnVector will set the entry to null when a null timestamp is passed in. timestampColVector.set(elementNum, timestampValue); } diff --git orc/src/java/org/apache/orc/impl/WriterImpl.java orc/src/java/org/apache/orc/impl/WriterImpl.java index b2966e0..9e3fe9d 100644 --- orc/src/java/org/apache/orc/impl/WriterImpl.java +++ orc/src/java/org/apache/orc/impl/WriterImpl.java @@ -1907,7 +1907,7 @@ void writeBatch(ColumnVector vector, int offset, DecimalColumnVector vec = (DecimalColumnVector) vector; if (vector.isRepeating) { if (vector.noNulls || !vector.isNull[0]) { - HiveDecimal value = vec.vector[0].getHiveDecimal(); + HiveDecimal value = vec.hiveDecimal(0); indexStatistics.updateDecimal(value); if (createBloomFilter) { bloomFilter.addString(value.toString()); @@ -1921,7 +1921,7 @@ void writeBatch(ColumnVector vector, int offset, } else { for(int i=0; i < length; ++i) { if (vec.noNulls || !vec.isNull[i + offset]) { - HiveDecimal value = vec.vector[i + offset].getHiveDecimal(); + HiveDecimal value = vec.hiveDecimal(i + offset); SerializationUtils.writeBigInteger(valueStream, value.unscaledValue()); scaleStream.write(value.scale()); diff --git orc/src/java/org/apache/orc/tools/FileDump.java orc/src/java/org/apache/orc/tools/FileDump.java index 1a1d8ab..697bae5 100644 --- orc/src/java/org/apache/orc/tools/FileDump.java +++ orc/src/java/org/apache/orc/tools/FileDump.java @@ -872,7 +872,7 @@ static void printValue(JSONWriter writer, ColumnVector vector, printBinary(writer, (BytesColumnVector) vector, row); break; case DECIMAL: - writer.value(((DecimalColumnVector) vector).vector[row].toString()); + writer.value(((DecimalColumnVector) vector).hiveDecimal(row).toString()); break; case DATE: writer.value(new DateWritable( diff --git orc/src/test/org/apache/orc/TestVectorOrcFile.java orc/src/test/org/apache/orc/TestVectorOrcFile.java index 112edb9..f5f2cfb 100644 --- orc/src/test/org/apache/orc/TestVectorOrcFile.java +++ orc/src/test/org/apache/orc/TestVectorOrcFile.java @@ -284,7 +284,7 @@ public void testReadFormat_0_11() throws Exception { assertEquals(Timestamp.valueOf("2000-03-12 15:00:00"), timestamp.asScratchTimestamp(0)); assertEquals(new HiveDecimalWritable(HiveDecimal.create("12345678.6547456")), - decs.vector[0]); + decs.get(0)); // check the contents of row 7499 rows.seekToRow(7499); @@ -324,7 +324,7 @@ public void testReadFormat_0_11() throws Exception { assertEquals(Timestamp.valueOf("2000-03-12 15:00:01"), timestamp.asScratchTimestamp(0)); assertEquals(new HiveDecimalWritable(HiveDecimal.create("12345678.6547457")), - decs.vector[0]); + decs.get(0)); // handle the close up Assert.assertEquals(false, rows.nextBatch(batch)); @@ -1396,7 +1396,7 @@ private static void setUnion(VectorizedRowBatch batch, int rowId, batch.cols[1].noNulls = false; } if (dec != null) { - ((DecimalColumnVector) batch.cols[2]).vector[rowId] = dec; + ((DecimalColumnVector) batch.cols[2]).set(rowId, dec); } else { batch.cols[2].isNull[rowId] = true; batch.cols[2].noNulls = false; @@ -1542,12 +1542,12 @@ public void testUnionAndTimestamp() throws Exception { assertEquals("2000-03-12 15:00:00.0", ts.asScratchTimestamp(0).toString()); assertEquals(0, union.tags[0]); assertEquals(42, longs.vector[0]); - assertEquals("12345678.6547456", decs.vector[0].toString()); + assertEquals("12345678.6547456", decs.hiveDecimal(0).toString()); assertEquals("2000-03-20 12:00:00.123456789", ts.asScratchTimestamp(1).toString()); assertEquals(1, union.tags[1]); assertEquals("hello", strs.toString(1)); - assertEquals("-5643.234", decs.vector[1].toString()); + assertEquals("-5643.234", decs.hiveDecimal(1).toString()); assertEquals(false, ts.noNulls); assertEquals(false, union.noNulls); @@ -1575,7 +1575,7 @@ public void testUnionAndTimestamp() throws Exception { assertEquals(false, longs.isNull[5]); assertEquals(200000, longs.vector[5]); assertEquals(false, decs.isNull[5]); - assertEquals("10000000000000000000", decs.vector[5].toString()); + assertEquals("10000000000000000000", decs.hiveDecimal(5).toString()); rand = new Random(42); for(int i=1970; i < 2038; ++i) { @@ -1590,7 +1590,7 @@ public void testUnionAndTimestamp() throws Exception { assertEquals(Integer.toString(i * i), strs.toString(row)); } assertEquals(new HiveDecimalWritable(HiveDecimal.create(new BigInteger(64, rand), - rand.nextInt(18))), decs.vector[row]); + rand.nextInt(18))), decs.get(row)); } // rebuild the row batch, so that we can read by 1000 rows @@ -1632,7 +1632,7 @@ public void testUnionAndTimestamp() throws Exception { assertEquals(Timestamp.valueOf("2000-03-20 12:00:00.123456789"), ts.asScratchTimestamp(0)); assertEquals(1, union.tags[0]); assertEquals("hello", strs.toString(0)); - assertEquals(new HiveDecimalWritable(HiveDecimal.create("-5643.234")), decs.vector[0]); + assertEquals(new HiveDecimalWritable(HiveDecimal.create("-5643.234")), decs.get(0)); rows.close(); } @@ -2167,8 +2167,8 @@ public void testRepeating() throws Exception { ((TimestampColumnVector) batch.cols[7]).set(0, new Timestamp(115, 9, 23, 10, 11, 59, 999999999)); - ((DecimalColumnVector) batch.cols[8]).vector[0] = - new HiveDecimalWritable("1.234567"); + ((DecimalColumnVector) batch.cols[8]).set(0, + new HiveDecimalWritable("1.234567")); ((BytesColumnVector) batch.cols[9]).setVal(0, "Echelon".getBytes()); ((BytesColumnVector) batch.cols[10]).setVal(0, "Juggernaut".getBytes()); ((BytesColumnVector) batch.cols[11]).setVal(0, "Dreadnaught".getBytes()); @@ -2222,8 +2222,8 @@ public void testRepeating() throws Exception { Timestamp ts = new Timestamp(115, 9, 25, 10, 11, 59 + r, 999999999); ((TimestampColumnVector) batch.cols[7]).set(r, ts); - ((DecimalColumnVector) batch.cols[8]).vector[r] = - new HiveDecimalWritable("1.234567"); + ((DecimalColumnVector) batch.cols[8]).set(r, + new HiveDecimalWritable("1.234567")); ((BytesColumnVector) batch.cols[9]).setVal(r, Integer.toString(r).getBytes()); ((BytesColumnVector) batch.cols[10]).setVal(r, @@ -2339,7 +2339,7 @@ public void testRepeating() throws Exception { new DateWritable((int) dates.vector[r]).toString()); assertEquals("row " + r, "2015-10-23 10:11:59.999999999", times.asScratchTimestamp(r).toString()); - assertEquals("row " + r, "1.234567", decs.vector[r].toString()); + assertEquals("row " + r, "1.234567", decs.hiveDecimal(r).toString()); assertEquals("row " + r, "Echelon", strs.toString(r)); assertEquals("row " + r, "Juggernaut", chars.toString(r)); assertEquals("row " + r, "Dreadnaugh", vcs.toString(r)); @@ -2386,7 +2386,7 @@ public void testRepeating() throws Exception { assertEquals("row " + r, new Timestamp(115, 9, 25, 10, 11, 59 + r, 999999999), times.asScratchTimestamp(r)); - assertEquals("row " + r, "1.234567", decs.vector[r].toString()); + assertEquals("row " + r, "1.234567", decs.hiveDecimal(r).toString()); assertEquals("row " + r, Integer.toString(r), strs.toString(r)); assertEquals("row " + r, Integer.toHexString(r), chars.toString(r)); assertEquals("row " + r, Integer.toHexString(r * 128), vcs.toString(r)); diff --git orc/src/test/org/apache/orc/tools/TestFileDump.java orc/src/test/org/apache/orc/tools/TestFileDump.java index ce3381e..2c54a88 100644 --- orc/src/test/org/apache/orc/tools/TestFileDump.java +++ orc/src/test/org/apache/orc/tools/TestFileDump.java @@ -148,7 +148,7 @@ static void appendAllTypes(VectorizedRowBatch batch, ((LongColumnVector) batch.cols[4]).vector[row] = l; ((DoubleColumnVector) batch.cols[5]).vector[row] = f; ((DoubleColumnVector) batch.cols[6]).vector[row] = d; - ((DecimalColumnVector) batch.cols[7]).vector[row].set(de); + ((DecimalColumnVector) batch.cols[7]).set(row, de); ((TimestampColumnVector) batch.cols[8]).set(row, t); ((LongColumnVector) batch.cols[9]).vector[row] = dt.getDays(); ((BytesColumnVector) batch.cols[10]).setVal(row, str.getBytes()); diff --git ql/src/gen/vectorization/ExpressionTemplates/ColumnArithmeticColumnDecimal.txt ql/src/gen/vectorization/ExpressionTemplates/ColumnArithmeticColumnDecimal.txt index e1df589..881f2d1 100644 --- ql/src/gen/vectorization/ExpressionTemplates/ColumnArithmeticColumnDecimal.txt +++ ql/src/gen/vectorization/ExpressionTemplates/ColumnArithmeticColumnDecimal.txt @@ -61,8 +61,6 @@ public class extends VectorExpression { DecimalColumnVector outputColVector = (DecimalColumnVector) batch.cols[outputColumn]; int[] sel = batch.selected; int n = batch.size; - HiveDecimalWritable[] vector1 = inputColVector1.vector; - HiveDecimalWritable[] vector2 = inputColVector2.vector; // return immediately if batch is empty if (n == 0) { @@ -96,40 +94,15 @@ public class extends VectorExpression { * conditional checks in the inner loop. */ if (inputColVector1.isRepeating && inputColVector2.isRepeating) { - DecimalUtil.Checked(0, vector1[0], vector2[0], outputColVector); - } else if (inputColVector1.isRepeating) { - if (batch.selectedInUse) { - for(int j = 0; j != n; j++) { - int i = sel[j]; - DecimalUtil.Checked(i, vector1[0], vector2[i], outputColVector); - } - } else { - for(int i = 0; i != n; i++) { - DecimalUtil.Checked(i, vector1[0], vector2[i], outputColVector); - } - } - } else if (inputColVector2.isRepeating) { - if (batch.selectedInUse) { - for(int j = 0; j != n; j++) { - int i = sel[j]; - DecimalUtil.Checked(i, vector1[i], vector2[0], outputColVector); - } - } else { - for(int i = 0; i != n; i++) { - DecimalUtil.Checked(i, vector1[i], vector2[0], outputColVector); - } - } + DecimalUtil.Checked(0, inputColVector1.get(0), inputColVector2.get(0), outputColVector); } else { - if (batch.selectedInUse) { - for(int j = 0; j != n; j++) { - int i = sel[j]; - DecimalUtil.Checked(i, vector1[i], vector2[i], outputColVector); - } - } else { - for(int i = 0; i != n; i++) { - DecimalUtil.Checked(i, vector1[i], vector2[i], outputColVector); - } - } + inputColVector1.flatten(batch.selectedInUse, batch.selected, batch.size); + inputColVector2.flatten(batch.selectedInUse, batch.selected, batch.size); + + outputColVector.(batch, inputColVector1, inputColVector2); + + inputColVector1.unFlatten(); + inputColVector2.unFlatten(); } /* For the case when the output can have null values, follow diff --git ql/src/gen/vectorization/ExpressionTemplates/ColumnArithmeticScalarDecimal.txt ql/src/gen/vectorization/ExpressionTemplates/ColumnArithmeticScalarDecimal.txt index 0bb1532..b384818 100644 --- ql/src/gen/vectorization/ExpressionTemplates/ColumnArithmeticScalarDecimal.txt +++ ql/src/gen/vectorization/ExpressionTemplates/ColumnArithmeticScalarDecimal.txt @@ -65,8 +65,7 @@ public class extends VectorExpression { outputColVector.noNulls = inputColVector.noNulls; outputColVector.isRepeating = inputColVector.isRepeating; int n = batch.size; - HiveDecimalWritable[] vector = inputColVector.vector; - + // return immediately if batch is empty if (n == 0) { return; @@ -89,37 +88,23 @@ public class extends VectorExpression { } // The following may override a "false" null setting if an error or overflow occurs. - DecimalUtil.Checked(0, vector[0], value, outputColVector); - } else if (inputColVector.noNulls) { - if (batch.selectedInUse) { - for(int j = 0; j != n; j++) { - int i = sel[j]; - DecimalUtil.Checked(i, vector[i], value, outputColVector); - } - } else { - for(int i = 0; i != n; i++) { - DecimalUtil.Checked(i, vector[i], value, outputColVector); - } - } - } else /* there are nulls */ { + DecimalUtil.Checked(0, inputColVector.get(0), value, outputColVector); + } else { if (batch.selectedInUse) { for(int j = 0; j != n; j++) { int i = sel[j]; outputIsNull[i] = inputIsNull[i]; - - // The following may override a "false" null setting if an error or overflow occurs. - DecimalUtil.Checked(i, vector[i], value, outputColVector); } } else { System.arraycopy(inputIsNull, 0, outputIsNull, 0, n); - for(int i = 0; i != n; i++) { - - // The following may override a "false" null setting if an error or overflow occurs. - DecimalUtil.Checked(i, vector[i], value, outputColVector); - } } + + inputColVector.flatten(batch.selectedInUse, batch.selected, batch.size); + DecimalColumnVector valueVector = new DecimalColumnVector(batch.getMaxSize(), value.precision(), value.scale()); + valueVector.fill(value, batch.getMaxSize()); + outputColVector.(batch, inputColVector, valueVector); + inputColVector.unFlatten(); } - /* * Null data entries are not set to a special non-zero value because all null math operations * are checked, meaning that a zero-divide always results in a null result. diff --git ql/src/gen/vectorization/ExpressionTemplates/ColumnDivideColumnDecimal.txt ql/src/gen/vectorization/ExpressionTemplates/ColumnDivideColumnDecimal.txt index 623bcfb..be4c95b 100644 --- ql/src/gen/vectorization/ExpressionTemplates/ColumnDivideColumnDecimal.txt +++ ql/src/gen/vectorization/ExpressionTemplates/ColumnDivideColumnDecimal.txt @@ -61,8 +61,6 @@ public class extends VectorExpression { DecimalColumnVector outputColVector = (DecimalColumnVector) batch.cols[outputColumn]; int[] sel = batch.selected; int n = batch.size; - HiveDecimalWritable[] vector1 = inputColVector1.vector; - HiveDecimalWritable[] vector2 = inputColVector2.vector; // return immediately if batch is empty if (n == 0) { @@ -96,40 +94,15 @@ public class extends VectorExpression { * conditional checks in the inner loop. */ if (inputColVector1.isRepeating && inputColVector2.isRepeating) { - DecimalUtil.Checked(0, vector1[0], vector2[0], outputColVector); - } else if (inputColVector1.isRepeating) { - if (batch.selectedInUse) { - for(int j = 0; j != n; j++) { - int i = sel[j]; - DecimalUtil.Checked(i, vector1[0], vector2[i], outputColVector); - } - } else { - for(int i = 0; i != n; i++) { - DecimalUtil.Checked(i, vector1[0], vector2[i], outputColVector); - } - } - } else if (inputColVector2.isRepeating) { - if (batch.selectedInUse) { - for(int j = 0; j != n; j++) { - int i = sel[j]; - DecimalUtil.Checked(i, vector1[i], vector2[0], outputColVector); - } - } else { - for(int i = 0; i != n; i++) { - DecimalUtil.Checked(i, vector1[i], vector2[0], outputColVector); - } - } + DecimalUtil.Checked(0, inputColVector1.get(0), inputColVector2.get(0), outputColVector); } else { - if (batch.selectedInUse) { - for(int j = 0; j != n; j++) { - int i = sel[j]; - DecimalUtil.Checked(i, vector1[i], vector2[i], outputColVector); - } - } else { - for(int i = 0; i != n; i++) { - DecimalUtil.Checked(i, vector1[i], vector2[i], outputColVector); - } - } + inputColVector1.flatten(batch.selectedInUse, batch.selected, batch.size); + inputColVector2.flatten(batch.selectedInUse, batch.selected, batch.size); + + outputColVector.(batch, inputColVector1, inputColVector2); + + inputColVector1.unFlatten(); + inputColVector2.unFlatten(); } } diff --git ql/src/gen/vectorization/ExpressionTemplates/ColumnDivideScalarDecimal.txt ql/src/gen/vectorization/ExpressionTemplates/ColumnDivideScalarDecimal.txt index 841ef93..37a158f 100644 --- ql/src/gen/vectorization/ExpressionTemplates/ColumnDivideScalarDecimal.txt +++ ql/src/gen/vectorization/ExpressionTemplates/ColumnDivideScalarDecimal.txt @@ -65,8 +65,6 @@ public class extends VectorExpression { outputColVector.noNulls = inputColVector.noNulls; outputColVector.isRepeating = inputColVector.isRepeating; int n = batch.size; - HiveDecimalWritable[] vector = inputColVector.vector; - HiveDecimalWritable[] outputVector = outputColVector.vector; // return immediately if batch is empty if (n == 0) { @@ -92,40 +90,26 @@ public class extends VectorExpression { outputColVector.isRepeating = true; outputIsNull[0] = true; } else if (inputColVector.isRepeating) { - DecimalUtil.Checked(0, vector[0], value, outputColVector); + DecimalUtil.Checked(0, inputColVector.get(0), value, outputColVector); // Even if there are no nulls, we always copy over entry 0. Simplifies code. outputIsNull[0] = inputIsNull[0]; - } else if (inputColVector.noNulls) { + } else { if (batch.selectedInUse) { for(int j = 0; j != n; j++) { int i = sel[j]; - DecimalUtil.Checked(i, vector[i], value, outputColVector); - } - } else { - for(int i = 0; i != n; i++) { - DecimalUtil.Checked(i, vector[i], value, outputColVector); - } - } - } else /* there are nulls */ { - if (batch.selectedInUse) { - for(int j = 0; j != n; j++) { - int i = sel[j]; - - // copy isNull entry first because operation may overwrite it outputIsNull[i] = inputIsNull[i]; - DecimalUtil.Checked(i, vector[i], value, outputColVector); } } else { - - // copy isNull entries first because operation may overwrite them System.arraycopy(inputIsNull, 0, outputIsNull, 0, n); - for(int i = 0; i != n; i++) { - DecimalUtil.Checked(i, vector[i], value, outputColVector); - } } - } + inputColVector.flatten(batch.selectedInUse, batch.selected, batch.size); + DecimalColumnVector valueVector = new DecimalColumnVector(batch.getMaxSize(), value.precision(), value.scale()); + valueVector.fill(value, batch.getMaxSize()); + outputColVector.(batch, inputColVector, valueVector); + inputColVector.unFlatten(); + } /* * Null data entries are not set to a special non-zero value because all null math operations * are checked, meaning that a zero-divide always results in a null result. diff --git ql/src/gen/vectorization/ExpressionTemplates/DecimalColumnUnaryFunc.txt ql/src/gen/vectorization/ExpressionTemplates/DecimalColumnUnaryFunc.txt index 619015e..d5391fd 100644 --- ql/src/gen/vectorization/ExpressionTemplates/DecimalColumnUnaryFunc.txt +++ ql/src/gen/vectorization/ExpressionTemplates/DecimalColumnUnaryFunc.txt @@ -59,7 +59,6 @@ public class extends VectorExpression { boolean[] outputIsNull = outputColVector.isNull; outputColVector.noNulls = inputColVector.noNulls; int n = batch.size; - HiveDecimalWritable[] vector = inputColVector.vector; // return immediately if batch is empty if (n == 0) { @@ -71,7 +70,7 @@ public class extends VectorExpression { // All must be selected otherwise size would be zero // Repeating property will not change. outputIsNull[0] = inputIsNull[0]; - (0, vector[0], outputColVector); + (0, inputColVector.get(0), outputColVector); outputColVector.isRepeating = true; } else if (inputColVector.noNulls) { if (batch.selectedInUse) { @@ -80,14 +79,14 @@ public class extends VectorExpression { // Set isNull because decimal operation can yield a null. outputIsNull[i] = false; - (i, vector[i], outputColVector); + (i, inputColVector.get(i), outputColVector); } } else { // Set isNull because decimal operation can yield a null. Arrays.fill(outputIsNull, 0, n, false); for(int i = 0; i != n; i++) { - (i, vector[i], outputColVector); + (i, inputColVector.get(i), outputColVector); } } outputColVector.isRepeating = false; @@ -96,12 +95,12 @@ public class extends VectorExpression { for(int j = 0; j != n; j++) { int i = sel[j]; outputIsNull[i] = inputIsNull[i]; - (i, vector[i], outputColVector); + (i, inputColVector.get(i), outputColVector); } } else { System.arraycopy(inputIsNull, 0, outputIsNull, 0, n); for(int i = 0; i != n; i++) { - (i, vector[i], outputColVector); + (i, inputColVector.get(i), outputColVector); } } outputColVector.isRepeating = false; diff --git ql/src/gen/vectorization/ExpressionTemplates/FilterDecimalColumnBetween.txt ql/src/gen/vectorization/ExpressionTemplates/FilterDecimalColumnBetween.txt index d68edfa..6786c52 100644 --- ql/src/gen/vectorization/ExpressionTemplates/FilterDecimalColumnBetween.txt +++ ql/src/gen/vectorization/ExpressionTemplates/FilterDecimalColumnBetween.txt @@ -62,7 +62,6 @@ public class extends VectorExpression { int[] sel = batch.selected; boolean[] nullPos = inputColVector.isNull; int n = batch.size; - HiveDecimalWritable[] vector = inputColVector.vector; // return immediately if batch is empty if (n == 0) { @@ -74,7 +73,8 @@ public class extends VectorExpression { // All must be selected otherwise size would be zero. // Repeating property will not change. - if ((DecimalUtil.compare(vector[0], leftValue) < 0 || DecimalUtil.compare(vector[0], rightValue) > 0)) { + HiveDecimalWritable value = inputColVector.get(0); + if ((DecimalUtil.compare(value, leftValue) < 0 || DecimalUtil.compare(value, rightValue) > 0)) { // Entire batch is filtered out. batch.size = 0; @@ -83,7 +83,8 @@ public class extends VectorExpression { int newSize = 0; for(int j = 0; j != n; j++) { int i = sel[j]; - if ((DecimalUtil.compare(leftValue, vector[i]) <= 0 && DecimalUtil.compare(vector[i], rightValue) <= 0)) { + HiveDecimalWritable value = inputColVector.get(i); + if ((DecimalUtil.compare(leftValue, value) <= 0 && DecimalUtil.compare(value, rightValue) <= 0)) { sel[newSize++] = i; } } @@ -91,7 +92,8 @@ public class extends VectorExpression { } else { int newSize = 0; for(int i = 0; i != n; i++) { - if ((DecimalUtil.compare(leftValue, vector[i]) <= 0 && DecimalUtil.compare(vector[i], rightValue) <= 0)) { + HiveDecimalWritable value = inputColVector.get(i); + if ((DecimalUtil.compare(leftValue, value) <= 0 && DecimalUtil.compare(value, rightValue) <= 0)) { sel[newSize++] = i; } } @@ -106,7 +108,8 @@ public class extends VectorExpression { // All must be selected otherwise size would be zero. // Repeating property will not change. if (!nullPos[0]) { - if ((DecimalUtil.compare(vector[0], leftValue) < 0 || DecimalUtil.compare(vector[0], rightValue) > 0)) { + HiveDecimalWritable value = inputColVector.get(0); + if ((DecimalUtil.compare(value, leftValue) < 0 || DecimalUtil.compare(value, rightValue) > 0)) { // Entire batch is filtered out. batch.size = 0; @@ -119,7 +122,8 @@ public class extends VectorExpression { for(int j = 0; j != n; j++) { int i = sel[j]; if (!nullPos[i]) { - if ((DecimalUtil.compare(leftValue, vector[i]) <= 0 && DecimalUtil.compare(vector[i], rightValue) <= 0)) { + HiveDecimalWritable value = inputColVector.get(i); + if ((DecimalUtil.compare(leftValue, value) <= 0 && DecimalUtil.compare(value, rightValue) <= 0)) { sel[newSize++] = i; } } @@ -131,7 +135,8 @@ public class extends VectorExpression { int newSize = 0; for(int i = 0; i != n; i++) { if (!nullPos[i]) { - if ((DecimalUtil.compare(leftValue, vector[i]) <= 0 && DecimalUtil.compare(vector[i], rightValue) <= 0)) { + HiveDecimalWritable value = inputColVector.get(i); + if ((DecimalUtil.compare(leftValue, value) <= 0 && DecimalUtil.compare(value, rightValue) <= 0)) { sel[newSize++] = i; } } diff --git ql/src/gen/vectorization/ExpressionTemplates/FilterDecimalColumnCompareDecimalColumn.txt ql/src/gen/vectorization/ExpressionTemplates/FilterDecimalColumnCompareDecimalColumn.txt index a2352c6..b402768 100644 --- ql/src/gen/vectorization/ExpressionTemplates/FilterDecimalColumnCompareDecimalColumn.txt +++ ql/src/gen/vectorization/ExpressionTemplates/FilterDecimalColumnCompareDecimalColumn.txt @@ -57,8 +57,6 @@ public class extends VectorExpression { boolean[] nullPos1 = inputColVector1.isNull; boolean[] nullPos2 = inputColVector2.isNull; int n = batch.size; - HiveDecimalWritable[] vector1 = inputColVector1.vector; - HiveDecimalWritable[] vector2 = inputColVector2.vector; // return immediately if batch is empty if (n == 0) { @@ -72,7 +70,7 @@ public class extends VectorExpression { /* Either all must remain selected or all will be eliminated. * Repeating property will not change. */ - if (!(vector1[0].compareTo(vector2[0]) 0)) { + if (!(inputColVector1.get(0).compareTo(inputColVector2.get(0)) 0)) { batch.size = 0; } } else if (inputColVector1.isRepeating) { @@ -80,7 +78,7 @@ public class extends VectorExpression { int newSize = 0; for(int j = 0; j != n; j++) { int i = sel[j]; - if (vector1[0].compareTo(vector2[i]) 0) { + if (inputColVector1.get(0).compareTo(inputColVector2.get(i)) 0) { sel[newSize++] = i; } } @@ -88,7 +86,7 @@ public class extends VectorExpression { } else { int newSize = 0; for(int i = 0; i != n; i++) { - if (vector1[0].compareTo(vector2[i]) 0) { + if (inputColVector1.get(0).compareTo(inputColVector2.get(i)) 0) { sel[newSize++] = i; } } @@ -102,7 +100,7 @@ public class extends VectorExpression { int newSize = 0; for(int j = 0; j != n; j++) { int i = sel[j]; - if (vector1[i].compareTo(vector2[0]) 0) { + if (inputColVector1.get(i).compareTo(inputColVector2.get(0)) 0) { sel[newSize++] = i; } } @@ -110,7 +108,7 @@ public class extends VectorExpression { } else { int newSize = 0; for(int i = 0; i != n; i++) { - if (vector1[i].compareTo(vector2[0]) 0) { + if (inputColVector1.get(i).compareTo(inputColVector2.get(0)) 0) { sel[newSize++] = i; } } @@ -123,7 +121,7 @@ public class extends VectorExpression { int newSize = 0; for(int j = 0; j != n; j++) { int i = sel[j]; - if (vector1[i].compareTo(vector2[i]) 0) { + if (inputColVector1.get(i).compareTo(inputColVector2.get(i)) 0) { sel[newSize++] = i; } } @@ -131,7 +129,7 @@ public class extends VectorExpression { } else { int newSize = 0; for(int i = 0; i != n; i++) { - if (vector1[i].compareTo(vector2[i]) 0) { + if (inputColVector1.get(i).compareTo(inputColVector2.get(i)) 0) { sel[newSize++] = i; } } @@ -145,7 +143,7 @@ public class extends VectorExpression { } else if (inputColVector1.noNulls) { if (inputColVector1.isRepeating && inputColVector2.isRepeating) { if (nullPos2[0] || - !(vector1[0].compareTo(vector2[0]) 0)) { + !(inputColVector1.get(0).compareTo(inputColVector2.get(0)) 0)) { batch.size = 0; } } else if (inputColVector1.isRepeating) { @@ -156,7 +154,7 @@ public class extends VectorExpression { for(int j = 0; j != n; j++) { int i = sel[j]; if (!nullPos2[i]) { - if (vector1[0].compareTo(vector2[i]) 0) { + if (inputColVector1.get(0).compareTo(inputColVector2.get(i)) 0) { sel[newSize++] = i; } } @@ -166,7 +164,7 @@ public class extends VectorExpression { int newSize = 0; for(int i = 0; i != n; i++) { if (!nullPos2[i]) { - if (vector1[0].compareTo(vector2[i]) 0) { + if (inputColVector1.get(0).compareTo(inputColVector2.get(i)) 0) { sel[newSize++] = i; } } @@ -187,7 +185,7 @@ public class extends VectorExpression { int newSize = 0; for(int j = 0; j != n; j++) { int i = sel[j]; - if (vector1[i].compareTo(vector2[0]) 0) { + if (inputColVector1.get(i).compareTo(inputColVector2.get(0)) 0) { sel[newSize++] = i; } } @@ -195,7 +193,7 @@ public class extends VectorExpression { } else { int newSize = 0; for(int i = 0; i != n; i++) { - if (vector1[i].compareTo(vector2[0]) 0) { + if (inputColVector1.get(i).compareTo(inputColVector2.get(0)) 0) { sel[newSize++] = i; } } @@ -210,7 +208,7 @@ public class extends VectorExpression { for(int j = 0; j != n; j++) { int i = sel[j]; if (!nullPos2[i]) { - if (vector1[i].compareTo(vector2[i]) 0) { + if (inputColVector1.get(i).compareTo(inputColVector2.get(i)) 0) { sel[newSize++] = i; } } @@ -220,7 +218,7 @@ public class extends VectorExpression { int newSize = 0; for(int i = 0; i != n; i++) { if (!nullPos2[i]) { - if (vector1[i].compareTo(vector2[i]) 0) { + if (inputColVector1.get(i).compareTo(inputColVector2.get(i)) 0) { sel[newSize++] = i; } } @@ -236,7 +234,7 @@ public class extends VectorExpression { } else if (inputColVector2.noNulls) { if (inputColVector1.isRepeating && inputColVector2.isRepeating) { if (nullPos1[0] || - !(vector1[0].compareTo(vector2[0]) 0)) { + !(inputColVector1.get(0).compareTo(inputColVector2.get(0)) 0)) { batch.size = 0; return; } @@ -251,7 +249,7 @@ public class extends VectorExpression { int newSize = 0; for(int j = 0; j != n; j++) { int i = sel[j]; - if (vector1[0].compareTo(vector2[i]) 0) { + if (inputColVector1.get(0).compareTo(inputColVector2.get(i)) 0) { sel[newSize++] = i; } } @@ -259,7 +257,7 @@ public class extends VectorExpression { } else { int newSize = 0; for(int i = 0; i != n; i++) { - if (vector1[0].compareTo(vector2[i]) 0) { + if (inputColVector1.get(0).compareTo(inputColVector2.get(i)) 0) { sel[newSize++] = i; } } @@ -274,7 +272,7 @@ public class extends VectorExpression { for(int j = 0; j != n; j++) { int i = sel[j]; if (!nullPos1[i]) { - if (vector1[i].compareTo(vector2[0]) 0) { + if (inputColVector1.get(i).compareTo(inputColVector2.get(0)) 0) { sel[newSize++] = i; } } @@ -284,7 +282,7 @@ public class extends VectorExpression { int newSize = 0; for(int i = 0; i != n; i++) { if (!nullPos1[i]) { - if (vector1[i].compareTo(vector2[0]) 0) { + if (inputColVector1.get(i).compareTo(inputColVector2.get(0)) 0) { sel[newSize++] = i; } } @@ -300,7 +298,7 @@ public class extends VectorExpression { for(int j = 0; j != n; j++) { int i = sel[j]; if (!nullPos1[i]) { - if (vector1[i].compareTo(vector2[i]) 0) { + if (inputColVector1.get(i).compareTo(inputColVector2.get(i)) 0) { sel[newSize++] = i; } } @@ -310,7 +308,7 @@ public class extends VectorExpression { int newSize = 0; for(int i = 0; i != n; i++) { if (!nullPos1[i]) { - if (vector1[i].compareTo(vector2[i]) 0) { + if (inputColVector1.get(i).compareTo(inputColVector2.get(i)) 0) { sel[newSize++] = i; } } @@ -326,7 +324,7 @@ public class extends VectorExpression { } else { if (inputColVector1.isRepeating && inputColVector2.isRepeating) { if (nullPos1[0] || nullPos2[0] || - !(vector1[0].compareTo(vector2[0]) 0)) { + !(inputColVector1.get(0).compareTo(inputColVector2.get(0)) 0)) { batch.size = 0; } } else if (inputColVector1.isRepeating) { @@ -339,7 +337,7 @@ public class extends VectorExpression { for(int j = 0; j != n; j++) { int i = sel[j]; if (!nullPos2[i]) { - if (vector1[0].compareTo(vector2[i]) 0) { + if (inputColVector1.get(0).compareTo(inputColVector2.get(i)) 0) { sel[newSize++] = i; } } @@ -349,7 +347,7 @@ public class extends VectorExpression { int newSize = 0; for(int i = 0; i != n; i++) { if (!nullPos2[i]) { - if (vector1[0].compareTo(vector2[i]) 0) { + if (inputColVector1.get(0).compareTo(inputColVector2.get(i)) 0) { sel[newSize++] = i; } } @@ -369,7 +367,7 @@ public class extends VectorExpression { for(int j = 0; j != n; j++) { int i = sel[j]; if (!nullPos1[i]) { - if (vector1[i].compareTo(vector2[0]) 0) { + if (inputColVector1.get(i).compareTo(inputColVector2.get(0)) 0) { sel[newSize++] = i; } } @@ -379,7 +377,7 @@ public class extends VectorExpression { int newSize = 0; for(int i = 0; i != n; i++) { if (!nullPos1[i]) { - if (vector1[i].compareTo(vector2[0]) 0) { + if (inputColVector1.get(i).compareTo(inputColVector2.get(0)) 0) { sel[newSize++] = i; } } @@ -395,7 +393,7 @@ public class extends VectorExpression { for(int j = 0; j != n; j++) { int i = sel[j]; if (!nullPos1[i] && !nullPos2[i]) { - if (vector1[i].compareTo(vector2[i]) 0) { + if (inputColVector1.get(i).compareTo(inputColVector2.get(i)) 0) { sel[newSize++] = i; } } @@ -405,7 +403,7 @@ public class extends VectorExpression { int newSize = 0; for(int i = 0; i != n; i++) { if (!nullPos1[i] && !nullPos2[i]) { - if (vector1[i].compareTo(vector2[i]) 0) { + if (inputColVector1.get(i).compareTo(inputColVector2.get(i)) 0) { sel[newSize++] = i; } } diff --git ql/src/gen/vectorization/ExpressionTemplates/FilterDecimalColumnCompareDecimalScalar.txt ql/src/gen/vectorization/ExpressionTemplates/FilterDecimalColumnCompareDecimalScalar.txt index bdd39b9..64788ad 100644 --- ql/src/gen/vectorization/ExpressionTemplates/FilterDecimalColumnCompareDecimalScalar.txt +++ ql/src/gen/vectorization/ExpressionTemplates/FilterDecimalColumnCompareDecimalScalar.txt @@ -54,7 +54,6 @@ public class extends VectorExpression { int[] sel = batch.selected; boolean[] nullPos = inputColVector.isNull; int n = batch.size; - HiveDecimalWritable[] vector = inputColVector.vector; // return immediately if batch is empty if (n == 0) { @@ -65,7 +64,7 @@ public class extends VectorExpression { if (inputColVector.isRepeating) { // All must be selected otherwise size would be zero. Repeating property will not change. - if (!(DecimalUtil.compare(vector[0], value) 0)) { + if (!(DecimalUtil.compare(inputColVector.get(0), value) 0)) { // Entire batch is filtered out. batch.size = 0; @@ -74,7 +73,7 @@ public class extends VectorExpression { int newSize = 0; for(int j = 0; j != n; j++) { int i = sel[j]; - if (DecimalUtil.compare(vector[i], value) 0) { + if (DecimalUtil.compare(inputColVector.get(i), value) 0) { sel[newSize++] = i; } } @@ -82,7 +81,7 @@ public class extends VectorExpression { } else { int newSize = 0; for(int i = 0; i != n; i++) { - if (DecimalUtil.compare(vector[i], value) 0) { + if (DecimalUtil.compare(inputColVector.get(i), value) 0) { sel[newSize++] = i; } } @@ -96,7 +95,7 @@ public class extends VectorExpression { // All must be selected otherwise size would be zero. Repeating property will not change. if (!nullPos[0]) { - if (!(DecimalUtil.compare(vector[0], value) 0)) { + if (!(DecimalUtil.compare(inputColVector.get(0), value) 0)) { // Entire batch is filtered out. batch.size = 0; @@ -109,7 +108,7 @@ public class extends VectorExpression { for(int j = 0; j != n; j++) { int i = sel[j]; if (!nullPos[i]) { - if (DecimalUtil.compare(vector[i], value) 0) { + if (DecimalUtil.compare(inputColVector.get(i), value) 0) { sel[newSize++] = i; } } @@ -121,7 +120,7 @@ public class extends VectorExpression { int newSize = 0; for(int i = 0; i != n; i++) { if (!nullPos[i]) { - if (DecimalUtil.compare(vector[i], value) 0) { + if (DecimalUtil.compare(inputColVector.get(i), value) 0) { sel[newSize++] = i; } } diff --git ql/src/gen/vectorization/ExpressionTemplates/FilterDecimalScalarCompareDecimalColumn.txt ql/src/gen/vectorization/ExpressionTemplates/FilterDecimalScalarCompareDecimalColumn.txt index 0608016..f6cd883 100644 --- ql/src/gen/vectorization/ExpressionTemplates/FilterDecimalScalarCompareDecimalColumn.txt +++ ql/src/gen/vectorization/ExpressionTemplates/FilterDecimalScalarCompareDecimalColumn.txt @@ -54,7 +54,6 @@ public class extends VectorExpression { int[] sel = batch.selected; boolean[] nullPos = inputColVector.isNull; int n = batch.size; - HiveDecimalWritable[] vector = inputColVector.vector; // return immediately if batch is empty if (n == 0) { @@ -65,7 +64,7 @@ public class extends VectorExpression { if (inputColVector.isRepeating) { // All must be selected otherwise size would be zero. Repeating property will not change. - if (!(DecimalUtil.compare(value, vector[0]) 0)) { + if (!(DecimalUtil.compare(value, inputColVector.get(0)) 0)) { // Entire batch is filtered out. batch.size = 0; @@ -74,7 +73,7 @@ public class extends VectorExpression { int newSize = 0; for(int j = 0; j != n; j++) { int i = sel[j]; - if (DecimalUtil.compare(value, vector[i]) 0) { + if (DecimalUtil.compare(value, inputColVector.get(i)) 0) { sel[newSize++] = i; } } @@ -82,7 +81,7 @@ public class extends VectorExpression { } else { int newSize = 0; for(int i = 0; i != n; i++) { - if (DecimalUtil.compare(value, vector[i]) 0) { + if (DecimalUtil.compare(value, inputColVector.get(i)) 0) { sel[newSize++] = i; } } @@ -96,7 +95,7 @@ public class extends VectorExpression { // All must be selected otherwise size would be zero. Repeating property will not change. if (!nullPos[0]) { - if (!(DecimalUtil.compare(value, vector[0]) 0)) { + if (!(DecimalUtil.compare(value, inputColVector.get(0)) 0)) { // Entire batch is filtered out. batch.size = 0; @@ -109,7 +108,7 @@ public class extends VectorExpression { for(int j = 0; j != n; j++) { int i = sel[j]; if (!nullPos[i]) { - if (DecimalUtil.compare(value, vector[i]) 0) { + if (DecimalUtil.compare(value, inputColVector.get(i)) 0) { sel[newSize++] = i; } } @@ -121,7 +120,7 @@ public class extends VectorExpression { int newSize = 0; for(int i = 0; i != n; i++) { if (!nullPos[i]) { - if (DecimalUtil.compare(value, vector[i]) 0) { + if (DecimalUtil.compare(value, inputColVector.get(i)) 0) { sel[newSize++] = i; } } diff --git ql/src/gen/vectorization/ExpressionTemplates/ScalarArithmeticColumnDecimal.txt ql/src/gen/vectorization/ExpressionTemplates/ScalarArithmeticColumnDecimal.txt index ea55bec..24eac76 100644 --- ql/src/gen/vectorization/ExpressionTemplates/ScalarArithmeticColumnDecimal.txt +++ ql/src/gen/vectorization/ExpressionTemplates/ScalarArithmeticColumnDecimal.txt @@ -65,8 +65,7 @@ public class extends VectorExpression { outputColVector.noNulls = inputColVector.noNulls; outputColVector.isRepeating = inputColVector.isRepeating; int n = batch.size; - HiveDecimalWritable[] vector = inputColVector.vector; - + // return immediately if batch is empty if (n == 0) { return; @@ -89,37 +88,24 @@ public class extends VectorExpression { } // The following may override a "false" null setting if an error or overflow occurs. - DecimalUtil.Checked(0, value, vector[0], outputColVector); - } else if (inputColVector.noNulls) { - if (batch.selectedInUse) { - for(int j = 0; j != n; j++) { - int i = sel[j]; - DecimalUtil.Checked(i, value, vector[i], outputColVector); - } - } else { - for(int i = 0; i != n; i++) { - DecimalUtil.Checked(i, value, vector[i], outputColVector); - } - } - } else /* there are nulls */ { + DecimalUtil.Checked(0, value, inputColVector.get(0), outputColVector); + } else { if (batch.selectedInUse) { for(int j = 0; j != n; j++) { int i = sel[j]; outputIsNull[i] = inputIsNull[i]; - - // The following may override a "false" null setting if an error or overflow occurs. - DecimalUtil.Checked(i, value, vector[i], outputColVector); } } else { System.arraycopy(inputIsNull, 0, outputIsNull, 0, n); - for(int i = 0; i != n; i++) { - - // The following may override a "false" null setting if an error or overflow occurs. - DecimalUtil.Checked(i, value, vector[i], outputColVector); - } } + + inputColVector.flatten(batch.selectedInUse, batch.selected, batch.size); + DecimalColumnVector valueVector = new DecimalColumnVector(batch.getMaxSize(), value.precision(), value.scale()); + valueVector.fill(value, batch.getMaxSize()); + outputColVector.(batch, valueVector, inputColVector); + inputColVector.unFlatten(); } - + NullUtil.setNullDataEntriesDecimal(outputColVector, batch.selectedInUse, sel, n); } diff --git ql/src/gen/vectorization/ExpressionTemplates/ScalarDivideColumnDecimal.txt ql/src/gen/vectorization/ExpressionTemplates/ScalarDivideColumnDecimal.txt index c8a5d17..cb63b16 100644 --- ql/src/gen/vectorization/ExpressionTemplates/ScalarDivideColumnDecimal.txt +++ ql/src/gen/vectorization/ExpressionTemplates/ScalarDivideColumnDecimal.txt @@ -65,8 +65,6 @@ public class extends VectorExpression { outputColVector.noNulls = inputColVector.noNulls; outputColVector.isRepeating = inputColVector.isRepeating; int n = batch.size; - HiveDecimalWritable[] vector = inputColVector.vector; - HiveDecimalWritable[] outputVector = outputColVector.vector; // return immediately if batch is empty if (n == 0) { @@ -85,38 +83,25 @@ public class extends VectorExpression { } if (inputColVector.isRepeating) { - DecimalUtil.Checked(0, value, vector[0], outputColVector); + DecimalUtil.Checked(0, value, inputColVector.get(0), outputColVector); // Even if there are no nulls, we always copy over entry 0. Simplifies code. outputIsNull[0] = inputIsNull[0]; - } else if (inputColVector.noNulls) { + } else { if (batch.selectedInUse) { for(int j = 0; j != n; j++) { int i = sel[j]; - DecimalUtil.Checked(i, value, vector[i], outputColVector); - } - } else { - for(int i = 0; i != n; i++) { - DecimalUtil.Checked(i, value, vector[i], outputColVector); - } - } - } else /* there are nulls */ { - if (batch.selectedInUse) { - for(int j = 0; j != n; j++) { - int i = sel[j]; - - // copy isNull entry first because the operation may overwrite it outputIsNull[i] = inputIsNull[i]; - DecimalUtil.Checked(i, value, vector[i], outputColVector); } } else { - - // copy isNull entries first because the operation may overwrite them System.arraycopy(inputIsNull, 0, outputIsNull, 0, n); - for(int i = 0; i != n; i++) { - DecimalUtil.Checked(i, value, vector[i], outputColVector); - } } + + inputColVector.flatten(batch.selectedInUse, batch.selected, batch.size); + DecimalColumnVector valueVector = new DecimalColumnVector(batch.getMaxSize(), value.precision(), value.scale()); + valueVector.fill(value, batch.getMaxSize()); + outputColVector.(batch, valueVector, inputColVector); + inputColVector.unFlatten(); } /* diff --git ql/src/gen/vectorization/UDAFTemplates/VectorUDAFMinMaxDecimal.txt ql/src/gen/vectorization/UDAFTemplates/VectorUDAFMinMaxDecimal.txt index 9a48171..4f41ea9 100644 --- ql/src/gen/vectorization/UDAFTemplates/VectorUDAFMinMaxDecimal.txt +++ ql/src/gen/vectorization/UDAFTemplates/VectorUDAFMinMaxDecimal.txt @@ -60,12 +60,12 @@ public class extends VectorAggregateExpression { value = new HiveDecimalWritable(); } - public void checkValue(HiveDecimalWritable writable, short scale) { - HiveDecimal value = writable.getHiveDecimal(); + public void checkValue(HiveDecimalWritable writable, int scale) { + HiveDecimalWritable value = writable; if (isNull) { isNull = false; this.value.set(value); - } else if (this.value.getHiveDecimal().compareTo(value) 0) { + } else if (this.value.compareTo(value) 0) { this.value.set(value); } } @@ -125,22 +125,21 @@ public class extends VectorAggregateExpression { DecimalColumnVector inputVector = (DecimalColumnVector)batch. cols[this.inputExpression.getOutputColumn()]; - HiveDecimalWritable[] vector = inputVector.vector; if (inputVector.noNulls) { if (inputVector.isRepeating) { iterateNoNullsRepeatingWithAggregationSelection( aggregationBufferSets, aggregrateIndex, - vector[0], inputVector.scale, batchSize); + inputVector.get(0), inputVector.scale(), batchSize); } else { if (batch.selectedInUse) { iterateNoNullsSelectionWithAggregationSelection( aggregationBufferSets, aggregrateIndex, - vector, inputVector.scale, batch.selected, batchSize); + inputVector, inputVector.scale(), batch.selected, batchSize); } else { iterateNoNullsWithAggregationSelection( aggregationBufferSets, aggregrateIndex, - vector, inputVector.scale, batchSize); + inputVector, inputVector.scale(), batchSize); } } } else { @@ -148,21 +147,21 @@ public class extends VectorAggregateExpression { if (batch.selectedInUse) { iterateHasNullsRepeatingSelectionWithAggregationSelection( aggregationBufferSets, aggregrateIndex, - vector[0], inputVector.scale, batchSize, batch.selected, inputVector.isNull); + inputVector.get(0), inputVector.scale(), batchSize, batch.selected, inputVector.isNull); } else { iterateHasNullsRepeatingWithAggregationSelection( aggregationBufferSets, aggregrateIndex, - vector[0], inputVector.scale, batchSize, inputVector.isNull); + inputVector.get(0), inputVector.scale(), batchSize, inputVector.isNull); } } else { if (batch.selectedInUse) { iterateHasNullsSelectionWithAggregationSelection( aggregationBufferSets, aggregrateIndex, - vector, inputVector.scale, batchSize, batch.selected, inputVector.isNull); + inputVector, inputVector.scale(), batchSize, batch.selected, inputVector.isNull); } else { iterateHasNullsWithAggregationSelection( aggregationBufferSets, aggregrateIndex, - vector, inputVector.scale, batchSize, inputVector.isNull); + inputVector, inputVector.scale(), batchSize, inputVector.isNull); } } } @@ -172,7 +171,7 @@ public class extends VectorAggregateExpression { VectorAggregationBufferRow[] aggregationBufferSets, int aggregrateIndex, HiveDecimalWritable value, - short scale, + int scale, int batchSize) { for (int i=0; i < batchSize; ++i) { @@ -187,8 +186,8 @@ public class extends VectorAggregateExpression { private void iterateNoNullsSelectionWithAggregationSelection( VectorAggregationBufferRow[] aggregationBufferSets, int aggregrateIndex, - HiveDecimalWritable[] values, - short scale, + DecimalColumnVector values, + int scale, int[] selection, int batchSize) { @@ -197,22 +196,22 @@ public class extends VectorAggregateExpression { aggregationBufferSets, aggregrateIndex, i); - myagg.checkValue(values[selection[i]], scale); + myagg.checkValue(values.get(selection[i]), scale); } } private void iterateNoNullsWithAggregationSelection( VectorAggregationBufferRow[] aggregationBufferSets, int aggregrateIndex, - HiveDecimalWritable[] values, - short scale, + DecimalColumnVector values, + int scale, int batchSize) { for (int i=0; i < batchSize; ++i) { Aggregation myagg = getCurrentAggregationBuffer( aggregationBufferSets, aggregrateIndex, i); - myagg.checkValue(values[i], scale); + myagg.checkValue(values.get(i), scale); } } @@ -220,7 +219,7 @@ public class extends VectorAggregateExpression { VectorAggregationBufferRow[] aggregationBufferSets, int aggregrateIndex, HiveDecimalWritable value, - short scale, + int scale, int batchSize, int[] selection, boolean[] isNull) { @@ -241,7 +240,7 @@ public class extends VectorAggregateExpression { VectorAggregationBufferRow[] aggregationBufferSets, int aggregrateIndex, HiveDecimalWritable value, - short scale, + int scale, int batchSize, boolean[] isNull) { @@ -261,8 +260,8 @@ public class extends VectorAggregateExpression { private void iterateHasNullsSelectionWithAggregationSelection( VectorAggregationBufferRow[] aggregationBufferSets, int aggregrateIndex, - HiveDecimalWritable[] values, - short scale, + DecimalColumnVector values, + int scale, int batchSize, int[] selection, boolean[] isNull) { @@ -274,7 +273,7 @@ public class extends VectorAggregateExpression { aggregationBufferSets, aggregrateIndex, j); - myagg.checkValue(values[i], scale); + myagg.checkValue(values.get(i), scale); } } } @@ -282,8 +281,8 @@ public class extends VectorAggregateExpression { private void iterateHasNullsWithAggregationSelection( VectorAggregationBufferRow[] aggregationBufferSets, int aggregrateIndex, - HiveDecimalWritable[] values, - short scale, + DecimalColumnVector values, + int scale, int batchSize, boolean[] isNull) { @@ -293,7 +292,7 @@ public class extends VectorAggregateExpression { aggregationBufferSets, aggregrateIndex, i); - myagg.checkValue(values[i], scale); + myagg.checkValue(values.get(i), scale); } } } @@ -315,38 +314,36 @@ public class extends VectorAggregateExpression { Aggregation myagg = (Aggregation)agg; - HiveDecimalWritable[] vector = inputVector.vector; - if (inputVector.isRepeating) { if (inputVector.noNulls && - (myagg.isNull || (myagg.value.compareTo(vector[0]) 0))) { + (myagg.isNull || (myagg.value.compareTo(inputVector.get(0)) 0))) { myagg.isNull = false; - HiveDecimal value = vector[0].getHiveDecimal(); + HiveDecimalWritable value = inputVector.get(0); myagg.value.set(value); } return; } if (!batch.selectedInUse && inputVector.noNulls) { - iterateNoSelectionNoNulls(myagg, vector, inputVector.scale, batchSize); + iterateNoSelectionNoNulls(myagg, inputVector, inputVector.scale(), batchSize); } else if (!batch.selectedInUse) { - iterateNoSelectionHasNulls(myagg, vector, inputVector.scale, + iterateNoSelectionHasNulls(myagg, inputVector, inputVector.scale(), batchSize, inputVector.isNull); } else if (inputVector.noNulls){ - iterateSelectionNoNulls(myagg, vector, inputVector.scale, batchSize, batch.selected); + iterateSelectionNoNulls(myagg, inputVector, inputVector.scale(), batchSize, batch.selected); } else { - iterateSelectionHasNulls(myagg, vector, inputVector.scale, + iterateSelectionHasNulls(myagg, inputVector, inputVector.scale(), batchSize, inputVector.isNull, batch.selected); } } private void iterateSelectionHasNulls( Aggregation myagg, - HiveDecimalWritable[] vector, - short scale, + DecimalColumnVector vector, + int scale, int batchSize, boolean[] isNull, int[] selected) { @@ -354,12 +351,12 @@ public class extends VectorAggregateExpression { for (int j=0; j< batchSize; ++j) { int i = selected[j]; if (!isNull[i]) { - HiveDecimal value = vector[i].getHiveDecimal(); + HiveDecimalWritable value = vector.get(i); if (myagg.isNull) { myagg.isNull = false; myagg.value.set(value); } - else if (myagg.value.getHiveDecimal().compareTo(value) 0) { + else if (myagg.value.compareTo(value) 0) { myagg.value.set(value); } } @@ -368,20 +365,20 @@ public class extends VectorAggregateExpression { private void iterateSelectionNoNulls( Aggregation myagg, - HiveDecimalWritable[] vector, - short scale, + DecimalColumnVector vector, + int scale, int batchSize, int[] selected) { if (myagg.isNull) { - HiveDecimal value = vector[selected[0]].getHiveDecimal(); + HiveDecimalWritable value = vector.get(selected[0]); myagg.value.set(value); myagg.isNull = false; } for (int i=0; i< batchSize; ++i) { - HiveDecimal value = vector[selected[i]].getHiveDecimal(); - if (myagg.value.getHiveDecimal().compareTo(value) 0) { + HiveDecimalWritable value = vector.get(selected[i]); + if (myagg.value.compareTo(value) 0) { myagg.value.set(value); } } @@ -389,19 +386,19 @@ public class extends VectorAggregateExpression { private void iterateNoSelectionHasNulls( Aggregation myagg, - HiveDecimalWritable[] vector, - short scale, + DecimalColumnVector vector, + int scale, int batchSize, boolean[] isNull) { for(int i=0;i 0) { + else if (myagg.value.compareTo(value) 0) { myagg.value.set(value); } } @@ -410,18 +407,18 @@ public class extends VectorAggregateExpression { private void iterateNoSelectionNoNulls( Aggregation myagg, - HiveDecimalWritable[] vector, - short scale, + DecimalColumnVector vector, + int scale, int batchSize) { if (myagg.isNull) { - HiveDecimal value = vector[0].getHiveDecimal(); + HiveDecimalWritable value = vector.get(0); myagg.value.set(value); myagg.isNull = false; } for (int i=0;i 0) { + HiveDecimalWritable value = vector.get(i); + if (myagg.value.compareTo(value) 0) { myagg.value.set(value); } } diff --git ql/src/gen/vectorization/UDAFTemplates/VectorUDAFVarDecimal.txt ql/src/gen/vectorization/UDAFTemplates/VectorUDAFVarDecimal.txt index 8fc94ba..06ab295 100644 --- ql/src/gen/vectorization/UDAFTemplates/VectorUDAFVarDecimal.txt +++ ql/src/gen/vectorization/UDAFTemplates/VectorUDAFVarDecimal.txt @@ -86,7 +86,7 @@ public class extends VectorAggregateExpression { variance = 0f; } - public void updateValueWithCheckAndInit(HiveDecimalWritable value, short scale) { + public void updateValueWithCheckAndInit(HiveDecimalWritable value, int scale) { if (this.isNull) { this.init(); } @@ -100,7 +100,7 @@ public class extends VectorAggregateExpression { } } - public void updateValueNoCheck(HiveDecimalWritable value, short scale) { + public void updateValueNoCheck(HiveDecimalWritable value, int scale) { double dval = value.getHiveDecimal().doubleValue(); this.sum += dval; this.count += 1; @@ -176,31 +176,29 @@ public class extends VectorAggregateExpression { return; } - HiveDecimalWritable[] vector = inputVector.vector; - if (inputVector.isRepeating) { if (inputVector.noNulls || !inputVector.isNull[0]) { iterateRepeatingNoNullsWithAggregationSelection( - aggregationBufferSets, aggregateIndex, vector[0], inputVector.scale, batchSize); + aggregationBufferSets, aggregateIndex, inputVector.get(0), inputVector.scale(), batchSize); } } else if (!batch.selectedInUse && inputVector.noNulls) { iterateNoSelectionNoNullsWithAggregationSelection( - aggregationBufferSets, aggregateIndex, vector, inputVector.scale, batchSize); + aggregationBufferSets, aggregateIndex, inputVector, inputVector.scale(), batchSize); } else if (!batch.selectedInUse) { iterateNoSelectionHasNullsWithAggregationSelection( - aggregationBufferSets, aggregateIndex, vector, inputVector.scale, + aggregationBufferSets, aggregateIndex, inputVector, inputVector.scale(), batchSize, inputVector.isNull); } else if (inputVector.noNulls){ iterateSelectionNoNullsWithAggregationSelection( - aggregationBufferSets, aggregateIndex, vector, inputVector.scale, + aggregationBufferSets, aggregateIndex, inputVector, inputVector.scale(), batchSize, batch.selected); } else { iterateSelectionHasNullsWithAggregationSelection( - aggregationBufferSets, aggregateIndex, vector, inputVector.scale, batchSize, + aggregationBufferSets, aggregateIndex, inputVector, inputVector.scale(), batchSize, inputVector.isNull, batch.selected); } @@ -210,7 +208,7 @@ public class extends VectorAggregateExpression { VectorAggregationBufferRow[] aggregationBufferSets, int aggregateIndex, HiveDecimalWritable value, - short scale, + int scale, int batchSize) { for (int i=0; i extends VectorAggregateExpression { private void iterateSelectionHasNullsWithAggregationSelection( VectorAggregationBufferRow[] aggregationBufferSets, int aggregateIndex, - HiveDecimalWritable[] vector, - short scale, + DecimalColumnVector vector, + int scale, int batchSize, boolean[] isNull, int[] selected) { @@ -238,7 +236,7 @@ public class extends VectorAggregateExpression { j); int i = selected[j]; if (!isNull[i]) { - HiveDecimalWritable value = vector[i]; + HiveDecimalWritable value = vector.get(i); myagg.updateValueWithCheckAndInit(value, scale); } } @@ -247,8 +245,8 @@ public class extends VectorAggregateExpression { private void iterateSelectionNoNullsWithAggregationSelection( VectorAggregationBufferRow[] aggregationBufferSets, int aggregateIndex, - HiveDecimalWritable[] vector, - short scale, + DecimalColumnVector vector, + int scale, int batchSize, int[] selected) { @@ -257,7 +255,7 @@ public class extends VectorAggregateExpression { aggregationBufferSets, aggregateIndex, i); - HiveDecimalWritable value = vector[selected[i]]; + HiveDecimalWritable value = vector.get(selected[i]); myagg.updateValueWithCheckAndInit(value, scale); } } @@ -265,8 +263,8 @@ public class extends VectorAggregateExpression { private void iterateNoSelectionHasNullsWithAggregationSelection( VectorAggregationBufferRow[] aggregationBufferSets, int aggregateIndex, - HiveDecimalWritable[] vector, - short scale, + DecimalColumnVector vector, + int scale, int batchSize, boolean[] isNull) { @@ -276,7 +274,7 @@ public class extends VectorAggregateExpression { aggregationBufferSets, aggregateIndex, i); - HiveDecimalWritable value = vector[i]; + HiveDecimalWritable value = vector.get(i); myagg.updateValueWithCheckAndInit(value, scale); } } @@ -285,8 +283,8 @@ public class extends VectorAggregateExpression { private void iterateNoSelectionNoNullsWithAggregationSelection( VectorAggregationBufferRow[] aggregationBufferSets, int aggregateIndex, - HiveDecimalWritable[] vector, - short scale, + DecimalColumnVector vector, + int scale, int batchSize) { for (int i=0; i extends VectorAggregateExpression { aggregationBufferSets, aggregateIndex, i); - HiveDecimalWritable value = vector[i]; + HiveDecimalWritable value = vector.get(i); myagg.updateValueWithCheckAndInit(value, scale); } } @@ -316,24 +314,22 @@ public class extends VectorAggregateExpression { Aggregation myagg = (Aggregation)agg; - HiveDecimalWritable[] vector = inputVector.vector; - if (inputVector.isRepeating) { if (inputVector.noNulls) { - iterateRepeatingNoNulls(myagg, vector[0], inputVector.scale, batchSize); + iterateRepeatingNoNulls(myagg, inputVector.get(0), inputVector.scale(), batchSize); } } else if (!batch.selectedInUse && inputVector.noNulls) { - iterateNoSelectionNoNulls(myagg, vector, inputVector.scale, batchSize); + iterateNoSelectionNoNulls(myagg, inputVector, inputVector.scale(), batchSize); } else if (!batch.selectedInUse) { - iterateNoSelectionHasNulls(myagg, vector, inputVector.scale, batchSize, inputVector.isNull); + iterateNoSelectionHasNulls(myagg, inputVector, inputVector.scale(), batchSize, inputVector.isNull); } else if (inputVector.noNulls){ - iterateSelectionNoNulls(myagg, vector, inputVector.scale, batchSize, batch.selected); + iterateSelectionNoNulls(myagg, inputVector, inputVector.scale(), batchSize, batch.selected); } else { - iterateSelectionHasNulls(myagg, vector, inputVector.scale, + iterateSelectionHasNulls(myagg, inputVector, inputVector.scale(), batchSize, inputVector.isNull, batch.selected); } } @@ -341,7 +337,7 @@ public class extends VectorAggregateExpression { private void iterateRepeatingNoNulls( Aggregation myagg, HiveDecimalWritable value, - short scale, + int scale, int batchSize) { // TODO: conjure a formula w/o iterating @@ -357,8 +353,8 @@ public class extends VectorAggregateExpression { private void iterateSelectionHasNulls( Aggregation myagg, - HiveDecimalWritable[] vector, - short scale, + DecimalColumnVector vector, + int scale, int batchSize, boolean[] isNull, int[] selected) { @@ -366,7 +362,7 @@ public class extends VectorAggregateExpression { for (int j=0; j< batchSize; ++j) { int i = selected[j]; if (!isNull[i]) { - HiveDecimalWritable value = vector[i]; + HiveDecimalWritable value = vector.get(i); myagg.updateValueWithCheckAndInit(value, scale); } } @@ -374,8 +370,8 @@ public class extends VectorAggregateExpression { private void iterateSelectionNoNulls( Aggregation myagg, - HiveDecimalWritable[] vector, - short scale, + DecimalColumnVector vector, + int scale, int batchSize, int[] selected) { @@ -383,27 +379,27 @@ public class extends VectorAggregateExpression { myagg.init (); } - HiveDecimalWritable value = vector[selected[0]]; + HiveDecimalWritable value = vector.get(selected[0]); myagg.updateValueWithCheckAndInit(value, scale); // i=0 was pulled out to remove the count > 1 check in the loop // for (int i=1; i< batchSize; ++i) { - value = vector[selected[i]]; + value = vector.get(selected[i]); myagg.updateValueNoCheck(value, scale); } } private void iterateNoSelectionHasNulls( Aggregation myagg, - HiveDecimalWritable[] vector, - short scale, + DecimalColumnVector vector, + int scale, int batchSize, boolean[] isNull) { for(int i=0;i extends VectorAggregateExpression { private void iterateNoSelectionNoNulls( Aggregation myagg, - HiveDecimalWritable[] vector, - short scale, + DecimalColumnVector vector, + int scale, int batchSize) { if (myagg.isNull) { myagg.init (); } - HiveDecimalWritable value = vector[0]; + HiveDecimalWritable value = vector.get(0); myagg.updateValueWithCheckAndInit(value, scale); // i=0 was pulled out to remove count > 1 check for (int i=1; i { - protected HiveDecimalWritable[] vector; + protected DecimalColumnVector vector; HiveDecimalWriter(int columnIndex) { super(columnIndex); @@ -497,7 +497,7 @@ boolean apply(VectorizedRowBatch batch, int batchIndex) throws IOException { if (colVector.isRepeating) { if (colVector.noNulls || !colVector.isNull[0]) { - serializeWrite.writeHiveDecimal(colVector.vector[0].getHiveDecimal(), colVector.scale); + serializeWrite.writeHiveDecimal(colVector.hiveDecimal(0), colVector.scale()); return true; } else { serializeWrite.writeNull(); @@ -505,7 +505,7 @@ boolean apply(VectorizedRowBatch batch, int batchIndex) throws IOException { } } else { if (colVector.noNulls || !colVector.isNull[batchIndex]) { - serializeWrite.writeHiveDecimal(colVector.vector[batchIndex].getHiveDecimal(), colVector.scale); + serializeWrite.writeHiveDecimal(colVector.hiveDecimal(batchIndex), colVector.scale()); return true; } else { serializeWrite.writeNull(); diff --git ql/src/java/org/apache/hadoop/hive/ql/exec/vector/VectorizedBatchUtil.java ql/src/java/org/apache/hadoop/hive/ql/exec/vector/VectorizedBatchUtil.java index 990e896..e3fa8e6 100644 --- ql/src/java/org/apache/hadoop/hive/ql/exec/vector/VectorizedBatchUtil.java +++ ql/src/java/org/apache/hadoop/hive/ql/exec/vector/VectorizedBatchUtil.java @@ -589,9 +589,8 @@ static ColumnVector cloneColumnVector(ColumnVector source return new BytesColumnVector(((BytesColumnVector) source).vector.length); } else if (source instanceof DecimalColumnVector) { DecimalColumnVector decColVector = (DecimalColumnVector) source; - return new DecimalColumnVector(decColVector.vector.length, - decColVector.precision, - decColVector.scale); + return new DecimalColumnVector(decColVector.getLength(), + decColVector.precision(), decColVector.scale()); } else if (source instanceof TimestampColumnVector) { return new TimestampColumnVector(((TimestampColumnVector) source).getLength()); } else if (source instanceof IntervalDayTimeColumnVector) { @@ -736,7 +735,7 @@ public static StringBuilder debugFormatOneRow(VectorizedRowBatch batch, sb.append("bytes: '" + displayBytes(bytes, start, length) + "'"); } } else if (colVector instanceof DecimalColumnVector) { - sb.append(((DecimalColumnVector) colVector).vector[index].toString()); + sb.append(((DecimalColumnVector) colVector).hiveDecimal(index).toString()); } else if (colVector instanceof TimestampColumnVector) { Timestamp timestamp = new Timestamp(0); ((TimestampColumnVector) colVector).timestampUpdate(timestamp, index); diff --git ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/CastDecimalToBoolean.java ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/CastDecimalToBoolean.java index 9621cd3..8317362 100644 --- ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/CastDecimalToBoolean.java +++ ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/CastDecimalToBoolean.java @@ -40,7 +40,7 @@ public CastDecimalToBoolean(int inputColumn, int outputColumn) { * If the input is 0 (i.e. the signum of the decimal is 0), return 0 for false. * Otherwise, return 1 for true. */ - protected void func(LongColumnVector outV, DecimalColumnVector inV, int i) { - outV.vector[i] = inV.vector[i].getHiveDecimal().signum() == 0 ? 0 : 1; + protected void func(LongColumnVector outV, DecimalColumnVector inV, int i) { + outV.vector[i] = inV.hiveDecimal(i).signum() == 0 ? 0 : 1; } } diff --git ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/CastDecimalToDecimal.java ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/CastDecimalToDecimal.java index ea235d9..49a4223 100644 --- ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/CastDecimalToDecimal.java +++ ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/CastDecimalToDecimal.java @@ -53,7 +53,7 @@ public CastDecimalToDecimal() { */ protected void convert(DecimalColumnVector outV, DecimalColumnVector inV, int i) { // The set routine enforces precision and scale. - outV.vector[i].set(inV.vector[i]); + outV.set(i, inV.get(i)); } /** diff --git ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/CastDecimalToDouble.java ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/CastDecimalToDouble.java index 63d878d..9512ebe 100644 --- ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/CastDecimalToDouble.java +++ ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/CastDecimalToDouble.java @@ -34,6 +34,6 @@ public CastDecimalToDouble(int inputCol, int outputCol) { } protected void func(DoubleColumnVector outV, DecimalColumnVector inV, int i) { - outV.vector[i] = inV.vector[i].getHiveDecimal().doubleValue(); + outV.vector[i] = inV.hiveDecimal(i).doubleValue(); } } diff --git ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/CastDecimalToLong.java ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/CastDecimalToLong.java index 2ff6b79..d9ffe8f 100644 --- ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/CastDecimalToLong.java +++ ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/CastDecimalToLong.java @@ -36,7 +36,7 @@ public CastDecimalToLong(int inputColumn, int outputColumn) { } @Override - protected void func(LongColumnVector outV, DecimalColumnVector inV, int i) { - outV.vector[i] = inV.vector[i].getHiveDecimal().longValue(); // TODO: lossy conversion! + protected void func(LongColumnVector outV, DecimalColumnVector inV, int i) { + outV.vector[i] = inV.hiveDecimal(i).longValue(); // TODO: lossy conversion! } } diff --git ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/CastDecimalToString.java ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/CastDecimalToString.java index 243a807..0b07822 100644 --- ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/CastDecimalToString.java +++ ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/CastDecimalToString.java @@ -43,7 +43,7 @@ protected void assign(BytesColumnVector outV, int i, byte[] bytes, int length) { @Override protected void func(BytesColumnVector outV, DecimalColumnVector inV, int i) { - String s = inV.vector[i].getHiveDecimal().toString(); + String s = inV.hiveDecimal(i).toString(); byte[] b = null; try { b = s.getBytes("UTF-8"); diff --git ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/CastDecimalToTimestamp.java ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/CastDecimalToTimestamp.java index 8963449..9b5992d 100644 --- ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/CastDecimalToTimestamp.java +++ ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/CastDecimalToTimestamp.java @@ -40,8 +40,8 @@ public CastDecimalToTimestamp() { } @Override - protected void func(TimestampColumnVector outV, DecimalColumnVector inV, int i) { - Timestamp timestamp = TimestampUtils.decimalToTimestamp(inV.vector[i].getHiveDecimal()); + protected void func(TimestampColumnVector outV, DecimalColumnVector inV, int i) { + Timestamp timestamp = TimestampUtils.decimalToTimestamp(inV.hiveDecimal(i)); outV.set(i, timestamp); } } diff --git ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/CastDoubleToDecimal.java ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/CastDoubleToDecimal.java index 6d6b588..6405d38 100644 --- ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/CastDoubleToDecimal.java +++ ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/CastDoubleToDecimal.java @@ -40,6 +40,6 @@ public CastDoubleToDecimal(int inputColumn, int outputColumn) { @Override protected void func(DecimalColumnVector outV, DoubleColumnVector inV, int i) { String s = ((Double) inV.vector[i]).toString(); - outV.vector[i].set(HiveDecimal.create(s)); + outV.set(i, HiveDecimal.create(s)); } } diff --git ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/CastLongToDecimal.java ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/CastLongToDecimal.java index ba8bcae..55d37af 100644 --- ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/CastLongToDecimal.java +++ ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/CastLongToDecimal.java @@ -41,6 +41,6 @@ public CastLongToDecimal(int inputColumn, int outputColumn) { @Override protected void func(DecimalColumnVector outV, LongColumnVector inV, int i) { - outV.vector[i].set(HiveDecimal.create(inV.vector[i])); + outV.set(i, HiveDecimal.create(inV.vector[i])); } } diff --git ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/CastStringToDecimal.java ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/CastStringToDecimal.java index 504b354..0f13ca5 100644 --- ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/CastStringToDecimal.java +++ ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/CastStringToDecimal.java @@ -59,7 +59,7 @@ protected void func(DecimalColumnVector outV, BytesColumnVector inV, int i) { * making a new string. */ s = new String(inV.vector[i], inV.start[i], inV.length[i], "UTF-8"); - outV.vector[i].set(HiveDecimal.create(s)); + outV.set(i, HiveDecimal.create(s)); } catch (Exception e) { // for any exception in conversion to decimal, produce NULL diff --git ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/ConstantVectorExpression.java ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/ConstantVectorExpression.java index 72749b7..f354159 100644 --- ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/ConstantVectorExpression.java +++ ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/ConstantVectorExpression.java @@ -145,7 +145,7 @@ private void evaluateDecimal(VectorizedRowBatch vrg) { dcv.isRepeating = true; dcv.noNulls = !isNullValue; if (!isNullValue) { - dcv.vector[0].set(decimalValue); + dcv.set(0, decimalValue); } else { dcv.isNull[0] = true; } diff --git ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/DecimalColumnInList.java ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/DecimalColumnInList.java index 0601c66..3b46724 100644 --- ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/DecimalColumnInList.java +++ ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/DecimalColumnInList.java @@ -73,7 +73,6 @@ public void evaluate(VectorizedRowBatch batch) { boolean[] nullPos = inputColVector.isNull; boolean[] outNulls = outputColVector.isNull; int n = batch.size; - HiveDecimalWritable[] vector = inputColVector.vector; long[] outputVector = outputColVector.vector; // return immediately if batch is empty @@ -88,16 +87,16 @@ public void evaluate(VectorizedRowBatch batch) { // All must be selected otherwise size would be zero // Repeating property will not change. - outputVector[0] = inSet.contains(vector[0].getHiveDecimal()) ? 1 : 0; + outputVector[0] = inSet.contains(inputColVector.hiveDecimal(0)) ? 1 : 0; outputColVector.isRepeating = true; } else if (batch.selectedInUse) { for(int j = 0; j != n; j++) { int i = sel[j]; - outputVector[i] = inSet.contains(vector[i].getHiveDecimal()) ? 1 : 0; + outputVector[i] = inSet.contains(inputColVector.hiveDecimal(i)) ? 1 : 0; } } else { for(int i = 0; i != n; i++) { - outputVector[i] = inSet.contains(vector[i].getHiveDecimal()) ? 1 : 0; + outputVector[i] = inSet.contains(inputColVector.hiveDecimal(i)) ? 1 : 0; } } } else { @@ -106,7 +105,7 @@ public void evaluate(VectorizedRowBatch batch) { //All must be selected otherwise size would be zero //Repeating property will not change. if (!nullPos[0]) { - outputVector[0] = inSet.contains(vector[0].getHiveDecimal()) ? 1 : 0; + outputVector[0] = inSet.contains(inputColVector.hiveDecimal(0)) ? 1 : 0; outNulls[0] = false; } else { outNulls[0] = true; @@ -117,14 +116,14 @@ public void evaluate(VectorizedRowBatch batch) { int i = sel[j]; outNulls[i] = nullPos[i]; if (!nullPos[i]) { - outputVector[i] = inSet.contains(vector[i].getHiveDecimal()) ? 1 : 0; + outputVector[i] = inSet.contains(inputColVector.hiveDecimal(i)) ? 1 : 0; } } } else { System.arraycopy(nullPos, 0, outNulls, 0, n); for(int i = 0; i != n; i++) { if (!nullPos[i]) { - outputVector[i] = inSet.contains(vector[i].getHiveDecimal()) ? 1 : 0; + outputVector[i] = inSet.contains(inputColVector.hiveDecimal(i)) ? 1 : 0; } } } diff --git ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/DecimalUtil.java ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/DecimalUtil.java index a01f7a2..2417ac0 100644 --- ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/DecimalUtil.java +++ ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/DecimalUtil.java @@ -298,7 +298,7 @@ public static void round(int i, HiveDecimalWritable input, int decimalPlaces, De public static void round(int i, HiveDecimal input, DecimalColumnVector outputColVector) { try { - outputColVector.set(i, RoundUtils.round(input, outputColVector.scale)); + outputColVector.set(i, RoundUtils.round(input, outputColVector.scale())); } catch (ArithmeticException e) { outputColVector.noNulls = false; outputColVector.isNull[i] = true; @@ -307,7 +307,7 @@ public static void round(int i, HiveDecimal input, DecimalColumnVector outputCol public static void round(int i, HiveDecimalWritable input, DecimalColumnVector outputColVector) { try { - outputColVector.set(i, RoundUtils.round(input.getHiveDecimal(), outputColVector.scale)); + outputColVector.set(i, RoundUtils.round(input.getHiveDecimal(), outputColVector.scale())); } catch (ArithmeticException e) { outputColVector.noNulls = false; outputColVector.isNull[i] = true; @@ -325,7 +325,7 @@ public static void bround(int i, HiveDecimalWritable input, int decimalPlaces, D public static void bround(int i, HiveDecimalWritable input, DecimalColumnVector outputColVector) { try { - outputColVector.set(i, RoundUtils.bround(input.getHiveDecimal(), outputColVector.scale)); + outputColVector.set(i, RoundUtils.bround(input.getHiveDecimal(), outputColVector.scale())); } catch (ArithmeticException e) { outputColVector.noNulls = false; outputColVector.isNull[i] = true; diff --git ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/FilterDecimalColumnInList.java ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/FilterDecimalColumnInList.java index a865343..aa292f2 100644 --- ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/FilterDecimalColumnInList.java +++ ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/FilterDecimalColumnInList.java @@ -68,7 +68,6 @@ public void evaluate(VectorizedRowBatch batch) { int[] sel = batch.selected; boolean[] nullPos = inputColVector.isNull; int n = batch.size; - HiveDecimalWritable[] vector = inputColVector.vector; // return immediately if batch is empty if (n == 0) { @@ -81,7 +80,7 @@ public void evaluate(VectorizedRowBatch batch) { // All must be selected otherwise size would be zero // Repeating property will not change. - if (!(inSet.contains(vector[0].getHiveDecimal()))) { + if (!(inSet.contains(inputColVector.hiveDecimal(0)))) { //Entire batch is filtered out. batch.size = 0; } @@ -89,7 +88,7 @@ public void evaluate(VectorizedRowBatch batch) { int newSize = 0; for(int j = 0; j != n; j++) { int i = sel[j]; - if (inSet.contains(vector[i].getHiveDecimal())) { + if (inSet.contains(inputColVector.hiveDecimal(i))) { sel[newSize++] = i; } } @@ -97,7 +96,7 @@ public void evaluate(VectorizedRowBatch batch) { } else { int newSize = 0; for(int i = 0; i != n; i++) { - if (inSet.contains(vector[i].getHiveDecimal())) { + if (inSet.contains(inputColVector.hiveDecimal(i))) { sel[newSize++] = i; } } @@ -112,7 +111,7 @@ public void evaluate(VectorizedRowBatch batch) { //All must be selected otherwise size would be zero //Repeating property will not change. if (!nullPos[0]) { - if (!inSet.contains(vector[0].getHiveDecimal())) { + if (!inSet.contains(inputColVector.hiveDecimal(0))) { //Entire batch is filtered out. batch.size = 0; @@ -125,7 +124,7 @@ public void evaluate(VectorizedRowBatch batch) { for(int j = 0; j != n; j++) { int i = sel[j]; if (!nullPos[i]) { - if (inSet.contains(vector[i].getHiveDecimal())) { + if (inSet.contains(inputColVector.hiveDecimal(i))) { sel[newSize++] = i; } } @@ -137,7 +136,7 @@ public void evaluate(VectorizedRowBatch batch) { int newSize = 0; for(int i = 0; i != n; i++) { if (!nullPos[i]) { - if (inSet.contains(vector[i].getHiveDecimal())) { + if (inSet.contains(inputColVector.hiveDecimal(i))) { sel[newSize++] = i; } } diff --git ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/FilterStructColumnInList.java ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/FilterStructColumnInList.java index 70b393c..8062999 100644 --- ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/FilterStructColumnInList.java +++ ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/FilterStructColumnInList.java @@ -112,7 +112,7 @@ public void evaluate(VectorizedRowBatch batch) { case DECIMAL: DecimalColumnVector decColVector = ((DecimalColumnVector) colVec); binarySortableSerializeWrite.writeHiveDecimal( - decColVector.vector[adjustedIndex].getHiveDecimal(), decColVector.scale); + decColVector.hiveDecimal(adjustedIndex), decColVector.scale()); break; default: diff --git ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/FuncRoundWithNumDigitsDecimalToDecimal.java ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/FuncRoundWithNumDigitsDecimalToDecimal.java index a18bb55..1b886be 100644 --- ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/FuncRoundWithNumDigitsDecimalToDecimal.java +++ ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/FuncRoundWithNumDigitsDecimalToDecimal.java @@ -61,7 +61,6 @@ public void evaluate(VectorizedRowBatch batch) { boolean[] outputIsNull = outputColVector.isNull; outputColVector.noNulls = inputColVector.noNulls; int n = batch.size; - HiveDecimalWritable[] vector = inputColVector.vector; // return immediately if batch is empty if (n == 0) { @@ -73,7 +72,7 @@ public void evaluate(VectorizedRowBatch batch) { // All must be selected otherwise size would be zero // Repeating property will not change. outputIsNull[0] = inputIsNull[0]; - round(0, vector[0], decimalPlaces, outputColVector); + round(0, inputColVector.get(0), decimalPlaces, outputColVector); outputColVector.isRepeating = true; } else if (inputColVector.noNulls) { if (batch.selectedInUse) { @@ -82,14 +81,14 @@ public void evaluate(VectorizedRowBatch batch) { // Set isNull because decimal operation can yield a null. outputIsNull[i] = false; - round(i, vector[i], decimalPlaces, outputColVector); + round(i, inputColVector.get(i), decimalPlaces, outputColVector); } } else { // Set isNull because decimal operation can yield a null. Arrays.fill(outputIsNull, 0, n, false); for(int i = 0; i != n; i++) { - round(i, vector[i], decimalPlaces, outputColVector); + round(i, inputColVector.get(i), decimalPlaces, outputColVector); } } outputColVector.isRepeating = false; @@ -98,12 +97,12 @@ public void evaluate(VectorizedRowBatch batch) { for(int j = 0; j != n; j++) { int i = sel[j]; outputIsNull[i] = inputIsNull[i]; - round(i, vector[i], decimalPlaces, outputColVector); + round(i, inputColVector.get(i), decimalPlaces, outputColVector); } } else { System.arraycopy(inputIsNull, 0, outputIsNull, 0, n); for(int i = 0; i != n; i++) { - round(i, vector[i], decimalPlaces, outputColVector); + round(i, inputColVector.get(i), decimalPlaces, outputColVector); } } outputColVector.isRepeating = false; diff --git ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/StructColumnInList.java ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/StructColumnInList.java index 769c70a..4974966 100644 --- ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/StructColumnInList.java +++ ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/StructColumnInList.java @@ -113,7 +113,7 @@ public void evaluate(VectorizedRowBatch batch) { case DECIMAL: DecimalColumnVector decColVector = ((DecimalColumnVector) colVec); binarySortableSerializeWrite.writeHiveDecimal( - decColVector.vector[adjustedIndex].getHiveDecimal(), decColVector.scale); + decColVector.hiveDecimal(adjustedIndex), decColVector.scale()); break; default: diff --git ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/VectorExpressionWriterFactory.java ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/VectorExpressionWriterFactory.java index c20bc68..c1ff1c3 100644 --- ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/VectorExpressionWriterFactory.java +++ ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/VectorExpressionWriterFactory.java @@ -385,13 +385,13 @@ public Object setValue(Object field, ColumnVector column, int row) throws HiveEx public Object writeValue(ColumnVector column, int row) throws HiveException { DecimalColumnVector dcv = (DecimalColumnVector) column; if (dcv.noNulls && !dcv.isRepeating) { - return writeValue(dcv.vector[row]); + return writeValue(dcv.get(row)); } else if (dcv.noNulls && dcv.isRepeating) { - return writeValue(dcv.vector[0]); + return writeValue(dcv.get(0)); } else if (!dcv.noNulls && !dcv.isRepeating && !dcv.isNull[row]) { - return writeValue(dcv.vector[row]); + return writeValue(dcv.get(row)); } else if (!dcv.noNulls && dcv.isRepeating && !dcv.isNull[0]) { - return writeValue(dcv.vector[0]); + return writeValue(dcv.get(0)); } else if (!dcv.noNulls && dcv.isRepeating && dcv.isNull[0]) { return null; } else if (!dcv.noNulls && !dcv.isRepeating && dcv.isNull[row]) { @@ -407,15 +407,15 @@ public Object writeValue(ColumnVector column, int row) throws HiveException { public Object setValue(Object field, ColumnVector column, int row) throws HiveException { DecimalColumnVector dcv = (DecimalColumnVector) column; if (dcv.noNulls && !dcv.isRepeating) { - return setValue(field, dcv.vector[row]); + return setValue(field, dcv.get(row)); } else if (dcv.noNulls && dcv.isRepeating) { - return setValue(field, dcv.vector[0]); + return setValue(field, dcv.get(0)); } else if (!dcv.noNulls && !dcv.isRepeating && !dcv.isNull[row]) { - return setValue(field, dcv.vector[row]); + return setValue(field, dcv.get(row)); } else if (!dcv.noNulls && !dcv.isRepeating && dcv.isNull[row]) { return null; } else if (!dcv.noNulls && dcv.isRepeating && !dcv.isNull[0]) { - return setValue(field, dcv.vector[0]); + return setValue(field, dcv.get(0)); } else if (!dcv.noNulls && dcv.isRepeating && dcv.isNull[0]) { return null; } diff --git ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/aggregates/VectorUDAFAvgDecimal.java ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/aggregates/VectorUDAFAvgDecimal.java index d0ff5fa..64cde5a 100644 --- ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/aggregates/VectorUDAFAvgDecimal.java +++ ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/aggregates/VectorUDAFAvgDecimal.java @@ -195,24 +195,23 @@ public void aggregateInputSelection( inputExpression.evaluate(batch); - DecimalColumnVector inputVector = ( DecimalColumnVector)batch. + DecimalColumnVector inputVector = (DecimalColumnVector)batch. cols[this.inputExpression.getOutputColumn()]; - HiveDecimalWritable[] vector = inputVector.vector; if (inputVector.noNulls) { if (inputVector.isRepeating) { iterateNoNullsRepeatingWithAggregationSelection( aggregationBufferSets, bufferIndex, - vector[0], batchSize); + inputVector.get(0), batchSize); } else { if (batch.selectedInUse) { iterateNoNullsSelectionWithAggregationSelection( aggregationBufferSets, bufferIndex, - vector, batch.selected, batchSize); + inputVector, batch.selected, batchSize); } else { iterateNoNullsWithAggregationSelection( aggregationBufferSets, bufferIndex, - vector, batchSize); + inputVector, batchSize); } } } else { @@ -220,21 +219,21 @@ public void aggregateInputSelection( if (batch.selectedInUse) { iterateHasNullsRepeatingSelectionWithAggregationSelection( aggregationBufferSets, bufferIndex, - vector[0], batchSize, batch.selected, inputVector.isNull); + inputVector.get(0), batchSize, batch.selected, inputVector.isNull); } else { iterateHasNullsRepeatingWithAggregationSelection( aggregationBufferSets, bufferIndex, - vector[0], batchSize, inputVector.isNull); + inputVector.get(0), batchSize, inputVector.isNull); } } else { if (batch.selectedInUse) { iterateHasNullsSelectionWithAggregationSelection( aggregationBufferSets, bufferIndex, - vector, batchSize, batch.selected, inputVector.isNull); + inputVector, batchSize, batch.selected, inputVector.isNull); } else { iterateHasNullsWithAggregationSelection( aggregationBufferSets, bufferIndex, - vector, batchSize, inputVector.isNull); + inputVector, batchSize, inputVector.isNull); } } } @@ -258,7 +257,7 @@ private void iterateNoNullsRepeatingWithAggregationSelection( private void iterateNoNullsSelectionWithAggregationSelection( VectorAggregationBufferRow[] aggregationBufferSets, int bufferIndex, - HiveDecimalWritable[] values, + DecimalColumnVector vector, int[] selection, int batchSize) { @@ -267,21 +266,21 @@ private void iterateNoNullsSelectionWithAggregationSelection( aggregationBufferSets, bufferIndex, i); - myagg.sumValueWithNullCheck(values[selection[i]], this.sumScale); + myagg.sumValueWithNullCheck(vector.get(selection[i]), this.sumScale); } } private void iterateNoNullsWithAggregationSelection( VectorAggregationBufferRow[] aggregationBufferSets, int bufferIndex, - HiveDecimalWritable[] values, + DecimalColumnVector vector, int batchSize) { for (int i=0; i < batchSize; ++i) { Aggregation myagg = getCurrentAggregationBuffer( aggregationBufferSets, bufferIndex, i); - myagg.sumValueWithNullCheck(values[i], this.sumScale); + myagg.sumValueWithNullCheck(vector.get(i), this.sumScale); } } @@ -330,7 +329,7 @@ private void iterateHasNullsRepeatingWithAggregationSelection( private void iterateHasNullsSelectionWithAggregationSelection( VectorAggregationBufferRow[] aggregationBufferSets, int bufferIndex, - HiveDecimalWritable[] values, + DecimalColumnVector vector, int batchSize, int[] selection, boolean[] isNull) { @@ -342,7 +341,7 @@ private void iterateHasNullsSelectionWithAggregationSelection( aggregationBufferSets, bufferIndex, j); - myagg.sumValueWithNullCheck(values[i], this.sumScale); + myagg.sumValueWithNullCheck(vector.get(i), this.sumScale); } } } @@ -350,7 +349,7 @@ private void iterateHasNullsSelectionWithAggregationSelection( private void iterateHasNullsWithAggregationSelection( VectorAggregationBufferRow[] aggregationBufferSets, int bufferIndex, - HiveDecimalWritable[] values, + DecimalColumnVector vector, int batchSize, boolean[] isNull) { @@ -360,7 +359,7 @@ private void iterateHasNullsWithAggregationSelection( aggregationBufferSets, bufferIndex, i); - myagg.sumValueWithNullCheck(values[i], this.sumScale); + myagg.sumValueWithNullCheck(vector.get(i), this.sumScale); } } } @@ -383,8 +382,6 @@ public void aggregateInput(AggregationBuffer agg, VectorizedRowBatch batch) Aggregation myagg = (Aggregation)agg; - HiveDecimalWritable[] vector = inputVector.vector; - if (inputVector.isRepeating) { if (inputVector.noNulls) { if (myagg.isNull) { @@ -392,7 +389,7 @@ public void aggregateInput(AggregationBuffer agg, VectorizedRowBatch batch) myagg.sum.set(HiveDecimal.ZERO); myagg.count = 0; } - HiveDecimal value = vector[0].getHiveDecimal(); + HiveDecimal value = inputVector.hiveDecimal(0); HiveDecimal multiple; try { multiple = value.multiply(HiveDecimal.create(batchSize)); @@ -414,22 +411,22 @@ public void aggregateInput(AggregationBuffer agg, VectorizedRowBatch batch) } if (!batch.selectedInUse && inputVector.noNulls) { - iterateNoSelectionNoNulls(myagg, vector, batchSize); + iterateNoSelectionNoNulls(myagg, inputVector, batchSize); } else if (!batch.selectedInUse) { - iterateNoSelectionHasNulls(myagg, vector, batchSize, inputVector.isNull); + iterateNoSelectionHasNulls(myagg, inputVector, batchSize, inputVector.isNull); } else if (inputVector.noNulls){ - iterateSelectionNoNulls(myagg, vector, batchSize, batch.selected); + iterateSelectionNoNulls(myagg, inputVector, batchSize, batch.selected); } else { - iterateSelectionHasNulls(myagg, vector, batchSize, inputVector.isNull, batch.selected); + iterateSelectionHasNulls(myagg, inputVector, batchSize, inputVector.isNull, batch.selected); } } private void iterateSelectionHasNulls( Aggregation myagg, - HiveDecimalWritable[] vector, + DecimalColumnVector vector, int batchSize, boolean[] isNull, int[] selected) { @@ -437,7 +434,7 @@ private void iterateSelectionHasNulls( for (int j=0; j< batchSize; ++j) { int i = selected[j]; if (!isNull[i]) { - HiveDecimalWritable value = vector[i]; + HiveDecimalWritable value = vector.get(i); myagg.sumValueWithNullCheck(value, this.sumScale); } } @@ -445,7 +442,7 @@ private void iterateSelectionHasNulls( private void iterateSelectionNoNulls( Aggregation myagg, - HiveDecimalWritable[] vector, + DecimalColumnVector vector, int batchSize, int[] selected) { @@ -456,20 +453,20 @@ private void iterateSelectionNoNulls( } for (int i=0; i< batchSize; ++i) { - HiveDecimalWritable value = vector[selected[i]]; + HiveDecimalWritable value = vector.get(selected[i]); myagg.sumValueNoNullCheck(value, this.sumScale); } } private void iterateNoSelectionHasNulls( Aggregation myagg, - HiveDecimalWritable[] vector, + DecimalColumnVector vector, int batchSize, boolean[] isNull) { for(int i=0;i 0) { readRepetitionAndDefinitionLevels(); if (definitionLevel >= maxDefLevel) { - c.vector[rowId].set(dataColumn.readBytes().getBytesUnsafe(), c.scale); + c.set(rowId, HiveDecimal.create(new BigInteger(dataColumn.readBytes().getBytesUnsafe()), c.scale())); c.isNull[rowId] = false; - c.isRepeating = c.isRepeating && (c.vector[0] == c.vector[rowId]); + c.isRepeating = c.isRepeating && c.equals(0, rowId); } else { c.isNull[rowId] = true; c.isRepeating = false; diff --git ql/src/test/org/apache/hadoop/hive/ql/exec/vector/expressions/TestConstantVectorExpression.java ql/src/test/org/apache/hadoop/hive/ql/exec/vector/expressions/TestConstantVectorExpression.java index 7b07293..6ac68f9 100644 --- ql/src/test/org/apache/hadoop/hive/ql/exec/vector/expressions/TestConstantVectorExpression.java +++ ql/src/test/org/apache/hadoop/hive/ql/exec/vector/expressions/TestConstantVectorExpression.java @@ -85,12 +85,12 @@ public void testConstantExpression() { assertTrue(bcv.length[0] == alphaBytes.length); assertTrue(sameFirstKBytes(alphaBytes, bcv.vector[0], alphaBytes.length)); - assertTrue(25.8 == dv.vector[0].getHiveDecimal().doubleValue()); + assertTrue(25.8 == dv.hiveDecimal(0).doubleValue()); // Evaluation of the decimal Constant Vector Expression after the vector is // modified. - ((DecimalColumnVector) (vrg.cols[3])).vector[0].set(HiveDecimal.create("39.7")); + ((DecimalColumnVector) (vrg.cols[3])).set(0, HiveDecimal.create("39.7")); decimalCve.evaluate(vrg); - assertTrue(25.8 == dv.vector[0].getHiveDecimal().doubleValue()); + assertTrue(25.8 == dv.hiveDecimal(0).doubleValue()); } private boolean sameFirstKBytes(byte[] o1, byte[] o2, int k) { diff --git ql/src/test/org/apache/hadoop/hive/ql/exec/vector/expressions/TestDecimalUtil.java ql/src/test/org/apache/hadoop/hive/ql/exec/vector/expressions/TestDecimalUtil.java index da9ebca..add02c0 100644 --- ql/src/test/org/apache/hadoop/hive/ql/exec/vector/expressions/TestDecimalUtil.java +++ ql/src/test/org/apache/hadoop/hive/ql/exec/vector/expressions/TestDecimalUtil.java @@ -36,37 +36,37 @@ public void testFloor() { HiveDecimal d1 = HiveDecimal.create("19.56778"); HiveDecimal expected1 = HiveDecimal.create("19"); DecimalUtil.floor(0, d1, dcv); - Assert.assertEquals(0, expected1.compareTo(dcv.vector[0].getHiveDecimal())); + Assert.assertEquals(0, expected1.compareTo(dcv.hiveDecimal(0))); // As of HIVE-8745, these decimal values should be trimmed of trailing zeros. HiveDecimal d2 = HiveDecimal.create("23.00000"); Assert.assertEquals(0, d2.scale()); HiveDecimal expected2 = HiveDecimal.create("23"); DecimalUtil.floor(0, d2, dcv); - Assert.assertEquals(0, expected2.compareTo(dcv.vector[0].getHiveDecimal())); + Assert.assertEquals(0, expected2.compareTo(dcv.hiveDecimal(0))); HiveDecimal d3 = HiveDecimal.create("-25.34567"); HiveDecimal expected3 = HiveDecimal.create("-26"); DecimalUtil.floor(0, d3, dcv); - Assert.assertEquals(0, expected3.compareTo(dcv.vector[0].getHiveDecimal())); + Assert.assertEquals(0, expected3.compareTo(dcv.hiveDecimal(0))); HiveDecimal d4 = HiveDecimal.create("-17.00000"); Assert.assertEquals(0, d4.scale()); HiveDecimal expected4 = HiveDecimal.create("-17"); DecimalUtil.floor(0, d4, dcv); - Assert.assertEquals(0, expected4.compareTo(dcv.vector[0].getHiveDecimal())); + Assert.assertEquals(0, expected4.compareTo(dcv.hiveDecimal(0))); HiveDecimal d5 = HiveDecimal.create("-0.30000"); Assert.assertEquals(1, d5.scale()); HiveDecimal expected5 = HiveDecimal.create("-1"); DecimalUtil.floor(0, d5, dcv); - Assert.assertEquals(0, expected5.compareTo(dcv.vector[0].getHiveDecimal())); + Assert.assertEquals(0, expected5.compareTo(dcv.hiveDecimal(0))); HiveDecimal d6 = HiveDecimal.create("0.30000"); Assert.assertEquals(1, d6.scale()); HiveDecimal expected6 = HiveDecimal.create("0"); DecimalUtil.floor(0, d6, dcv); - Assert.assertEquals(0, expected6.compareTo(dcv.vector[0].getHiveDecimal())); + Assert.assertEquals(0, expected6.compareTo(dcv.hiveDecimal(0))); } @Test @@ -75,37 +75,37 @@ public void testCeiling() { HiveDecimal d1 = HiveDecimal.create("19.56778"); HiveDecimal expected1 = HiveDecimal.create("20"); DecimalUtil.ceiling(0, d1, dcv); - Assert.assertEquals(0, expected1.compareTo(dcv.vector[0].getHiveDecimal())); + Assert.assertEquals(0, expected1.compareTo(dcv.hiveDecimal(0))); // As of HIVE-8745, these decimal values should be trimmed of trailing zeros. HiveDecimal d2 = HiveDecimal.create("23.00000"); Assert.assertEquals(0, d2.scale()); HiveDecimal expected2 = HiveDecimal.create("23"); DecimalUtil.ceiling(0, d2, dcv); - Assert.assertEquals(0, expected2.compareTo(dcv.vector[0].getHiveDecimal())); + Assert.assertEquals(0, expected2.compareTo(dcv.hiveDecimal(0))); HiveDecimal d3 = HiveDecimal.create("-25.34567"); HiveDecimal expected3 = HiveDecimal.create("-25"); DecimalUtil.ceiling(0, d3, dcv); - Assert.assertEquals(0, expected3.compareTo(dcv.vector[0].getHiveDecimal())); + Assert.assertEquals(0, expected3.compareTo(dcv.hiveDecimal(0))); HiveDecimal d4 = HiveDecimal.create("-17.00000"); Assert.assertEquals(0, d4.scale()); HiveDecimal expected4 = HiveDecimal.create("-17"); DecimalUtil.ceiling(0, d4, dcv); - Assert.assertEquals(0, expected4.compareTo(dcv.vector[0].getHiveDecimal())); + Assert.assertEquals(0, expected4.compareTo(dcv.hiveDecimal(0))); HiveDecimal d5 = HiveDecimal.create("-0.30000"); Assert.assertEquals(1, d5.scale()); HiveDecimal expected5 = HiveDecimal.create("0"); DecimalUtil.ceiling(0, d5, dcv); - Assert.assertEquals(0, expected5.compareTo(dcv.vector[0].getHiveDecimal())); + Assert.assertEquals(0, expected5.compareTo(dcv.hiveDecimal(0))); HiveDecimal d6 = HiveDecimal.create("0.30000"); Assert.assertEquals(1, d6.scale()); HiveDecimal expected6 = HiveDecimal.create("1"); DecimalUtil.ceiling(0, d6, dcv); - Assert.assertEquals(0, expected6.compareTo(dcv.vector[0].getHiveDecimal())); + Assert.assertEquals(0, expected6.compareTo(dcv.hiveDecimal(0))); } @Test @@ -113,12 +113,12 @@ public void testAbs() { DecimalColumnVector dcv = new DecimalColumnVector(4 ,20, 13); HiveDecimal d1 = HiveDecimal.create("19.56778"); DecimalUtil.abs(0, d1, dcv); - Assert.assertEquals(0, d1.compareTo(dcv.vector[0].getHiveDecimal())); + Assert.assertEquals(0, d1.compareTo(dcv.hiveDecimal(0))); HiveDecimal d2 = HiveDecimal.create("-25.34567"); HiveDecimal expected2 = HiveDecimal.create("25.34567"); DecimalUtil.abs(0, d2, dcv); - Assert.assertEquals(0, expected2.compareTo(dcv.vector[0].getHiveDecimal())); + Assert.assertEquals(0, expected2.compareTo(dcv.hiveDecimal(0))); } @Test @@ -127,35 +127,35 @@ public void testRound() { HiveDecimal d1 = HiveDecimal.create("19.56778"); HiveDecimal expected1 = HiveDecimal.create("20"); DecimalUtil.round(0, d1, dcv); - Assert.assertEquals(0, expected1.compareTo(dcv.vector[0].getHiveDecimal())); + Assert.assertEquals(0, expected1.compareTo(dcv.hiveDecimal(0))); // As of HIVE-8745, these decimal values should be trimmed of trailing zeros. HiveDecimal d2 = HiveDecimal.create("23.00000"); Assert.assertEquals(0, d2.scale()); HiveDecimal expected2 = HiveDecimal.create("23"); DecimalUtil.round(0, d2, dcv); - Assert.assertEquals(0, expected2.compareTo(dcv.vector[0].getHiveDecimal())); + Assert.assertEquals(0, expected2.compareTo(dcv.hiveDecimal(0))); HiveDecimal d3 = HiveDecimal.create("-25.34567"); HiveDecimal expected3 = HiveDecimal.create("-25"); DecimalUtil.round(0, d3, dcv); - Assert.assertEquals(0, expected3.compareTo(dcv.vector[0].getHiveDecimal())); + Assert.assertEquals(0, expected3.compareTo(dcv.hiveDecimal(0))); HiveDecimal d4 = HiveDecimal.create("-17.00000"); Assert.assertEquals(0, d4.scale()); HiveDecimal expected4 = HiveDecimal.create("-17"); DecimalUtil.round(0, d4, dcv); - Assert.assertEquals(0, expected4.compareTo(dcv.vector[0].getHiveDecimal())); + Assert.assertEquals(0, expected4.compareTo(dcv.hiveDecimal(0))); HiveDecimal d5 = HiveDecimal.create("19.36778"); HiveDecimal expected5 = HiveDecimal.create("19"); DecimalUtil.round(0, d5, dcv); - Assert.assertEquals(0, expected5.compareTo(dcv.vector[0].getHiveDecimal())); + Assert.assertEquals(0, expected5.compareTo(dcv.hiveDecimal(0))); HiveDecimal d6 = HiveDecimal.create("-25.54567"); HiveDecimal expected6 = HiveDecimal.create("-26"); DecimalUtil.round(0, d6, dcv); - Assert.assertEquals(0, expected6.compareTo(dcv.vector[0].getHiveDecimal())); + Assert.assertEquals(0, expected6.compareTo(dcv.hiveDecimal(0))); } @Test @@ -164,35 +164,35 @@ public void testRoundWithDigits() { HiveDecimal d1 = HiveDecimal.create("19.56778"); HiveDecimal expected1 = HiveDecimal.create("19.568"); DecimalUtil.round(0, d1, dcv); - Assert.assertEquals(0, expected1.compareTo(dcv.vector[0].getHiveDecimal())); + Assert.assertEquals(0, expected1.compareTo(dcv.hiveDecimal(0))); // As of HIVE-8745, these decimal values should be trimmed of trailing zeros. HiveDecimal d2 = HiveDecimal.create("23.56700"); Assert.assertEquals(3, d2.scale()); HiveDecimal expected2 = HiveDecimal.create("23.567"); DecimalUtil.round(0, d2, dcv); - Assert.assertEquals(0, expected2.compareTo(dcv.vector[0].getHiveDecimal())); + Assert.assertEquals(0, expected2.compareTo(dcv.hiveDecimal(0))); HiveDecimal d3 = HiveDecimal.create("-25.34567"); HiveDecimal expected3 = HiveDecimal.create("-25.346"); DecimalUtil.round(0, d3, dcv); - Assert.assertEquals(0, expected3.compareTo(dcv.vector[0].getHiveDecimal())); + Assert.assertEquals(0, expected3.compareTo(dcv.hiveDecimal(0))); HiveDecimal d4 = HiveDecimal.create("-17.23400"); Assert.assertEquals(3, d4.scale()); HiveDecimal expected4 = HiveDecimal.create("-17.234"); DecimalUtil.round(0, d4, dcv); - Assert.assertEquals(0, expected4.compareTo(dcv.vector[0].getHiveDecimal())); + Assert.assertEquals(0, expected4.compareTo(dcv.hiveDecimal(0))); HiveDecimal d5 = HiveDecimal.create("19.36748"); HiveDecimal expected5 = HiveDecimal.create("19.367"); DecimalUtil.round(0, d5, dcv); - Assert.assertEquals(0, expected5.compareTo(dcv.vector[0].getHiveDecimal())); + Assert.assertEquals(0, expected5.compareTo(dcv.hiveDecimal(0))); HiveDecimal d6 = HiveDecimal.create("-25.54537"); HiveDecimal expected6 = HiveDecimal.create("-25.545"); DecimalUtil.round(0, d6, dcv); - Assert.assertEquals(0, expected6.compareTo(dcv.vector[0].getHiveDecimal())); + Assert.assertEquals(0, expected6.compareTo(dcv.hiveDecimal(0))); } @Test @@ -201,19 +201,19 @@ public void testNegate() { HiveDecimal d1 = HiveDecimal.create("19.56778"); HiveDecimal expected1 = HiveDecimal.create("-19.56778"); DecimalUtil.negate(0, d1, dcv); - Assert.assertEquals(0, expected1.compareTo(dcv.vector[0].getHiveDecimal())); + Assert.assertEquals(0, expected1.compareTo(dcv.hiveDecimal(0))); HiveDecimal d2 = HiveDecimal.create("-25.34567"); HiveDecimal expected2 = HiveDecimal.create("25.34567"); DecimalUtil.negate(0, d2, dcv); - Assert.assertEquals(0, expected2.compareTo(dcv.vector[0].getHiveDecimal())); + Assert.assertEquals(0, expected2.compareTo(dcv.hiveDecimal(0))); // As of HIVE-8745, these decimal values should be trimmed of trailing zeros. HiveDecimal d3 = HiveDecimal.create("0.00000"); Assert.assertEquals(0, d3.scale()); HiveDecimal expected3 = HiveDecimal.create("0"); DecimalUtil.negate(0, d3, dcv); - Assert.assertEquals(0, expected3.compareTo(dcv.vector[0].getHiveDecimal())); + Assert.assertEquals(0, expected3.compareTo(dcv.hiveDecimal(0))); } @Test diff --git ql/src/test/org/apache/hadoop/hive/ql/exec/vector/expressions/TestVectorArithmeticExpressions.java ql/src/test/org/apache/hadoop/hive/ql/exec/vector/expressions/TestVectorArithmeticExpressions.java index ea06ea0..d991a3b 100644 --- ql/src/test/org/apache/hadoop/hive/ql/exec/vector/expressions/TestVectorArithmeticExpressions.java +++ ql/src/test/org/apache/hadoop/hive/ql/exec/vector/expressions/TestVectorArithmeticExpressions.java @@ -315,9 +315,9 @@ public void testDecimalColAddDecimalColumn() { // test without nulls expr.evaluate(b); - assertTrue(r.vector[0].getHiveDecimal().equals(HiveDecimal.create("2.20"))); - assertTrue(r.vector[1].getHiveDecimal().equals(HiveDecimal.create("-2.30"))); - assertTrue(r.vector[2].getHiveDecimal().equals(HiveDecimal.create("1.00"))); + assertTrue(r.hiveDecimal(0).equals(HiveDecimal.create("2.20"))); + assertTrue(r.hiveDecimal(1).equals(HiveDecimal.create("-2.30"))); + assertTrue(r.hiveDecimal(2).equals(HiveDecimal.create("1.00"))); // test nulls propagation b = getVectorizedRowBatch3DecimalCols(); @@ -330,18 +330,18 @@ public void testDecimalColAddDecimalColumn() { // Verify null output data entry is not 0, but rather the value specified by design, // which is the minimum non-0 value, 0.01 in this case. - assertTrue(r.vector[0].getHiveDecimal().equals(HiveDecimal.create("0.01"))); + assertTrue(r.hiveDecimal(0).equals(HiveDecimal.create("0.01"))); // test that overflow produces NULL b = getVectorizedRowBatch3DecimalCols(); c0 = (DecimalColumnVector) b.cols[0]; - c0.vector[0].set(HiveDecimal.create("9999999999999999.99")); // set to max possible value + c0.set(0, HiveDecimal.create("9999999999999999.99")); // set to max possible value r = (DecimalColumnVector) b.cols[2]; expr.evaluate(b); // will cause overflow for result at position 0, must yield NULL assertTrue(!r.noNulls && r.isNull[0]); // verify proper null output data value - assertTrue(r.vector[0].getHiveDecimal().equals(HiveDecimal.create("0.01"))); + assertTrue(r.hiveDecimal(0).equals(HiveDecimal.create("0.01"))); // test left input repeating b = getVectorizedRowBatch3DecimalCols(); @@ -349,25 +349,25 @@ public void testDecimalColAddDecimalColumn() { c0.isRepeating = true; r = (DecimalColumnVector) b.cols[2]; expr.evaluate(b); - assertTrue(r.vector[0].getHiveDecimal().equals(HiveDecimal.create("2.20"))); - assertTrue(r.vector[1].getHiveDecimal().equals(HiveDecimal.create("2.20"))); - assertTrue(r.vector[2].getHiveDecimal().equals(HiveDecimal.create("2.20"))); + assertTrue(r.hiveDecimal(0).equals(HiveDecimal.create("2.20"))); + assertTrue(r.hiveDecimal(1).equals(HiveDecimal.create("2.20"))); + assertTrue(r.hiveDecimal(2).equals(HiveDecimal.create("2.20"))); // test both inputs repeating DecimalColumnVector c1 = (DecimalColumnVector) b.cols[1]; c1.isRepeating = true; expr.evaluate(b); assertTrue(r.isRepeating); - assertTrue(r.vector[0].getHiveDecimal().equals(HiveDecimal.create("2.20"))); + assertTrue(r.hiveDecimal(0).equals(HiveDecimal.create("2.20"))); // test right input repeating b = getVectorizedRowBatch3DecimalCols(); c1 = (DecimalColumnVector) b.cols[1]; c1.isRepeating = true; - c1.vector[0].set(HiveDecimal.create("2.00")); + c1.set(0, HiveDecimal.create("2.00")); r = (DecimalColumnVector) b.cols[2]; expr.evaluate(b); - assertTrue(r.vector[2].getHiveDecimal().equals(HiveDecimal.create("2.00"))); + assertTrue(r.hiveDecimal(2).equals(HiveDecimal.create("2.00"))); } // Spot check decimal column-column subtract @@ -379,14 +379,14 @@ public void testDecimalColSubtractDecimalColumn() { // test without nulls expr.evaluate(b); - assertTrue(r.vector[0].getHiveDecimal().equals(HiveDecimal.create("0.20"))); - assertTrue(r.vector[1].getHiveDecimal().equals(HiveDecimal.create("-4.30"))); - assertTrue(r.vector[2].getHiveDecimal().equals(HiveDecimal.create("-1.00"))); + assertTrue(r.hiveDecimal(0).equals(HiveDecimal.create("0.20"))); + assertTrue(r.hiveDecimal(1).equals(HiveDecimal.create("-4.30"))); + assertTrue(r.hiveDecimal(2).equals(HiveDecimal.create("-1.00"))); // test that underflow produces NULL b = getVectorizedRowBatch3DecimalCols(); DecimalColumnVector c0 = (DecimalColumnVector) b.cols[0]; - c0.vector[0].set(HiveDecimal.create("-9999999999999999.99")); // set to min possible value + c0.set(0, HiveDecimal.create("-9999999999999999.99")); // set to min possible value r = (DecimalColumnVector) b.cols[2]; expr.evaluate(b); // will cause underflow for result at position 0, must yield NULL assertTrue(!r.noNulls && r.isNull[0]); @@ -401,16 +401,16 @@ public void testDecimalColMultiplyDecimalColumn() { // test without nulls expr.evaluate(b); - assertTrue(r.vector[0].getHiveDecimal().equals(HiveDecimal.create("1.20"))); - assertTrue(r.vector[1].getHiveDecimal().equals(HiveDecimal.create("-3.30"))); - assertTrue(r.vector[2].getHiveDecimal().equals(HiveDecimal.create("0.00"))); + assertTrue(r.hiveDecimal(0).equals(HiveDecimal.create("1.20"))); + assertTrue(r.hiveDecimal(1).equals(HiveDecimal.create("-3.30"))); + assertTrue(r.hiveDecimal(2).equals(HiveDecimal.create("0.00"))); // test that underflow produces NULL b = getVectorizedRowBatch3DecimalCols(); DecimalColumnVector c0 = (DecimalColumnVector) b.cols[0]; - c0.vector[0].set(HiveDecimal.create("9999999999999999.99")); // set to max possible value + c0.set(0, HiveDecimal.create("9999999999999999.99")); // set to max possible value DecimalColumnVector c1 = (DecimalColumnVector) b.cols[1]; - c1.vector[0].set(HiveDecimal.create("2.00")); + c1.set(0, HiveDecimal.create("2.00")); r = (DecimalColumnVector) b.cols[2]; expr.evaluate(b); // will cause overflow for result at position 0, must yield NULL assertTrue(!r.noNulls && r.isNull[0]); @@ -428,9 +428,9 @@ public void testDecimalColAddDecimalScalar() { // test without nulls expr.evaluate(b); DecimalColumnVector r = (DecimalColumnVector) b.cols[2]; - assertTrue(r.vector[0].getHiveDecimal().equals(HiveDecimal.create("2.20"))); - assertTrue(r.vector[1].getHiveDecimal().equals(HiveDecimal.create("-2.30"))); - assertTrue(r.vector[2].getHiveDecimal().equals(HiveDecimal.create("1"))); + assertTrue(r.hiveDecimal(0).equals(HiveDecimal.create("2.20"))); + assertTrue(r.hiveDecimal(1).equals(HiveDecimal.create("-2.30"))); + assertTrue(r.hiveDecimal(2).equals(HiveDecimal.create("1"))); // test null propagation b = getVectorizedRowBatch3DecimalCols(); @@ -449,7 +449,7 @@ public void testDecimalColAddDecimalScalar() { expr.evaluate(b); r = (DecimalColumnVector) b.cols[2]; assertTrue(r.isRepeating); - assertTrue(r.vector[0].getHiveDecimal().equals(HiveDecimal.create("2.20"))); + assertTrue(r.hiveDecimal(0).equals(HiveDecimal.create("2.20"))); // test repeating case for null value b = getVectorizedRowBatch3DecimalCols(); @@ -466,7 +466,7 @@ public void testDecimalColAddDecimalScalar() { // test that overflow produces null b = getVectorizedRowBatch3DecimalCols(); in = (DecimalColumnVector) b.cols[0]; - in.vector[0].set(HiveDecimal.create("9999999999999999.99")); // set to max possible value + in.set(0, HiveDecimal.create("9999999999999999.99")); // set to max possible value expr.evaluate(b); r = (DecimalColumnVector) b.cols[2]; assertFalse(r.noNulls); @@ -487,9 +487,9 @@ public void testDecimalColDivideDecimalScalar() { // test without nulls expr.evaluate(b); DecimalColumnVector r = (DecimalColumnVector) b.cols[2]; - assertTrue(r.vector[0].getHiveDecimal().equals(HiveDecimal.create("0.6"))); - assertTrue(r.vector[1].getHiveDecimal().equals(HiveDecimal.create("-1.65"))); - assertTrue(r.vector[2].getHiveDecimal().equals(HiveDecimal.create("0"))); + assertTrue(r.hiveDecimal(0).equals(HiveDecimal.create("0.6"))); + assertTrue(r.hiveDecimal(1).equals(HiveDecimal.create("-1.65"))); + assertTrue(r.hiveDecimal(2).equals(HiveDecimal.create("0"))); // test null propagation b = getVectorizedRowBatch3DecimalCols(); @@ -508,7 +508,7 @@ public void testDecimalColDivideDecimalScalar() { expr.evaluate(b); r = (DecimalColumnVector) b.cols[2]; assertTrue(r.isRepeating); - assertTrue(r.vector[0].getHiveDecimal().equals(HiveDecimal.create("0.6"))); + assertTrue(r.hiveDecimal(0).equals(HiveDecimal.create("0.6"))); // test repeating case for null value b = getVectorizedRowBatch3DecimalCols(); @@ -545,8 +545,8 @@ public void testDecimalScalarDivideDecimalColumn() { // test without nulls expr.evaluate(b); DecimalColumnVector r = (DecimalColumnVector) b.cols[2]; - assertTrue(r.vector[0].getHiveDecimal().equals(HiveDecimal.create("3.3"))); - assertTrue(r.vector[1].getHiveDecimal().equals(HiveDecimal.create("-1.2"))); + assertTrue(r.hiveDecimal(0).equals(HiveDecimal.create("3.3"))); + assertTrue(r.hiveDecimal(1).equals(HiveDecimal.create("-1.2"))); assertFalse(r.noNulls); // entry 2 is null due to zero-divide assertTrue(r.isNull[2]); @@ -567,7 +567,7 @@ public void testDecimalScalarDivideDecimalColumn() { expr.evaluate(b); r = (DecimalColumnVector) b.cols[2]; assertTrue(r.isRepeating); - assertTrue(r.vector[0].getHiveDecimal().equals(HiveDecimal.create("3.3"))); + assertTrue(r.hiveDecimal(0).equals(HiveDecimal.create("3.3"))); // test repeating case for null value b = getVectorizedRowBatch3DecimalCols(); @@ -592,22 +592,22 @@ public void testDecimalColModuloDecimalScalar() { // test without nulls expr.evaluate(b); DecimalColumnVector r = (DecimalColumnVector) b.cols[2]; - assertTrue(r.vector[0].getHiveDecimal().equals(HiveDecimal.create("1.20"))); - assertTrue(r.vector[1].getHiveDecimal().equals(HiveDecimal.create("-1.30"))); - assertTrue(r.vector[2].getHiveDecimal().equals(HiveDecimal.create("0"))); + assertTrue(r.hiveDecimal(0).equals(HiveDecimal.create("1.20"))); + assertTrue(r.hiveDecimal(1).equals(HiveDecimal.create("-1.30"))); + assertTrue(r.hiveDecimal(2).equals(HiveDecimal.create("0"))); // try again with some different data values and divisor DecimalColumnVector in = (DecimalColumnVector) b.cols[0]; - in.vector[0].set(HiveDecimal.create("15.40")); - in.vector[1].set(HiveDecimal.create("-17.20")); - in.vector[2].set(HiveDecimal.create("70.00")); + in.set(0, HiveDecimal.create("15.40")); + in.set(1, HiveDecimal.create("-17.20")); + in.set(2, HiveDecimal.create("70.00")); d = HiveDecimal.create("4.75"); expr = new DecimalColModuloDecimalScalar(0, d, 2); expr.evaluate(b); - assertTrue(r.vector[0].getHiveDecimal().equals(HiveDecimal.create("1.15"))); - assertTrue(r.vector[1].getHiveDecimal().equals(HiveDecimal.create("-2.95"))); - assertTrue(r.vector[2].getHiveDecimal().equals(HiveDecimal.create("3.50"))); + assertTrue(r.hiveDecimal(0).equals(HiveDecimal.create("1.15"))); + assertTrue(r.hiveDecimal(1).equals(HiveDecimal.create("-2.95"))); + assertTrue(r.hiveDecimal(2).equals(HiveDecimal.create("3.50"))); // try a zero-divide to show a repeating NULL is produced d = HiveDecimal.create("0.00"); @@ -628,22 +628,22 @@ public void testDecimalScalarModuloDecimalColumn() { // test without nulls expr.evaluate(b); DecimalColumnVector r = (DecimalColumnVector) b.cols[2]; - assertTrue(r.vector[0].getHiveDecimal().equals(HiveDecimal.create("0.80"))); - assertTrue(r.vector[1].getHiveDecimal().equals(HiveDecimal.create("2.00"))); + assertTrue(r.hiveDecimal(0).equals(HiveDecimal.create("0.80"))); + assertTrue(r.hiveDecimal(1).equals(HiveDecimal.create("2.00"))); assertFalse(r.noNulls); // entry 2 will be null due to zero-divide assertTrue(r.isNull[2]); // try again with some different data values DecimalColumnVector in = (DecimalColumnVector) b.cols[0]; expr = new DecimalScalarModuloDecimalColumn(d, 0, 2); - in.vector[0].set(HiveDecimal.create("0.50")); - in.vector[1].set(HiveDecimal.create("0.80")); - in.vector[2].set(HiveDecimal.create("0.70")); + in.set(0, HiveDecimal.create("0.50")); + in.set(1, HiveDecimal.create("0.80")); + in.set(2, HiveDecimal.create("0.70")); expr.evaluate(b); - assertTrue(r.vector[0].getHiveDecimal().equals(HiveDecimal.create("0.00"))); - assertTrue(r.vector[1].getHiveDecimal().equals(HiveDecimal.create("0.40"))); - assertTrue(r.vector[2].getHiveDecimal().equals(HiveDecimal.create("0.60"))); + assertTrue(r.hiveDecimal(0).equals(HiveDecimal.create("0.00"))); + assertTrue(r.hiveDecimal(1).equals(HiveDecimal.create("0.40"))); + assertTrue(r.hiveDecimal(2).equals(HiveDecimal.create("0.60"))); } @Test @@ -651,16 +651,16 @@ public void testDecimalColDivideDecimalColumn() { VectorizedRowBatch b = getVectorizedRowBatch3DecimalCols(); DecimalColumnVector in1 = (DecimalColumnVector) b.cols[1]; for (int i = 0; i < 3; i++) { - in1.vector[i].set(HiveDecimal.create("0.50")); + in1.set(i, HiveDecimal.create("0.50")); } VectorExpression expr = new DecimalColDivideDecimalColumn(0, 1, 2); expr.evaluate(b); DecimalColumnVector r = (DecimalColumnVector) b.cols[2]; // all divides are by 0.50 so the result column is 2 times col 0. - assertTrue(r.vector[0].getHiveDecimal().equals(HiveDecimal.create("2.4"))); - assertTrue(r.vector[1].getHiveDecimal().equals(HiveDecimal.create("-6.6"))); - assertTrue(r.vector[2].getHiveDecimal().equals(HiveDecimal.create("0"))); + assertTrue(r.hiveDecimal(0).equals(HiveDecimal.create("2.4"))); + assertTrue(r.hiveDecimal(1).equals(HiveDecimal.create("-6.6"))); + assertTrue(r.hiveDecimal(2).equals(HiveDecimal.create("0"))); // test null on left b.cols[0].noNulls = false; @@ -695,14 +695,14 @@ public void testDecimalColDivideDecimalColumn() { b.cols[0].isRepeating = true; expr.evaluate(b); r = (DecimalColumnVector) b.cols[2]; - assertTrue(r.vector[2].getHiveDecimal().equals(HiveDecimal.create("1.2"))); + assertTrue(r.hiveDecimal(2).equals(HiveDecimal.create("1.2"))); // test repeating on right b = getVectorizedRowBatch3DecimalCols(); b.cols[1].isRepeating = true; expr.evaluate(b); r = (DecimalColumnVector) b.cols[2]; - assertTrue(r.vector[2].getHiveDecimal().equals(HiveDecimal.create("0"))); + assertTrue(r.hiveDecimal(2).equals(HiveDecimal.create("0"))); // test both repeating b = getVectorizedRowBatch3DecimalCols(); @@ -711,11 +711,11 @@ public void testDecimalColDivideDecimalColumn() { expr.evaluate(b); r = (DecimalColumnVector) b.cols[2]; assertTrue(r.isRepeating); - assertTrue(r.vector[0].getHiveDecimal().equals(HiveDecimal.create("1.2"))); + assertTrue(r.hiveDecimal(0).equals(HiveDecimal.create("1.2"))); // test zero-divide to show it results in NULL b = getVectorizedRowBatch3DecimalCols(); - ((DecimalColumnVector) b.cols[1]).vector[0].set(HiveDecimal.create("0")); + ((DecimalColumnVector) b.cols[1]).set(0, HiveDecimal.create("0")); expr.evaluate(b); r = (DecimalColumnVector) b.cols[2]; assertFalse(r.noNulls); @@ -728,15 +728,15 @@ public void testDecimalColModuloDecimalColumn() { VectorizedRowBatch b = getVectorizedRowBatch3DecimalCols(); DecimalColumnVector in1 = (DecimalColumnVector) b.cols[1]; for (int i = 0; i < 3; i++) { - in1.vector[i].set(HiveDecimal.create("0.50")); + in1.set(i, HiveDecimal.create("0.50")); } VectorExpression expr = new DecimalColModuloDecimalColumn(0, 1, 2); expr.evaluate(b); DecimalColumnVector r = (DecimalColumnVector) b.cols[2]; - assertTrue(r.vector[0].getHiveDecimal().equals(HiveDecimal.create("0.20"))); - assertTrue(r.vector[1].getHiveDecimal().equals(HiveDecimal.create("-0.30"))); - assertTrue(r.vector[2].getHiveDecimal().equals(HiveDecimal.create("0"))); + assertTrue(r.hiveDecimal(0).equals(HiveDecimal.create("0.20"))); + assertTrue(r.hiveDecimal(1).equals(HiveDecimal.create("-0.30"))); + assertTrue(r.hiveDecimal(2).equals(HiveDecimal.create("0"))); } /* Spot check correctness of decimal column subtract decimal scalar. The case for @@ -751,14 +751,14 @@ public void testDecimalColSubtractDecimalScalar() { // test without nulls expr.evaluate(b); DecimalColumnVector r = (DecimalColumnVector) b.cols[2]; - assertTrue(r.vector[0].getHiveDecimal().equals(HiveDecimal.create("0.20"))); - assertTrue(r.vector[1].getHiveDecimal().equals(HiveDecimal.create("-4.30"))); - assertTrue(r.vector[2].getHiveDecimal().equals(HiveDecimal.create("-1"))); + assertTrue(r.hiveDecimal(0).equals(HiveDecimal.create("0.20"))); + assertTrue(r.hiveDecimal(1).equals(HiveDecimal.create("-4.30"))); + assertTrue(r.hiveDecimal(2).equals(HiveDecimal.create("-1"))); // test that underflow produces null b = getVectorizedRowBatch3DecimalCols(); DecimalColumnVector in = (DecimalColumnVector) b.cols[0]; - in.vector[0].set(HiveDecimal.create("-9999999999999999.99")); // set to min possible value + in.set(0, HiveDecimal.create("-9999999999999999.99")); // set to min possible value expr.evaluate(b); r = (DecimalColumnVector) b.cols[2]; assertFalse(r.noNulls); @@ -777,14 +777,14 @@ public void testDecimalColMultiplyDecimalScalar() { // test without nulls expr.evaluate(b); DecimalColumnVector r = (DecimalColumnVector) b.cols[2]; - assertTrue(r.vector[0].getHiveDecimal().equals(HiveDecimal.create("2.40"))); - assertTrue(r.vector[1].getHiveDecimal().equals(HiveDecimal.create("-6.60"))); - assertTrue(r.vector[2].getHiveDecimal().equals(HiveDecimal.create("0"))); + assertTrue(r.hiveDecimal(0).equals(HiveDecimal.create("2.40"))); + assertTrue(r.hiveDecimal(1).equals(HiveDecimal.create("-6.60"))); + assertTrue(r.hiveDecimal(2).equals(HiveDecimal.create("0"))); // test that overflow produces null b = getVectorizedRowBatch3DecimalCols(); DecimalColumnVector in = (DecimalColumnVector) b.cols[0]; - in.vector[0].set(HiveDecimal.create("9999999999999999.99")); // set to max possible value + in.set(0, HiveDecimal.create("9999999999999999.99")); // set to max possible value expr.evaluate(b); r = (DecimalColumnVector) b.cols[2]; assertFalse(r.noNulls); @@ -803,9 +803,9 @@ public void testDecimalScalarAddDecimalColumn() { // test without nulls expr.evaluate(b); DecimalColumnVector r = (DecimalColumnVector) b.cols[2]; - assertTrue(r.vector[0].getHiveDecimal().equals(HiveDecimal.create("2.20"))); - assertTrue(r.vector[1].getHiveDecimal().equals(HiveDecimal.create("-2.30"))); - assertTrue(r.vector[2].getHiveDecimal().equals(HiveDecimal.create("1"))); + assertTrue(r.hiveDecimal(0).equals(HiveDecimal.create("2.20"))); + assertTrue(r.hiveDecimal(1).equals(HiveDecimal.create("-2.30"))); + assertTrue(r.hiveDecimal(2).equals(HiveDecimal.create("1"))); // test null propagation b = getVectorizedRowBatch3DecimalCols(); @@ -824,7 +824,7 @@ public void testDecimalScalarAddDecimalColumn() { expr.evaluate(b); r = (DecimalColumnVector) b.cols[2]; assertTrue(r.isRepeating); - assertTrue(r.vector[0].getHiveDecimal().equals(HiveDecimal.create("2.20"))); + assertTrue(r.hiveDecimal(0).equals(HiveDecimal.create("2.20"))); // test repeating case for null value b = getVectorizedRowBatch3DecimalCols(); @@ -841,7 +841,7 @@ public void testDecimalScalarAddDecimalColumn() { // test that overflow produces null b = getVectorizedRowBatch3DecimalCols(); in = (DecimalColumnVector) b.cols[0]; - in.vector[0].set(HiveDecimal.create("9999999999999999.99")); // set to max possible value + in.set(0, HiveDecimal.create("9999999999999999.99")); // set to max possible value expr.evaluate(b); r = (DecimalColumnVector) b.cols[2]; assertFalse(r.noNulls); @@ -860,14 +860,14 @@ public void testDecimalScalarSubtractDecimalColumn() { // test without nulls expr.evaluate(b); DecimalColumnVector r = (DecimalColumnVector) b.cols[2]; - assertTrue(r.vector[0].getHiveDecimal().equals(HiveDecimal.create("-0.20"))); - assertTrue(r.vector[1].getHiveDecimal().equals(HiveDecimal.create("4.30"))); - assertTrue(r.vector[2].getHiveDecimal().equals(HiveDecimal.create("1"))); + assertTrue(r.hiveDecimal(0).equals(HiveDecimal.create("-0.20"))); + assertTrue(r.hiveDecimal(1).equals(HiveDecimal.create("4.30"))); + assertTrue(r.hiveDecimal(2).equals(HiveDecimal.create("1"))); // test that overflow produces null b = getVectorizedRowBatch3DecimalCols(); DecimalColumnVector in = (DecimalColumnVector) b.cols[0]; - in.vector[0].set(HiveDecimal.create("-9999999999999999.99")); // set to min possible value + in.set(0, HiveDecimal.create("-9999999999999999.99")); // set to min possible value expr.evaluate(b); r = (DecimalColumnVector) b.cols[2]; assertFalse(r.noNulls); @@ -887,14 +887,14 @@ public void testDecimalScalarMultiplyDecimalColumn() { // test without nulls expr.evaluate(b); DecimalColumnVector r = (DecimalColumnVector) b.cols[2]; - assertTrue(r.vector[0].getHiveDecimal().equals(HiveDecimal.create("2.40"))); - assertTrue(r.vector[1].getHiveDecimal().equals(HiveDecimal.create("-6.60"))); - assertTrue(r.vector[2].getHiveDecimal().equals(HiveDecimal.create("0"))); + assertTrue(r.hiveDecimal(0).equals(HiveDecimal.create("2.40"))); + assertTrue(r.hiveDecimal(1).equals(HiveDecimal.create("-6.60"))); + assertTrue(r.hiveDecimal(2).equals(HiveDecimal.create("0"))); // test that overflow produces null b = getVectorizedRowBatch3DecimalCols(); DecimalColumnVector in = (DecimalColumnVector) b.cols[0]; - in.vector[0].set(HiveDecimal.create("9999999999999999.99")); // set to max possible value + in.set(0, HiveDecimal.create("9999999999999999.99")); // set to max possible value expr.evaluate(b); r = (DecimalColumnVector) b.cols[2]; assertFalse(r.noNulls); @@ -905,16 +905,16 @@ public void testDecimalScalarMultiplyDecimalColumn() { private VectorizedRowBatch getVectorizedRowBatch3DecimalCols() { VectorizedRowBatch b = new VectorizedRowBatch(3); DecimalColumnVector v0, v1; - b.cols[0] = v0 = new DecimalColumnVector(18, 2); - b.cols[1] = v1 = new DecimalColumnVector(18, 2); - b.cols[2] = new DecimalColumnVector(18, 2); - v0.vector[0].set(HiveDecimal.create("1.20")); - v0.vector[1].set(HiveDecimal.create("-3.30")); - v0.vector[2].set(HiveDecimal.create("0")); - - v1.vector[0].set(HiveDecimal.create("1.00")); - v1.vector[1].set(HiveDecimal.create("1.00")); - v1.vector[2].set(HiveDecimal.create("1.00")); + b.cols[0] = v0 = new DecimalColumnVector(3, 18, 2); + b.cols[1] = v1 = new DecimalColumnVector(3, 18, 2); + b.cols[2] = new DecimalColumnVector(3, 18, 2); + v0.set(0, HiveDecimal.create("1.20")); + v0.set(1, HiveDecimal.create("-3.30")); + v0.set(2, HiveDecimal.create("0")); + + v1.set(0, HiveDecimal.create("1.00")); + v1.set(1, HiveDecimal.create("1.00")); + v1.set(2, HiveDecimal.create("1.00")); b.size = 3; diff --git ql/src/test/org/apache/hadoop/hive/ql/exec/vector/expressions/TestVectorExpressionWriters.java ql/src/test/org/apache/hadoop/hive/ql/exec/vector/expressions/TestVectorExpressionWriters.java index 02602f4..ccbe7b6 100644 --- ql/src/test/org/apache/hadoop/hive/ql/exec/vector/expressions/TestVectorExpressionWriters.java +++ ql/src/test/org/apache/hadoop/hive/ql/exec/vector/expressions/TestVectorExpressionWriters.java @@ -165,7 +165,7 @@ private void testWriterDecimal(DecimalTypeInfo type) throws HiveException { for (int i = 0; i < vectorSize; i++) { Writable w = (Writable) vew.writeValue(dcv, i); if (w != null) { - Writable expected = getWritableValue(type, dcv.vector[i].getHiveDecimal()); + Writable expected = getWritableValue(type, dcv.hiveDecimal(i)); Assert.assertEquals(expected, w); } else { Assert.assertTrue(dcv.isNull[i]); @@ -184,7 +184,7 @@ private void testSetterDecimal(DecimalTypeInfo type) throws HiveException { values[i] = null; // setValue() should be able to handle null input values[i] = vew.setValue(values[i], dcv, i); if (values[i] != null) { - Writable expected = getWritableValue(type, dcv.vector[i].getHiveDecimal()); + Writable expected = getWritableValue(type, dcv.hiveDecimal(i)); Assert.assertEquals(expected, values[i]); } else { Assert.assertTrue(dcv.isNull[i]); diff --git ql/src/test/org/apache/hadoop/hive/ql/exec/vector/expressions/TestVectorFilterExpressions.java ql/src/test/org/apache/hadoop/hive/ql/exec/vector/expressions/TestVectorFilterExpressions.java index 80f55dc..003c64e 100644 --- ql/src/test/org/apache/hadoop/hive/ql/exec/vector/expressions/TestVectorFilterExpressions.java +++ ql/src/test/org/apache/hadoop/hive/ql/exec/vector/expressions/TestVectorFilterExpressions.java @@ -1026,9 +1026,9 @@ private VectorizedRowBatch getVectorizedRowBatch1DecimalCol() { VectorizedRowBatch b = new VectorizedRowBatch(1); DecimalColumnVector v0; b.cols[0] = v0 = new DecimalColumnVector(18, 2); - v0.vector[0].set(HiveDecimal.create("1.20")); - v0.vector[1].set(HiveDecimal.create("-3.30")); - v0.vector[2].set(HiveDecimal.create("0")); + v0.set(0, HiveDecimal.create("1.20")); + v0.set(1, HiveDecimal.create("-3.30")); + v0.set(2, HiveDecimal.create("0")); b.size = 3; return b; @@ -1038,14 +1038,14 @@ private VectorizedRowBatch getVectorizedRowBatch2DecimalCol() { VectorizedRowBatch b = new VectorizedRowBatch(2); DecimalColumnVector v0, v1; b.cols[0] = v0 = new DecimalColumnVector(18, 2); - v0.vector[0].set(HiveDecimal.create("1.20")); - v0.vector[1].set(HiveDecimal.create("-3.30")); - v0.vector[2].set(HiveDecimal.create("0")); + v0.set(0, HiveDecimal.create("1.20")); + v0.set(1, HiveDecimal.create("-3.30")); + v0.set(2, HiveDecimal.create("0")); b.cols[1] = v1 = new DecimalColumnVector(18, 2); - v1.vector[0].set(HiveDecimal.create("-1.00")); - v1.vector[1].set(HiveDecimal.create("-3.30")); - v1.vector[2].set(HiveDecimal.create("10.00")); + v1.set(0, HiveDecimal.create("-1.00")); + v1.set(1, HiveDecimal.create("-3.30")); + v1.set(2, HiveDecimal.create("10.00")); b.size = 3; return b; diff --git ql/src/test/org/apache/hadoop/hive/ql/exec/vector/expressions/TestVectorTypeCasts.java ql/src/test/org/apache/hadoop/hive/ql/exec/vector/expressions/TestVectorTypeCasts.java index e7a044e..962f565 100644 --- ql/src/test/org/apache/hadoop/hive/ql/exec/vector/expressions/TestVectorTypeCasts.java +++ ql/src/test/org/apache/hadoop/hive/ql/exec/vector/expressions/TestVectorTypeCasts.java @@ -248,7 +248,7 @@ public void testCastDecimalToBoolean() { VectorizedRowBatch b = getBatchDecimalLong(); VectorExpression expr = new CastDecimalToBoolean(0, 1); DecimalColumnVector in = (DecimalColumnVector) b.cols[0]; - in.vector[1].set(HiveDecimal.create(0)); + in.set(1, HiveDecimal.create(0)); expr.evaluate(b); LongColumnVector r = (LongColumnVector) b.cols[1]; assertEquals(1, r.vector[0]); @@ -265,9 +265,9 @@ private VectorizedRowBatch getBatchDecimalLong() { b.size = 3; - dv.vector[0].set(HiveDecimal.create("1.1").setScale(scale)); - dv.vector[1].set(HiveDecimal.create("-2.2").setScale(scale)); - dv.vector[2].set(HiveDecimal.create("9999999999999999.00").setScale(scale)); + dv.set(0, HiveDecimal.create("1.1").setScale(scale)); + dv.set(1, HiveDecimal.create("-2.2").setScale(scale)); + dv.set(2, HiveDecimal.create("9999999999999999.00").setScale(scale)); return b; } @@ -325,9 +325,9 @@ private VectorizedRowBatch getBatchDecimalDouble() { b.size = 3; - dv.vector[0].set(HiveDecimal.create("1.1").setScale(scale)); - dv.vector[1].set(HiveDecimal.create("-2.2").setScale(scale)); - dv.vector[2].set(HiveDecimal.create("9999999999999999.00").setScale(scale)); + dv.set(0, HiveDecimal.create("1.1").setScale(scale)); + dv.set(1, HiveDecimal.create("-2.2").setScale(scale)); + dv.set(2, HiveDecimal.create("9999999999999999.00").setScale(scale)); return b; } @@ -366,9 +366,9 @@ private VectorizedRowBatch getBatchDecimalString() { b.size = 3; - dv.vector[0].set(HiveDecimal.create("1.1").setScale(scale)); - dv.vector[1].set(HiveDecimal.create("-2.2").setScale(scale)); - dv.vector[2].set(HiveDecimal.create("9999999999999999.00").setScale(scale)); + dv.set(0, HiveDecimal.create("1.1").setScale(scale)); + dv.set(1, HiveDecimal.create("-2.2").setScale(scale)); + dv.set(2, HiveDecimal.create("9999999999999999.00").setScale(scale)); return b; } @@ -399,9 +399,9 @@ private VectorizedRowBatch getBatchDecimalLong2() { b.size = 3; - dv.vector[0].set(HiveDecimal.create("1.111111111").setScale(scale)); - dv.vector[1].set(HiveDecimal.create("-2.222222222").setScale(scale)); - dv.vector[2].set(HiveDecimal.create("31536000.999999999").setScale(scale)); + dv.set(0, HiveDecimal.create("1.111111111").setScale(scale)); + dv.set(1, HiveDecimal.create("-2.222222222").setScale(scale)); + dv.set(2, HiveDecimal.create("31536000.999999999").setScale(scale)); return b; } @@ -434,9 +434,9 @@ public void testCastLongToDecimal() { VectorExpression expr = new CastLongToDecimal(0, 1); expr.evaluate(b); DecimalColumnVector r = (DecimalColumnVector) b.cols[1]; - assertTrue(r.vector[0].getHiveDecimal().equals(HiveDecimal.create("0"))); - assertTrue(r.vector[1].getHiveDecimal().equals(HiveDecimal.create("-1"))); - assertTrue(r.vector[2].getHiveDecimal().equals(HiveDecimal.create("99999999999999"))); + assertTrue(r.hiveDecimal(0).equals(HiveDecimal.create("0"))); + assertTrue(r.hiveDecimal(1).equals(HiveDecimal.create("-1"))); + assertTrue(r.hiveDecimal(2).equals(HiveDecimal.create("99999999999999"))); } private VectorizedRowBatch getBatchLongDecimal() { @@ -499,15 +499,15 @@ public void testCastDoubleToDecimal() { DecimalColumnVector r = (DecimalColumnVector) b.cols[1]; HiveDecimal hd0 = HiveDecimal.create("0.0"); - if (!hd0.equals(r.vector[0].getHiveDecimal())) { + if (!hd0.equals(r.hiveDecimal(0))) { assertTrue(false); } HiveDecimal hd1 = HiveDecimal.create("-1.0"); - if (!hd1.equals(r.vector[1].getHiveDecimal())) { + if (!hd1.equals(r.hiveDecimal(1))) { assertTrue(false); } HiveDecimal hd2 = HiveDecimal.create("99999999999999"); - if (!hd2.equals(r.vector[2].getHiveDecimal())) { + if (!hd2.equals(r.hiveDecimal(2))) { assertTrue(false); } } @@ -534,9 +534,9 @@ public void testCastStringToDecimal() { VectorExpression expr = new CastStringToDecimal(0, 1); expr.evaluate(b); DecimalColumnVector r = (DecimalColumnVector) b.cols[1]; - assertTrue(r.vector[0].getHiveDecimal().equals(HiveDecimal.create("1.10"))); - assertTrue(r.vector[1].getHiveDecimal().equals(HiveDecimal.create("-2.20"))); - assertTrue(r.vector[2].getHiveDecimal().equals(HiveDecimal.create("99999999999999.0"))); + assertTrue(r.hiveDecimal(0).equals(HiveDecimal.create("1.10"))); + assertTrue(r.hiveDecimal(1).equals(HiveDecimal.create("-2.20"))); + assertTrue(r.hiveDecimal(2).equals(HiveDecimal.create("99999999999999.0"))); } private VectorizedRowBatch getBatchStringDecimal() { @@ -570,7 +570,7 @@ public void testCastTimestampToDecimal() { expr.evaluate(b); DecimalColumnVector r = (DecimalColumnVector) b.cols[1]; for (int i = 0; i < hiveDecimalValues.length; i++) { - HiveDecimal hiveDecimal = r.vector[i].getHiveDecimal(); + HiveDecimal hiveDecimal = r.hiveDecimal(i); HiveDecimal expectedHiveDecimal = hiveDecimalValues[i]; if (!hiveDecimal.equals(expectedHiveDecimal)) { assertTrue(false); @@ -583,7 +583,7 @@ public void testCastTimestampToDecimal() { expr.evaluate(b); r = (DecimalColumnVector) b.cols[1]; for (int i = 0; i < hiveDecimalValues.length; i++) { - HiveDecimal hiveDecimal = r.vector[i].getHiveDecimal(); + HiveDecimal hiveDecimal = r.hiveDecimal(i); HiveDecimal expectedHiveDecimal = hiveDecimalValues[i]; if (HiveDecimal.enforcePrecisionScale(expectedHiveDecimal, 5, 2) == null) { assertTrue(r.isNull[i]); @@ -619,11 +619,11 @@ private VectorizedRowBatch getBatchDecimalDecimal() { b.cols[0] = v0 = new DecimalColumnVector(18, 4); b.cols[1] = v1 = new DecimalColumnVector(5, 2); - v0.vector[0].set(HiveDecimal.create("10.0001")); - v0.vector[1].set(HiveDecimal.create("-9999999.9999")); + v0.set(0, HiveDecimal.create("10.0001")); + v0.set(1, HiveDecimal.create("-9999999.9999")); - v1.vector[0].set(HiveDecimal.create("100.01")); - v1.vector[1].set(HiveDecimal.create("-200.02")); + v1.set(0, HiveDecimal.create("100.01")); + v1.set(1, HiveDecimal.create("-200.02")); b.size = 2; return b; diff --git ql/src/test/org/apache/hadoop/hive/ql/exec/vector/util/VectorizedRowGroupGenUtil.java ql/src/test/org/apache/hadoop/hive/ql/exec/vector/util/VectorizedRowGroupGenUtil.java index 84717b1..82d76d6 100644 --- ql/src/test/org/apache/hadoop/hive/ql/exec/vector/util/VectorizedRowGroupGenUtil.java +++ ql/src/test/org/apache/hadoop/hive/ql/exec/vector/util/VectorizedRowGroupGenUtil.java @@ -159,17 +159,18 @@ public static DecimalColumnVector generateDecimalColumnVector(DecimalTypeInfo ty for(int i = 0; i < size; i++) { if(nulls && (repeating || i % nullFrequency == 0)) { dcv.isNull[i] = true; - dcv.vector[i] = null;//Decimal128.ONE; + dcv.noNulls = false; + dcv.setNullDataValue(i); }else { dcv.isNull[i] = false; if (repeating) { - dcv.vector[i].set(repeatingValue); + dcv.set(i, repeatingValue); } else { - dcv.vector[i].set(HiveDecimal.create(((Double) rand.nextDouble()).toString()).setScale((short) typeInfo.scale())); + dcv.set(i, HiveDecimal.create(((Double) rand.nextDouble()).toString()).setScale((short) typeInfo.scale())); } - if(dcv.vector[i].getHiveDecimal().doubleValue() == 0) { + if(dcv.hiveDecimal(i).doubleValue() == 0) { i--; } } diff --git ql/src/test/org/apache/hadoop/hive/ql/io/orc/TestInputOutputFormat.java ql/src/test/org/apache/hadoop/hive/ql/io/orc/TestInputOutputFormat.java index d6b48a3..c97c26a 100644 --- ql/src/test/org/apache/hadoop/hive/ql/io/orc/TestInputOutputFormat.java +++ ql/src/test/org/apache/hadoop/hive/ql/io/orc/TestInputOutputFormat.java @@ -2272,7 +2272,7 @@ public void testVectorizationWithAcid() throws Exception { assertEquals("checking string " + i, new Text(Long.toHexString(i)), strValue); assertEquals("checking decimal " + i, HiveDecimal.create(i), - decimalColumn.vector[i].getHiveDecimal()); + decimalColumn.hiveDecimal(i)); assertEquals("checking date " + i, i, dateColumn.vector[i]); long millis = (long) i * MILLIS_IN_DAY; millis -= LOCAL_TIMEZONE.getOffset(millis); diff --git ql/src/test/org/apache/hadoop/hive/ql/io/orc/TestVectorizedORCReader.java ql/src/test/org/apache/hadoop/hive/ql/io/orc/TestVectorizedORCReader.java index a52b3ef..0e228dc 100644 --- ql/src/test/org/apache/hadoop/hive/ql/io/orc/TestVectorizedORCReader.java +++ ql/src/test/org/apache/hadoop/hive/ql/io/orc/TestVectorizedORCReader.java @@ -190,7 +190,7 @@ private void checkVectorizedReader() throws Exception { } else if (a instanceof HiveDecimalWritable) { // Decimals are stored as BigInteger, so convert and compare HiveDecimalWritable dec = (HiveDecimalWritable) a; - HiveDecimalWritable b = ((DecimalColumnVector) cv).vector[i]; + HiveDecimalWritable b = ((DecimalColumnVector) cv).get(i); Assert.assertEquals(dec, b); } else if (a instanceof DoubleWritable) { diff --git storage-api/src/java/org/apache/hadoop/hive/common/type/HiveDecimal.java storage-api/src/java/org/apache/hadoop/hive/common/type/HiveDecimal.java index 674400c..318f790 100644 --- storage-api/src/java/org/apache/hadoop/hive/common/type/HiveDecimal.java +++ storage-api/src/java/org/apache/hadoop/hive/common/type/HiveDecimal.java @@ -30,6 +30,7 @@ public class HiveDecimal implements Comparable { public static final int MAX_PRECISION = 38; public static final int MAX_SCALE = 38; + public static final int MAX_HALF_PRECISION = 18; /** * Default precision/scale when user doesn't specify in the column metadata, such as diff --git storage-api/src/java/org/apache/hadoop/hive/ql/exec/vector/DecimalColumnVector.java storage-api/src/java/org/apache/hadoop/hive/ql/exec/vector/DecimalColumnVector.java index 2488631..d31d013 100644 --- storage-api/src/java/org/apache/hadoop/hive/ql/exec/vector/DecimalColumnVector.java +++ storage-api/src/java/org/apache/hadoop/hive/ql/exec/vector/DecimalColumnVector.java @@ -6,9 +6,9 @@ * 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 - * + *

+ * 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. @@ -17,52 +17,232 @@ */ package org.apache.hadoop.hive.ql.exec.vector; -import java.math.BigInteger; -import org.apache.hadoop.hive.serde2.io.HiveDecimalWritable; import org.apache.hadoop.hive.common.type.HiveDecimal; +import org.apache.hadoop.hive.ql.exec.vector.decimal.ScaledVector; +import org.apache.hadoop.hive.ql.exec.vector.decimal.Unscaled128Value; +import org.apache.hadoop.hive.serde2.io.HiveDecimalWritable; + +import java.math.BigInteger; +import java.nio.ByteBuffer; +import java.util.Arrays; +/** + * This class represents a nullable decimal column vector. + * This class will use two 64-bit long values to hold the biggest possible value. + * + * The vector field is not public by design, while providing high-performance + * instance methods for the inner loop of query execution. + * + * This class handles representation changes. + */ public class DecimalColumnVector extends ColumnVector { + ScaledVector scaledVector; + int length; - /** - * A vector of HiveDecimalWritable objects. - * - * For high performance and easy access to this low-level structure, - * the fields are public by design (as they are in other ColumnVector - * types). - */ - public HiveDecimalWritable[] vector; - public short scale; - public short precision; + public DecimalColumnVector(int len, int precision, int scale) { + super(len); + scaledVector = new ScaledVector(len, precision, scale, this); + length = len; + } public DecimalColumnVector(int precision, int scale) { this(VectorizedRowBatch.DEFAULT_SIZE, precision, scale); } - public DecimalColumnVector(int size, int precision, int scale) { - super(size); - this.precision = (short) precision; - this.scale = (short) scale; - vector = new HiveDecimalWritable[size]; - for (int i = 0; i < size; i++) { - vector[i] = new HiveDecimalWritable(HiveDecimal.ZERO); + + // Precision and scale + public int precision() { + return scaledVector.precision; + } + + public int scale() { + return scaledVector.scale; + } + + public void setPrecision(int precision) { + scaledVector.precision = precision; + } + + public void setScale(int scale) { + scaledVector.scale = scale; + } + + + // Getters and setters + public HiveDecimal hiveDecimal(int index) { + if (!noNulls && isNull[index]) { + return HiveDecimal.create(BigInteger.ONE, scale()); + } else { + return HiveDecimal.create(new BigInteger(bytes(index)), scale()); + } + } + + public HiveDecimalWritable get(int index) { + if (!noNulls && isNull[index]) { + return new HiveDecimalWritable(HiveDecimal.ZERO); + } else { + return new HiveDecimalWritable(hiveDecimal(index)); + } + } + + private byte[] bytes(int index) { + long upper = scaledVector.getUpper()[index]; + long lower = scaledVector.getLower()[index]; + ByteBuffer buffer = ByteBuffer.allocate(Long.SIZE / Byte.SIZE * 2); + buffer.putLong(upper); + buffer.putLong(lower); + return buffer.array(); + } + + public void set(int index, HiveDecimal value) { + value = HiveDecimal.enforcePrecisionScale(value, precision(), scale()); + if (value == null) { + isNull[index] = true; + noNulls = false; + } else { + BigInteger bigInteger = value.unscaledValue(); + + // Sign + boolean negated = false; + if (bigInteger.compareTo(BigInteger.ZERO) < 0) { + negated = true; + bigInteger = bigInteger.negate(); + } + + // Scale + if (value.scale() != scale()) { + int scaleDiff = scale() - value.scale(); + if (scaleDiff > 0) { + bigInteger = bigInteger.multiply(BigInteger.TEN.pow(scaleDiff)); + } else { + BigInteger pow = BigInteger.TEN.pow(-scaleDiff); + BigInteger[] divideAndRemainder = bigInteger.divideAndRemainder(pow); + bigInteger = divideAndRemainder[0]; + if (divideAndRemainder[1].compareTo(pow.divide(BigInteger.valueOf(2))) >= 0) { + bigInteger = bigInteger.add(BigInteger.ONE); + } + } + } + + // Precision limit + if (bigInteger.compareTo(BigInteger.TEN.pow(precision())) > 0) { + isNull[index] = true; + noNulls = false; + return; + } + + byte[] bytes = bigInteger.toByteArray(); + long upper = 0; + long lower = 0; + if (bytes.length <= 8) { + int min = Math.min(8, bytes.length); + for (int i = 0; i < min; i++) { + lower |= (0xFFL & bytes[i]) << ((min - 1 - i) * 8); + } + } else { + int min = Math.min(8, bytes.length - 8); + for (int i = 0; i < min; i++) { + upper |= (0xFFL & bytes[i]) << ((min - 1 - i) * 8); + } + for (int i = 0; i < 8; i++) { + lower |= (0xFFL & bytes[i + min]) << ((7 - i) * 8); + } + } + + if (negated) { + Unscaled128Value unscaled128Value = new Unscaled128Value(upper, lower); + Unscaled128Value negatedValue = new Unscaled128Value(); + negatedValue.negate(unscaled128Value); + scaledVector.getUpper()[index] = negatedValue.getUpper(); + scaledVector.getLower()[index] = negatedValue.getLower(); + } else { + scaledVector.getUpper()[index] = upper; + scaledVector.getLower()[index] = lower; + } + } + } + + public void set(int index, HiveDecimalWritable writable) { + if (writable == null) { + isNull[index] = true; + noNulls = false; + } else { + set(index, writable.getHiveDecimal()); } } - // Fill the all the vector entries with provided value - public void fill(HiveDecimal value) { - noNulls = true; - isRepeating = true; - if (vector[0] == null) { - vector[0] = new HiveDecimalWritable(value); + public void fill(VectorizedRowBatch batch, HiveDecimal element) { + fill(element, batch.size); + } + + public void fill(HiveDecimal element, int size) { + element = HiveDecimal.enforcePrecisionScale(element, precision(), scale()); + if (element != null) { + set(0, element); + long[] upperArray = scaledVector.getUpper(); + long[] lowerArray = scaledVector.getLower(); + long upperValue = upperArray[0]; + long lowerValue = lowerArray[0]; + for (int i = 1; i < size; i++) { + upperArray[i] = upperValue; + lowerArray[i] = lowerValue; + } + noNulls = true; + Arrays.fill(isNull, false); } else { - vector[0].set(value); + noNulls = false; + Arrays.fill(isNull, true); + } + } + + public void setNullDataValue(int index) { + scaledVector.getUpper()[index] = 0; + scaledVector.getLower()[index] = 1; + } + + public int getLength() { + return length; + } + + public boolean equals(int indexA, int indexB) { + return (scaledVector.getUpper()[indexA] == scaledVector.getUpper()[indexB]) + && (scaledVector.getLower()[indexA] == scaledVector.getLower()[indexB]); + } + + + // ColumnVector overrides + @Override + public void ensureSize(int size, boolean presesrveData) { + super.ensureSize(size, presesrveData); + + if (size > this.length) { + this.length = size; + ScaledVector oldScaledVector = scaledVector; + scaledVector = new ScaledVector(size); + if (presesrveData) { + scaledVector.set(oldScaledVector); + } } } @Override public void flatten(boolean selectedInUse, int[] sel, int size) { - // TODO Auto-generated method stub + flattenPush(); + if (isRepeating) { + isRepeating = false; + HiveDecimal repeatVal = hiveDecimal(0); + if (selectedInUse) { + for (int j = 0; j < size; j++) { + int i = sel[j]; + set(i, repeatVal); + } + } else { + fill(repeatVal, size); + } + flattenRepeatingNulls(selectedInUse, sel, size); + } + flattenNoNulls(selectedInUse, sel, size); } @Override @@ -71,15 +251,13 @@ public void setElement(int outElementNum, int inputElementNum, ColumnVector inpu inputElementNum = 0; } if (inputVector.noNulls || !inputVector.isNull[inputElementNum]) { - HiveDecimal hiveDec = - ((DecimalColumnVector) inputVector).vector[inputElementNum] - .getHiveDecimal(precision, scale); + HiveDecimal hiveDec = HiveDecimal.enforcePrecisionScale( + ((DecimalColumnVector) inputVector).hiveDecimal(inputElementNum), precision(), scale()); if (hiveDec == null) { isNull[outElementNum] = true; noNulls = false; } else { - isNull[outElementNum] = false; - vector[outElementNum].set(hiveDec); + set(outElementNum, hiveDec); } } else { isNull[outElementNum] = true; @@ -89,62 +267,110 @@ public void setElement(int outElementNum, int inputElementNum, ColumnVector inpu @Override public void stringifyValue(StringBuilder buffer, int row) { - if (isRepeating) { - row = 0; - } - if (noNulls || !isNull[row]) { - buffer.append(vector[row].toString()); - } else { - buffer.append("null"); - } + buffer.append(hiveDecimal(row).toString()); } - public void set(int elementNum, HiveDecimalWritable writeable) { - if (writeable == null) { - noNulls = false; - isNull[elementNum] = true; - } else { - HiveDecimal hiveDec = writeable.getHiveDecimal(precision, scale); - if (hiveDec == null) { - noNulls = false; - isNull[elementNum] = true; - } else { - vector[elementNum].set(hiveDec); - } - } + + // Arithmetic + public DecimalColumnVector set(VectorizedRowBatch batch, DecimalColumnVector input) { + scaledVector.set(batch, input.scaledVector); + return this; } - public void set(int elementNum, HiveDecimal hiveDec) { - HiveDecimal checkedDec = HiveDecimal.enforcePrecisionScale(hiveDec, precision, scale); - if (checkedDec == null) { - noNulls = false; - isNull[elementNum] = true; - } else { - vector[elementNum].set(checkedDec); - } + public DecimalColumnVector negate(VectorizedRowBatch batch, DecimalColumnVector input) { + scaledVector.negate(batch, input.scaledVector); + return this; + } + + public DecimalColumnVector add(VectorizedRowBatch batch, DecimalColumnVector left, DecimalColumnVector right) { + scaledVector.add(batch, left.scaledVector, right.scaledVector); + return this; + } + + public DecimalColumnVector subtract(VectorizedRowBatch batch, DecimalColumnVector left, DecimalColumnVector right) { + scaledVector.subtract(batch, left.scaledVector, right.scaledVector); + return this; + } + + public DecimalColumnVector multiply(VectorizedRowBatch batch, DecimalColumnVector left, DecimalColumnVector right) { + scaledVector.multiply(batch, left.scaledVector, right.scaledVector); + return this; + } + + public DecimalColumnVector divide(VectorizedRowBatch batch, DecimalColumnVector left, DecimalColumnVector right) { + scaledVector.divide(batch, left.scaledVector, right.scaledVector); + return this; + } + + public DecimalColumnVector modulo(VectorizedRowBatch batch, DecimalColumnVector left, DecimalColumnVector right) { + scaledVector.modulo(batch, left.scaledVector, right.scaledVector); + return this; } - public void setNullDataValue(int elementNum) { - // E.g. For scale 2 the minimum is "0.01" - HiveDecimal minimumNonZeroValue = HiveDecimal.create(BigInteger.ONE, scale); - vector[elementNum].set(minimumNonZeroValue); + public DecimalColumnVector scaleByPowerOfTen(VectorizedRowBatch batch, DecimalColumnVector input, int scale) { + scaledVector.scaleByPowerOfTen(batch, input.scaledVector, scale); + return this; } + public DecimalColumnVector pow(VectorizedRowBatch batch, DecimalColumnVector left, int right) { + scaledVector.pow(batch, left.scaledVector, right); + return this; + } + + public DecimalColumnVector abs(VectorizedRowBatch batch, DecimalColumnVector input) { + scaledVector.abs(batch, input.scaledVector); + return this; + } + + + // Object overrides @Override - public void ensureSize(int size, boolean preserveData) { - super.ensureSize(size, preserveData); - if (size <= vector.length) return; // We assume the existing vector is always valid. - HiveDecimalWritable[] oldArray = vector; - vector = new HiveDecimalWritable[size]; - int initPos = 0; - if (preserveData) { - // we copy all of the values to avoid creating more objects - // TODO: it might be cheaper to always preserve data or reset existing objects - initPos = oldArray.length; - System.arraycopy(oldArray, 0, vector, 0 , oldArray.length); + public boolean equals(Object obj) { + if (!(obj instanceof DecimalColumnVector)) { + return false; } - for (int i = initPos; i < vector.length; ++i) { - vector[i] = new HiveDecimalWritable(HiveDecimal.ZERO); + DecimalColumnVector that = (DecimalColumnVector) obj; + long[] thisUpper = this.scaledVector.getUpper(); + long[] thisLower = this.scaledVector.getLower(); + long[] thatUpper = that.scaledVector.getUpper(); + long[] thatLower = that.scaledVector.getLower(); + + if (!((this.precision() == that.precision()) && (this.scale() == that.scale()))) { + return false; } + if (scaledVector.is64Bit()) { + for (int i = 0; i < length; i++) { + boolean isNull = this.isNull[i]; + if (isNull != that.isNull[i]) { + return false; + } + if (!isNull) { + if (thisLower[i] != thatLower[i]) { + return false; + } + } + } + } else { + for (int i = 0; i < length; i++) { + boolean isNull = this.isNull[i]; + if (isNull != that.isNull[i]) { + return false; + } + if (!isNull) { + if (thisUpper[i] != thatUpper[i]) { + return false; + } + if (thisLower[i] != thatLower[i]) { + return false; + } + } + } + } + return true; + } + + @Override + public String toString() { + return scaledVector.toString(); } } diff --git storage-api/src/java/org/apache/hadoop/hive/ql/exec/vector/decimal/RoundingMode.java storage-api/src/java/org/apache/hadoop/hive/ql/exec/vector/decimal/RoundingMode.java new file mode 100644 index 0000000..7e6ab06 --- /dev/null +++ storage-api/src/java/org/apache/hadoop/hive/ql/exec/vector/decimal/RoundingMode.java @@ -0,0 +1,23 @@ +/** + * 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.hadoop.hive.ql.exec.vector.decimal; + +enum RoundingMode { + FLOOR, HALF_UP, CEILING, DOWN, HALF_EVEN +} diff --git storage-api/src/java/org/apache/hadoop/hive/ql/exec/vector/decimal/ScaledVector.java storage-api/src/java/org/apache/hadoop/hive/ql/exec/vector/decimal/ScaledVector.java new file mode 100644 index 0000000..ddd7469 --- /dev/null +++ storage-api/src/java/org/apache/hadoop/hive/ql/exec/vector/decimal/ScaledVector.java @@ -0,0 +1,476 @@ +/** + * 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.hadoop.hive.ql.exec.vector.decimal; + +import org.apache.hadoop.hive.common.type.HiveDecimal; +import org.apache.hadoop.hive.ql.exec.vector.ColumnVector; +import org.apache.hadoop.hive.ql.exec.vector.DecimalColumnVector; +import org.apache.hadoop.hive.ql.exec.vector.VectorizedRowBatch; + +import java.util.Arrays; + +/** + * This class represents an internal scaled vector. It handles precision and scale. + * It delegates actual arithmetic operations to Unscaled128Vector or Unscaled64Vector + * depending on scale. + */ +public class ScaledVector { + public int precision; + public int scale; + + int size; + Unscaled128Vector unscaledVector; + ColumnVector columnVector; + + // Internal operation classes + Add add; + Divide divide; + Modulo modulo; + Pow pow; + Abs abs; + Multiply multiply; + + public ScaledVector(int size) { + this(size, 0, 0, null); + } + + public ScaledVector(int len, int precision, int scale, DecimalColumnVector columnVector) { + size = len; + unscaledVector = new Unscaled128Vector(size); + this.precision = precision; + this.scale = scale; + this.columnVector = columnVector; + } + + public boolean is64Bit() { + return this.precision <= HiveDecimal.MAX_HALF_PRECISION; + } + + + // Public arithmetic + public ScaledVector scaleByPowerOfTen(VectorizedRowBatch batch, ScaledVector input, int scale) { + if (scale > 0) { + return this.multiplyByPowerOfTen(batch, input, scale); + } else if (scale < 0) { + return this.divideByPowerOfTen(batch, input, -scale); + } + return this.set(batch, input); + } + + public ScaledVector negate(VectorizedRowBatch batch, ScaledVector input) { + this.precision = input.precision; + this.scale = input.scale; + + if (input.is64Bit()) { + unscaledVector.lower.negate(batch, input.unscaledVector.lower); + unscaledVector.propagateSign(batch); + } else { + unscaledVector.negate(batch, input.unscaledVector); + } + return this; + } + + public ScaledVector set(VectorizedRowBatch batch, ScaledVector input) { + precision = input.precision; + scale = input.scale; + + unscaledVector.set(batch, input.unscaledVector); + + return this; + } + + public ScaledVector set(ScaledVector input) { + precision = input.precision; + scale = input.scale; + + unscaledVector.set(input.unscaledVector); + + return this; + } + + public ScaledVector add(VectorizedRowBatch batch, ScaledVector left, ScaledVector right) { + getAdd().add(batch, left, right); + return this; + } + + public ScaledVector subtract(VectorizedRowBatch batch, ScaledVector left, ScaledVector right) { + getAdd().subtract(batch, left, right); + return this; + } + + public ScaledVector multiply(VectorizedRowBatch batch, ScaledVector left, ScaledVector right) { + getMultiply().multiply(batch, left, right); + return this; + } + + public ScaledVector modulo(VectorizedRowBatch batch, ScaledVector left, ScaledVector right) { + getModulo().modulo(batch, left, right); + return this; + } + + public ScaledVector divide(VectorizedRowBatch batch, ScaledVector left, ScaledVector right) { + getDivide().divide(batch, left, right); + return this; + } + + public ScaledVector pow(VectorizedRowBatch batch, ScaledVector left, int right) { + getPow().pow(batch, left, right); + return this; + } + + public ScaledVector abs(VectorizedRowBatch batch, ScaledVector input) { + getAbs().abs(batch, input); + return this; + } + + public ScaledVector rescale(VectorizedRowBatch batch, ScaledVector input, int scale) { + return rescale(batch, input, scale, RoundingMode.HALF_UP); + } + + // Internal scale + ScaledVector multiplyByPowerOfTen(VectorizedRowBatch batch, ScaledVector input, int scale) { + this.precision = input.precision + scale; + this.scale = input.scale + scale; + + if (this.is64Bit()) { + unscaledVector.lower.multiplyByPowerOfTen(batch, input.unscaledVector.lower, scale); + unscaledVector.propagateSign(batch); + } else { + unscaledVector.multiplyByPowerOfTen(batch, input.unscaledVector, scale); + } + return this; + } + + ScaledVector divideByPowerOfTen(VectorizedRowBatch batch, ScaledVector input, int scale) { + this.precision = input.precision - scale; + this.scale = input.scale - scale; + + if (input.is64Bit()) { + unscaledVector.lower.divideByPowerOfTen(batch, input.unscaledVector.lower, scale, RoundingMode.HALF_UP); + unscaledVector.propagateSign(batch); + } else { + unscaledVector.divideByPowerOfTen(batch, input.unscaledVector, scale, RoundingMode.HALF_UP); + } + return this; + } + + ScaledVector rescale(VectorizedRowBatch batch, ScaledVector input, int scale, RoundingMode roundingMode) { + int scaleDiff = scale - input.scale; + + this.scale = input.scale + scaleDiff; + this.precision = input.precision + scaleDiff; + + if (scaleDiff > 0) { + if (this.is64Bit()) { + unscaledVector.lower.multiplyByPowerOfTen(batch, input.unscaledVector.lower, scaleDiff); + unscaledVector.propagateSign(batch); + } else { + unscaledVector.multiplyByPowerOfTen(batch, input.unscaledVector, scaleDiff); + } + } else if (scaleDiff < 0) { + if (this.is64Bit()) { + unscaledVector.lower.divideByPowerOfTen(batch, input.unscaledVector.lower, -scaleDiff, roundingMode); + unscaledVector.propagateSign(batch); + } else { + unscaledVector.divideByPowerOfTen(batch, input.unscaledVector, -scaleDiff, roundingMode); + } + } else { + unscaledVector.set(batch, input.unscaledVector); + } + return this; + } + + + // Vector + public long[] getUpper() { + return unscaledVector.upper.array; + } + + public long[] getLower() { + return unscaledVector.lower.array; + } + + // Classes + class Pow { + ScaledVector copy = new ScaledVector(size); + + ScaledVector pow(VectorizedRowBatch batch, ScaledVector left, int right) { + ScaledVector output = ScaledVector.this; + output.set(batch, left); + for (int i = 1; i < right; i++) { + copy.set(batch, output); + output.multiply(batch, left, copy); + } + unscaledVector.lower.makeExceedingNull(batch, precision, columnVector); + + return output; + } + } + + class Add { + ScaledVector leftAdjust = new ScaledVector(size); + ScaledVector rightAdjust = new ScaledVector(size); + + ScaledVector subtract(VectorizedRowBatch batch, ScaledVector left, ScaledVector right) { + if (!this.prepareAddOrSubtract(batch, left, right)) { + return ScaledVector.this; + } + + if (is64Bit()) { + unscaledVector.lower.subtract(batch, leftAdjust.unscaledVector.lower, rightAdjust.unscaledVector.lower); + unscaledVector.propagateSign(batch); + + unscaledVector.lower.makeExceedingNull(batch, precision, columnVector); + } else { + unscaledVector.subtract(batch, leftAdjust.unscaledVector, rightAdjust.unscaledVector); + + unscaledVector.makeExceedingNull(batch, precision, columnVector); + } + return ScaledVector.this; + } + + ScaledVector add(VectorizedRowBatch batch, ScaledVector left, ScaledVector right) { + if (!this.prepareAddOrSubtract(batch, left, right)) { + return ScaledVector.this; + } + + if (is64Bit()) { + unscaledVector.lower.add(batch, leftAdjust.unscaledVector.lower, rightAdjust.unscaledVector.lower); + unscaledVector.propagateSign(batch); + + unscaledVector.lower.makeExceedingNull(batch, precision, columnVector); + } else { + unscaledVector.add(batch, leftAdjust.unscaledVector, rightAdjust.unscaledVector); + + unscaledVector.makeExceedingNull(batch, precision, columnVector); + } + return ScaledVector.this; + } + + boolean prepareAddOrSubtract(VectorizedRowBatch batch, ScaledVector left, ScaledVector right) { + // Prepare values + final int leftInteger = left.precision - left.scale; + final int rightInteger = right.precision - right.scale; + final int actualResultInteger = Math.max(leftInteger, rightInteger) + 1; + final int preferredResultScale = Math.max(left.scale, right.scale); + final int preferredResultPrecision = actualResultInteger + preferredResultScale; + int actualResultScale = preferredResultScale; + int actualResultPrecision = preferredResultPrecision; + + // If the result is too large, try to rescale inputs + if (preferredResultPrecision > HiveDecimal.MAX_PRECISION) { + + // If it's adjustable, rescale inputs + if (actualResultInteger <= HiveDecimal.MAX_PRECISION) { + actualResultPrecision = HiveDecimal.MAX_PRECISION; + actualResultScale = actualResultPrecision - actualResultInteger; + } + + // If it's not adjustable, fill nulls + else { + columnVector.noNulls = false; + Arrays.fill(columnVector.isNull, true); + return false; + } + } + + // Rescale + leftAdjust.rescale(batch, left, actualResultScale); + rightAdjust.rescale(batch, right, actualResultScale); + + scale = actualResultScale; + precision = actualResultPrecision; + return true; + } + } + + class Multiply { + ScaledVector leftAdjust = new ScaledVector(size); + ScaledVector rightAdjust = new ScaledVector(size); + + ScaledVector multiply(VectorizedRowBatch batch, ScaledVector left, ScaledVector right) { + ScaledVector output = ScaledVector.this; + + int preferredScale = left.scale + right.scale; + if (preferredScale == output.scale) { + leftAdjust.set(batch, left); + rightAdjust.set(batch, right); + } else { + int scaleDiff = preferredScale - output.scale; + int leftScale = left.scale - (scaleDiff / 2); + int rightScale = scaleDiff - leftScale; + + leftAdjust.rescale(batch, left, leftScale); + rightAdjust.rescale(batch, right, rightScale); + } + + // Prepare values + if (output.is64Bit()) { + output.unscaledVector.lower.multiply(batch, leftAdjust.unscaledVector.lower, rightAdjust.unscaledVector.lower); + output.unscaledVector.propagateSign(batch); + + unscaledVector.lower.makeExceedingNull(batch, precision, columnVector); + } else { + output.unscaledVector.multiply(batch, leftAdjust.unscaledVector, rightAdjust.unscaledVector, columnVector); + + unscaledVector.makeExceedingNull(batch, precision, columnVector); + } + return output; + } + } + + class Modulo { + ScaledVector leftAdjust = new ScaledVector(size); + ScaledVector rightAdjust = new ScaledVector(size); + + ScaledVector modulo(VectorizedRowBatch batch, ScaledVector left, ScaledVector right) { + // Precision and scale + leftAdjust.rescale(batch, left, scale); + rightAdjust.rescale(batch, right, scale); + + // Remainder + if (leftAdjust.is64Bit() && rightAdjust.is64Bit()) { + unscaledVector.lower.moduloChecked( + batch, leftAdjust.unscaledVector.lower, rightAdjust.unscaledVector.lower, + columnVector); + unscaledVector.propagateSign(batch); + + unscaledVector.lower.makeExceedingNull(batch, precision, columnVector); + } else { + unscaledVector.moduloChecked( + batch, leftAdjust.unscaledVector, rightAdjust.unscaledVector, + columnVector, rightAdjust.precision); + + unscaledVector.makeExceedingNull(batch, precision, columnVector); + } + return ScaledVector.this; + } + } + + class Divide { + ScaledVector leftAdjusted = new ScaledVector(size); + ScaledVector resultX10 = new ScaledVector(size); + + ScaledVector divide(VectorizedRowBatch batch, ScaledVector left, ScaledVector right) { + // Prepare values + leftAdjusted.rescale(batch, left, right.scale + 1 + scale); + + // Divide + if (leftAdjusted.is64Bit()) { + resultX10.unscaledVector.lower.divideChecked( + batch, leftAdjusted.unscaledVector.lower, right.unscaledVector.lower, + columnVector); + resultX10.unscaledVector.propagateSign(batch); + + unscaledVector.lower.divideByPowerOfTen(batch, resultX10.unscaledVector.lower, 1, RoundingMode.HALF_UP); + unscaledVector.propagateSign(batch); + + unscaledVector.lower.makeExceedingNull(batch, precision, columnVector); + } else { + resultX10.unscaledVector.divideChecked( + batch, leftAdjusted.unscaledVector, right.unscaledVector, + columnVector, right.precision); + + unscaledVector.divideByPowerOfTen(batch, resultX10.unscaledVector, 1, RoundingMode.HALF_UP); + + unscaledVector.makeExceedingNull(batch, precision, columnVector); + } + + return ScaledVector.this; + } + } + + class Abs { + Unscaled128Vector copied = new Unscaled128Vector(size); + + ScaledVector abs(VectorizedRowBatch batch, ScaledVector input) { + precision = input.precision; + scale = input.scale; + if (is64Bit()) { + unscaledVector.lower.unsignedShiftRight(batch, input.unscaledVector.lower, 63); + unscaledVector.lower.sign(batch, input.unscaledVector.lower, unscaledVector.lower); + unscaledVector.propagateSign(batch); + + unscaledVector.lower.makeExceedingNull(batch, precision, columnVector); + } else { + unscaledVector.unsignedShiftRight(batch, input.unscaledVector, 127); + unscaledVector.sign(batch, input.unscaledVector, copied.set(batch, unscaledVector)); + + unscaledVector.makeExceedingNull(batch, precision, columnVector); + } + return ScaledVector.this; + } + } + + Add getAdd() { + if (add == null) { + add = new Add(); + } + return add; + } + + Divide getDivide() { + if (divide == null) { + divide = new Divide(); + } + return divide; + } + + Modulo getModulo() { + if (modulo == null) { + modulo = new Modulo(); + } + return modulo; + } + + Abs getAbs() { + if (abs == null) { + abs = new Abs(); + } + return abs; + } + + Pow getPow() { + if (pow == null) { + pow = new Pow(); + } + return pow; + } + + Multiply getMultiply() { + if (multiply == null) { + multiply = new Multiply(); + } + return multiply; + } + + + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof ScaledVector)) { + return false; + } + ScaledVector that = (ScaledVector) obj; + return (this.precision == that.precision && this.scale == that.scale && + this.unscaledVector.equals(that.unscaledVector)); + } +} diff --git storage-api/src/java/org/apache/hadoop/hive/ql/exec/vector/decimal/Unscaled128Value.java storage-api/src/java/org/apache/hadoop/hive/ql/exec/vector/decimal/Unscaled128Value.java new file mode 100644 index 0000000..34fa18e --- /dev/null +++ storage-api/src/java/org/apache/hadoop/hive/ql/exec/vector/decimal/Unscaled128Value.java @@ -0,0 +1,87 @@ +/** + * 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.hadoop.hive.ql.exec.vector.decimal; + +import org.apache.hadoop.hive.ql.exec.vector.VectorizedRowBatch; + +public class Unscaled128Value { + private Unscaled128Vector vector = new Unscaled128Vector(1); + private final static VectorizedRowBatch BATCH = new VectorizedRowBatch(0, 1); + + public Unscaled128Value(long upper, long lower) { + set(upper, lower); + } + + public Unscaled128Value() { + } + + void set(long upper, long lower) { + setUpper(upper); + setLower(lower); + } + + void setUpper(long upper) { + vector.upper.array[0] = upper; + } + + void setLower(long lower) { + vector.lower.array[0] = lower; + } + + public long getUpper() { + return vector.upper.array[0]; + } + + public long getLower() { + return vector.lower.array[0]; + } + + int compareTo(Unscaled128Value o) { + Unscaled128Value compare = new Unscaled128Value(); + compare.subtract(this, o); + if (compare.getUpper() == 0 && compare.getLower() == 0) { + return 0; + } + if (compare.getUpper() >= 0) { + return 1; + } else { + return -1; + } + } + + public Unscaled128Value negate(Unscaled128Value input) { + this.vector.negate(BATCH, input.vector); + return this; + } + + Unscaled128Value subtract(Unscaled128Value left, Unscaled128Value right) { + this.vector.subtract(BATCH, left.vector, right.vector); + return this; + } + + Unscaled128Value multiplyByPowerOfTen(Unscaled128Value left, int right) { + this.vector.multiplyByPowerOfTen(BATCH, left.vector, right); + return this; + } + + @Override + public String toString() { + return "(" + vector.upper.array[0] + ", " + vector.lower.array[0] + ")"; + } +} diff --git storage-api/src/java/org/apache/hadoop/hive/ql/exec/vector/decimal/Unscaled128Vector.java storage-api/src/java/org/apache/hadoop/hive/ql/exec/vector/decimal/Unscaled128Vector.java new file mode 100644 index 0000000..0b2795c --- /dev/null +++ storage-api/src/java/org/apache/hadoop/hive/ql/exec/vector/decimal/Unscaled128Vector.java @@ -0,0 +1,1032 @@ +/** + * 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.hadoop.hive.ql.exec.vector.decimal; + +import org.apache.hadoop.hive.common.type.HiveDecimal; +import org.apache.hadoop.hive.ql.exec.vector.ColumnVector; +import org.apache.hadoop.hive.ql.exec.vector.VectorizedRowBatch; + +/** + * This class provides high-performance 128-bit arithmetic operations. + */ +class Unscaled128Vector { + Unscaled64Vector upper; + Unscaled64Vector lower; + + int size; + Negate negate; + Divide divide; + Multiply multiply; + Sign sign; + + Unscaled128Vector(int size) { + this.size = size; + upper = new Unscaled64Vector(size); + lower = new Unscaled64Vector(size); + } + + Unscaled128Vector(int size, Unscaled64Vector lower, Unscaled64Vector upper) { + this.size = size; + this.lower = lower; + this.upper = upper; + } + + Unscaled128Vector propagateSign(VectorizedRowBatch batch) { + upper.signedShiftRight(batch, lower, 63); + return this; + } + + Unscaled128Vector signedShiftRight(VectorizedRowBatch batch, Unscaled128Vector left, int right) { + long[] leftUpper = left.upper.array; + long[] leftLower = left.lower.array; + long[] outputLower = this.lower.array; + + if (right == 0) { + this.set(batch, left); + } else if (right == 64) { + upper.fill(batch, 0); + lower.set(batch, left.upper); + } else if (right > 64) { + upper.fill(batch, 0); + lower.signedShiftRight(batch, left.upper, right - 64); + } else { // right < 64 + upper.signedShiftRight(batch, left.upper, right); + if (batch.selectedInUse) { + for (int j = 0; j < batch.size; j++) { + int i = batch.selected[j]; + outputLower[i] = (leftLower[i] >> right) | (leftUpper[i] << (64 - right)); + } + } else { + for (int i = 0; i < batch.size; i++) { + outputLower[i] = (leftLower[i] >> right) | (leftUpper[i] << (64 - right)); + } + } + } + return this; + } + + Unscaled128Vector unsignedShiftRight(VectorizedRowBatch batch, Unscaled128Vector left, int right) { + long[] leftUpper = left.upper.array; + long[] leftLower = left.lower.array; + long[] outputLower = this.lower.array; + + if (right == 0) { + this.set(batch, left); + } else if (right == 64) { + upper.fill(batch, 0); + lower.set(batch, left.upper); + } else if (right > 64) { + upper.fill(batch, 0); + lower.unsignedShiftRight(batch, left.upper, right - 64); + } else { // right < 64 + upper.unsignedShiftRight(batch, left.upper, right); + if (batch.selectedInUse) { + for (int j = 0; j < batch.size; j++) { + int i = batch.selected[j]; + outputLower[i] = (leftLower[i] >>> right) | (leftUpper[i] << (64 - right)); + } + } else { + for (int i = 0; i < batch.size; i++) { + outputLower[i] = (leftLower[i] >>> right) | (leftUpper[i] << (64 - right)); + } + } + } + return this; + } + + Unscaled128Vector not(VectorizedRowBatch batch, Unscaled128Vector input) { + upper.not(batch, input.upper); + lower.not(batch, input.lower); + return this; + } + + Unscaled128Vector add(VectorizedRowBatch batch, Unscaled128Vector left, Unscaled128Vector right) { + return this.add(batch, left, right.upper, right.lower); + } + + Unscaled128Vector add(VectorizedRowBatch batch, Unscaled128Vector left, long right) { + return this.add(batch, left, 0, right); + } + + Unscaled128Vector negate(VectorizedRowBatch batch, Unscaled128Vector input) { + return getNegate().negate(batch, input); + } + + Unscaled128Vector subtract(VectorizedRowBatch batch, Unscaled128Vector left, Unscaled128Vector right) { + return this.subtract(batch, left, right.upper, right.lower); + } + + Unscaled128Vector multiply(VectorizedRowBatch batch, Unscaled128Vector multiplicand, Unscaled128Vector multiplier, ColumnVector isNull) { + return getMultiply().multiply(batch, multiplicand, multiplier, isNull); + } + + Unscaled128Vector divideChecked(VectorizedRowBatch batch, Unscaled128Vector left, Unscaled128Vector right, ColumnVector isNull, int rightPrecision) { + return getDivide().divideChecked(batch, left, right, isNull, rightPrecision); + } + + Unscaled128Vector divideUnchecked(VectorizedRowBatch batch, Unscaled128Vector left, Unscaled128Vector right, int rightPrecision) { + return getDivide().divideUnchecked(batch, left, right, rightPrecision); + } + + Unscaled128Vector moduloChecked(VectorizedRowBatch batch, Unscaled128Vector left, Unscaled128Vector right, ColumnVector isNull, int rightPrecision) { + return getDivide().moduloChecked(batch, left, right, isNull, rightPrecision); + } + + Unscaled128Vector multiplyByPowerOfTen(VectorizedRowBatch batch, Unscaled128Vector left, int right) { + return getMultiply().multiplyByPowerOfTen(batch, left, right); + } + + Unscaled128Vector divideByPowerOfTen(VectorizedRowBatch batch, Unscaled128Vector left, int right, RoundingMode roundingMode) { + return getDivide().divideByPowerOfTen(batch, left, right, roundingMode); + } + + Unscaled128Vector set(VectorizedRowBatch batch, Unscaled128Vector input) { + return this.set(batch, input.upper, input.lower); + } + + Unscaled128Vector set(Unscaled128Vector input) { + return this.set(input.upper, input.lower); + } + + Unscaled128Vector set(Unscaled64Vector upper, Unscaled64Vector lower) { + this.upper.set(upper); + this.lower.set(lower); + return this; + } + + Unscaled128Vector and(VectorizedRowBatch batch, Unscaled128Vector left, Unscaled128Vector right) { + return this.and(batch, left, right.upper, right.lower); + } + + Unscaled128Vector or(VectorizedRowBatch batch, Unscaled128Vector left, Unscaled128Vector right) { + return this.or(batch, left, right.upper, right.lower); + } + + Unscaled128Vector xor(VectorizedRowBatch batch, Unscaled128Vector left, Unscaled128Vector right) { + return xor(batch, left, right.upper, right.lower); + } + + Unscaled128Vector shiftLeft(VectorizedRowBatch batch, Unscaled128Vector left, int right) { + return shiftLeft(batch, left.upper, left.lower, right); + } + + Unscaled128Vector sign(VectorizedRowBatch batch, Unscaled128Vector input, Unscaled128Vector sign) { + return getSign().sign(batch, input, sign); + } + + Sign getSign() { + if (sign == null) { + sign = new Sign(); + } + return sign; + } + + Unscaled128Vector fill(VectorizedRowBatch batch, Unscaled128Value value) { + return this.fill(batch, value.getUpper(), value.getLower()); + } + + Unscaled128Vector fill(VectorizedRowBatch batch, long inputUpper, long inputLower) { + upper.fill(batch, inputUpper); + lower.fill(batch, inputLower); + return this; + } + + Unscaled128Vector set(VectorizedRowBatch batch, Unscaled64Vector inputUpper, Unscaled64Vector inputLower) { + upper.set(batch, inputUpper); + lower.set(batch, inputLower); + return this; + } + + Unscaled128Vector set(VectorizedRowBatch batch, long inputUpper, Unscaled64Vector inputLower) { + upper.fill(batch, inputUpper); + lower.set(batch, inputLower); + return this; + } + + Unscaled128Vector set(int index, Unscaled128Value value) { + upper.array[index] = value.getUpper(); + lower.array[index] = value.getLower(); + return this; + } + + Unscaled128Vector add(VectorizedRowBatch batch, Unscaled128Vector left, Unscaled64Vector rightUpper, Unscaled64Vector rightLower) { + lower.add(batch, left.lower, rightLower); + upper.add(batch, left.upper, rightUpper); + + long[] leftLower = left.lower.array; + long[] outputUpper = upper.array; + long[] outputLower = lower.array; + long[] rightLowerArray = rightLower.array; + + // if (leftLower.0 == 1 && rightLower.0 == 1) return outputUpper += 1; + // if (leftLower.0 == 0 && rightLower.0 == 0) return outputUpper += 0; + // if (outputLower.0 == 0) return outputUpper += 1; + // if (outputLower.0 == 1) return outputUpper += 0; + + // if (leftLower.0 + rightLower.0 == 2) return outputUpper += 1; + // if (leftLower.0 + rightLower.0 == 0) return outputUpper += 0; + // if (leftLower.0 + rightLower.0 == 1) return outputUpper += outputLower.0; + if (batch.selectedInUse) { + for (int j = 0; j < batch.size; j++) { + int i = batch.selected[j]; + long carry = (leftLower[i] >>> 63) + (rightLowerArray[i] >>> 63); + outputUpper[i] += ((carry & 2) >> 1) | ((carry & 1) & ~(outputLower[i] >>> 63)); + } + } else { + for (int i = 0; i < batch.size; i++) { + long carry = (leftLower[i] >>> 63) + (rightLowerArray[i] >>> 63); + outputUpper[i] += ((carry & 2) >> 1) | ((carry & 1) & ~(outputLower[i] >>> 63)); + } + } + return this; + } + + Unscaled128Vector subtract(VectorizedRowBatch batch, Unscaled128Vector left, Unscaled64Vector rightUpper, Unscaled64Vector rightLower) { + lower.subtract(batch, left.lower, rightLower); + upper.subtract(batch, left.upper, rightUpper); + + long[] leftLower = left.lower.array; + long[] outputUpper = upper.array; + long[] outputLower = lower.array; + long[] rightLowerArray = rightLower.array; + + // if (leftLower.0 == 0 && rightLower.0 == 1) return outputUpper -= 1; + // if (leftLower.0 == 1 && rightLower.0 == 0) return outputUpper -= 0; + // if (outputLower.0 == 0) return outputUpper -= 0; + // if (outputLower.0 == 1) return outputUpper -= 1; + + // if (~leftLower.0 + rightLower.0 == 2) return outputUpper -= 1; + // if (~leftLower.0 + rightLower.0 == 0) return outputUpper -= 0; + // if (~leftLower.0 + rightLower.0 == 1) return outputUpper -= outputLower.0; + if (batch.selectedInUse) { + for (int j = 0; j < batch.size; j++) { + int i = batch.selected[j]; + long borrow = (((~leftLower[i]) >>> 63) + (rightLowerArray[i] >>> 63)); + outputUpper[i] -= ((borrow & 2) >> 1) | ((borrow & 1) & (outputLower[i] >>> 63)); + } + } else { + for (int i = 0; i < batch.size; i++) { + long borrow = (((~leftLower[i]) >>> 63) + (rightLowerArray[i] >>> 63)); + outputUpper[i] -= ((borrow & 2) >> 1) | ((borrow & 1) & (outputLower[i] >>> 63)); + } + } + return this; + } + + Unscaled128Vector add(VectorizedRowBatch batch, Unscaled128Vector left, long rightUpper, Unscaled64Vector rightLower) { + lower.add(batch, left.lower, rightLower); + upper.add(batch, left.upper, rightUpper); + + long[] leftLower = left.lower.array; + long[] outputUpper = upper.array; + long[] outputLower = lower.array; + long[] rightLowerArray = rightLower.array; + + if (batch.selectedInUse) { + for (int j = 0; j < batch.size; j++) { + int i = batch.selected[j]; + long carry = (leftLower[i] >>> 63) + (rightLowerArray[i] >>> 63); + outputUpper[i] += ((carry & 2) >> 1) + ((carry & 1) & ~(outputLower[i] >>> 63)); + } + } else { + for (int i = 0; i < batch.size; i++) { + long carry = (leftLower[i] >>> 63) + (rightLowerArray[i] >>> 63); + outputUpper[i] += ((carry & 2) >> 1) + ((carry & 1) & ~(outputLower[i] >>> 63)); + } + } + return this; + } + + Unscaled128Vector add(VectorizedRowBatch batch, Unscaled128Vector left, long rightUpper, long rightLower) { + lower.add(batch, left.lower, rightLower); + upper.add(batch, left.upper, rightUpper); + + long[] leftLower = left.lower.array; + long[] outputUpper = this.upper.array; + long[] outputLower = this.lower.array; + + if (batch.selectedInUse) { + for (int j = 0; j < batch.size; j++) { + int i = batch.selected[j]; + long carry = (leftLower[i] >>> 63) + (rightLower >>> 63); + outputUpper[i] += ((carry & 2) >> 1) + ((carry & 1) & ~(outputLower[i] >>> 63)); + } + } else { + for (int i = 0; i < batch.size; i++) { + long carry = (leftLower[i] >>> 63) + (rightLower >>> 63); + outputUpper[i] += ((carry & 2) >> 1) + ((carry & 1) & ~(outputLower[i] >>> 63)); + } + } + return this; + } + + Unscaled128Vector subtract(VectorizedRowBatch batch, Unscaled128Vector left, long rightUpper, Unscaled64Vector rightLower) { + lower.subtract(batch, left.lower, rightLower); + upper.subtract(batch, left.upper, rightUpper); + + long[] leftLower = left.lower.array; + long[] outputUpper = upper.array; + long[] outputLower = lower.array; + long[] rightLowerArray = rightLower.array; + + if (batch.selectedInUse) { + for (int j = 0; j < batch.size; j++) { + int i = batch.selected[j]; + long borrow = (((~leftLower[i]) >>> 63) + (rightLowerArray[i] >>> 63)); + outputUpper[i] -= ((borrow & 2) >> 1) | ((borrow & 1) & (outputLower[i] >>> 63)); + } + } else { + for (int i = 0; i < batch.size; i++) { + long borrow = (((~leftLower[i]) >>> 63) + (rightLowerArray[i] >>> 63)); + outputUpper[i] -= ((borrow & 2) >> 1) | ((borrow & 1) & (outputLower[i] >>> 63)); + } + } + return this; + } + + Unscaled128Vector or(VectorizedRowBatch batch, Unscaled128Vector left, Unscaled64Vector rightUpper, Unscaled64Vector rightLower) { + upper.or(batch, left.upper, rightUpper); + lower.or(batch, left.lower, rightLower); + return this; + } + + Unscaled128Vector or(VectorizedRowBatch batch, Unscaled128Vector left, long rightUpper, Unscaled64Vector rightLower) { + upper.or(batch, left.upper, rightUpper); + lower.or(batch, left.lower, rightLower); + return this; + } + + Unscaled128Vector not(VectorizedRowBatch batch, Unscaled64Vector upper, Unscaled64Vector lower) { + this.upper.not(batch, upper); + this.lower.not(batch, lower); + return this; + } + + Unscaled128Vector xor(VectorizedRowBatch batch, Unscaled128Vector left, Unscaled64Vector rightUpper, Unscaled64Vector rightLower) { + upper.xor(batch, left.upper, rightUpper); + lower.xor(batch, left.lower, rightLower); + return this; + } + + Unscaled128Vector and(VectorizedRowBatch batch, Unscaled128Vector left, Unscaled64Vector rightUpper, Unscaled64Vector rightLower) { + upper.and(batch, left.upper, rightUpper); + lower.and(batch, left.lower, rightLower); + return this; + } + + Unscaled128Vector shiftLeft(VectorizedRowBatch batch, Unscaled64Vector leftUpper, Unscaled64Vector leftLower, int right) { + long[] leftUpperArray = leftUpper.array; + long[] leftLowerArray = leftLower.array; + long[] outputUpper = upper.array; + + if (right == 0) { + this.set(batch, leftUpper, leftLower); + } else if (right == 64) { + upper.set(batch, leftLower); + lower.fill(batch, 0); + } else if (right > 64) { + upper.shiftLeft(batch, leftLower, right - 64); + lower.fill(batch, 0); + } else { // right < 64 + lower.shiftLeft(batch, leftLower, right); + if (batch.selectedInUse) { + for (int j = 0; j < batch.size; j++) { + int i = batch.selected[j]; + outputUpper[i] = (leftUpperArray[i] << right) | (leftLowerArray[i] >>> (64 - right)); + } + } else { + for (int i = 0; i < batch.size; i++) { + outputUpper[i] = (leftUpperArray[i] << right) | (leftLowerArray[i] >>> (64 - right)); + } + } + } + return this; + } + + Unscaled128Vector shiftLeft(VectorizedRowBatch batch, long leftUpper, Unscaled64Vector leftLower, int right) { + long[] leftLowerArray = leftLower.array; + long[] outputUpper = upper.array; + + if (right == 0) { + this.set(batch, leftUpper, leftLower); + } else if (right == 64) { + upper.set(batch, leftLower); + lower.fill(batch, 0); + } else if (right > 64) { + upper.shiftLeft(batch, leftLower, right - 64); + lower.fill(batch, 0); + } else { // right < 64 + lower.shiftLeft(batch, leftLower, right); + if (batch.selectedInUse) { + for (int j = 0; j < batch.size; j++) { + int i = batch.selected[j]; + outputUpper[i] = (leftUpper << right) | (leftLowerArray[i] >>> (64 - right)); + } + } else { + for (int i = 0; i < batch.size; i++) { + outputUpper[i] = (leftUpper << right) | (leftLowerArray[i] >>> (64 - right)); + } + } + } + return this; + } + + Unscaled128Vector divideByPowerOfTen(VectorizedRowBatch batch, Unscaled128Vector left, int right) { + return divideByPowerOfTen(batch, left, right, RoundingMode.HALF_UP); + } + + Unscaled128Vector makeExceedingNull(VectorizedRowBatch batch, int precision, ColumnVector isNull) { + Unscaled128Value powerOfTen = new Unscaled128Value(); + Unscaled128Value copy = new Unscaled128Value(0, 1); + powerOfTen.multiplyByPowerOfTen(copy, precision - 1); + Unscaled128Value negativePowerOfTen = new Unscaled128Value(); + negativePowerOfTen.negate(powerOfTen); + Unscaled128Value zero = new Unscaled128Value(); + + Unscaled128Value value = new Unscaled128Value(); + if (batch.selectedInUse) { + for (int j = 0; j < batch.size; j++) { + int i = batch.selected[j]; + this.get(i, value); + int signum = value.compareTo(zero); + if (signum == 1) { + if (value.compareTo(powerOfTen) == 1) { + isNull.isNull[i] = true; + isNull.noNulls = false; + } + } else if (signum == -1) { + if (value.compareTo(negativePowerOfTen) == -1) { + isNull.isNull[i] = true; + isNull.noNulls = false; + } + } + } + } else { + for (int i = 0; i < batch.size; i++) { + this.get(i, value); + int signum = value.compareTo(zero); + if (signum == 1) { + if (value.compareTo(powerOfTen) == 1) { + isNull.isNull[i] = true; + isNull.noNulls = false; + } + } else if (signum == -1) { + if (value.compareTo(negativePowerOfTen) == -1) { + isNull.isNull[i] = true; + isNull.noNulls = false; + } + } + } + } + + return this; + } + + void get(int index, Unscaled128Value value) { + value.setUpper(upper.array[index]); + value.setLower(lower.array[index]); + } + + class Sign { + Unscaled128Vector copy = new Unscaled128Vector(size); + + Unscaled128Vector sign(VectorizedRowBatch batch, Unscaled128Vector input, Unscaled128Vector sign) { + Unscaled128Vector output = Unscaled128Vector.this; + copy.negate(batch, sign); + copy.xor(batch, input, copy); + return output.add(batch, copy, sign); + } + } + + class Negate { + Unscaled128Vector not = new Unscaled128Vector(size); + + Unscaled128Vector negate(VectorizedRowBatch batch, Unscaled128Vector input) { + Unscaled128Vector output = Unscaled128Vector.this; + not.not(batch, input); + output.add(batch, not, 0, 1); + return output; + } + } + + class Multiply { + Unscaled128Vector leftAbs = new Unscaled128Vector(size); + Unscaled128Vector leftSign = new Unscaled128Vector(size); + Unscaled128Vector rightAbs = new Unscaled128Vector(size); + Unscaled128Vector rightSign = new Unscaled128Vector(size); + Unscaled128Vector outputShift = new Unscaled128Vector(size); + Unscaled128Vector outputCopy = new Unscaled128Vector(size); + Unscaled128Vector combinedSign = new Unscaled128Vector(size); + + Unscaled64Vector output128_191 = new Unscaled64Vector(size); + Unscaled64Vector multiplied = new Unscaled64Vector(size); + Unscaled128Vector shifted = new Unscaled128Vector(size); + Unscaled128Vector max = new Unscaled128Vector(size); + Unscaled64Vector or = new Unscaled64Vector(size); + + Unscaled64Vector l0 = new Unscaled64Vector(size); + Unscaled64Vector l1 = new Unscaled64Vector(size); + Unscaled64Vector l2 = new Unscaled64Vector(size); + Unscaled64Vector l3 = new Unscaled64Vector(size); + + Unscaled64Vector r0 = new Unscaled64Vector(size); + Unscaled64Vector r1 = new Unscaled64Vector(size); + Unscaled64Vector r2 = new Unscaled64Vector(size); + Unscaled64Vector r3 = new Unscaled64Vector(size); + + Unscaled128Vector multiply(VectorizedRowBatch batch, Unscaled128Vector left, Unscaled128Vector right, ColumnVector isNull) { + Unscaled128Vector output = Unscaled128Vector.this; + + // Absolute + leftSign.unsignedShiftRight(batch, left, 127); + leftAbs.sign(batch, left, leftSign); + rightSign.unsignedShiftRight(batch, right, 127); + rightAbs.sign(batch, right, rightSign); + + unsignedMultiply(batch, leftAbs, rightAbs, isNull); + + // Reverse absolute + return output.sign(batch, outputCopy.set(batch, output), combinedSign.xor(batch, leftSign, rightSign)); + } + + Unscaled128Vector unsignedMultiply(VectorizedRowBatch batch, Unscaled128Vector left, Unscaled128Vector right, ColumnVector isNull) { + Unscaled128Vector output = Unscaled128Vector.this; + Unscaled128Vector output64_191 = new Unscaled128Vector(batch.size, output.upper, output128_191); + + output128_191.fill(batch, 0); + + l0.lower(batch, left.lower); + l1.upper(batch, left.lower); + l2.lower(batch, left.upper); + l3.upper(batch, left.upper); + r0.lower(batch, right.lower); + r1.upper(batch, right.lower); + r2.lower(batch, right.upper); + r3.upper(batch, right.upper); + + output.set(batch, 0, multiplied.multiply(batch, l0, r0)); + output.add(batch, outputCopy.set(batch, output), shifted.shiftLeft(batch, 0, multiplied.multiply(batch, l0, r1), 32)); + output.add(batch, outputCopy.set(batch, output), shifted.shiftLeft(batch, 0, multiplied.multiply(batch, l1, r0), 32)); + output64_191.add(batch, outputCopy.set(batch, output64_191), 0, multiplied.multiply(batch, l0, r2)); + output64_191.add(batch, outputCopy.set(batch, output64_191), 0, multiplied.multiply(batch, l1, r1)); + output64_191.add(batch, outputCopy.set(batch, output64_191), 0, multiplied.multiply(batch, l2, r0)); + output64_191.add(batch, outputCopy.set(batch, output64_191), shifted.shiftLeft(batch, 0, multiplied.multiply(batch, l0, r3), 32)); + output64_191.add(batch, outputCopy.set(batch, output64_191), shifted.shiftLeft(batch, 0, multiplied.multiply(batch, l1, r2), 32)); + output64_191.add(batch, outputCopy.set(batch, output64_191), shifted.shiftLeft(batch, 0, multiplied.multiply(batch, l2, r1), 32)); + output64_191.add(batch, outputCopy.set(batch, output64_191), shifted.shiftLeft(batch, 0, multiplied.multiply(batch, l3, r0), 32)); + + or.set(batch, output64_191.upper); + or.or(batch, or, multiplied.multiply(batch, l1, r3)); + or.or(batch, or, multiplied.multiply(batch, l2, r2)); + or.or(batch, or, multiplied.multiply(batch, l3, r1)); + or.or(batch, or, multiplied.multiply(batch, l2, r3)); + or.or(batch, or, multiplied.multiply(batch, l3, r2)); + or.or(batch, or, multiplied.multiply(batch, l3, r3)); + + if (batch.selectedInUse) { + for (int j = 0; j < batch.size; j++) { + int i = batch.selected[j]; + if ((or.array[i] != 0) | (output128_191.array[i] != 0)) { + isNull.isNull[i] = true; + isNull.noNulls = false; + } + } + } else { + for (int i = 0; i < batch.size; i++) { + if ((or.array[i] != 0) | (output128_191.array[i] != 0)) { + isNull.isNull[i] = true; + isNull.noNulls = false; + } + } + } + + return output; + } + + Unscaled128Vector multiplyByPowerOfTen(VectorizedRowBatch batch, Unscaled128Vector input, int scale) { + Unscaled128Vector output = Unscaled128Vector.this; + output.set(batch, input); + for (int i = 0; i < scale; i++) { + outputCopy.shiftLeft(batch, output, 1); + output.add(batch, outputCopy, outputShift.shiftLeft(batch, outputCopy, 2)); + } + return output; + } + } + + class Divide { + // Left + Unscaled128Vector leftAbs = new Unscaled128Vector(size); + Unscaled128Vector leftSign = new Unscaled128Vector(size); + + // Right + Unscaled128Vector rightAbs = new Unscaled128Vector(size); + Unscaled128Vector rightSign = new Unscaled128Vector(size); + + // Quotient + Unscaled128Vector quotient = new Unscaled128Vector(size); + + // Remainder + Unscaled128Vector rem = new Unscaled128Vector(size); + Unscaled128Vector combinedSign = new Unscaled128Vector(size); + + // Copy + Unscaled128Vector copy = new Unscaled128Vector(size); + + // Rounding + Unscaled64Vector remainder = new Unscaled64Vector(size); + Unscaled64Vector round = new Unscaled64Vector(size); + Unscaled64Vector shift = new Unscaled64Vector(size); + Unscaled64Vector middle = new Unscaled64Vector(size); + Unscaled64Vector last = new Unscaled64Vector(size); + + void divideOrModuloUnchecked128By128(boolean isDivide, int i) { + long leftUpper; + long leftLower; + long rightUpper; + long rightLower; + long remainderUpper; + long remainderLower; + long remainderSubtractUpper; + long remainderSubtractLower; + long quotientUpper; + long quotientLower; + long[] leftUpperArray = leftAbs.upper.array; + long[] leftLowerArray = leftAbs.lower.array; + long[] rightUpperArray = rightAbs.upper.array; + long[] rightLowerArray = rightAbs.lower.array; + long[] quotientUpperArray = quotient.upper.array; + long[] quotientLowerArray = quotient.lower.array; + long[] remainderUpperArray = rem.upper.array; + long[] remainderLowerArray = rem.lower.array; + + leftUpper = leftUpperArray[i]; + leftLower = leftLowerArray[i]; + rightUpper = rightUpperArray[i]; + rightLower = rightLowerArray[i]; + remainderUpper = 0; + remainderLower = 0; + quotientUpper = 0; + quotientLower = 0; + + int leftLeadingZeros; + if (leftUpper > 0) { + leftLeadingZeros = Long.numberOfLeadingZeros(leftUpper); + } else { + leftLeadingZeros = Long.numberOfLeadingZeros(leftLower) + 64; + } + + int rightLeadingZeros; + if (isDivide) { + if (rightUpper > 0) { + rightLeadingZeros = Long.numberOfLeadingZeros(rightUpper); + } else { + rightLeadingZeros = Long.numberOfLeadingZeros(rightUpper) + 64; + } + } else { + rightLeadingZeros = 128; + } + + if (leftLeadingZeros < 64) { + int end = Math.min(rightLeadingZeros, 64); + for (int k = leftLeadingZeros; k < end; k++) { + // Shift the new remainder to left + remainderUpper = (remainderUpper << 1) | (remainderLower >>> 63); + remainderLower <<= 1; + + // Read bits into the remainder + remainderLower |= ((leftUpper >>> (63 - k)) & 1); + + // Negate the remainder by the divisor + remainderSubtractUpper = remainderUpper - rightUpper; + remainderSubtractLower = remainderLower - rightLower; + long borrow = ((~remainderLower) >>> 63) + (rightLower >>> 63); + remainderSubtractUpper -= ((borrow & 2) >> 1) | ((borrow & 1) & (remainderSubtractLower >>> 63)); + + if (remainderSubtractUpper >= 0) { + remainderUpper = remainderSubtractUpper; + remainderLower = remainderSubtractLower; + quotientUpper |= (1L << (63 - k)); + } + } + } + + int start; + if (leftLeadingZeros > 64) { + start = leftLeadingZeros; + } else { + start = 64; + } + for (int k = start; k < rightLeadingZeros; k++) { + // Shift the new remainder to left + remainderUpper = (remainderUpper << 1) | (remainderLower >>> 63); + remainderLower <<= 1; + + // Read bits into the remainder + remainderLower |= ((leftLower >>> (127 - k)) & 1); + + // Negate the remainder by the divisor + remainderSubtractUpper = remainderUpper - rightUpper; + remainderSubtractLower = remainderLower - rightLower; + long borrow = (((~remainderLower) >>> 63) + (rightLower >>> 63)); + remainderSubtractUpper -= ((borrow & 2) >> 1) | ((borrow & 1) & (remainderSubtractLower >>> 63)); + + if (remainderSubtractUpper >= 0) { + remainderUpper = remainderSubtractUpper; + remainderLower = remainderSubtractLower; + quotientLower |= (1L << (127 - k)); + } + } + + quotientUpperArray[i] = quotientUpper; + quotientLowerArray[i] = quotientLower; + remainderUpperArray[i] = remainderUpper; + remainderLowerArray[i] = remainderLower; + } + + void divideOrModuloUnchecked128By128(VectorizedRowBatch batch, Unscaled128Vector left, Unscaled128Vector right, boolean isDivide) { + // Prepare variables + rem.fill(batch, 0, 0); + quotient.fill(batch, 0, 0); + + // Absolute + leftSign.unsignedShiftRight(batch, left, 127); + leftAbs.sign(batch, left, leftSign); + + rightSign.unsignedShiftRight(batch, right, 127); + rightAbs.sign(batch, right, rightSign); + + if (batch.selectedInUse) { + for (int j = 0; j < batch.size; j++) { + int i = batch.selected[j]; + divideOrModuloUnchecked128By128(isDivide, i); + } + } else { + for (int i = 0; i < batch.size; i++) { + divideOrModuloUnchecked128By128(isDivide, i); + } + } + } + + Unscaled128Vector divideUnchecked(VectorizedRowBatch batch, Unscaled128Vector left, Unscaled128Vector right, int rightPrecision) { + if (rightPrecision > 4) { + divideOrModuloUnchecked128By128(batch, left, right, true); + quotient.sign(batch, quotient, combinedSign.xor(batch, leftSign, rightSign)); + } else { + divideOrModuloUnchecked128By16(batch, left, right); + quotient.sign(batch, quotient, combinedSign.xor(batch, leftSign, rightSign)); + } + + // Put the quotient into the output + return Unscaled128Vector.this.set(batch, quotient); + } + + Unscaled128Vector divideChecked(VectorizedRowBatch batch, Unscaled128Vector left, Unscaled128Vector right, + ColumnVector isNull, int rightPrecision) { + long[] rightUpper = right.upper.array; + long[] rightLower = right.lower.array; + + // Handle divide by zero + if (batch.selectedInUse) { + for (int j = 0; j < batch.size; j++) { + int i = batch.selected[j]; + if ((rightUpper[i] == 0) && (rightLower[i] == 0)) { + isNull.isNull[i] = true; + isNull.noNulls = false; + rightLower[i] = 1; + } + } + } else { + for (int i = 0; i < batch.size; i++) { + if ((rightUpper[i] == 0) && (rightLower[i] == 0)) { + isNull.isNull[i] = true; + isNull.noNulls = false; + rightLower[i] = 1; + } + } + } + + return this.divideUnchecked(batch, left, right, rightPrecision); + } + + Unscaled128Vector moduloChecked(VectorizedRowBatch batch, Unscaled128Vector left, Unscaled128Vector right, + ColumnVector isNull, int rightPrecision) { + long[] rightUpper = right.upper.array; + long[] rightLower = right.lower.array; + + if (batch.selectedInUse) { + for (int j = 0; j < batch.size; j++) { + int i = batch.selected[j]; + if ((rightUpper[i] == 0) && (rightLower[i] == 0)) { + isNull.isNull[i] = true; + isNull.noNulls = false; + rightLower[i] = 1; + } + } + } else { + for (int i = 0; i < batch.size; i++) { + if ((rightUpper[i] == 0) && (rightLower[i] == 0)) { + isNull.isNull[i] = true; + isNull.noNulls = false; + rightLower[i] = 1; + } + } + } + + if (rightPrecision > 4) { + divideOrModuloUnchecked128By128(batch, left, right, false); + rem.sign(batch, rem, leftSign); + } else { + divideOrModuloUnchecked128By16(batch, left, right); + rem.sign(batch, rem, leftSign); + } + return Unscaled128Vector.this.set(batch, rem); + } + + void divideOrModuloUnchecked128By16(VectorizedRowBatch batch, Unscaled128Vector left, Unscaled128Vector right) { + // Absolute + leftSign.unsignedShiftRight(batch, left, 127); + leftAbs.sign(batch, left, leftSign); + + last.fill(batch, 0); + remainder.fill(batch, 0); + quotient.set(batch, leftAbs); + + Unscaled64Vector first = quotient.upper; + middle.upper(batch, quotient.lower); + last.lower(batch, quotient.lower); + + remainder.remainderUnchecked(batch, first, right.lower); + first.divideUnchecked(batch, first, right.lower); + + middle.or(batch, shift.shiftLeft(batch, remainder, 32), middle); // Carry + remainder.remainderUnchecked(batch, middle, right.lower); + middle.divideUnchecked(batch, middle, right.lower); + + last.or(batch, shift.shiftLeft(batch, remainder, 32), last); // Carry + remainder.remainderUnchecked(batch, last, right.lower); + last.divideUnchecked(batch, last, right.lower); + + quotient.lower.or(batch, shift.shiftLeft(batch, middle, 32), last); + } + + Unscaled128Vector divideByPowerOfTen(VectorizedRowBatch batch, Unscaled128Vector left, int right, RoundingMode roundingMode) { + Unscaled128Vector output = Unscaled128Vector.this; + + // Absolute + leftSign.unsignedShiftRight(batch, left, 127); + leftAbs.sign(batch, left, leftSign); + + last.fill(batch, 0); + remainder.fill(batch, 0); + Unscaled128Vector.this.set(batch, leftAbs); + + Unscaled64Vector first = output.upper; + for (int i = 0; i < right; i++) { + middle.upper(batch, output.lower); + last.lower(batch, output.lower); + + remainder.remainderByTen(batch, first); + first.divideByTen(batch, first); + + middle.or(batch, shift.shiftLeft(batch, remainder, 32), middle); // Carry + remainder.remainderByTen(batch, middle); + middle.divideByTen(batch, middle); + + last.or(batch, shift.shiftLeft(batch, remainder, 32), last); // Carry + if (i == right - 1) { + remainder.remainderByTen(batch, last); + } + last.divideByTen(batch, last); + + output.lower.or(batch, shift.shiftLeft(batch, middle, 32), last); + } + + switch (roundingMode) { + case HALF_UP: { + long[] remainderArray = remainder.array; + long[] roundArray = round.array; + if (batch.selectedInUse) { + for (int j = 0; j < batch.size; j++) { + int i = batch.selected[j]; + roundArray[i] = (4 - remainderArray[i]) >>> 63; + } + } else { + for (int i = 0; i < batch.size; i++) { + roundArray[i] = (4 - remainderArray[i]) >>> 63; + } + } + output.add(batch, output, 0, round); + + // Sign + output.sign(batch, output, leftSign); + break; + } + + case CEILING: { + // Sign + output.sign(batch, output, leftSign); + remainder.sign(batch, remainder, leftSign.lower); + + remainder.negate(batch, remainder); + shift.unsignedShiftRight(batch, remainder, 63); + output.add(batch, output, 0, shift); + break; + } + + case FLOOR: { + // Sign + output.sign(batch, output, leftSign); + remainder.sign(batch, remainder, leftSign.lower); + + shift.unsignedShiftRight(batch, remainder, 63); + output.subtract(batch, copy.set(batch, output), 0, shift); + break; + } + + case DOWN: { + // Sign + output.sign(batch, output, leftSign); + break; + } + + case HALF_EVEN: + throw new UnsupportedOperationException(); + } + + return output; + } + } + + Negate getNegate() { + if (negate == null) { + negate = new Negate(); + } + return negate; + } + + Multiply getMultiply() { + if (multiply == null) { + multiply = new Multiply(); + } + return multiply; + } + + Divide getDivide() { + if (divide == null) { + divide = new Divide(); + } + return divide; + } + + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof Unscaled128Vector)) { + return false; + } + Unscaled128Vector that = (Unscaled128Vector) obj; + return this.upper.equals(that.upper) && this.lower.equals(that.lower); + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append('['); + if (size > 0) { + builder.append('('); + builder.append(upper.array[0]); + builder.append(", "); + builder.append(lower.array[0]); + builder.append(')'); + } + for (int i = 1; i < size; i++) { + builder.append(", "); + builder.append('('); + builder.append(upper.array[i]); + builder.append(", "); + builder.append(lower.array[i]); + builder.append(')'); + } + builder.append(']'); + return builder.toString(); + } +} diff --git storage-api/src/java/org/apache/hadoop/hive/ql/exec/vector/decimal/Unscaled64Vector.java storage-api/src/java/org/apache/hadoop/hive/ql/exec/vector/decimal/Unscaled64Vector.java new file mode 100644 index 0000000..45a02d4 --- /dev/null +++ storage-api/src/java/org/apache/hadoop/hive/ql/exec/vector/decimal/Unscaled64Vector.java @@ -0,0 +1,690 @@ +/** + * 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.hadoop.hive.ql.exec.vector.decimal; + +import org.apache.hadoop.hive.ql.exec.vector.ColumnVector; +import org.apache.hadoop.hive.ql.exec.vector.VectorizedRowBatch; + +/** + * This class provides high-performance 64-bit arithmetic operations. + */ +class Unscaled64Vector { + // Children + Divide divide; + long[] array; + + Unscaled64Vector(int size) { + array = new long[size]; + } + + Unscaled64Vector add(VectorizedRowBatch batch, Unscaled64Vector left, Unscaled64Vector right) { + long[] outputArray = this.array; + long[] leftArray = left.array; + long[] rightArray = right.array; + + if (batch.selectedInUse) { + for (int j = 0; j < batch.size; j++) { + int i = batch.selected[j]; + outputArray[i] = leftArray[i] + rightArray[i]; + } + } else { + for (int i = 0; i < batch.size; i++) { + outputArray[i] = leftArray[i] + rightArray[i]; + } + } + return this; + } + + Unscaled64Vector add(VectorizedRowBatch batch, Unscaled64Vector left, long right) { + long[] outputArray = this.array; + long[] leftArray = left.array; + + if (batch.selectedInUse) { + for (int j = 0; j < batch.size; j++) { + int i = batch.selected[j]; + outputArray[i] = leftArray[i] + right; + } + } else { + for (int i = 0; i < batch.size; i++) { + outputArray[i] = leftArray[i] + right; + } + } + return this; + } + + Unscaled64Vector negate(VectorizedRowBatch batch, Unscaled64Vector input) { + long[] outputArray = this.array; + long[] inputArray = input.array; + + if (batch.selectedInUse) { + for (int j = 0; j < batch.size; j++) { + int i = batch.selected[j]; + outputArray[i] = -inputArray[i]; + } + } else { + for (int i = 0; i < batch.size; i++) { + outputArray[i] = -inputArray[i]; + } + } + return this; + } + + Unscaled64Vector subtract(VectorizedRowBatch batch, Unscaled64Vector left, Unscaled64Vector right) { + long[] outputArray = this.array; + long[] leftArray = left.array; + long[] rightArray = right.array; + + if (batch.selectedInUse) { + for (int j = 0; j < batch.size; j++) { + int i = batch.selected[j]; + outputArray[i] = leftArray[i] - rightArray[i]; + } + } else { + for (int i = 0; i < batch.size; i++) { + outputArray[i] = leftArray[i] - rightArray[i]; + } + } + return this; + } + + Unscaled64Vector subtract(VectorizedRowBatch batch, Unscaled64Vector left, long right) { + long[] outputArray = this.array; + long[] leftArray = left.array; + + if (batch.selectedInUse) { + for (int j = 0; j < batch.size; j++) { + int i = batch.selected[j]; + outputArray[i] = leftArray[i] - right; + } + } else { + for (int i = 0; i < batch.size; i++) { + outputArray[i] = leftArray[i] - right; + } + } + return this; + } + + Unscaled64Vector multiply(VectorizedRowBatch batch, Unscaled64Vector left, Unscaled64Vector right) { + long[] leftArray = left.array; + long[] rightArray = right.array; + long[] outputArray = this.array; + + if (batch.selectedInUse) { + for (int j = 0; j < batch.size; j++) { + int i = batch.selected[j]; + outputArray[i] = leftArray[i] * rightArray[i]; + } + } else { + for (int i = 0; i < batch.size; i++) { + outputArray[i] = leftArray[i] * rightArray[i]; + } + } + return this; + } + + Unscaled64Vector divideChecked(VectorizedRowBatch batch, Unscaled64Vector left, Unscaled64Vector right, ColumnVector isNull) { + long[] rightArray = right.array; + + if (batch.selectedInUse) { + for (int j = 0; j < batch.size; j++) { + int i = batch.selected[j]; + if (rightArray[i] == 0) { + isNull.isNull[i] = true; + isNull.noNulls = false; + rightArray[i] = 1; + } + } + } else { + for (int i = 0; i < batch.size; i++) { + if (rightArray[i] == 0) { + isNull.isNull[i] = true; + isNull.noNulls = false; + rightArray[i] = 1; + } + } + } + return this.divideUnchecked(batch, left, right); + } + + Unscaled64Vector divideUnchecked(VectorizedRowBatch batch, Unscaled64Vector left, Unscaled64Vector right) { + long[] outputArray = this.array; + long[] leftArray = left.array; + long[] rightArray = right.array; + + if (batch.selectedInUse) { + for (int j = 0; j < batch.size; j++) { + int i = batch.selected[j]; + outputArray[i] = leftArray[i] / rightArray[i]; + } + } else { + for (int i = 0; i < batch.size; i++) { + outputArray[i] = leftArray[i] / rightArray[i]; + } + } + return this; + } + + Unscaled64Vector moduloChecked(VectorizedRowBatch batch, Unscaled64Vector left, Unscaled64Vector right, ColumnVector isNull) { + long[] outputArray = this.array; + long[] leftArray = left.array; + long[] rightArray = right.array; + + if (batch.selectedInUse) { + for (int j = 0; j < batch.size; j++) { + int i = batch.selected[j]; + if (right.array[i] == 0) { + isNull.isNull[i] = true; + isNull.noNulls = false; + right.array[i] = 1; + } + } + } else { + for (int i = 0; i < batch.size; i++) { + if (right.array[i] == 0) { + isNull.isNull[i] = true; + isNull.noNulls = false; + right.array[i] = 1; + } + } + } + if (batch.selectedInUse) { + for (int j = 0; j < batch.size; j++) { + int i = batch.selected[j]; + outputArray[i] = leftArray[i] % rightArray[i]; + } + } else { + for (int i = 0; i < batch.size; i++) { + outputArray[i] = leftArray[i] % rightArray[i]; + } + } + return this; + } + + Unscaled64Vector xor(VectorizedRowBatch batch, Unscaled64Vector left, Unscaled64Vector right) { + long[] outputArray = this.array; + long[] leftArray = left.array; + long[] rightArray = right.array; + + if (batch.selectedInUse) { + for (int j = 0; j < batch.size; j++) { + int i = batch.selected[j]; + outputArray[i] = leftArray[i] ^ rightArray[i]; + } + } else { + for (int i = 0; i < batch.size; i++) { + outputArray[i] = leftArray[i] ^ rightArray[i]; + } + } + return this; + } + + Unscaled64Vector unsignedShiftRight(VectorizedRowBatch batch, Unscaled64Vector left, int right) { + long[] leftArray = left.array; + + if (batch.selectedInUse) { + for (int j = 0; j < batch.size; j++) { + int i = batch.selected[j]; + array[i] = leftArray[i] >>> right; + } + } else { + for (int i = 0; i < batch.size; i++) { + array[i] = leftArray[i] >>> right; + } + } + return this; + } + + Unscaled64Vector signedShiftRight(VectorizedRowBatch batch, Unscaled64Vector left, int right) { + long[] leftArray = left.array; + + if (batch.selectedInUse) { + for (int j = 0; j < batch.size; j++) { + int i = batch.selected[j]; + array[i] = leftArray[i] >> right; + } + } else { + for (int i = 0; i < batch.size; i++) { + array[i] = leftArray[i] >> right; + } + } + return this; + } + + Unscaled64Vector shiftLeft(VectorizedRowBatch batch, Unscaled64Vector left, int right) { + long[] outputArray = this.array; + long[] leftArray = left.array; + + if (batch.selectedInUse) { + for (int j = 0; j < batch.size; j++) { + int i = batch.selected[j]; + outputArray[i] = leftArray[i] << right; + } + } else { + for (int i = 0; i < batch.size; i++) { + outputArray[i] = leftArray[i] << right; + } + } + return this; + } + + Unscaled64Vector divideByPowerOfTen(VectorizedRowBatch batch, Unscaled64Vector left, int right, RoundingMode roundingMode) { + return getDivide().divideByPowerOfTen(batch, left, right, roundingMode); + } + + Unscaled64Vector multiplyByPowerOfTen(VectorizedRowBatch batch, Unscaled64Vector input, int scale) { + long powerOfTen = 1; + for (int i = 0; i < scale; i++) { + powerOfTen *= 10; + } + + long[] inputArray = input.array; + long[] outputArray = this.array; + if (batch.selectedInUse) { + for (int j = 0; j < batch.size; j++) { + int i = batch.selected[j]; + outputArray[i] = inputArray[i] * powerOfTen; + } + } else { + for (int i = 0; i < batch.size; i++) { + outputArray[i] = inputArray[i] * powerOfTen; + } + } + return this; + } + + Unscaled64Vector set(VectorizedRowBatch batch, Unscaled64Vector input) { + long[] inputArray = input.array; + long[] outputArray = this.array; + if (batch.selectedInUse) { + for (int j = 0; j < batch.size; j++) { + int i = batch.selected[j]; + outputArray[i] = inputArray[i]; + } + } else { + System.arraycopy(inputArray, 0, outputArray, 0, batch.size); + } + return this; + } + + Unscaled64Vector set(Unscaled64Vector input) { + System.arraycopy(input.array, 0, this.array, 0, Math.min(this.array.length, input.array.length)); + return this; + } + + Unscaled64Vector not(VectorizedRowBatch batch, Unscaled64Vector input) { + long[] inputArray = input.array; + long[] outputArray = this.array; + + if (batch.selectedInUse) { + for (int j = 0; j < batch.size; j++) { + int i = batch.selected[j]; + outputArray[i] = ~inputArray[i]; + } + } else { + for (int i = 0; i < batch.size; i++) { + outputArray[i] = ~inputArray[i]; + } + } + return this; + } + + Unscaled64Vector and(VectorizedRowBatch batch, Unscaled64Vector left, Unscaled64Vector right) { + long[] leftArray = left.array; + long[] rightArray = right.array; + long[] outputArray = this.array; + + if (batch.selectedInUse) { + for (int j = 0; j < batch.size; j++) { + int i = batch.selected[j]; + outputArray[i] = leftArray[i] & rightArray[i]; + } + } else { + for (int i = 0; i < batch.size; i++) { + outputArray[i] = leftArray[i] & rightArray[i]; + } + } + return this; + } + + Unscaled64Vector or(VectorizedRowBatch batch, Unscaled64Vector left, Unscaled64Vector right) { + long[] leftArray = left.array; + long[] rightArray = right.array; + + if (batch.selectedInUse) { + for (int j = 0; j < batch.size; j++) { + int i = batch.selected[j]; + array[i] = leftArray[i] | rightArray[i]; + } + } else { + for (int i = 0; i < batch.size; i++) { + array[i] = leftArray[i] | rightArray[i]; + } + } + return this; + } + + Unscaled64Vector divideByPowerOfTen(VectorizedRowBatch batch, Unscaled64Vector left, int right) { + return divideByPowerOfTen(batch, left, right, RoundingMode.HALF_UP); + } + + Unscaled64Vector fill(VectorizedRowBatch batch, long input) { + long[] inputArray = this.array; + + if (batch.selectedInUse) { + for (int j = 0; j < batch.size; j++) { + int i = batch.selected[j]; + inputArray[i] = input; + } + } else { + for (int i = 0; i < batch.size; i++) { + inputArray[i] = input; + } + } + return this; + } + + Unscaled64Vector and(VectorizedRowBatch batch, Unscaled64Vector left, long right) { + long[] leftArray = left.array; + long[] outputArray = this.array; + + if (batch.selectedInUse) { + for (int j = 0; j < batch.size; j++) { + int i = batch.selected[j]; + outputArray[i] = leftArray[i] & right; + } + } else { + for (int i = 0; i < batch.size; i++) { + outputArray[i] = leftArray[i] & right; + } + } + return this; + } + + Unscaled64Vector or(VectorizedRowBatch batch, Unscaled64Vector left, long right) { + long[] leftArray = left.array; + + if (batch.selectedInUse) { + for (int j = 0; j < batch.size; j++) { + int i = batch.selected[j]; + array[i] = leftArray[i] | right; + } + } else { + for (int i = 0; i < batch.size; i++) { + array[i] = leftArray[i] | right; + } + } + return this; + } + + Unscaled64Vector xor(VectorizedRowBatch batch, Unscaled64Vector left, long right) { + long[] outputArray = this.array; + long[] leftArray = left.array; + + if (batch.selectedInUse) { + for (int j = 0; j < batch.size; j++) { + int i = batch.selected[j]; + outputArray[i] = leftArray[i] ^ right; + } + } else { + for (int i = 0; i < batch.size; i++) { + outputArray[i] = leftArray[i] ^ right; + } + } + return this; + } + + Unscaled64Vector upper(VectorizedRowBatch batch, Unscaled64Vector input) { + return this.unsignedShiftRight(batch, input, 32); + } + + Unscaled64Vector lower(VectorizedRowBatch batch, Unscaled64Vector input) { + return this.and(batch, input, 0xFFFFFFFFL); + } + + Unscaled64Vector remainderByTen(VectorizedRowBatch batch, Unscaled64Vector input) { + long[] inputArray = input.array; + if (batch.selectedInUse) { + for (int j = 0; j < batch.size; j++) { + int i = batch.selected[j]; + array[i] = inputArray[i] % 10; + } + } else { + for (int i = 0; i < batch.size; i++) { + array[i] = inputArray[i] % 10; + } + } + return this; + } + + Unscaled64Vector divideByTen(VectorizedRowBatch batch, Unscaled64Vector input) { + long[] inputArray = input.array; + if (batch.selectedInUse) { + for (int j = 0; j < batch.size; j++) { + int i = batch.selected[j]; + array[i] = inputArray[i] / 10; + } + } else { + for (int i = 0; i < batch.size; i++) { + array[i] = inputArray[i] / 10; + } + } + return this; + } + + Unscaled64Vector makeExceedingNull(VectorizedRowBatch batch, int precision, ColumnVector isNull) { + long powerOfTen = 1; + for (int i = 0; i < precision; i++) { + powerOfTen *= 10; + } + + if (batch.selectedInUse) { + for (int j = 0; j < batch.size; j++) { + int i = batch.selected[j]; + long inputValue = array[i]; + if ((inputValue > 0 && inputValue >= powerOfTen) || + (inputValue < 0 && inputValue <= -powerOfTen)) { + isNull.isNull[i] = true; + isNull.noNulls = false; + } + } + } else { + for (int i = 0; i < batch.size; i++) { + long inputValue = array[i]; + if ((inputValue > 0 && inputValue >= powerOfTen) || + (inputValue < 0 && inputValue <= -powerOfTen)) { + isNull.isNull[i] = true; + isNull.noNulls = false; + } + } + } + return this; + } + + Unscaled64Vector sign(VectorizedRowBatch batch, Unscaled64Vector input, Unscaled64Vector sign) { + long[] inputArray = input.array; + long[] signArray = sign.array; + + if (batch.selectedInUse) { + for (int j = 0; j < batch.size; j++) { + int i = batch.selected[j]; + array[i] = (inputArray[i] ^ (-signArray[i])) + signArray[i]; + } + } else { + for (int i = 0; i < batch.size; i++) { + array[i] = (inputArray[i] ^ (-signArray[i])) + signArray[i]; + } + } + return this; + } + + Unscaled64Vector divideUnchecked(VectorizedRowBatch batch, Unscaled64Vector left, long right) { + long[] outputArray = this.array; + long[] leftArray = left.array; + + if (batch.selectedInUse) { + for (int j = 0; j < batch.size; j++) { + int i = batch.selected[j]; + outputArray[i] = leftArray[i] / right; + } + } else { + for (int i = 0; i < batch.size; i++) { + outputArray[i] = leftArray[i] / right; + } + } + return this; + } + + Unscaled64Vector remainderUnchecked(VectorizedRowBatch batch, Unscaled64Vector left, long right) { + long[] remainderArray = this.array; + long[] leftArray = left.array; + + if (batch.selectedInUse) { + for (int j = 0; j < batch.size; j++) { + int i = batch.selected[j]; + remainderArray[i] = leftArray[i] % right; + } + } else { + for (int i = 0; i < batch.size; i++) { + remainderArray[i] = leftArray[i] % right; + } + } + return this; + } + + Unscaled64Vector remainderUnchecked(VectorizedRowBatch batch, Unscaled64Vector left, Unscaled64Vector right) { + long[] remainderArray = this.array; + long[] leftArray = left.array; + long[] rightArray = right.array; + + if (batch.selectedInUse) { + for (int j = 0; j < batch.size; j++) { + int i = batch.selected[j]; + remainderArray[i] = leftArray[i] % rightArray[i]; + } + } else { + for (int i = 0; i < batch.size; i++) { + remainderArray[i] = leftArray[i] % rightArray[i]; + } + } + return this; + } + + class Divide { + Unscaled64Vector remainder = new Unscaled64Vector(array.length); + Unscaled64Vector sign = new Unscaled64Vector(array.length); + Unscaled64Vector temp = new Unscaled64Vector(array.length); + + Unscaled64Vector divideByPowerOfTen(VectorizedRowBatch batch, Unscaled64Vector left, int right, RoundingMode roundingMode) { + Unscaled64Vector output = Unscaled64Vector.this; + + long powerOfTen = 1; + for (int i = 0; i < right; i++) { + powerOfTen *= 10; + } + output.divideUnchecked(batch, left, powerOfTen); + + switch (roundingMode) { + case HALF_UP: { + remainder.remainderUnchecked(batch, left, powerOfTen); + + // Absolute + sign.unsignedShiftRight(batch, left, 63); + output.sign(batch, output, sign); + remainder.sign(batch, remainder, sign); + + long roundingBase = powerOfTen / 2 - 1; + temp.fill(batch, roundingBase); + temp.subtract(batch, temp, remainder); + temp.unsignedShiftRight(batch, temp, 63); + output.add(batch, output, temp); + + // Sign + output.sign(batch, output, sign); + break; + } + + case CEILING: { + remainder.remainderUnchecked(batch, left, powerOfTen); + remainder.negate(batch, remainder); + sign.unsignedShiftRight(batch, remainder, 63); + output.add(batch, output, sign); + break; + } + + case FLOOR: { + remainder.remainderUnchecked(batch, left, powerOfTen); + sign.unsignedShiftRight(batch, remainder, 63); + output.subtract(batch, output, sign); + break; + } + + case DOWN: { + break; + } + + case HALF_EVEN: + throw new UnsupportedOperationException(); + } + + return output; + } + } + + Divide getDivide() { + if (divide == null) { + divide = new Divide(); + } + return divide; + } + + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof Unscaled64Vector)) { + return false; + } + Unscaled64Vector that = (Unscaled64Vector) obj; + if (this.array.length != that.array.length) { + return false; + } + for (int i = 0; i < array.length; i++) { + if (this.array[i] != that.array[i]) { + return false; + } + } + return true; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append('['); + if (array.length > 0) { + builder.append(array[0]); + } + for (int i = 1; i < array.length; i++) { + builder.append(", "); + builder.append(array[i]); + } + builder.append(']'); + return builder.toString(); + } +} diff --git storage-api/src/test/org/apache/hadoop/hive/ql/exec/vector/TestDecimalColumnVector.java storage-api/src/test/org/apache/hadoop/hive/ql/exec/vector/TestDecimalColumnVector.java new file mode 100644 index 0000000..2807b11 --- /dev/null +++ storage-api/src/test/org/apache/hadoop/hive/ql/exec/vector/TestDecimalColumnVector.java @@ -0,0 +1,482 @@ +/** + * 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.hadoop.hive.ql.exec.vector; + +import org.apache.hadoop.hive.common.type.HiveDecimal; +import org.apache.hadoop.hive.ql.exec.vector.DecimalColumnVector; +import org.apache.hadoop.hive.ql.exec.vector.VectorizedRowBatch; +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class TestDecimalColumnVector { + DecimalColumnVector left; + DecimalColumnVector right; + DecimalColumnVector output; + DecimalColumnVector expected; + + int size = 9; + boolean[] isNull; + + VectorizedRowBatch batch = new VectorizedRowBatch(3, size); + + @Before + public void before() { + isNull = new boolean[] {false, false, false, false, false, false, false, false, false}; + } + + void set(DecimalColumnVector vector, long[] upper, long[] lower) { + set(vector, upper, lower, + new boolean[] {false, false, false, false, false, false, false, false, false}); + } + + void set(DecimalColumnVector vector, long[] upper, long[] lower, boolean[] isNull) { + System.arraycopy(isNull, 0, vector.isNull, 0, size); + System.arraycopy(upper, 0, vector.scaledVector.getUpper(), 0, size); + System.arraycopy(lower, 0, vector.scaledVector.getLower(), 0, size); + } + + @Test + public void testSet64() throws Exception { + left = new DecimalColumnVector(size, 1, 0); + output = new DecimalColumnVector(size, 1, 0); + expected = new DecimalColumnVector(size, 1, 0); + + set(left, + new long[] {-1, -1, -1, 0, 0, 0, 0, 0, 0}, + new long[] {-1, -1, -1, 0, 0, 0, 1, 1, 1}); + + output.set(batch, left); + + set(expected, + new long[] {-1, -1, -1, 0, 0, 0, 0, 0, 0}, + new long[] {-1, -1, -1, 0, 0, 0, 1, 1, 1}); + assertEquals(expected, output); + } + + @Test + public void testNegate64() throws Exception { + left = new DecimalColumnVector(size, 1, 0); + output = new DecimalColumnVector(size, 1, 0); + expected = new DecimalColumnVector(size, 1, 0); + + set(left, + new long[] {-1, -1, -1, 0, 0, 0, 0, 0, 0}, + new long[] {-1, -1, -1, 0, 0, 0, 1, 1, 1}); + + output.negate(batch, left); + + set(expected, + new long[] {0, 0, 0, 0, 0, 0, -1, -1, -1}, + new long[] {1, 1, 1, 0, 0, 0, -1, -1, -1}); + assertEquals(expected, output); + } + + @Test + public void testAdd64() throws Exception { + left = new DecimalColumnVector(size, 1, 0); + right = new DecimalColumnVector(size, 1, 0); + output = new DecimalColumnVector(size, 2, 0); + expected = new DecimalColumnVector(size, 2, 0); + + set(left, + new long[] {-1, -1, -1, 0, 0, 0, 0, 0, 0}, + new long[] {-1, -1, -1, 0, 0, 0, 1, 1, 1}); + set(right, + new long[] {-1, 0, 0, -1, 0, 0, -1, 0, 0}, + new long[] {-1, 0, 1, -1, 0, 1, -1, 0, 1}); + + output.add(batch, left, right); + + set(expected, + new long[] {-1, -1, 0, -1, 0, 0, 0, 0, 0}, + new long[] {-2, -1, 0, -1, 0, 1, 0, 1, 2}); + assertEquals(expected, output); + + + left = new DecimalColumnVector(size, 2, 1); + right = new DecimalColumnVector(size, 1, 0); + output = new DecimalColumnVector(size, 3, 1); + expected = new DecimalColumnVector(size, 3, 1); + + set(left, + new long[] {-1, -1, -1, 0, 0, 0, 0, 0, 0}, + new long[] {-10, -10, -10, 0, 0, 0, 10, 10, 10}); + set(right, + new long[] {-1, 0, 0, -1, 0, 0, -1, 0, 0}, + new long[] {-1, 0, 1, -1, 0, 1, -1, 0, 1}); + + output.add(batch, left, right); + + set(expected, + new long[] {-1, -1, 0, -1, 0, 0, 0, 0, 0}, + new long[] {-20, -10, 0, -10, 0, 10, 0, 10, 20}); + assertEquals(expected, output); + } + + @Test + public void testSubtract64() throws Exception { + left = new DecimalColumnVector(size, 1, 0); + right = new DecimalColumnVector(size, 1, 0); + output = new DecimalColumnVector(size, 2, 0); + expected = new DecimalColumnVector(size, 2, 0); + + set(left, + new long[] {-1, -1, -1, 0, 0, 0, 0, 0, 0}, + new long[] {-1, -1, -1, 0, 0, 0, 1, 1, 1}); + set(right, + new long[] {-1, 0, 0, -1, 0, 0, -1, 0, 0}, + new long[] {-1, 0, 1, -1, 0, 1, -1, 0, 1}); + + output.subtract(batch, left, right); + + set(expected, + new long[] {0, -1, -1, 0, 0, -1, 0, 0, 0}, + new long[] {0, -1, -2, 1, 0, -1, 2, 1, 0}); + assertEquals(expected, output); + } + + @Test + public void testMultiply64() throws Exception { + left = new DecimalColumnVector(size, 1, 0); + right = new DecimalColumnVector(size, 1, 0); + output = new DecimalColumnVector(size, 3, 0); + expected = new DecimalColumnVector(size, 3, 0); + + set(left, + new long[] {-1, -1, -1, 0, 0, 0, 0, 0, 0}, + new long[] {-1, -1, -1, 0, 0, 0, 1, 1, 1}); + set(right, + new long[] {-1, 0, 0, -1, 0, 0, -1, 0, 0}, + new long[] {-1, 0, 1, -1, 0, 1, -1, 0, 1}); + + output.multiply(batch, left, right); + + set(expected, + new long[] {0, 0, -1, 0, 0, 0, -1, 0, 0}, + new long[] {1, 0, -1, 0, 0, 0, -1, 0, 1}); + assertEquals(expected, output); + } + + @Test + public void testDivide64() throws Exception { + left = new DecimalColumnVector(size, 3, 1); + right = new DecimalColumnVector(size, 2, 1); + output = new DecimalColumnVector(size, 9, 6); + expected = new DecimalColumnVector(size, 9, 6); + + set(left, + new long[] {-1, -1, -1, 0, 0, 0, 0, 0, 0}, + new long[] {-123, -123, -123, 0, 0, 0, 123, 123, 123}); + set(right, + new long[] {-1, 0, 0, -1, 0, 0, -1, 0, 0}, + new long[] {-45, 0, 45, -45, 0, 45, -45, 0, 45}); + + output.divide(batch, left, right); + + set(expected, + new long[] {0, -1, -1, 0, 0, 0, -1, 0, 0}, + new long[] {2733333, -2733333, -2733333, 0, 0, 0, -2733333, 2733333, 2733333}, + new boolean[] {false, true, false, false, true, false, false, true, false}); + assertEquals(expected, output); + + + left = new DecimalColumnVector(size, 5, 3); + right = new DecimalColumnVector(size, 4, 3); + output = new DecimalColumnVector(size, 13, 8); + expected = new DecimalColumnVector(size, 13, 8); + + set(left, + new long[] {-1, -1, -1, 0, 0, 0, 0, 0, 0}, + new long[] {-12300, -12300, -12300, 0, 0, 0, 12300, 12300, 12300}); + set(right, + new long[] {-1, 0, 0, -1, 0, 0, -1, 0, 0}, + new long[] {-4500, 0, 4500, -4500, 0, 4500, -4500, 0, 4500}); + + output.divide(batch, left, right); + + set(expected, + new long[] {0, -1, -1, 0, 0, 0, -1, 0, 0}, + new long[] {273333333, -273333333, -273333333, 0, 0, 0, -273333333, 273333333, 273333333}, + new boolean[] {false, true, false, false, true, false, false, true, false}); + assertEquals(expected, output); + } + + @Test + public void testRemainder64() throws Exception { + left = new DecimalColumnVector(size, 1, 0); + right = new DecimalColumnVector(size, 1, 0); + output = new DecimalColumnVector(size, 1, 0); + expected = new DecimalColumnVector(size, 1, 0); + + set(left, + new long[] {-1, -1, -1, 0, 0, 0, 0, 0, 0}, + new long[] {-1, -1, -1, 0, 0, 0, 1, 1, 1}); + set(right, + new long[] {-1, 0, 0, -1, 0, 0, -1, 0, 0}, + new long[] {-1, 0, 1, -1, 0, 1, -1, 0, 1}); + + output.modulo(batch, left, right); + + set(expected, + new long[] {0, 0, 0, 0, 0, 0, 0, 0, 0}, + new long[] {0, -1, 0, 0, 0, 0, 0, 1, 0}, + new boolean[] {false, true, false, false, true, false, false, true, false}); + assertEquals(expected, output); + } + + @Test + public void testScaleByPowerOfTen64() throws Exception { + left = new DecimalColumnVector(size, 1, 0); + output = new DecimalColumnVector(size, 2, 1); + expected = new DecimalColumnVector(size, 2, 1); + + set(left, + new long[] {-1, -1, -1, 0, 0, 0, 0, 0, 0}, + new long[] {-1, -1, -1, 0, 0, 0, 1, 1, 1}); + + output.scaleByPowerOfTen(batch, left, 1); + + set(expected, + new long[] {-1, -1, -1, 0, 0, 0, 0, 0, 0}, + new long[] {-10, -10, -10, 0, 0, 0, 10, 10, 10}); + assertEquals(expected, output); + + left = new DecimalColumnVector(size, 1, 0); + left.scaleByPowerOfTen(batch, output, -1); + + output = new DecimalColumnVector(size, 1, 0); + output.set(batch, left); + + expected = new DecimalColumnVector(size, 1, 0); + set(expected, + new long[] {-1, -1, -1, 0, 0, 0, 0, 0, 0}, + new long[] {-1, -1, -1, 0, 0, 0, 1, 1, 1}); + assertEquals(expected, output); + } + + @Test + public void testSet128() throws Exception { + left = new DecimalColumnVector(size, 20, 10); + output = new DecimalColumnVector(size, 20, 10); + + set(left, + new long[] {-1, -1, -1, 0, 0, 0, 0, 0, 0}, + new long[] {-1, -1, -1, 0, 0, 0, 1, 1, 1}); + + output.set(batch, left); + + assertEquals(left, output); + } + + @Test + public void testNegate128() throws Exception { + left = new DecimalColumnVector(size, 20, 10); + output = new DecimalColumnVector(size, 20, 10); + expected = new DecimalColumnVector(size, 20, 10); + + set(left, + new long[] {-1, -1, -1, 0, 0, 0, 0, 0, 0}, + new long[] {-1, -1, -1, 0, 0, 0, 1, 1, 1}); + + output.negate(batch, left); + + set(expected, + new long[] {0, 0, 0, 0, 0, 0, -1, -1, -1}, + new long[] {1, 1, 1, 0, 0, 0, -1, -1, -1}); + assertEquals(expected, output); + } + + @Test + public void testAdd128() throws Exception { + left = new DecimalColumnVector(size, 20, 10); + right = new DecimalColumnVector(size, 20, 10); + output = new DecimalColumnVector(size, 21, 10); + expected = new DecimalColumnVector(size, 21, 10); + + set(left, + new long[] {-1, -1, -1, 0, 0, 0, 0, 0, 0}, + new long[] {-1, -1, -1, 0, 0, 0, 1, 1, 1}); + set(right, + new long[] {-1, 0, 0, -1, 0, 0, -1, 0, 0}, + new long[] {-1, 0, 1, -1, 0, 1, -1, 0, 1}); + + output.add(batch, left, right); + + set(expected, + new long[] {-1, -1, 0, -1, 0, 0, 0, 0, 0}, + new long[] {-2, -1, 0, -1, 0, 1, 0, 1, 2}); + assertEquals(expected, output); + } + + @Test + public void testSubtract128() throws Exception { + left = new DecimalColumnVector(size, 20, 10); + right = new DecimalColumnVector(size, 20, 10); + output = new DecimalColumnVector(size, 21, 10); + expected = new DecimalColumnVector(size, 21, 10); + + set(left, + new long[] {-1, -1, -1, 0, 0, 0, 0, 0, 0}, + new long[] {-1, -1, -1, 0, 0, 0, 1, 1, 1}); + set(right, + new long[] {-1, 0, 0, -1, 0, 0, -1, 0, 0}, + new long[] {-1, 0, 1, -1, 0, 1, -1, 0, 1}); + + output.subtract(batch, left, right); + + set(expected, + new long[] {0, -1, -1, 0, 0, -1, 0, 0, 0}, + new long[] {0, -1, -2, 1, 0, -1, 2, 1, 0}); + assertEquals(expected, output); + } + + @Test + public void testMultiply128() throws Exception { + left = new DecimalColumnVector(size, 20, 10); + right = new DecimalColumnVector(size, 1, 0); + output = new DecimalColumnVector(size, 22, 10); + expected = new DecimalColumnVector(size, 22, 10); + + set(left, + new long[] {-1, -1, -1, 0, 0, 0, 0, 0, 0}, + new long[] {-1, -1, -1, 0, 0, 0, 1, 1, 1}); + set(right, + new long[] {-1, 0, 0, -1, 0, 0, -1, 0, 0}, + new long[] {-1, 0, 1, -1, 0, 1, -1, 0, 1}); + + output.multiply(batch, left, right); + + set(expected, + new long[] {0, 0, -1, 0, 0, 0, -1, 0, 0}, + new long[] {1, 0, -1, 0, 0, 0, -1, 0, 1}); + assertEquals(expected, output); + } + + @Test + public void testDivide128() { + output = new DecimalColumnVector(size, 3, 1); + left = new DecimalColumnVector(size, 10, 8); + set(output, + new long[] {-1, -1, -1, 0, 0, 0, 0, 0, 0}, + new long[] {-123, -123, -123, 0, 0, 0, 123, 123, 123}); + left.scaledVector.rescale(batch, output.scaledVector, 8); + + output = new DecimalColumnVector(size, 2, 1); + right = new DecimalColumnVector(size, 10, 8); + set(output, + new long[] {-1, 0, 0, -1, 0, 0, -1, 0, 0}, + new long[] {-45, 0, 45, -45, 0, 45, -45, 0, 45}); + right.scaledVector.rescale(batch, output.scaledVector, 8); + + output = new DecimalColumnVector(size, 28, 18); + expected = new DecimalColumnVector(size, 28, 18); + output.divide(batch, left, right); + + set(expected, + new long[] {0, 0, -1, 0, 0, 0, -1, 0, 0}, + new long[] {2733333333333333333L, 0, -2733333333333333333L, + 0, 0, 0, -2733333333333333333L, 0, 2733333333333333333L}, + new boolean[] {false, true, false, false, true, false, false, true, false}); + assertEquals(expected, output); + } + + @Test + public void testRemainder128() throws Exception { + left = new DecimalColumnVector(size, 20, 10); + right = new DecimalColumnVector(size, 20, 10); + output = new DecimalColumnVector(size, 20, 10); + expected = new DecimalColumnVector(size, 20, 10); + + set(left, + new long[] {0, 0, 0, 0, 0, 0, 0, -1, -1}, + new long[] {2, 3, 5, 7, 0, 7, 7, -7, -7}); + set(right, + new long[] {0, 0, 0, 0, 0, 0, -1, 0, -1}, + new long[] {3, 3, 3, 3, 0, 3, -3, 3, -3}); + + output.modulo(batch, left, right); + + set(expected, + new long[] {0, 0, 0, 0, 0, 0, 0, -1, -1}, + new long[] {2, 0, 2, 1, 0, 1, 1, -1, -1}, + new boolean[] {false, false, false, false, true, false, false, false, false}); + assertEquals(expected, output); + } + + @Test + public void testScaleByPowerOfTen128() throws Exception { + left = new DecimalColumnVector(size, 20, 10); + right = new DecimalColumnVector(size, 1, 0); + output = new DecimalColumnVector(size, 21, 11); + expected = new DecimalColumnVector(size, 21, 11); + + set(left, + new long[] {-1, -1, -1, 0, 0, 0, 0, 0, 0}, + new long[] {-1, -1, -1, 0, 0, 0, 1, 1, 1}); + set(right, + new long[] {-1, 0, 0, -1, 0, 0, -1, 0, 0}, + new long[] {-1, 0, 1, -1, 0, 1, -1, 0, 1}); + + output.scaleByPowerOfTen(batch, left, 1); + + set(expected, + new long[] {-1, -1, -1, 0, 0, 0, 0, 0, 0}, + new long[] {-10, -10, -10, 0, 0, 0, 10, 10, 10}); + assertEquals(expected, output); + + right = new DecimalColumnVector(size, 20, 10); + right.scaleByPowerOfTen(batch, output, -1); + + output = new DecimalColumnVector(size, 20, 10); + output.set(batch, right); + + expected = new DecimalColumnVector(size, 20, 10); + set(expected, + new long[] {-1, -1, -1, 0, 0, 0, 0, 0, 0}, + new long[] {-1, -1, -1, 0, 0, 0, 1, 1, 1}); + assertEquals(expected, output); + } + + @Test + public void testA() { + // SELECT dec, dec * 2, dec / 3 FROM DECIMAL_PRECISION + // 1.2345678901 2.4691357802 0.411522630033333333 + left = new DecimalColumnVector(1, 11, 10); + right = new DecimalColumnVector(1, 1, 0); + + output = new DecimalColumnVector(1, 11, 10); + left.set(0, HiveDecimal.create("1.2345678901")); + output.set(batch, left); + assertEquals(HiveDecimal.create("1.2345678901"), output.hiveDecimal(0)); + + output = new DecimalColumnVector(1, 12, 10); + left.set(0, HiveDecimal.create("1.2345678901")); + right.set(0, HiveDecimal.create("2")); + output.multiply(batch, left, right); + assertEquals(HiveDecimal.create("2.4691357802"), output.hiveDecimal(0)); + + output = new DecimalColumnVector(1, 18, 18); + left.set(0, HiveDecimal.create("1.2345678901")); + right.set(0, HiveDecimal.create("3")); + output.divide(batch, left, right); + assertEquals(HiveDecimal.create("0.411522630033333333"), output.hiveDecimal(0)); + } +} \ No newline at end of file