FAQ
Author: ehans
Date: Thu Jan 16 23:09:57 2014
New Revision: 1558956

URL: http://svn.apache.org/r1558956
Log:
HIVE-6124: Support basic Decimal arithmetic in vector mode (+, -, *) (Eric Hanson)

Added:
     hive/trunk/ql/src/gen/vectorization/ExpressionTemplates/ColumnArithmeticColumnDecimal.txt
     hive/trunk/ql/src/gen/vectorization/ExpressionTemplates/ColumnArithmeticScalarDecimal.txt
     hive/trunk/ql/src/gen/vectorization/ExpressionTemplates/ScalarArithmeticColumnDecimal.txt
     hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/DecimalUtil.java
Modified:
     hive/trunk/ant/src/org/apache/hadoop/hive/ant/GenVectorCode.java
     hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/NullUtil.java
     hive/trunk/ql/src/test/org/apache/hadoop/hive/ql/exec/vector/expressions/TestVectorArithmeticExpressions.java

Modified: hive/trunk/ant/src/org/apache/hadoop/hive/ant/GenVectorCode.java
URL: http://svn.apache.org/viewvc/hive/trunk/ant/src/org/apache/hadoop/hive/ant/GenVectorCode.java?rev=1558956&r1=1558955&r2=1558956&view=diff
==============================================================================
--- hive/trunk/ant/src/org/apache/hadoop/hive/ant/GenVectorCode.java (original)
+++ hive/trunk/ant/src/org/apache/hadoop/hive/ant/GenVectorCode.java Thu Jan 16 23:09:57 2014
@@ -107,6 +107,18 @@ public class GenVectorCode extends Task
        {"ColumnDivideColumn", "Modulo", "double", "long", "%"},
        {"ColumnDivideColumn", "Modulo", "double", "double", "%"},

+ {"ColumnArithmeticScalarDecimal", "Add"},
+ {"ColumnArithmeticScalarDecimal", "Subtract"},
+ {"ColumnArithmeticScalarDecimal", "Multiply"},
+
+ {"ScalarArithmeticColumnDecimal", "Add"},
+ {"ScalarArithmeticColumnDecimal", "Subtract"},
+ {"ScalarArithmeticColumnDecimal", "Multiply"},
+
+ {"ColumnArithmeticColumnDecimal", "Add"},
+ {"ColumnArithmeticColumnDecimal", "Subtract"},
+ {"ColumnArithmeticColumnDecimal", "Multiply"},
+
        {"ColumnCompareScalar", "Equal", "long", "double", "=="},
        {"ColumnCompareScalar", "Equal", "double", "double", "=="},
        {"ColumnCompareScalar", "NotEqual", "long", "double", "!="},
