Skip to content

Commit

Permalink
HIVE-6752: Vectorized Between and IN expressions don't work with deci…
Browse files Browse the repository at this point in the history
…mal, date types. (reviewed by Eric Hanson, Sergey)

git-svn-id: https://svn.apache.org/repos/asf/hive/trunk@1582915 13f79535-47bb-0310-9956-ffa450edef68
  • Loading branch information
jnp committed Mar 28, 2014
1 parent 79bc1ad commit 215c4f6
Show file tree
Hide file tree
Showing 12 changed files with 1,428 additions and 93 deletions.
19 changes: 19 additions & 0 deletions ant/src/org/apache/hadoop/hive/ant/GenVectorCode.java
Expand Up @@ -329,6 +329,9 @@ public class GenVectorCode extends Task {
{"FilterColumnBetween", "long", "!"},
{"FilterColumnBetween", "double", "!"},

{"FilterDecimalColumnBetween", ""},
{"FilterDecimalColumnBetween", "!"},

{"ColumnCompareColumn", "Equal", "long", "double", "=="},
{"ColumnCompareColumn", "Equal", "double", "double", "=="},
{"ColumnCompareColumn", "NotEqual", "long", "double", "!="},
Expand Down Expand Up @@ -659,6 +662,8 @@ private void generate() throws Exception {
generateFilterStringColumnCompareScalar(tdesc);
} else if (tdesc[0].equals("FilterStringColumnBetween")) {
generateFilterStringColumnBetween(tdesc);
} else if (tdesc[0].equals("FilterDecimalColumnBetween")) {
generateFilterDecimalColumnBetween(tdesc);
} else if (tdesc[0].equals("StringColumnCompareScalar")) {
generateStringColumnCompareScalar(tdesc);
} else if (tdesc[0].equals("FilterStringScalarCompareColumn")) {
Expand Down Expand Up @@ -705,6 +710,20 @@ private void generateFilterStringColumnBetween(String[] tdesc) throws IOExceptio
className, templateString);
}

private void generateFilterDecimalColumnBetween(String[] tdesc) throws IOException {
String optionalNot = tdesc[1];
String className = "FilterDecimalColumn" + (optionalNot.equals("!") ? "Not" : "")
+ "Between";
// Read the template into a string, expand it, and write it.
File templateFile = new File(joinPath(this.expressionTemplateDirectory, tdesc[0] + ".txt"));
String templateString = readFile(templateFile);
templateString = templateString.replaceAll("<ClassName>", className);
templateString = templateString.replaceAll("<OptionalNot>", optionalNot);

writeFile(templateFile.lastModified(), expressionOutputDirectory, expressionClassesDirectory,
className, templateString);
}

