2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
19 package org.apache.hadoop.hive.ql.exec.vector.expressions.gen;
21 import org.apache.hadoop.hive.ql.exec.vector.expressions.VectorExpression;
22 import org.apache.hadoop.hive.ql.exec.vector.expressions.NullUtil;
23 import org.apache.hadoop.hive.ql.exec.vector.*;
24 import org.apache.hadoop.hive.ql.exec.vector.VectorizedRowBatch;
25 import org.apache.hadoop.hive.ql.exec.vector.VectorExpressionDescriptor;
28 * Generated from template ColumnArithmeticColumn.txt, which covers binary arithmetic
29 * expressions between columns.
31 public class <ClassName> extends VectorExpression {
33 private static final long serialVersionUID = 1L;
37 private int outputColumn;
39 public <ClassName>(int colNum1, int colNum2, int outputColumn) {
40 this.colNum1 = colNum1;
41 this.colNum2 = colNum2;
42 this.outputColumn = outputColumn;
45 public <ClassName>() {
49 public void evaluate(VectorizedRowBatch batch) {
51 if (childExpressions != null) {
52 super.evaluateChildren(batch);
55 <InputColumnVectorType1> inputColVector1 = (<InputColumnVectorType1>) batch.cols[colNum1];
56 <InputColumnVectorType2> inputColVector2 = (<InputColumnVectorType2>) batch.cols[colNum2];
57 <OutputColumnVectorType> outputColVector = (<OutputColumnVectorType>) batch.cols[outputColumn];
58 int[] sel = batch.selected;
60 <OperandType1>[] vector1 = inputColVector1.vector;
61 <OperandType2>[] vector2 = inputColVector2.vector;
62 <ReturnType>[] outputVector = outputColVector.vector;
64 // return immediately if batch is empty
69 outputColVector.isRepeating =
70 inputColVector1.isRepeating && inputColVector2.isRepeating
71 || inputColVector1.isRepeating && !inputColVector1.noNulls && inputColVector1.isNull[0]
72 || inputColVector2.isRepeating && !inputColVector2.noNulls && inputColVector2.isNull[0];
75 NullUtil.propagateNullsColCol(
76 inputColVector1, inputColVector2, outputColVector, sel, n, batch.selectedInUse);
78 /* Disregard nulls for processing. In other words,
79 * the arithmetic operation is performed even if one or
80 * more inputs are null. This is to improve speed by avoiding
81 * conditional checks in the inner loop.
83 boolean hasDivBy0 = false;
84 if (inputColVector1.isRepeating && inputColVector2.isRepeating) {
85 <OperandType2> denom = vector2[0];
86 outputVector[0] = vector1[0] <OperatorSymbol> denom;
87 hasDivBy0 = hasDivBy0 || (denom == 0);
88 } else if (inputColVector1.isRepeating) {
89 final <OperandType1> vector1Value = vector1[0];
90 if (batch.selectedInUse) {
91 for(int j = 0; j != n; j++) {
93 <OperandType2> denom = vector2[i];
94 outputVector[i] = vector1Value <OperatorSymbol> denom;
95 hasDivBy0 = hasDivBy0 || (denom == 0);
98 for(int i = 0; i != n; i++) {
99 outputVector[i] = vector1Value <OperatorSymbol> vector2[i];
102 for(int i = 0; i != n; i++) {
103 hasDivBy0 = hasDivBy0 || (vector2[i] == 0);
106 } else if (inputColVector2.isRepeating) {
107 final <OperandType2> vector2Value = vector2[0];
108 if (vector2Value == 0) {
109 // Denominator is zero, convert the batch to nulls
110 outputColVector.noNulls = false;
111 outputColVector.isRepeating = true;
112 outputColVector.isNull[0] = true;
113 } else if (batch.selectedInUse) {
114 for(int j = 0; j != n; j++) {
116 outputVector[i] = vector1[i] <OperatorSymbol> vector2Value;
119 for(int i = 0; i != n; i++) {
120 outputVector[i] = vector1[i] <OperatorSymbol> vector2Value;
124 if (batch.selectedInUse) {
125 for(int j = 0; j != n; j++) {
127 <OperandType2> denom = vector2[i];
128 outputVector[i] = vector1[i] <OperatorSymbol> denom;
129 hasDivBy0 = hasDivBy0 || (denom == 0);
132 for(int i = 0; i != n; i++) {
133 outputVector[i] = vector1[i] <OperatorSymbol> vector2[i];
136 for(int i = 0; i != n; i++) {
137 hasDivBy0 = hasDivBy0 || (vector2[i] == 0);
142 /* For the case when the output can have null values, follow
143 * the convention that the data values must be 1 for long and
144 * NaN for double. This is to prevent possible later zero-divide errors
145 * in complex arithmetic expressions like col2 <OperatorSymbol> (col1 - 1)
146 * in the case when some col1 entries are null.
149 NullUtil.setNullDataEntries<CamelReturnType>(outputColVector, batch.selectedInUse, sel, n);
151 NullUtil.setNullAndDivBy0DataEntries<CamelReturnType>(
152 outputColVector, batch.selectedInUse, sel, n, inputColVector2);
157 public int getOutputColumn() {
162 public String getOutputType() {
163 return "<ReturnType>";
166 public int getColNum1() {
170 public void setColNum1(int colNum1) {
171 this.colNum1 = colNum1;
174 public int getColNum2() {
178 public void setColNum2(int colNum2) {
179 this.colNum2 = colNum2;
182 public void setOutputColumn(int outputColumn) {
183 this.outputColumn = outputColumn;
187 public String vectorExpressionParameters() {
188 return "col " + colNum1 + ", col " + + colNum2;
192 public VectorExpressionDescriptor.Descriptor getDescriptor() {
193 return (new VectorExpressionDescriptor.Builder())
195 VectorExpressionDescriptor.Mode.PROJECTION)
198 VectorExpressionDescriptor.ArgumentType.getType("<OperandType1>"),
199 VectorExpressionDescriptor.ArgumentType.getType("<OperandType2>"))
200 .setInputExpressionTypes(
201 VectorExpressionDescriptor.InputExpressionType.COLUMN,
202 VectorExpressionDescriptor.InputExpressionType.COLUMN).build();