@@ -560,6 +572,12 @@ public class GenVectorCode extends Task
      for (String [] tdesc : templateExpansions) {
        if (tdesc[0].equals("ColumnArithmeticScalar") || tdesc[0].equals("ColumnDivideScalar")) {
          generateColumnArithmeticScalar(tdesc);
+ } else if (tdesc[0].equals("ColumnArithmeticScalarDecimal")) {
+ generateColumnArithmeticScalarDecimal(tdesc);
+ } else if (tdesc[0].equals("ScalarArithmeticColumnDecimal")) {
+ generateScalarArithmeticColumnDecimal(tdesc);
+ } else if (tdesc[0].equals("ColumnArithmeticColumnDecimal")) {
+ generateColumnArithmeticColumnDecimal(tdesc);
        } else if (tdesc[0].equals("ColumnCompareScalar")) {
          generateColumnCompareScalar(tdesc);
        } else if (tdesc[0].equals("ScalarCompareColumn")) {
@@ -1143,6 +1161,48 @@ public class GenVectorCode extends Task
      generateColumnBinaryOperatorScalar(tdesc, returnType, className);
    }

+ private void generateColumnArithmeticScalarDecimal(String[] tdesc) throws IOException {
+ String operatorName = tdesc[1];
+ String className = "DecimalCol" + operatorName + "DecimalScalar";
+
+ // Read the template into a string;
+ File templateFile = new File(joinPath(this.expressionTemplateDirectory, tdesc[0] + ".txt"));
+ String templateString = readFile(templateFile);
+ templateString = templateString.replaceAll("<ClassName>", className);
+ templateString = templateString.replaceAll("<Operator>", operatorName.toLowerCase());
+
+ writeFile(templateFile.lastModified(), expressionOutputDirectory, expressionClassesDirectory,
+ className, templateString);
+ }
+
+ private void generateScalarArithmeticColumnDecimal(String[] tdesc) throws IOException {
+ String operatorName = tdesc[1];
+ String className = "DecimalScalar" + operatorName + "DecimalColumn";
+
+ // Read the template into a string;
+ File templateFile = new File(joinPath(this.expressionTemplateDirectory, tdesc[0] + ".txt"));
+ String templateString = readFile(templateFile);
+ templateString = templateString.replaceAll("<ClassName>", className);
+ templateString = templateString.replaceAll("<Operator>", operatorName.toLowerCase());
+
+ writeFile(templateFile.lastModified(), expressionOutputDirectory, expressionClassesDirectory,
+ className, templateString);
+ }
+
+ private void generateColumnArithmeticColumnDecimal(String[] tdesc) throws IOException {
+ String operatorName = tdesc[1];
+ String className = "DecimalCol" + operatorName + "DecimalColumn";
+
+ // Read the template into a string;
+ File templateFile = new File(joinPath(this.expressionTemplateDirectory, tdesc[0] + ".txt"));
+ String templateString = readFile(templateFile);
+ templateString = templateString.replaceAll("<ClassName>", className);
+ templateString = templateString.replaceAll("<Operator>", operatorName.toLowerCase());
+
+ writeFile(templateFile.lastModified(), expressionOutputDirectory, expressionClassesDirectory,
+ className, templateString);
+ }
+
    private void generateScalarArithmeticColumn(String[] tdesc) throws IOException {
      String operatorName = tdesc[1];
      String operandType1 = tdesc[2];

Added: hive/trunk/ql/src/gen/vectorization/ExpressionTemplates/ColumnArithmeticColumnDecimal.txt
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/gen/vectorization/ExpressionTemplates/ColumnArithmeticColumnDecimal.txt?rev=1558956&view=auto
==============================================================================
--- hive/trunk/ql/src/gen/vectorization/ExpressionTemplates/ColumnArithmeticColumnDecimal.txt (added)
+++ hive/trunk/ql/src/gen/vectorization/ExpressionTemplates/ColumnArithmeticColumnDecimal.txt Thu Jan 16 23:09:57 2014
@@ -0,0 +1,185 @@
+/**
+ * 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.expressions.gen;
+
+import org.apache.hadoop.hive.ql.exec.vector.expressions.VectorExpression;
+import org.apache.hadoop.hive.ql.exec.vector.DecimalColumnVector;
+import org.apache.hadoop.hive.ql.exec.vector.VectorizedRowBatch;
+import org.apache.hadoop.hive.ql.exec.vector.expressions.NullUtil;
+import org.apache.hadoop.hive.ql.exec.vector.expressions.DecimalUtil;
+import org.apache.hadoop.hive.ql.exec.vector.VectorExpressionDescriptor;
+import org.apache.hadoop.hive.common.type.Decimal128;
+
+/**
+ * Generated from template ColumnArithmeticColumnDecimal.txt, which covers binary arithmetic
+ * expressions between a column and a scalar.
+ */
+public class <ClassName> extends VectorExpression {
+
+ private static final long serialVersionUID = 1L;
+
+ private int colNum1;
+ private int colNum2;
+ private int outputColumn;
+
+ public <ClassName>(int colNum1, int colNum2, int outputColumn) {
+ this.colNum1 = colNum1;
+ this.colNum2 = colNum2;
+ this.outputColumn = outputColumn;
+ }
+
+ public <ClassName>() {
+ }
+
+ @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;
+ Decimal128[] vector1 = inputColVector1.vector;
+ Decimal128[] vector2 = inputColVector2.vector;
+
+ // 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.<Operator>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.<Operator>Checked(i, vector1[0], vector2[i], outputColVector);
+ }
+ } else {
+ for(int i = 0; i != n; i++) {
+ DecimalUtil.<Operator>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.<Operator>Checked(i, vector1[i], vector2[0], outputColVector);
+ }
+ } else {
+ for(int i = 0; i != n; i++) {
+ DecimalUtil.<Operator>Checked(i, vector1[i], vector2[0], outputColVector);
+ }
+ }
+ } else {
+ if (batch.selectedInUse) {
+ for(int j = 0; j != n; j++) {
+ int i = sel[j];
+ DecimalUtil.<Operator>Checked(i, vector1[i], vector2[i], outputColVector);
+ }
+ } else {
+ for(int i = 0; i != n; i++) {
+ DecimalUtil.<Operator>Checked(i, vector1[i], vector2[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;
+ }
+
+ @Override
+ public String getOutputType() {
+ return "decimal";
+ }
+
+ 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();
+ }
+}

Added: hive/trunk/ql/src/gen/vectorization/ExpressionTemplates/ColumnArithmeticScalarDecimal.txt
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/gen/vectorization/ExpressionTemplates/ColumnArithmeticScalarDecimal.txt?rev=1558956&view=auto
==============================================================================
--- hive/trunk/ql/src/gen/vectorization/ExpressionTemplates/ColumnArithmeticScalarDecimal.txt (added)
+++ hive/trunk/ql/src/gen/vectorization/ExpressionTemplates/ColumnArithmeticScalarDecimal.txt Thu Jan 16 23:09:57 2014
@@ -0,0 +1,166 @@
+/**
+ * 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.expressions.gen;
+
+import org.apache.hadoop.hive.ql.exec.vector.expressions.VectorExpression;
+import org.apache.hadoop.hive.ql.exec.vector.DecimalColumnVector;
+import org.apache.hadoop.hive.ql.exec.vector.VectorizedRowBatch;
+import org.apache.hadoop.hive.ql.exec.vector.expressions.NullUtil;
+import org.apache.hadoop.hive.ql.exec.vector.expressions.DecimalUtil;
+import org.apache.hadoop.hive.ql.exec.vector.VectorExpressionDescriptor;
+import org.apache.hadoop.hive.common.type.Decimal128;
+
+/**
+ * Generated from template ColumnArithmeticScalarDecimal.txt, which covers binary arithmetic
+ * expressions between a column and a scalar.
+ */
+public class <ClassName> extends VectorExpression {
+
+ private static final long serialVersionUID = 1L;
+
+ private int colNum;
+ private Decimal128 value;
+ private int outputColumn;
+
+ public <ClassName>(int colNum, Decimal128 value, int outputColumn) {
+ this.colNum = colNum;
+ this.value = value;
+ this.outputColumn = outputColumn;
+ }
+
+ public <ClassName>() {
+ }
+
+ @Override
+ public void evaluate(VectorizedRowBatch batch) {
+
+ if (childExpressions != null) {
+ super.evaluateChildren(batch);
+ }
+
+ DecimalColumnVector inputColVector = (DecimalColumnVector) batch.cols[colNum];
+ DecimalColumnVector outputColVector = (DecimalColumnVector) batch.cols[outputColumn];
+ int[] sel = batch.selected;
+ boolean[] inputIsNull = inputColVector.isNull;
+ boolean[] outputIsNull = outputColVector.isNull;
+ outputColVector.noNulls = inputColVector.noNulls;
+ outputColVector.isRepeating = inputColVector.isRepeating;
+ int n = batch.size;
+ Decimal128[] vector = inputColVector.vector;
+
+ // return immediately if batch is empty
+ if (n == 0) {
+ return;
+ }
+
+ if (inputColVector.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, inputColVector.isRepeating,
+ batch.selectedInUse, sel, n);
+ }
+
+ if (inputColVector.isRepeating) {
+ if (!inputColVector.noNulls) {
+ outputIsNull[0] = inputIsNull[0];
+ }
+
+ // The following may override a "false" null setting if an error or overflow occurs.
+ DecimalUtil.<Operator>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.<Operator>Checked(i, vector[i], value, outputColVector);
+ }
+ } else {
+ for(int i = 0; i != n; i++) {
+ DecimalUtil.<Operator>Checked(i, vector[i], value, outputColVector);
+ }
+ }
+ } else /* there are nulls */ {
+ 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.<Operator>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.<Operator>Checked(i, vector[i], value, outputColVector);
+ }
+ }
+ }
+
+ NullUtil.setNullDataEntriesDecimal(outputColVector, batch.selectedInUse, sel, n);
+ }
+
+ @Override
+ public int getOutputColumn() {
+ return outputColumn;
+ }
+
+ @Override
+ public String getOutputType() {
+ return "decimal";
+ }
+
+ public int getColNum() {
+ return colNum;
+ }
+
+ public void setColNum(int colNum) {
+ this.colNum = colNum;
+ }
+
+ public Decimal128 getValue() {
+ return value;
+ }
+
+ public void setValue(Decimal128 value) {
+ this.value = value;
+ }
+
+ 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.SCALAR).build();
+ }
+}