private void generateFilterColumnBetween(String[] tdesc) throws Exception {
String operandType = tdesc[1];
String optionalNot = tdesc[2];
Expand Down
@@ -0,0 +1,194 @@
/**
* 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.common.type.Decimal128;
import org.apache.hadoop.hive.ql.exec.vector.DecimalColumnVector;
import org.apache.hadoop.hive.ql.exec.vector.expressions.VectorExpression;
import org.apache.hadoop.hive.ql.exec.vector.VectorizedRowBatch;
import org.apache.hadoop.hive.ql.exec.vector.VectorExpressionDescriptor;

/**
* Generated from template FilterDecimalColumnBetween.txt, which covers [NOT] BETWEEN filter
* expressions where a column is [NOT] between one scalar and another.
* Output is not produced in a separate column. The selected vector of the input
* {@link VectorizedRowBatch} is updated for in-place filtering.
*/
public class <ClassName> extends VectorExpression {

private static final long serialVersionUID = 1L;

private int colNum;

// The comparison is of the form "column BETWEEN leftValue AND rightValue"
private Decimal128 leftValue;
private Decimal128 rightValue;

public <ClassName>(int colNum, Decimal128 leftValue, Decimal128 rightValue) {
this.colNum = colNum;
this.leftValue = leftValue;
this.rightValue = rightValue;
}

public <ClassName>() {
}

@Override
public void evaluate(VectorizedRowBatch batch) {

if (childExpressions != null) {
super.evaluateChildren(batch);
}

DecimalColumnVector inputColVector = (DecimalColumnVector) batch.cols[colNum];
int[] sel = batch.selected;
boolean[] nullPos = inputColVector.isNull;
int n = batch.size;
Decimal128[] vector = inputColVector.vector;

// return immediately if batch is empty
if (n == 0) {
return;
}

if (inputColVector.noNulls) {
if (inputColVector.isRepeating) {

// All must be selected otherwise size would be zero.
// Repeating property will not change.
if (<OptionalNot>(vector[0].compareTo(leftValue) < 0 || vector[0].compareTo(rightValue) > 0)) {

// Entire batch is filtered out.
batch.size = 0;
}
} else if (batch.selectedInUse) {
int newSize = 0;
for(int j = 0; j != n; j++) {
int i = sel[j];
if (<OptionalNot>(leftValue.compareTo(vector[i]) <= 0 && vector[i].compareTo(rightValue) <= 0)) {
sel[newSize++] = i;
}
}
batch.size = newSize;
} else {
int newSize = 0;
for(int i = 0; i != n; i++) {
if (<OptionalNot>(leftValue.compareTo(vector[i]) <= 0 && vector[i].compareTo(rightValue) <= 0)) {
sel[newSize++] = i;
}
}
if (newSize < n) {
batch.size = newSize;
batch.selectedInUse = true;
}
}
} else {
if (inputColVector.isRepeating) {

// All must be selected otherwise size would be zero.
// Repeating property will not change.
if (!nullPos[0]) {
if (<OptionalNot>(vector[0].compareTo(leftValue) < 0 || vector[0].compareTo(rightValue) > 0)) {

// Entire batch is filtered out.
batch.size = 0;
}
} else {
batch.size = 0;
}
} else if (batch.selectedInUse) {
int newSize = 0;
for(int j = 0; j != n; j++) {
int i = sel[j];
if (!nullPos[i]) {
if (<OptionalNot>(leftValue.compareTo(vector[i]) <= 0 && vector[i].compareTo(rightValue) <= 0)) {
sel[newSize++] = i;
}
}
}

// Change the selected vector
batch.size = newSize;
} else {
int newSize = 0;
for(int i = 0; i != n; i++) {
if (!nullPos[i]) {
if (<OptionalNot>(leftValue.compareTo(vector[i]) <= 0 && vector[i].compareTo(rightValue) <= 0)) {
sel[newSize++] = i;
}
}
}
if (newSize < n) {
batch.size = newSize;
batch.selectedInUse = true;
}
}
}
}

@Override
public int getOutputColumn() {
return -1;
}

@Override
public String getOutputType() {
return "boolean";
}

public int getColNum() {
return colNum;
}

public void setColNum(int colNum) {
this.colNum = colNum;
}

public Decimal128 getLeftValue() {
return leftValue;
}

public void setLeftValue(Decimal128 value) {
this.leftValue = value;
}

public Decimal128 getRightValue() {
return rightValue;
}

public void setRightValue(Decimal128 value) {
this.leftValue = value;
}

@Override
public VectorExpressionDescriptor.Descriptor getDescriptor() {
return (new VectorExpressionDescriptor.Builder())
.setMode(
VectorExpressionDescriptor.Mode.FILTER)
.setNumArguments(3)
.setArgumentTypes(
VectorExpressionDescriptor.ArgumentType.getType("decimal"),
VectorExpressionDescriptor.ArgumentType.getType("decimal"),
VectorExpressionDescriptor.ArgumentType.getType("decimal"))
.setInputExpressionTypes(
VectorExpressionDescriptor.InputExpressionType.COLUMN,
VectorExpressionDescriptor.InputExpressionType.SCALAR,
VectorExpressionDescriptor.InputExpressionType.SCALAR).build();
}
}
Expand Up @@ -222,7 +222,8 @@ public void assignNullString(int index) {
}

public void assignDecimal(int index, Decimal128 value) {
decimalValues[index].update(value);
decimalValues[index].update(value);
isNull[longValues.length + doubleValues.length + byteValues.length + index] = false;
}

public void assignNullDecimal(int index) {
Expand Down

0 comments on commit 215c4f6

Please sign in to comment.