Return-Path: X-Original-To: apmail-hive-commits-archive@www.apache.org Delivered-To: apmail-hive-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 993E110954 for ; Thu, 16 Jan 2014 23:10:29 +0000 (UTC) Received: (qmail 32506 invoked by uid 500); 16 Jan 2014 23:10:28 -0000 Delivered-To: apmail-hive-commits-archive@hive.apache.org Received: (qmail 32429 invoked by uid 500); 16 Jan 2014 23:10:28 -0000 Mailing-List: contact commits-help@hive.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: hive-dev@hive.apache.org Delivered-To: mailing list commits@hive.apache.org Received: (qmail 32421 invoked by uid 99); 16 Jan 2014 23:10:28 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 16 Jan 2014 23:10:28 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 16 Jan 2014 23:10:19 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id C682D23888D7; Thu, 16 Jan 2014 23:09:57 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1558956 - in /hive/trunk: ant/src/org/apache/hadoop/hive/ant/ ql/src/gen/vectorization/ExpressionTemplates/ ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/ ql/src/test/org/apache/hadoop/hive/ql/exec/vector/expressions/ Date: Thu, 16 Jan 2014 23:09:57 -0000 To: commits@hive.apache.org From: ehans@apache.org X-Mailer: svnmailer-1.0.9 Message-Id: <20140116230957.C682D23888D7@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org 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); + templateString = templateString.replaceAll("", 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); + templateString = templateString.replaceAll("", 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); + templateString = templateString.replaceAll("", 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 extends VectorExpression { + + private static final long serialVersionUID = 1L; + + private int colNum1; + private int colNum2; + private int outputColumn; + + public (int colNum1, int colNum2, int outputColumn) { + this.colNum1 = colNum1; + this.colNum2 = colNum2; + this.outputColumn = outputColumn; + } + + public () { + } + + @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.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); + } + } + } 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); + } + } + } + + /* 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 extends VectorExpression { + + private static final long serialVersionUID = 1L; + + private int colNum; + private Decimal128 value; + private int outputColumn; + + public (int colNum, Decimal128 value, int outputColumn) { + this.colNum = colNum; + this.value = value; + this.outputColumn = outputColumn; + } + + public () { + } + + @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.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 */ { + 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); + } + } + } + + 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 extends VectorExpression { + + private static final long serialVersionUID = 1L; + + private int colNum; + private Decimal128 value; + private int outputColumn; + + public (Decimal128 value, int colNum, int outputColumn) { + this.colNum = colNum; + this.value = value; + this.outputColumn = outputColumn; + } + + public () { + } + + @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.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 */ { + 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); + } + } + } + + 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;