Added: hive/trunk/ql/src/gen/vectorization/ExpressionTemplates/ScalarArithmeticColumnDecimal.txt
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/gen/vectorization/ExpressionTemplates/ScalarArithmeticColumnDecimal.txt?rev=1558956&view=auto
==============================================================================
--- hive/trunk/ql/src/gen/vectorization/ExpressionTemplates/ScalarArithmeticColumnDecimal.txt (added)
+++ hive/trunk/ql/src/gen/vectorization/ExpressionTemplates/ScalarArithmeticColumnDecimal.txt Thu Jan 16 23:09:57 2014
@@ -0,0 +1,166 @@
+/**
+ * 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.expressions.gen;
+
+import org.apache.hadoop.hive.ql.exec.vector.expressions.VectorExpression;
+import org.apache.hadoop.hive.ql.exec.vector.DecimalColumnVector;
+import org.apache.hadoop.hive.ql.exec.vector.VectorizedRowBatch;
+import org.apache.hadoop.hive.ql.exec.vector.expressions.NullUtil;
+import org.apache.hadoop.hive.ql.exec.vector.expressions.DecimalUtil;
+import org.apache.hadoop.hive.ql.exec.vector.VectorExpressionDescriptor;
+import org.apache.hadoop.hive.common.type.Decimal128;
+
+/**
+ * Generated from template ScalarArithmeticColumnDecimal.txt, which covers binary arithmetic
+ * expressions between a scalar and a column.
+ */
+public class <ClassName> extends VectorExpression {
+
+ private static final long serialVersionUID = 1L;
+
+ private int colNum;
+ private Decimal128 value;
+ private int outputColumn;
+
+ public <ClassName>(Decimal128 value, int colNum, int outputColumn) {
+ this.colNum = colNum;
+ this.value = value;
+ this.outputColumn = outputColumn;
+ }
+
+ public <ClassName>() {
+ }
+
+ @Override
+ public void evaluate(VectorizedRowBatch batch) {
+
+ if (childExpressions != null) {
+ super.evaluateChildren(batch);
+ }
+
+ DecimalColumnVector inputColVector = (DecimalColumnVector) batch.cols[colNum];
+ DecimalColumnVector outputColVector = (DecimalColumnVector) batch.cols[outputColumn];
+ int[] sel = batch.selected;
+ boolean[] inputIsNull = inputColVector.isNull;
+ boolean[] outputIsNull = outputColVector.isNull;
+ outputColVector.noNulls = inputColVector.noNulls;
+ outputColVector.isRepeating = inputColVector.isRepeating;
+ int n = batch.size;
+ Decimal128[] vector = inputColVector.vector;
+
+ // return immediately if batch is empty
+ if (n == 0) {
+ return;
+ }
+
+ if (inputColVector.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, inputColVector.isRepeating,
+ batch.selectedInUse, sel, n);
+ }
+
+ if (inputColVector.isRepeating) {
+ if (!inputColVector.noNulls) {
+ outputIsNull[0] = inputIsNull[0];
+ }
+
+ // The following may override a "false" null setting if an error or overflow occurs.
+ DecimalUtil.<Operator>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.<Operator>Checked(i, value, vector[i], outputColVector);
+ }
+ } else {
+ for(int i = 0; i != n; i++) {
+ DecimalUtil.<Operator>Checked(i, value, vector[i], outputColVector);
+ }
+ }
+ } else /* there are nulls */ {
+ 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.<Operator>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.<Operator>Checked(i, value, vector[i], outputColVector);
+ }
+ }
+ }
+
+ NullUtil.setNullDataEntriesDecimal(outputColVector, batch.selectedInUse, sel, n);
+ }
+
+ @Override
+ public int getOutputColumn() {
+ return outputColumn;
+ }
+
+ @Override
+ public String getOutputType() {
+ return "decimal";
+ }
+
+ public int getColNum() {
+ return colNum;
+ }
+
+ public void setColNum(int colNum) {
+ this.colNum = colNum;
+ }
+
+ public Decimal128 getValue() {
+ return value;
+ }
+
+ public void setValue(Decimal128 value) {
+ this.value = value;
+ }
+
+ 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.SCALAR,
+ VectorExpressionDescriptor.InputExpressionType.COLUMN).build();
+ }
+}

