/**
* 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 static org.junit.Assert.*;
import org.apache.hadoop.hive.ql.exec.vector.BytesColumnVector;
import org.apache.hadoop.hive.ql.exec.vector.DoubleColumnVector;
import org.apache.hadoop.hive.ql.exec.vector.LongColumnVector;
import org.apache.hadoop.hive.ql.exec.vector.VectorizedRowBatch;
import org.apache.hadoop.hive.ql.exec.vector.expressions.gen.IfExprLongColumnLongColumn;
import org.apache.hadoop.hive.ql.exec.vector.expressions.gen.IfExprDoubleColumnDoubleColumn;
import org.apache.hadoop.hive.ql.exec.vector.expressions.gen.IfExprLongColumnLongScalar;
import org.apache.hadoop.hive.ql.exec.vector.expressions.gen.IfExprLongScalarLongColumn;
import org.apache.hadoop.hive.ql.exec.vector.expressions.gen.IfExprLongScalarLongScalar;
import org.apache.hadoop.hive.ql.exec.vector.expressions.gen.IfExprDoubleScalarDoubleScalar;
import org.apache.hadoop.hive.ql.exec.vector.expressions.gen.IfExprDoubleScalarDoubleColumn;
import org.apache.hadoop.hive.ql.exec.vector.expressions.gen.IfExprDoubleColumnDoubleScalar;
import org.apache.hadoop.hive.ql.exec.vector.expressions.IfExprStringGroupColumnStringGroupColumn;
import org.apache.hadoop.hive.ql.exec.vector.expressions.IfExprStringGroupColumnStringScalar;
import org.apache.hadoop.hive.ql.exec.vector.expressions.IfExprStringScalarStringGroupColumn;
import org.apache.hadoop.hive.ql.exec.vector.expressions.IfExprStringScalarStringScalar;
import org.junit.Test;
/**
* Test vectorized conditional expression handling.
*/
public class TestVectorConditionalExpressions {
private VectorizedRowBatch getBatch4LongVectors() {
VectorizedRowBatch batch = new VectorizedRowBatch(4);
LongColumnVector v = new LongColumnVector();
// set first argument to IF -- boolean flag
v.vector[0] = 0;
v.vector[1] = 0;
v.vector[2] = 1;
v.vector[3] = 1;
batch.cols[0] = v;
// set second argument to IF
v = new LongColumnVector();
v.vector[0] = -1;
v.vector[1] = -2;
v.vector[2] = -3;
v.vector[3] = -4;
batch.cols[1] = v;
// set third argument to IF
v = new LongColumnVector();
v.vector[0] = 1;
v.vector[1] = 2;
v.vector[2] = 3;
v.vector[3] = 4;
batch.cols[2] = v;
// set output column
batch.cols[3] = new LongColumnVector();
batch.size = 4;
return batch;
}
private VectorizedRowBatch getBatch1Long3DoubleVectors() {
VectorizedRowBatch batch = new VectorizedRowBatch(4);
LongColumnVector lv = new LongColumnVector();
// set first argument to IF -- boolean flag
lv.vector[0] = 0;
lv.vector[1] = 0;
lv.vector[2] = 1;
lv.vector[3] = 1;
batch.cols[0] = lv;
// set second argument to IF
DoubleColumnVector v = new DoubleColumnVector();
v.vector[0] = -1;
v.vector[1] = -2;
v.vector[2] = -3;
v.vector[3] = -4;
batch.cols[1] = v;
// set third argument to IF
v = new DoubleColumnVector();
v.vector[0] = 1;
v.vector[1] = 2;
v.vector[2] = 3;
v.vector[3] = 4;
batch.cols[2] = v;
// set output column
batch.cols[3] = new DoubleColumnVector();
batch.size = 4;
return batch;
}
private VectorizedRowBatch getBatch1Long3BytesVectors() {
VectorizedRowBatch batch = new VectorizedRowBatch(4);
LongColumnVector lv = new LongColumnVector();
// set first argument to IF -- boolean flag
lv.vector[0] = 0;
lv.vector[1] = 0;
lv.vector[2] = 1;
lv.vector[3] = 1;
batch.cols[0] = lv;
// set second argument to IF
BytesColumnVector v = new BytesColumnVector();
v.initBuffer();
setString(v, 0, "arg2_0");
setString(v, 1, "arg2_1");
setString(v, 2, "arg2_2");
setString(v, 3, "arg2_3");
batch.cols[1] = v;
// set third argument to IF
v = new BytesColumnVector();
v.initBuffer();
setString(v, 0, "arg3_0");
setString(v, 1, "arg3_1");
setString(v, 2, "arg3_2");
setString(v, 3, "arg3_3");
batch.cols[2] = v;
// set output column
v = new BytesColumnVector();
v.initBuffer();
batch.cols[3] = v;
batch.size = 4;
return batch;
}
private void setString(BytesColumnVector v, int i, String s) {
byte[] b = getUTF8Bytes(s);
v.setVal(i, b, 0, b.length);
}
private byte[] getUTF8Bytes(String s) {
byte[] b = null;
try {
b = s.getBytes("UTF-8");
} catch (Exception e) {
; // eat it
}
return b;
}
private String getString(BytesColumnVector v, int i) {
String s = null;
try {
s = new String(v.vector[i], v.start[i], v.length[i], "UTF-8");
} catch (Exception e) {
; // eat it
}
return s;
}
@Test
public void testLongColumnColumnIfExpr() {
VectorizedRowBatch batch = getBatch4LongVectors();
VectorExpression expr = new IfExprLongColumnLongColumn(0, 1, 2, 3);
expr.evaluate(batch);
// get result vector
LongColumnVector r = (LongColumnVector) batch.cols[3];
// verify standard case
assertEquals(1, r.vector[0]);
assertEquals(2, r.vector[1]);
assertEquals(-3, r.vector[2]);
assertEquals(-4, r.vector[3]);
assertEquals(true, r.noNulls);
assertEquals(false, r.isRepeating);
// verify when first argument (boolean flags) is repeating
batch = getBatch4LongVectors();
r = (LongColumnVector) batch.cols[3];
batch.cols[0].isRepeating = true;
expr.evaluate(batch);
assertEquals(1, r.vector[0]);
assertEquals(4, r.vector[3]);
// verify when second argument is repeating
batch = getBatch4LongVectors();
r = (LongColumnVector) batch.cols[3];
batch.cols[1].isRepeating = true;
expr.evaluate(batch);
assertEquals(1, r.vector[0]);
assertEquals(2, r.vector[1]);
assertEquals(-1, r.vector[2]);
assertEquals(-1, r.vector[3]);
// verify when third argument is repeating
batch = getBatch4LongVectors();
r = (LongColumnVector) batch.cols[3];
batch.cols[2].isRepeating = true;
expr.evaluate(batch);
assertEquals(1, r.vector[0]);
assertEquals(1, r.vector[1]);
assertEquals(-3, r.vector[2]);
assertEquals(-4, r.vector[3]);
// test when first argument has nulls
batch = getBatch4LongVectors();
r = (LongColumnVector) batch.cols[3];
batch.cols[0].noNulls = false;
batch.cols[0].isNull[1] = true;
batch.cols[0].isNull[2] = true;
expr.evaluate(batch);
assertEquals(1, r.vector[0]);
assertEquals(2, r.vector[1]);
assertEquals(3, r.vector[2]);
assertEquals(-4, r.vector[3]);
assertEquals(true, r.noNulls);
assertEquals(false, r.isRepeating);
// test when second argument has nulls
batch = getBatch4LongVectors();
r = (LongColumnVector) batch.cols[3];
batch.cols[1].noNulls = false;
batch.cols[1].isNull[1] = true;
batch.cols[1].isNull[2] = true;
expr.evaluate(batch);
assertEquals(1, r.vector[0]);
assertEquals(2, r.vector[1]);
assertEquals(true, r.isNull[2]);
assertEquals(-4, r.vector[3]);
assertEquals(false, r.noNulls);
assertEquals(false, r.isRepeating);
// test when third argument has nulls
batch = getBatch4LongVectors();
r = (LongColumnVector) batch.cols[3];
batch.cols[2].noNulls = false;
batch.cols[2].isNull[1] = true;
batch.cols[2].isNull[2] = true;
expr.evaluate(batch);
assertEquals(1, r.vector[0]);
assertEquals(true, r.isNull[1]);
assertEquals(-3, r.vector[2]);
assertEquals(-4, r.vector[3]);
assertEquals(false, r.noNulls);
assertEquals(false, r.isRepeating);
// test when second argument has nulls and repeats
batch = getBatch4LongVectors();
r = (LongColumnVector) batch.cols[3];
batch.cols[1].noNulls = false;
batch.cols[1].isNull[0] = true;
batch.cols[1].isRepeating = true;
expr.evaluate(batch);
assertEquals(1, r.vector[0]);
assertEquals(2, r.vector[1]);
assertEquals(true, r.isNull[2]);
assertEquals(true, r.isNull[3]);
assertEquals(false, r.noNulls);
assertEquals(false, r.isRepeating);
// test when third argument has nulls and repeats
batch = getBatch4LongVectors();
r = (LongColumnVector) batch.cols[3];
batch.cols[2].noNulls = false;
batch.cols[2].isNull[0] = true;
batch.cols[2].isRepeating = true;
expr.evaluate(batch);
assertEquals(true, r.isNull[0]);
assertEquals(true, r.isNull[1]);
assertEquals(-3, r.vector[2]);
assertEquals(-4, r.vector[3]);
assertEquals(false, r.noNulls);
assertEquals(false, r.isRepeating);
}
@Test
public void testDoubleColumnColumnIfExpr() {
// Just spot check because we already checked the logic for long.
// The code is from the same template file.
VectorizedRowBatch batch = getBatch1Long3DoubleVectors();
VectorExpression expr = new IfExprDoubleColumnDoubleColumn(0, 1, 2, 3);
expr.evaluate(batch);
// get result vector
DoubleColumnVector r = (DoubleColumnVector) batch.cols[3];
// verify standard case
assertEquals(true, 1d == r.vector[0]);
assertEquals(true, 2d == r.vector[1]);
assertEquals(true, -3d == r.vector[2]);
assertEquals(true, -4d == r.vector[3]);
assertEquals(true, r.noNulls);
assertEquals(false, r.isRepeating);
}
@Test
public void testLongColumnScalarIfExpr() {
VectorizedRowBatch batch = getBatch4LongVectors();
VectorExpression expr = new IfExprLongColumnLongScalar(0, 1, 100, 3);
LongColumnVector r = (LongColumnVector) batch.cols[3];
expr.evaluate(batch);
assertEquals(100, r.vector[0]);
assertEquals(100, r.vector[1]);
assertEquals(-3, r.vector[2]);
assertEquals(-4, r.vector[3]);
}
@Test
public void testLongScalarColumnIfExpr() {
VectorizedRowBatch batch = getBatch4LongVectors();
VectorExpression expr = new IfExprLongScalarLongColumn(0, 100, 2, 3);
LongColumnVector r = (LongColumnVector) batch.cols[3];
expr.evaluate(batch);
assertEquals(1, r.vector[0]);
assertEquals(2, r.vector[1]);
assertEquals(100, r.vector[2]);
assertEquals(100, r.vector[3]);
}
@Test
public void testLongScalarScalarIfExpr() {
VectorizedRowBatch batch = getBatch4LongVectors();
VectorExpression expr = new IfExprLongScalarLongScalar(0, 100, 200, 3);
LongColumnVector r = (LongColumnVector) batch.cols[3];
expr.evaluate(batch);
assertEquals(200, r.vector[0]);
assertEquals(200, r.vector[1]);
assertEquals(100, r.vector[2]);
assertEquals(100, r.vector[3]);
}
@Test
public void testDoubleScalarScalarIfExpr() {
VectorizedRowBatch batch = getBatch1Long3DoubleVectors();
VectorExpression expr = new IfExprDoubleScalarDoubleScalar(0, 100.0d, 200.0d, 3);
DoubleColumnVector r = (DoubleColumnVector) batch.cols[3];
expr.evaluate(batch);
assertEquals(true, 200d == r.vector[0]);
assertEquals(true, 200d == r.vector[1]);
assertEquals(true, 100d == r.vector[2]);
assertEquals(true, 100d == r.vector[3]);
}
@Test
public void testDoubleScalarColumnIfExpr() {
VectorizedRowBatch batch = getBatch1Long3DoubleVectors();
VectorExpression expr = new IfExprDoubleScalarDoubleColumn(0, 100.0d, 2, 3);
DoubleColumnVector r = (DoubleColumnVector) batch.cols[3];
expr.evaluate(batch);
assertEquals(true, 1d == r.vector[0]);
assertEquals(true, 2d == r.vector[1]);
assertEquals(true, 100d == r.vector[2]);
assertEquals(true, 100d == r.vector[3]);
}
@Test
public void testDoubleColumnScalarIfExpr() {
VectorizedRowBatch batch = getBatch1Long3DoubleVectors();
VectorExpression expr = new IfExprDoubleColumnDoubleScalar(0, 1, 200d, 3);
DoubleColumnVector r = (DoubleColumnVector) batch.cols[3];
expr.evaluate(batch);
assertEquals(true, 200d == r.vector[0]);
assertEquals(true, 200d == r.vector[1]);
assertEquals(true, -3d == r.vector[2]);
assertEquals(true, -4d == r.vector[3]);
}
@Test
public void testIfExprStringColumnStringColumn() {
VectorizedRowBatch batch = getBatch1Long3BytesVectors();
VectorExpression expr = new IfExprStringGroupColumnStringGroupColumn(0, 1, 2, 3);
BytesColumnVector r = (BytesColumnVector) batch.cols[3];
expr.evaluate(batch);
assertTrue(getString(r, 0).equals("arg3_0"));
assertTrue(getString(r, 1).equals("arg3_1"));
assertTrue(getString(r, 2).equals("arg2_2"));
assertTrue(getString(r, 3).equals("arg2_3"));
// test first IF argument repeating
batch = getBatch1Long3BytesVectors();
batch.cols[0].isRepeating = true;
r = (BytesColumnVector) batch.cols[3];
expr.evaluate(batch);
assertTrue(getString(r, 0).equals("arg3_0"));
assertTrue(getString(r, 1).equals("arg3_1"));
assertTrue(getString(r, 2).equals("arg3_2"));
assertTrue(getString(r, 3).equals("arg3_3"));
// test second IF argument repeating
batch = getBatch1Long3BytesVectors();
batch.cols[1].isRepeating = true;
r = (BytesColumnVector) batch.cols[3];
expr.evaluate(batch);
assertTrue(getString(r, 0).equals("arg3_0"));
assertTrue(getString(r, 1).equals("arg3_1"));
assertTrue(getString(r, 2).equals("arg2_0"));
assertTrue(getString(r, 3).equals("arg2_0"));
// test third IF argument repeating
batch = getBatch1Long3BytesVectors();
batch.cols[2].isRepeating = true;
r = (BytesColumnVector) batch.cols[3];
expr.evaluate(batch);
assertTrue(getString(r, 0).equals("arg3_0"));
assertTrue(getString(r, 1).equals("arg3_0"));
assertTrue(getString(r, 2).equals("arg2_2"));
assertTrue(getString(r, 3).equals("arg2_3"));
// test second IF argument with nulls
batch = getBatch1Long3BytesVectors();
batch.cols[1].noNulls = false;
batch.cols[1].isNull[2] = true;
// set vector[2] to null to verify correct null handling
((BytesColumnVector) batch.cols[1]).vector[2] = null;
r = (BytesColumnVector) batch.cols[3];
expr.evaluate(batch);
assertTrue(getString(r, 0).equals("arg3_0"));
assertTrue(getString(r, 1).equals("arg3_1"));
assertTrue(!r.noNulls && r.isNull[2]);
assertTrue(getString(r, 3).equals("arg2_3"));
assertFalse(r.isNull[0] || r.isNull[1] || r.isNull[3]);
// test third IF argument with nulls
batch = getBatch1Long3BytesVectors();
batch.cols[2].noNulls = false;
batch.cols[2].isNull[0] = true;
// set vector[0] to null object reference to verify correct null handling
((BytesColumnVector) batch.cols[2]).vector[0] = null;
r = (BytesColumnVector) batch.cols[3];
expr.evaluate(batch);
assertTrue(!r.noNulls && r.isNull[0]);
assertTrue(getString(r, 1).equals("arg3_1"));
assertTrue(getString(r, 2).equals("arg2_2"));
assertTrue(getString(r, 3).equals("arg2_3"));
assertFalse(r.isNull[1] || r.isNull[2] || r.isNull[3]);
// test second IF argument with nulls and repeating
batch = getBatch1Long3BytesVectors();
batch.cols[1].noNulls = false;
batch.cols[1].isNull[0] = true;
batch.cols[1].isRepeating = true;
r = (BytesColumnVector) batch.cols[3];
expr.evaluate(batch);
assertTrue(getString(r, 0).equals("arg3_0"));
assertTrue(getString(r, 1).equals("arg3_1"));
assertTrue(!r.noNulls && r.isNull[2]);
assertTrue(!r.noNulls && r.isNull[3]);
assertFalse(r.isNull[0] || r.isNull[1]);
}
@Test
public void testIfExprStringColumnStringScalar() {
VectorizedRowBatch batch = getBatch1Long3BytesVectors();
byte[] scalar = getUTF8Bytes("scalar");
VectorExpression expr = new IfExprStringGroupColumnStringScalar(0, 1, scalar, 3);
BytesColumnVector r = (BytesColumnVector) batch.cols[3];
expr.evaluate(batch);
assertTrue(getString(r, 0).equals("scalar"));
assertTrue(getString(r, 1).equals("scalar"));
assertTrue(getString(r, 2).equals("arg2_2"));
assertTrue(getString(r, 3).equals("arg2_3"));
assertTrue(r.noNulls);
// test for null input strings
batch = getBatch1Long3BytesVectors();
BytesColumnVector arg2 = (BytesColumnVector) batch.cols[1];
arg2.noNulls = false;
arg2.isNull[2] = true;
arg2.vector[2] = null;
expr.evaluate(batch);
r = (BytesColumnVector) batch.cols[3];
assertTrue(!r.noNulls && r.isNull[2]);
}
@Test
public void testIfExprStringScalarStringColumn() {
VectorizedRowBatch batch = getBatch1Long3BytesVectors();
byte[] scalar = getUTF8Bytes("scalar");
VectorExpression expr = new IfExprStringScalarStringGroupColumn(0,scalar, 2, 3);
BytesColumnVector r = (BytesColumnVector) batch.cols[3];
expr.evaluate(batch);
assertTrue(getString(r, 0).equals("arg3_0"));
assertTrue(getString(r, 1).equals("arg3_1"));
assertTrue(getString(r, 2).equals("scalar"));
assertTrue(getString(r, 3).equals("scalar"));
assertTrue(r.noNulls);
// test for null input strings
batch = getBatch1Long3BytesVectors();
BytesColumnVector arg3 = (BytesColumnVector) batch.cols[2];
arg3.noNulls = false;
arg3.isNull[1] = true;
arg3.vector[1] = null;
expr.evaluate(batch);
r = (BytesColumnVector) batch.cols[3];
assertTrue(!r.noNulls && r.isNull[1]);
}
@Test
public void testIfExprStringScalarStringScalar() {
// standard case
VectorizedRowBatch batch = getBatch1Long3BytesVectors();
byte[] scalar1 = getUTF8Bytes("scalar1");
byte[] scalar2 = getUTF8Bytes("scalar2");
VectorExpression expr = new IfExprStringScalarStringScalar(0,scalar1, scalar2, 3);
BytesColumnVector r = (BytesColumnVector) batch.cols[3];
expr.evaluate(batch);
assertTrue(getString(r, 0).equals("scalar2"));
assertTrue(getString(r, 1).equals("scalar2"));
assertTrue(getString(r, 2).equals("scalar1"));
assertTrue(getString(r, 3).equals("scalar1"));
assertFalse(r.isRepeating);
// repeating case for first (boolean flag) argument to IF
batch = getBatch1Long3BytesVectors();
batch.cols[0].isRepeating = true;
expr.evaluate(batch);
r = (BytesColumnVector) batch.cols[3];
assertTrue(r.isRepeating);
assertTrue(getString(r, 0).equals("scalar2"));
}
}