Modified: hive/trunk/ql/src/test/org/apache/hadoop/hive/ql/exec/vector/TestVectorizationContext.java URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/test/org/apache/hadoop/hive/ql/exec/vector/TestVectorizationContext.java?rev=1550488&r1=1550487&r2=1550488&view=diff ============================================================================== --- hive/trunk/ql/src/test/org/apache/hadoop/hive/ql/exec/vector/TestVectorizationContext.java (original) +++ hive/trunk/ql/src/test/org/apache/hadoop/hive/ql/exec/vector/TestVectorizationContext.java Thu Dec 12 19:01:09 2013 @@ -37,6 +37,10 @@ import org.apache.hadoop.hive.ql.exec.ve import org.apache.hadoop.hive.ql.exec.vector.expressions.FuncLogWithBaseDoubleToDouble; import org.apache.hadoop.hive.ql.exec.vector.expressions.FuncLogWithBaseLongToDouble; import org.apache.hadoop.hive.ql.exec.vector.expressions.FuncPowerDoubleToDouble; +import org.apache.hadoop.hive.ql.exec.vector.expressions.IfExprStringColumnStringColumn; +import org.apache.hadoop.hive.ql.exec.vector.expressions.IfExprStringColumnStringScalar; +import org.apache.hadoop.hive.ql.exec.vector.expressions.IfExprStringScalarStringColumn; +import org.apache.hadoop.hive.ql.exec.vector.expressions.IfExprStringScalarStringScalar; import org.apache.hadoop.hive.ql.exec.vector.expressions.IsNotNull; import org.apache.hadoop.hive.ql.exec.vector.expressions.IsNull; import org.apache.hadoop.hive.ql.exec.vector.expressions.LongColumnInList; @@ -56,6 +60,15 @@ import org.apache.hadoop.hive.ql.exec.ve import org.apache.hadoop.hive.ql.exec.vector.expressions.FilterStringColumnInList; import org.apache.hadoop.hive.ql.exec.vector.expressions.FilterLongColumnInList; import org.apache.hadoop.hive.ql.exec.vector.expressions.FilterDoubleColumnInList; +import org.apache.hadoop.hive.ql.exec.vector.expressions.gen.IfExprLongColumnLongColumn; +import org.apache.hadoop.hive.ql.exec.vector.expressions.gen.IfExprLongColumnLongScalar; +import org.apache.hadoop.hive.ql.exec.vector.expressions.gen.IfExprLongScalarLongScalar; +import org.apache.hadoop.hive.ql.exec.vector.expressions.gen.IfExprLongScalarLongColumn; +import org.apache.hadoop.hive.ql.exec.vector.expressions.gen.IfExprDoubleColumnDoubleColumn; +import org.apache.hadoop.hive.ql.exec.vector.expressions.gen.IfExprDoubleColumnDoubleScalar; +import org.apache.hadoop.hive.ql.exec.vector.expressions.gen.IfExprDoubleScalarDoubleColumn; +import org.apache.hadoop.hive.ql.exec.vector.expressions.gen.IfExprDoubleScalarDoubleScalar; +import org.apache.hadoop.hive.ql.exec.vector.expressions.gen.IfExprDoubleScalarLongColumn; import org.apache.hadoop.hive.ql.exec.vector.expressions.gen.DoubleColUnaryMinus; import org.apache.hadoop.hive.ql.exec.vector.expressions.gen.FilterDoubleColLessDoubleScalar; import org.apache.hadoop.hive.ql.exec.vector.expressions.gen.FilterDoubleColumnBetween; @@ -93,6 +106,7 @@ import org.apache.hadoop.hive.ql.udf.UDF import org.apache.hadoop.hive.ql.udf.generic.GenericUDF; import org.apache.hadoop.hive.ql.udf.generic.GenericUDFBetween; import org.apache.hadoop.hive.ql.udf.generic.GenericUDFBridge; +import org.apache.hadoop.hive.ql.udf.generic.GenericUDFIf; import org.apache.hadoop.hive.ql.udf.generic.GenericUDFIn; import org.apache.hadoop.hive.ql.udf.generic.GenericUDFLower; import org.apache.hadoop.hive.ql.udf.generic.GenericUDFOPAnd; @@ -111,6 +125,7 @@ import org.apache.hadoop.hive.ql.udf.gen import org.apache.hadoop.hive.ql.udf.generic.GenericUDFRound; import org.apache.hadoop.hive.ql.udf.generic.GenericUDFOPPlus; import org.apache.hadoop.hive.ql.udf.generic.GenericUDFToUnixTimeStamp; +import org.apache.hadoop.hive.ql.udf.generic.GenericUDFTimestamp; import org.apache.hadoop.hive.serde2.typeinfo.TypeInfoFactory; import org.junit.Test; @@ -1004,4 +1019,177 @@ public class TestVectorizationContext { ve = vc.getVectorExpression(exprDesc, VectorExpressionDescriptor.Mode.PROJECTION); assertTrue(ve instanceof DoubleColumnInList); } + + /** + * Test that correct VectorExpression classes are chosen for the + * IF (expr1, expr2, expr3) conditional expression for integer, float, + * boolean, timestamp and string input types. expr1 is always an input column expression + * of type long. expr2 and expr3 can be column expressions or constants of other types + * but must have the same type. + */ + @Test + public void testIfConditionalExprs() throws HiveException { + ExprNodeColumnDesc col1Expr = new ExprNodeColumnDesc(Long.class, "col1", "table", false); + ExprNodeColumnDesc col2Expr = new ExprNodeColumnDesc(Long.class, "col2", "table", false); + ExprNodeColumnDesc col3Expr = new ExprNodeColumnDesc(Long.class, "col3", "table", false); + + ExprNodeConstantDesc constDesc2 = new ExprNodeConstantDesc(new Integer(1)); + ExprNodeConstantDesc constDesc3 = new ExprNodeConstantDesc(new Integer(2)); + + // long column/column IF + GenericUDFIf udf = new GenericUDFIf(); + ExprNodeGenericFuncDesc exprDesc = new ExprNodeGenericFuncDesc(); + exprDesc.setGenericUDF(udf); + List<ExprNodeDesc> children1 = new ArrayList<ExprNodeDesc>(); + children1.add(col1Expr); + children1.add(col2Expr); + children1.add(col3Expr); + exprDesc.setChildren(children1); + + Map<String, Integer> columnMap = new HashMap<String, Integer>(); + columnMap.put("col1", 1); + columnMap.put("col2", 2); + columnMap.put("col3", 3); + VectorizationContext vc = new VectorizationContext(columnMap, 3); + VectorExpression ve = vc.getVectorExpression(exprDesc); + assertTrue(ve instanceof IfExprLongColumnLongColumn); + + // long column/scalar IF + children1.set(2, new ExprNodeConstantDesc(1L)); + ve = vc.getVectorExpression(exprDesc); + assertTrue(ve instanceof IfExprLongColumnLongScalar); + + // long scalar/scalar IF + children1.set(1, new ExprNodeConstantDesc(1L)); + ve = vc.getVectorExpression(exprDesc); + assertTrue(ve instanceof IfExprLongScalarLongScalar); + + // long scalar/column IF + children1.set(2, col3Expr); + ve = vc.getVectorExpression(exprDesc); + assertTrue(ve instanceof IfExprLongScalarLongColumn); + + // test for double type + col2Expr = new ExprNodeColumnDesc(Double.class, "col2", "table", false); + col3Expr = new ExprNodeColumnDesc(Double.class, "col3", "table", false); + + // double column/column IF + children1.set(1, col2Expr); + children1.set(2, col3Expr); + ve = vc.getVectorExpression(exprDesc); + assertTrue(ve instanceof IfExprDoubleColumnDoubleColumn); + + // double column/scalar IF + children1.set(2, new ExprNodeConstantDesc(1D)); + ve = vc.getVectorExpression(exprDesc); + assertTrue(ve instanceof IfExprDoubleColumnDoubleScalar); + + // double scalar/scalar IF + children1.set(1, new ExprNodeConstantDesc(1D)); + ve = vc.getVectorExpression(exprDesc); + assertTrue(ve instanceof IfExprDoubleScalarDoubleScalar); + + // double scalar/column IF + children1.set(2, col3Expr); + ve = vc.getVectorExpression(exprDesc); + assertTrue(ve instanceof IfExprDoubleScalarDoubleColumn); + + // double scalar/long column IF + children1.set(2, new ExprNodeColumnDesc(Long.class, "col3", "table", false)); + ve = vc.getVectorExpression(exprDesc); + assertTrue(ve instanceof IfExprDoubleScalarLongColumn); + + // Additional combinations of (long,double)X(column,scalar) for each of the second + // and third arguments are omitted. We have coverage of all the source templates + // already. + + // test for timestamp type + col2Expr = new ExprNodeColumnDesc(Timestamp.class, "col2", "table", false); + col3Expr = new ExprNodeColumnDesc(Timestamp.class, "col3", "table", false); + + // timestamp column/column IF + children1.set(1, col2Expr); + children1.set(2, col3Expr); + ve = vc.getVectorExpression(exprDesc); + assertTrue(ve instanceof IfExprLongColumnLongColumn); + + // timestamp column/scalar IF where scalar is really a CAST of a constant to timestamp. + ExprNodeGenericFuncDesc f = new ExprNodeGenericFuncDesc(); + f.setGenericUDF(new GenericUDFTimestamp()); + f.setTypeInfo(TypeInfoFactory.timestampTypeInfo); + List<ExprNodeDesc> children2 = new ArrayList<ExprNodeDesc>(); + f.setChildren(children2); + children2.add(new ExprNodeConstantDesc("2013-11-05 00:00:00.000")); + children1.set(2, f); + ve = vc.getVectorExpression(exprDesc); + + // We check for two different classes below because initially the result + // is IfExprLongColumnLongColumn but in the future if the system is enhanced + // with constant folding then the result will be IfExprLongColumnLongScalar. + assertTrue(IfExprLongColumnLongColumn.class == ve.getClass() + || IfExprLongColumnLongScalar.class == ve.getClass()); + + // timestamp scalar/scalar + children1.set(1, f); + ve = vc.getVectorExpression(exprDesc); + assertTrue(IfExprLongColumnLongColumn.class == ve.getClass() + || IfExprLongScalarLongScalar.class == ve.getClass()); + + // timestamp scalar/column + children1.set(2, col3Expr); + assertTrue(IfExprLongColumnLongColumn.class == ve.getClass() + || IfExprLongScalarLongColumn.class == ve.getClass()); + + // test for boolean type + col2Expr = new ExprNodeColumnDesc(Boolean.class, "col2", "table", false); + col3Expr = new ExprNodeColumnDesc(Boolean.class, "col3", "table", false); + + // column/column + children1.set(1, col2Expr); + children1.set(2, col3Expr); + ve = vc.getVectorExpression(exprDesc); + assertTrue(ve instanceof IfExprLongColumnLongColumn); + + // column/scalar IF + children1.set(2, new ExprNodeConstantDesc(true)); + ve = vc.getVectorExpression(exprDesc); + assertTrue(ve instanceof IfExprLongColumnLongScalar); + + // scalar/scalar IF + children1.set(1, new ExprNodeConstantDesc(true)); + ve = vc.getVectorExpression(exprDesc); + assertTrue(ve instanceof IfExprLongScalarLongScalar); + + // scalar/column IF + children1.set(2, col3Expr); + ve = vc.getVectorExpression(exprDesc); + assertTrue(ve instanceof IfExprLongScalarLongColumn); + + // test for string type + constDesc2 = new ExprNodeConstantDesc("Alpha"); + constDesc3 = new ExprNodeConstantDesc("Bravo"); + col2Expr = new ExprNodeColumnDesc(String.class, "col2", "table", false); + col3Expr = new ExprNodeColumnDesc(String.class, "col3", "table", false); + + // column/column + children1.set(1, col2Expr); + children1.set(2, col3Expr); + ve = vc.getVectorExpression(exprDesc); + assertTrue(ve instanceof IfExprStringColumnStringColumn); + + // column/scalar + children1.set(2, constDesc3); + ve = vc.getVectorExpression(exprDesc); + assertTrue(ve instanceof IfExprStringColumnStringScalar); + + // scalar/scalar + children1.set(1, constDesc2); + ve = vc.getVectorExpression(exprDesc); + assertTrue(ve instanceof IfExprStringScalarStringScalar); + + // scalar/column + children1.set(2, col3Expr); + ve = vc.getVectorExpression(exprDesc); + assertTrue(ve instanceof IfExprStringScalarStringColumn); + } }
Modified: hive/trunk/ql/src/test/org/apache/hadoop/hive/ql/exec/vector/TestVectorizedRowBatch.java URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/test/org/apache/hadoop/hive/ql/exec/vector/TestVectorizedRowBatch.java?rev=1550488&r1=1550487&r2=1550488&view=diff ============================================================================== --- hive/trunk/ql/src/test/org/apache/hadoop/hive/ql/exec/vector/TestVectorizedRowBatch.java (original) +++ hive/trunk/ql/src/test/org/apache/hadoop/hive/ql/exec/vector/TestVectorizedRowBatch.java Thu Dec 12 19:01:09 2013 @@ -27,11 +27,11 @@ import org.junit.Test; * Test creation and basic manipulation of VectorizedRowBatch. */ public class TestVectorizedRowBatch { - + // test fields static final String[] COLORS = {"red", "yellow", "green", "blue", "violet", "orange"}; private static byte[][] colorsBytes; - + private VectorizedRowBatch makeBatch() { VectorizedRowBatch batch = new VectorizedRowBatch(3); LongColumnVector lv = new LongColumnVector(); @@ -44,29 +44,29 @@ public class TestVectorizedRowBatch { addRandomNulls(batch); return batch; } - + @Test /** - * Make sure you can create a batch and that all columns are the + * Make sure you can create a batch and that all columns are the * default size. */ public void testVectorizedRowBatchCreate() { VectorizedRowBatch batch = makeBatch(); Assert.assertEquals(3, batch.numCols); Assert.assertEquals(VectorizedRowBatch.DEFAULT_SIZE, batch.size); - Assert.assertEquals(((LongColumnVector) batch.cols[0]).vector.length, + Assert.assertEquals(((LongColumnVector) batch.cols[0]).vector.length, VectorizedRowBatch.DEFAULT_SIZE); - Assert.assertEquals(((DoubleColumnVector) batch.cols[1]).vector.length, - VectorizedRowBatch.DEFAULT_SIZE); - Assert.assertEquals(((BytesColumnVector) batch.cols[2]).vector.length, + Assert.assertEquals(((DoubleColumnVector) batch.cols[1]).vector.length, + VectorizedRowBatch.DEFAULT_SIZE); + Assert.assertEquals(((BytesColumnVector) batch.cols[2]).vector.length, VectorizedRowBatch.DEFAULT_SIZE); } - + /* * Test routines to exercise VectorizedRowBatch * by filling column vectors with data and null values. */ - + public static void setRandom(VectorizedRowBatch batch) { batch.size = VectorizedRowBatch.DEFAULT_SIZE; for (int i = 0; i != batch.numCols; i++) { @@ -84,24 +84,24 @@ public class TestVectorizedRowBatch { /** * Set to sample data, re-using existing columns in batch. - * + * * @param batch */ public static void setSampleOverwrite(VectorizedRowBatch batch) { - + // Put sample data in the columns. for (int i = 0; i != batch.numCols; i++) { setSampleLongCol((LongColumnVector) batch.cols[i]); } - + // Reset the selection vector. batch.selectedInUse = false; batch.size = VectorizedRowBatch.DEFAULT_SIZE; } - + /** * Sprinkle null values in this column vector. - * + * * @param col */ public static void addRandomNulls(ColumnVector col) { @@ -111,10 +111,10 @@ public class TestVectorizedRowBatch { col.isNull[i] = Math.abs(rand.nextInt() % 11) == 0; } } - + /** * Add null values, but do it faster, by avoiding use of Random(). - * + * * @param col */ public void addSampleNulls(ColumnVector col) { @@ -136,20 +136,20 @@ public class TestVectorizedRowBatch { addSampleNulls(batch.cols[i]); } } - + /** * Set vector elements to sample string data from colorsBytes string table. * @param col */ - public static void setSampleStringCol(BytesColumnVector col) { + public static void setSampleStringCol(BytesColumnVector col) { initColors(); int size = col.vector.length; for(int i = 0; i != size; i++) { int pos = i % colorsBytes.length; col.setRef(i, colorsBytes[pos], 0, colorsBytes[pos].length); - } + } } - + /* * Initialize string table in a lazy fashion. */ @@ -161,7 +161,7 @@ public class TestVectorizedRowBatch { } } } - + /** * Set the vector to sample data that repeats an iteration from 0 to 99. @@ -190,7 +190,7 @@ public class TestVectorizedRowBatch { col.isRepeating = true; col.vector[0] = 50; } - + /** * Set the vector to sample data that repeats an iteration from 0 to 99. * @param col @@ -218,4 +218,64 @@ public class TestVectorizedRowBatch { col.isRepeating = true; col.vector[0] = 50.0; } + + @Test + public void testFlatten() { + verifyFlatten(new LongColumnVector()); + verifyFlatten(new DoubleColumnVector()); + verifyFlatten(new BytesColumnVector()); + } + + private void verifyFlatten(ColumnVector v) { + + // verify that flattening and unflattenting no-nulls works + v.noNulls = true; + v.isNull[1] = true; + int[] sel = {0, 2}; + int size = 2; + v.flatten(true, sel, size); + Assert.assertFalse(v.noNulls); + Assert.assertFalse(v.isNull[0] || v.isNull[2]); + v.unFlatten(); + Assert.assertTrue(v.noNulls); + + // verify that flattening and unflattening "isRepeating" works + v.isRepeating = true; + v.noNulls = false; + v.isNull[0] = true; + v.flatten(true, sel, 2); + Assert.assertFalse(v.noNulls); + Assert.assertTrue(v.isNull[0] && v.isNull[2]); + Assert.assertFalse(v.isRepeating); + v.unFlatten(); + Assert.assertFalse(v.noNulls); + Assert.assertTrue(v.isRepeating); + + // verify extension of values in the array + v.noNulls = true; + if (v instanceof LongColumnVector) { + ((LongColumnVector) v).vector[0] = 100; + v.flatten(true, sel, 2); + Assert.assertTrue(((LongColumnVector) v).vector[2] == 100); + } else if (v instanceof DoubleColumnVector) { + ((DoubleColumnVector) v).vector[0] = 200d; + v.flatten(true, sel, 2); + Assert.assertTrue(((DoubleColumnVector) v).vector[2] == 200d); + } else if (v instanceof BytesColumnVector) { + BytesColumnVector bv = (BytesColumnVector) v; + byte[] b = null; + try { + b = "foo".getBytes("UTF-8"); + } catch (Exception e) { + ; // eat it + } + bv.setRef(0, b, 0, b.length); + bv.flatten(true, sel, 2); + Assert.assertEquals(bv.vector[0], bv.vector[2]); + Assert.assertEquals(bv.start[0], bv.start[2]); + Assert.assertEquals(bv.length[0], bv.length[2]); + } + } + + } Added: hive/trunk/ql/src/test/org/apache/hadoop/hive/ql/exec/vector/expressions/TestVectorConditionalExpressions.java URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/test/org/apache/hadoop/hive/ql/exec/vector/expressions/TestVectorConditionalExpressions.java?rev=1550488&view=auto ============================================================================== --- hive/trunk/ql/src/test/org/apache/hadoop/hive/ql/exec/vector/expressions/TestVectorConditionalExpressions.java (added) +++ hive/trunk/ql/src/test/org/apache/hadoop/hive/ql/exec/vector/expressions/TestVectorConditionalExpressions.java Thu Dec 12 19:01:09 2013 @@ -0,0 +1,545 @@ +/** + * 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.IfExprStringColumnStringColumn; +import org.apache.hadoop.hive.ql.exec.vector.expressions.IfExprStringColumnStringScalar; +import org.apache.hadoop.hive.ql.exec.vector.expressions.IfExprStringScalarStringScalar; +import org.apache.hadoop.hive.ql.exec.vector.expressions.IfExprStringScalarStringColumn; + +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 IfExprStringColumnStringColumn(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 IfExprStringColumnStringScalar(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 IfExprStringScalarStringColumn(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")); + } +}