Added: hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/DecimalUtil.java
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/DecimalUtil.java?rev=1558956&view=auto
==============================================================================
--- hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/DecimalUtil.java (added)
+++ hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/DecimalUtil.java Thu Jan 16 23:09:57 2014
@@ -0,0 +1,92 @@
+/**
+ * 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.expressions;
+
+import org.apache.hadoop.hive.common.type.Decimal128;
+import org.apache.hadoop.hive.ql.exec.vector.DecimalColumnVector;
+
+/**
+ * Utility functions for vector operations on decimal values.
+ */
+public class DecimalUtil {
+
+ // Addition with overflow check. Overflow produces NULL output.
+ public static void addChecked(int i, Decimal128 left, Decimal128 right,
+ DecimalColumnVector outputColVector) {
+ try {
+ Decimal128.add(left, right, outputColVector.vector[i], outputColVector.scale);
+ outputColVector.vector[i].checkPrecisionOverflow(outputColVector.precision);
+ } catch (ArithmeticException e) { // catch on overflow
+ outputColVector.noNulls = false;
+ outputColVector.isNull[i] = true;
+ }
+ }
+
+ // Subtraction with overflow check. Overflow produces NULL output.
+ public static void subtractChecked(int i, Decimal128 left, Decimal128 right,
+ DecimalColumnVector outputColVector) {
+ try {
+ Decimal128.subtract(left, right, outputColVector.vector[i], outputColVector.scale);
+ outputColVector.vector[i].checkPrecisionOverflow(outputColVector.precision);
+ } catch (ArithmeticException e) { // catch on overflow
+ outputColVector.noNulls = false;
+ outputColVector.isNull[i] = true;
+ }
+ }
+
+ // Multiplication with overflow check. Overflow produces NULL output.
+ public static void multiplyChecked(int i, Decimal128 left, Decimal128 right,
+ DecimalColumnVector outputColVector) {
+ try {
+ Decimal128.multiply(left, right, outputColVector.vector[i], outputColVector.scale);
+ outputColVector.vector[i].checkPrecisionOverflow(outputColVector.precision);
+ } catch (ArithmeticException e) { // catch on overflow
+ outputColVector.noNulls = false;
+ outputColVector.isNull[i] = true;
+ }
+ }
+
+ // Division with overflow/zero-divide check. Error produces NULL output.
+ // Remainder argument is necessary to match up with the Decimal128.divide() interface.
+ // It will be discarded so just pass in a dummy argument.
+ public static void divideChecked(int i, Decimal128 left, Decimal128 right,
+ DecimalColumnVector outputColVector, Decimal128 remainder) {
+ try {
+ Decimal128.divide(left, right, outputColVector.vector[i], remainder, outputColVector.scale);
+ outputColVector.vector[i].checkPrecisionOverflow(outputColVector.precision);
+ } catch (ArithmeticException e) { // catch on error
+ outputColVector.noNulls = false;
+ outputColVector.isNull[i] = true;
+ }
+ }
+
+ // Modulo operator with overflow/zero-divide check.
+ // Quotient argument is necessary to match up with Decimal128.divide() interface.
+ // It will be discarded so just pass in a dummy argument.
+ public static void moduloChecked(int i, Decimal128 left, Decimal128 right,
+ DecimalColumnVector outputColVector, Decimal128 quotient) {
+ try {
+ Decimal128.divide(left, right, quotient, outputColVector.vector[i], outputColVector.scale);
+ outputColVector.vector[i].checkPrecisionOverflow(outputColVector.precision);
+ } catch (ArithmeticException e) { // catch on error
+ outputColVector.noNulls = false;
+ outputColVector.isNull[i] = true;
+ }
+ }
+}

Modified: hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/NullUtil.java
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/NullUtil.java?rev=1558956&r1=1558955&r2=1558956&view=diff
==============================================================================
--- hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/NullUtil.java (original)
+++ hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/NullUtil.java Thu Jan 16 23:09:57 2014
@@ -18,13 +18,14 @@

  package org.apache.hadoop.hive.ql.exec.vector.expressions;

+import java.util.Arrays;
+
  import org.apache.hadoop.hive.common.type.Decimal128;
  import org.apache.hadoop.hive.ql.exec.vector.DecimalColumnVector;
  import org.apache.hadoop.hive.ql.exec.vector.LongColumnVector;
  import org.apache.hadoop.hive.ql.exec.vector.DoubleColumnVector;
  import org.apache.hadoop.hive.ql.exec.vector.ColumnVector;

-
  /**
   * Utility functions to handle null propagation.
   */
@@ -317,4 +318,22 @@ public class NullUtil {
        }
      }
    }
+
+ // Initialize any entries that could be used in an output vector to have false for null value.
+ public static void initOutputNullsToFalse(ColumnVector v, boolean isRepeating, boolean selectedInUse,
+ int[] sel, int n) {
+ if (v.isRepeating) {
+ v.isNull[0] = false;
+ return;
+ }
+
+ if (selectedInUse) {
+ for (int j = 0; j != n; j++) {
+ int i = sel[j];
+ v.isNull[i] = false;
+ }
+ } else {
+ Arrays.fill(v.isNull, 0, n, false);
+ }
+ }
  }

Modified: hive/trunk/ql/src/test/org/apache/hadoop/hive/ql/exec/vector/expressions/TestVectorArithmeticExpressions.java
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/test/org/apache/hadoop/hive/ql/exec/vector/expressions/TestVectorArithmeticExpressions.java?rev=1558956&r1=1558955&r2=1558956&view=diff
==============================================================================
--- hive/trunk/ql/src/test/org/apache/hadoop/hive/ql/exec/vector/expressions/TestVectorArithmeticExpressions.java (original)
+++ hive/trunk/ql/src/test/org/apache/hadoop/hive/ql/exec/vector/expressions/TestVectorArithmeticExpressions.java Thu Jan 16 23:09:57 2014
@@ -31,6 +31,15 @@ import org.apache.hadoop.hive.ql.exec.ve
  import org.apache.hadoop.hive.ql.exec.vector.VectorizedRowBatch;
  import org.apache.hadoop.hive.ql.exec.vector.expressions.gen.LongColAddLongColumn;
  import org.apache.hadoop.hive.ql.exec.vector.expressions.gen.LongColAddLongScalar;
+import org.apache.hadoop.hive.ql.exec.vector.expressions.gen.DecimalColSubtractDecimalColumn;
+import org.apache.hadoop.hive.ql.exec.vector.expressions.gen.DecimalColAddDecimalColumn;
+import org.apache.hadoop.hive.ql.exec.vector.expressions.gen.DecimalColMultiplyDecimalColumn;
+import org.apache.hadoop.hive.ql.exec.vector.expressions.gen.DecimalColAddDecimalScalar;
+import org.apache.hadoop.hive.ql.exec.vector.expressions.gen.DecimalColSubtractDecimalScalar;
+import org.apache.hadoop.hive.ql.exec.vector.expressions.gen.DecimalColMultiplyDecimalScalar;
+import org.apache.hadoop.hive.ql.exec.vector.expressions.gen.DecimalScalarAddDecimalColumn;
+import org.apache.hadoop.hive.ql.exec.vector.expressions.gen.DecimalScalarSubtractDecimalColumn;
+import org.apache.hadoop.hive.ql.exec.vector.expressions.gen.DecimalScalarMultiplyDecimalColumn;
  import org.apache.hadoop.hive.ql.exec.vector.util.VectorizedRowGroupGenUtil;
  import org.junit.Test;

@@ -324,6 +333,336 @@ public class TestVectorArithmeticExpress
      assertTrue(r.vector[0].equals(new Decimal128("0.01", (short) 2)));
    }

+ // Test decimal column-column addition
+ @Test
+ public void testDecimalColumnAddDecimalColumn() {
+ VectorizedRowBatch b = getVectorizedRowBatch3DecimalCols();
+ VectorExpression expr = new DecimalColAddDecimalColumn(0, 1, 2);
+ DecimalColumnVector r = (DecimalColumnVector) b.cols[2];
+
+ // test without nulls
+ expr.evaluate(b);
+ assertTrue(r.vector[0].equals(new Decimal128("2.20", (short) 2)));
+ assertTrue(r.vector[1].equals(new Decimal128("-2.30", (short) 2)));
+ assertTrue(r.vector[2].equals(new Decimal128("1.00", (short) 2)));
+
+ // test nulls propagation
+ b = getVectorizedRowBatch3DecimalCols();
+ DecimalColumnVector c0 = (DecimalColumnVector) b.cols[0];
+ c0.noNulls = false;
+ c0.isNull[0] = true;
+ r = (DecimalColumnVector) b.cols[2];
+ expr.evaluate(b);
+ assertTrue(!r.noNulls && r.isNull[0]);
+
+ // 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].equals(new Decimal128("0.01", (short) 2)));
+
+ // test that overflow produces NULL
+ b = getVectorizedRowBatch3DecimalCols();
+ c0 = (DecimalColumnVector) b.cols[0];
+ c0.vector[0].update("9999999999999999.99", (short) 2); // 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].equals(new Decimal128("0.01", (short) 2)));
+
+ // test left input repeating
+ b = getVectorizedRowBatch3DecimalCols();
+ c0 = (DecimalColumnVector) b.cols[0];
+ c0.isRepeating = true;
+ r = (DecimalColumnVector) b.cols[2];
+ expr.evaluate(b);
+ assertTrue(r.vector[0].equals(new Decimal128("2.20", (short) 2)));
+ assertTrue(r.vector[1].equals(new Decimal128("2.20", (short) 2)));
+ assertTrue(r.vector[2].equals(new Decimal128("2.20", (short) 2)));
+
+ // test both inputs repeating
+ DecimalColumnVector c1 = (DecimalColumnVector) b.cols[1];
+ c1.isRepeating = true;
+ expr.evaluate(b);
+ assertTrue(r.isRepeating);
+ assertTrue(r.vector[0].equals(new Decimal128("2.20", (short) 2)));
+
+ // test right input repeating
+ b = getVectorizedRowBatch3DecimalCols();
+ c1 = (DecimalColumnVector) b.cols[1];
+ c1.isRepeating = true;
+ c1.vector[0].update("2", (short) 2);
+ r = (DecimalColumnVector) b.cols[2];
+ expr.evaluate(b);
+ assertTrue(r.vector[2].equals(new Decimal128("2", (short) 2)));
+ }
+
+ // Spot check decimal column-column subtract
+ @Test
+ public void testDecimalColumnSubtractDecimalColumn() {
+ VectorizedRowBatch b = getVectorizedRowBatch3DecimalCols();
+ VectorExpression expr = new DecimalColSubtractDecimalColumn(0, 1, 2);
+ DecimalColumnVector r = (DecimalColumnVector) b.cols[2];
+
+ // test without nulls
+ expr.evaluate(b);
+ assertTrue(r.vector[0].equals(new Decimal128("0.20", (short) 2)));
+ assertTrue(r.vector[1].equals(new Decimal128("-4.30", (short) 2)));
+ assertTrue(r.vector[2].equals(new Decimal128("-1.00", (short) 2)));
+
+ // test that underflow produces NULL
+ b = getVectorizedRowBatch3DecimalCols();
+ DecimalColumnVector c0 = (DecimalColumnVector) b.cols[0];
+ c0.vector[0].update("-9999999999999999.99", (short) 2); // 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]);
+ }
+
+ // Spot check decimal column-column multiply
+ @Test
+ public void testDecimalColumnMultiplyDecimalColumn() {
+ VectorizedRowBatch b = getVectorizedRowBatch3DecimalCols();
+ VectorExpression expr = new DecimalColMultiplyDecimalColumn(0, 1, 2);
+ DecimalColumnVector r = (DecimalColumnVector) b.cols[2];
+
+ // test without nulls
+ expr.evaluate(b);
+ assertTrue(r.vector[0].equals(new Decimal128("1.20", (short) 2)));
+ assertTrue(r.vector[1].equals(new Decimal128("-3.30", (short) 2)));
+ assertTrue(r.vector[2].equals(new Decimal128("0.00", (short) 2)));
+
+ // test that underflow produces NULL
+ b = getVectorizedRowBatch3DecimalCols();
+ DecimalColumnVector c0 = (DecimalColumnVector) b.cols[0];
+ c0.vector[0].update("9999999999999999.99", (short) 2); // set to max possible value
+ DecimalColumnVector c1 = (DecimalColumnVector) b.cols[1];
+ c1.vector[0].update("2", (short) 2);
+ 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]);
+ }
+
+ /* Test decimal column to decimal scalar addition. This is used to cover all the
+ * cases used in the source code template ColumnArithmeticScalarDecimal.txt.
+ */
+ @Test
+ public void testDecimalColAddDecimalScalar() {
+ VectorizedRowBatch b = getVectorizedRowBatch3DecimalCols();
+ Decimal128 d = new Decimal128(1);
+ VectorExpression expr = new DecimalColAddDecimalScalar(0, d, 2);
+
+ // test without nulls
+ expr.evaluate(b);
+ DecimalColumnVector r = (DecimalColumnVector) b.cols[2];
+ assertTrue(r.vector[0].equals(new Decimal128("2.20", (short) 2)));
+ assertTrue(r.vector[1].equals(new Decimal128("-2.30", (short) 2)));
+ assertTrue(r.vector[2].equals(new Decimal128("1.00", (short) 2)));
+
+ // test null propagation
+ b = getVectorizedRowBatch3DecimalCols();
+ DecimalColumnVector in = (DecimalColumnVector) b.cols[0];
+ r = (DecimalColumnVector) b.cols[2];
+ in.noNulls = false;
+ in.isNull[0] = true;
+ expr.evaluate(b);
+ assertTrue(!r.noNulls);
+ assertTrue(r.isNull[0]);
+
+ // test repeating case, no nulls
+ b = getVectorizedRowBatch3DecimalCols();
+ in = (DecimalColumnVector) b.cols[0];
+ in.isRepeating = true;
+ expr.evaluate(b);
+ r = (DecimalColumnVector) b.cols[2];
+ assertTrue(r.isRepeating);
+ assertTrue(r.vector[0].equals(new Decimal128("2.20", (short) 2)));
+
+ // test repeating case for null value
+ b = getVectorizedRowBatch3DecimalCols();
+ in = (DecimalColumnVector) b.cols[0];
+ in.isRepeating = true;
+ in.isNull[0] = true;
+ in.noNulls = false;
+ expr.evaluate(b);
+ r = (DecimalColumnVector) b.cols[2];
+ assertTrue(r.isRepeating);
+ assertTrue(!r.noNulls);
+ assertTrue(r.isNull[0]);
+
+ // test that overflow produces null
+ b = getVectorizedRowBatch3DecimalCols();
+ in = (DecimalColumnVector) b.cols[0];
+ in.vector[0].update("9999999999999999.99", (short) 2); // set to max possible value
+ expr.evaluate(b);
+ r = (DecimalColumnVector) b.cols[2];
+ assertFalse(r.noNulls);
+ assertTrue(r.isNull[0]);
+ }
+
+ /* Spot check correctness of decimal column subtract decimal scalar. The case for
+ * addition checks all the cases for the template, so don't do that redundantly here.
+ */
+ @Test
+ public void testDecimalColSubtractDecimalScalar() {
+ VectorizedRowBatch b = getVectorizedRowBatch3DecimalCols();
+ Decimal128 d = new Decimal128(1);
+ VectorExpression expr = new DecimalColSubtractDecimalScalar(0, d, 2);
+
+ // test without nulls
+ expr.evaluate(b);
+ DecimalColumnVector r = (DecimalColumnVector) b.cols[2];
+ assertTrue(r.vector[0].equals(new Decimal128("0.20", (short) 2)));
+ assertTrue(r.vector[1].equals(new Decimal128("-4.30", (short) 2)));
+ assertTrue(r.vector[2].equals(new Decimal128("-1.00", (short) 2)));
+
+ // test that underflow produces null
+ b = getVectorizedRowBatch3DecimalCols();
+ DecimalColumnVector in = (DecimalColumnVector) b.cols[0];
+ in.vector[0].update("-9999999999999999.99", (short) 2); // set to min possible value
+ expr.evaluate(b);
+ r = (DecimalColumnVector) b.cols[2];
+ assertFalse(r.noNulls);
+ assertTrue(r.isNull[0]);
+ }
+
+ /* Spot check correctness of decimal column multiply decimal scalar. The case for
+ * addition checks all the cases for the template, so don't do that redundantly here.
+ */
+ @Test
+ public void testDecimalColMultiplyDecimalScalar() {
+ VectorizedRowBatch b = getVectorizedRowBatch3DecimalCols();
+ Decimal128 d = new Decimal128(2);
+ VectorExpression expr = new DecimalColMultiplyDecimalScalar(0, d, 2);
+
+ // test without nulls
+ expr.evaluate(b);
+ DecimalColumnVector r = (DecimalColumnVector) b.cols[2];
+ assertTrue(r.vector[0].equals(new Decimal128("2.40", (short) 2)));
+ assertTrue(r.vector[1].equals(new Decimal128("-6.60", (short) 2)));
+ assertTrue(r.vector[2].equals(new Decimal128("0", (short) 2)));
+
+ // test that overflow produces null
+ b = getVectorizedRowBatch3DecimalCols();
+ DecimalColumnVector in = (DecimalColumnVector) b.cols[0];
+ in.vector[0].update("9999999999999999.99", (short) 2); // set to max possible value
+ expr.evaluate(b);
+ r = (DecimalColumnVector) b.cols[2];
+ assertFalse(r.noNulls);
+ assertTrue(r.isNull[0]);
+ }
+
+ /* Test decimal scalar to decimal column addition. This is used to cover all the
+ * cases used in the source code template ScalarArithmeticColumnDecimal.txt.
+ */
+ @Test
+ public void testDecimalScalarAddDecimalColumn() {
+ VectorizedRowBatch b = getVectorizedRowBatch3DecimalCols();
+ Decimal128 d = new Decimal128(1);
+ VectorExpression expr = new DecimalScalarAddDecimalColumn(d, 0, 2);
+
+ // test without nulls
+ expr.evaluate(b);
+ DecimalColumnVector r = (DecimalColumnVector) b.cols[2];
+ assertTrue(r.vector[0].equals(new Decimal128("2.20", (short) 2)));
+ assertTrue(r.vector[1].equals(new Decimal128("-2.30", (short) 2)));
+ assertTrue(r.vector[2].equals(new Decimal128("1.00", (short) 2)));
+
+ // test null propagation
+ b = getVectorizedRowBatch3DecimalCols();
+ DecimalColumnVector in = (DecimalColumnVector) b.cols[0];
+ r = (DecimalColumnVector) b.cols[2];
+ in.noNulls = false;
+ in.isNull[0] = true;
+ expr.evaluate(b);
+ assertTrue(!r.noNulls);
+ assertTrue(r.isNull[0]);
+
+ // test repeating case, no nulls
+ b = getVectorizedRowBatch3DecimalCols();
+ in = (DecimalColumnVector) b.cols[0];
+ in.isRepeating = true;
+ expr.evaluate(b);
+ r = (DecimalColumnVector) b.cols[2];
+ assertTrue(r.isRepeating);
+ assertTrue(r.vector[0].equals(new Decimal128("2.20", (short) 2)));
+
+ // test repeating case for null value
+ b = getVectorizedRowBatch3DecimalCols();
+ in = (DecimalColumnVector) b.cols[0];
+ in.isRepeating = true;
+ in.isNull[0] = true;
+ in.noNulls = false;
+ expr.evaluate(b);
+ r = (DecimalColumnVector) b.cols[2];
+ assertTrue(r.isRepeating);
+ assertTrue(!r.noNulls);
+ assertTrue(r.isNull[0]);
+
+ // test that overflow produces null
+ b = getVectorizedRowBatch3DecimalCols();
+ in = (DecimalColumnVector) b.cols[0];
+ in.vector[0].update("9999999999999999.99", (short) 2); // set to max possible value
+ expr.evaluate(b);
+ r = (DecimalColumnVector) b.cols[2];
+ assertFalse(r.noNulls);
+ assertTrue(r.isNull[0]);
+ }
+
+ /* Spot check correctness of decimal scalar subtract decimal column. The case for
+ * addition checks all the cases for the template, so don't do that redundantly here.
+ */
+ @Test
+ public void testDecimalScalarSubtractDecimalColumn() {
+ VectorizedRowBatch b = getVectorizedRowBatch3DecimalCols();
+ Decimal128 d = new Decimal128(1);
+ VectorExpression expr = new DecimalScalarSubtractDecimalColumn(d, 0, 2);
+
+ // test without nulls
+ expr.evaluate(b);
+ DecimalColumnVector r = (DecimalColumnVector) b.cols[2];
+ assertTrue(r.vector[0].equals(new Decimal128("-0.20", (short) 2)));
+ assertTrue(r.vector[1].equals(new Decimal128("4.30", (short) 2)));
+ assertTrue(r.vector[2].equals(new Decimal128("1.00", (short) 2)));
+
+ // test that overflow produces null
+ b = getVectorizedRowBatch3DecimalCols();
+ DecimalColumnVector in = (DecimalColumnVector) b.cols[0];
+ in.vector[0].update("-9999999999999999.99", (short) 2); // set to min possible value
+ expr.evaluate(b);
+ r = (DecimalColumnVector) b.cols[2];
+ assertFalse(r.noNulls);
+ assertTrue(r.isNull[0]);
+ }
+
+ /* Spot check correctness of decimal scalar multiply decimal column. The case for
+ * addition checks all the cases for the template, so don't do that redundantly here.
+ */
+
+ @Test
+ public void testDecimalScalarMultiplyDecimalColumn() {
+ VectorizedRowBatch b = getVectorizedRowBatch3DecimalCols();
+ Decimal128 d = new Decimal128(2);
+ VectorExpression expr = new DecimalScalarMultiplyDecimalColumn(d, 0, 2);
+
+ // test without nulls
+ expr.evaluate(b);
+ DecimalColumnVector r = (DecimalColumnVector) b.cols[2];
+ assertTrue(r.vector[0].equals(new Decimal128("2.40", (short) 2)));
+ assertTrue(r.vector[1].equals(new Decimal128("-6.60", (short) 2)));
+ assertTrue(r.vector[2].equals(new Decimal128("0", (short) 2)));
+
+ // test that overflow produces null
+ b = getVectorizedRowBatch3DecimalCols();
+ DecimalColumnVector in = (DecimalColumnVector) b.cols[0];
+ in.vector[0].update("9999999999999999.99", (short) 2); // set to max possible value
+ expr.evaluate(b);
+ r = (DecimalColumnVector) b.cols[2];
+ assertFalse(r.noNulls);
+ assertTrue(r.isNull[0]);
+ }
+
+ // Make a decimal batch with three columns, including two for inputs and one for the result.
    private VectorizedRowBatch getVectorizedRowBatch3DecimalCols() {
      VectorizedRowBatch b = new VectorizedRowBatch(3);
      DecimalColumnVector v0, v1;

Search Discussions

Related Discussions

Discussion Navigation
viewthread | post
posts ‹ prev | 1 of 1 | next ›
Discussion Overview
groupcommits @
categorieshive, hadoop
postedJan 16, '14 at 11:10p
activeJan 16, '14 at 11:10p
posts1
users1
websitehive.apache.org

1 user in discussion

Ehans: 1 post

People

Translate

site design / logo © 2021 Grokbase