You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hive.apache.org by mm...@apache.org on 2018/03/03 11:50:59 UTC

[7/7] hive git commit: HIVE-18819: Vectorization: Optimize IF statement expression evaluation of THEN/ELSE (Matt McCline, reviewed by Teddy Choi)

HIVE-18819: Vectorization: Optimize IF statement expression evaluation of THEN/ELSE (Matt McCline, reviewed by Teddy Choi)


Project: http://git-wip-us.apache.org/repos/asf/hive/repo
Commit: http://git-wip-us.apache.org/repos/asf/hive/commit/53980ba6
Tree: http://git-wip-us.apache.org/repos/asf/hive/tree/53980ba6
Diff: http://git-wip-us.apache.org/repos/asf/hive/diff/53980ba6

Branch: refs/heads/master
Commit: 53980ba66df815c64c8d644b36cb37b314ac2d7f
Parents: 1a3090f
Author: Matt McCline <mm...@hortonworks.com>
Authored: Sat Mar 3 05:50:40 2018 -0600
Committer: Matt McCline <mm...@hortonworks.com>
Committed: Sat Mar 3 05:50:40 2018 -0600

----------------------------------------------------------------------
 .../org/apache/hadoop/hive/conf/HiveConf.java   |    7 +-
 data/files/student_10_lines                     |   10 +
 data/files/student_2_lines                      |    2 -
 .../test/resources/testconfiguration.properties |    2 +
 .../ql/exec/vector/VectorizationContext.java    |  210 ++-
 .../expressions/IfExprColumnCondExpr.java       |  125 ++
 .../vector/expressions/IfExprCondExprBase.java  |  171 +++
 .../expressions/IfExprCondExprColumn.java       |  125 ++
 .../expressions/IfExprCondExprCondExpr.java     |  122 ++
 .../vector/expressions/IfExprCondExprNull.java  |  115 ++
 .../vector/expressions/IfExprNullCondExpr.java  |  117 ++
 .../queries/clientpositive/vector_case_when_1.q |  281 ++++
 .../queries/clientpositive/vector_case_when_2.q |  208 +++
 .../clientpositive/vector_udf_adaptor_1.q       |  210 ++-
 .../llap/vector_case_when_1.q.out               | 1204 ++++++++++++++++++
 .../llap/vector_case_when_2.q.out               |  884 +++++++++++++
 .../llap/vector_groupby_grouping_id1.q.out      |    8 +-
 .../llap/vector_udf_adaptor_1.q.out             | 1062 ++++++++++++++-
 .../llap/vector_when_case_null.q.out            |    6 +-
 .../clientpositive/llap/vectorized_case.q.out   |   32 +-
 .../clientpositive/spark/vectorized_case.q.out  |   32 +-
 .../clientpositive/vector_case_when_1.q.out     | 1126 ++++++++++++++++
 .../clientpositive/vector_case_when_2.q.out     |  806 ++++++++++++
 .../clientpositive/vector_when_case_null.q.out  |    6 +-
 .../clientpositive/vectorized_case.q.out        |   32 +-
 25 files changed, 6730 insertions(+), 173 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/hive/blob/53980ba6/common/src/java/org/apache/hadoop/hive/conf/HiveConf.java
----------------------------------------------------------------------
diff --git a/common/src/java/org/apache/hadoop/hive/conf/HiveConf.java b/common/src/java/org/apache/hadoop/hive/conf/HiveConf.java
index 1e322b8..edea129 100644
--- a/common/src/java/org/apache/hadoop/hive/conf/HiveConf.java
+++ b/common/src/java/org/apache/hadoop/hive/conf/HiveConf.java
@@ -2978,7 +2978,12 @@ public class HiveConf extends Configuration {
         "Which vectorized input format support features are enabled for vectorization.\n" +
         "That is, if a VectorizedInputFormat input format does support \"decimal_64\" for example\n" +
         "this variable must enable that to be used in vectorization"),
-
+    HIVE_VECTORIZED_IF_EXPR_MODE("hive.vectorized.if.expr.mode", "better", new StringSet("adaptor", "good", "better"),
+        "Specifies the extent to which SQL IF statements will be vectorized.\n" +
+        "0. adaptor: only use the VectorUDFAdaptor to vectorize IF statements\n" +
+        "1. good   : use regular vectorized IF expression classes that get good performance\n" +
+        "2. better : use vectorized IF expression classes that conditionally execute THEN/ELSE\n" +
+        "            expressions for better performance.\n"),
     HIVE_TEST_VECTORIZATION_ENABLED_OVERRIDE("hive.test.vectorized.execution.enabled.override",
         "none", new StringSet("none", "enable", "disable"),
         "internal use only, used to override the hive.vectorized.execution.enabled setting and\n" +

http://git-wip-us.apache.org/repos/asf/hive/blob/53980ba6/data/files/student_10_lines
----------------------------------------------------------------------
diff --git a/data/files/student_10_lines b/data/files/student_10_lines
new file mode 100644
index 0000000..2f1b331
--- /dev/null
+++ b/data/files/student_10_lines
@@ -0,0 +1,10 @@
+tom thompson420.53
+luke king280.47
+priscilla falkner551.16
+luke brown601.14
+ulysses garcia352.74
+calvin brown282.70
+oscar thompson352.98
+xavier garcia331.06
+nick johnson34
+quinn ovid19

http://git-wip-us.apache.org/repos/asf/hive/blob/53980ba6/data/files/student_2_lines
----------------------------------------------------------------------
diff --git a/data/files/student_2_lines b/data/files/student_2_lines
deleted file mode 100644
index 9e86836..0000000
--- a/data/files/student_2_lines
+++ /dev/null
@@ -1,2 +0,0 @@
-tom thompson420.53
-luke king280.47

http://git-wip-us.apache.org/repos/asf/hive/blob/53980ba6/itests/src/test/resources/testconfiguration.properties
----------------------------------------------------------------------
diff --git a/itests/src/test/resources/testconfiguration.properties b/itests/src/test/resources/testconfiguration.properties
index 544c836..9d80920 100644
--- a/itests/src/test/resources/testconfiguration.properties
+++ b/itests/src/test/resources/testconfiguration.properties
@@ -314,6 +314,8 @@ minillaplocal.shared.query.files=alter_merge_2_orc.q,\
   vector_binary_join_groupby.q,\
   vector_bround.q,\
   vector_bucket.q,\
+  vector_case_when_1.q,\
+  vector_case_when_2.q,\
   vector_cast_constant.q,\
   vector_char_2.q,\
   vector_char_4.q,\

http://git-wip-us.apache.org/repos/asf/hive/blob/53980ba6/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/VectorizationContext.java
----------------------------------------------------------------------
diff --git a/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/VectorizationContext.java b/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/VectorizationContext.java
index 4df6e97..93212ce 100644
--- a/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/VectorizationContext.java
+++ b/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/VectorizationContext.java
@@ -133,6 +133,21 @@ public class VectorizationContext {
   }
 
   private HiveVectorAdaptorUsageMode hiveVectorAdaptorUsageMode;
+
+  public enum HiveVectorIfStmtMode {
+    ADAPTOR,
+    GOOD,
+    BETTER;
+
+    public static HiveVectorIfStmtMode getHiveConfValue(HiveConf hiveConf) {
+      String string = HiveConf.getVar(hiveConf,
+          HiveConf.ConfVars.HIVE_VECTORIZED_IF_EXPR_MODE);
+      return valueOf(string.toUpperCase());
+    }
+  }
+
+  private HiveVectorIfStmtMode hiveVectorIfStmtMode;
+
   //when set to true use the overflow checked vector expressions
   private boolean useCheckedVectorExpressions;
 
@@ -141,6 +156,7 @@ public class VectorizationContext {
 
   private void setHiveConfVars(HiveConf hiveConf) {
     hiveVectorAdaptorUsageMode = HiveVectorAdaptorUsageMode.getHiveConfValue(hiveConf);
+    hiveVectorIfStmtMode = HiveVectorIfStmtMode.getHiveConfValue(hiveConf);
     this.reuseScratchColumns =
         HiveConf.getBoolVar(hiveConf, ConfVars.HIVE_VECTORIZATION_TESTING_REUSE_SCRATCH_COLUMNS);
     this.ocm.setReuseColumns(reuseScratchColumns);
@@ -150,6 +166,7 @@ public class VectorizationContext {
 
   private void copyHiveConfVars(VectorizationContext vContextEnvironment) {
     hiveVectorAdaptorUsageMode = vContextEnvironment.hiveVectorAdaptorUsageMode;
+    hiveVectorIfStmtMode = vContextEnvironment.hiveVectorIfStmtMode;
     this.reuseScratchColumns = vContextEnvironment.reuseScratchColumns;
     this.ocm.setReuseColumns(reuseScratchColumns);
   }
@@ -765,7 +782,7 @@ public class VectorizationContext {
       // and that would require converting their data types to evaluate the udf.
       // For example decimal column added to an integer column would require integer column to be
       // cast to decimal.
-	  // Note: this is a no-op for custom UDFs
+      // Note: this is a no-op for custom UDFs
       List<ExprNodeDesc> childExpressions = getChildExpressionsWithImplicitCast(expr.getGenericUDF(),
           exprDesc.getChildren(), exprDesc.getTypeInfo());
       ve = getGenericUdfVectorExpression(expr.getGenericUDF(),
@@ -1978,6 +1995,8 @@ public class VectorizationContext {
       ve = getBetweenFilterExpression(childExpr, mode, returnType);
     } else if (udf instanceof GenericUDFIn) {
       ve = getInExpression(childExpr, mode, returnType);
+    } else if (udf instanceof GenericUDFIf) {
+      ve = getIfExpression((GenericUDFIf) udf, childExpr, mode, returnType);
     } else if (udf instanceof GenericUDFWhen) {
       ve = getWhenExpression(childExpr, mode, returnType);
     } else if (udf instanceof GenericUDFOPPositive) {
@@ -2911,38 +2930,56 @@ public class VectorizationContext {
     return createVectorExpression(cl, childrenAfterNot, VectorExpressionDescriptor.Mode.PROJECTION, returnType);
   }
 
+  private boolean isCondExpr(ExprNodeDesc exprNodeDesc) {
+    if (exprNodeDesc instanceof ExprNodeConstantDesc ||
+        exprNodeDesc instanceof ExprNodeColumnDesc) {
+      return false;
+    }
+    return true;   // Requires conditional evaluation for good performance.
+  }
+
   private boolean isNullConst(ExprNodeDesc exprNodeDesc) {
     //null constant could be typed so we need to check the value
     if (exprNodeDesc instanceof ExprNodeConstantDesc &&
         ((ExprNodeConstantDesc) exprNodeDesc).getValue() == null) {
-        return true;
+      return true;
     }
     return false;
   }
 
-  private VectorExpression getWhenExpression(List<ExprNodeDesc> childExpr,
+  private VectorExpression getIfExpression(GenericUDFIf genericUDFIf, List<ExprNodeDesc> childExpr,
       VectorExpressionDescriptor.Mode mode, TypeInfo returnType) throws HiveException {
 
     if (mode != VectorExpressionDescriptor.Mode.PROJECTION) {
       return null;
     }
-    final int size = childExpr.size();
 
-    final ExprNodeDesc whenDesc = childExpr.get(0);
-    final ExprNodeDesc thenDesc = childExpr.get(1);
-    final ExprNodeDesc elseDesc;
+    // Add HiveConf variable with 3 modes:
+    //   1) adaptor: Always use VectorUDFAdaptor for IF statements.
+    //
+    //   2) good: Vectorize but don't optimize conditional expressions
+    //
+    //   3) better: Vectorize and Optimize conditional expressions.
+    //
 
-    if (size == 2) {
-      elseDesc = new ExprNodeConstantDesc(returnType, null);
-    } else if (size == 3) {
-      elseDesc = childExpr.get(2);
-    } else {
-      final GenericUDFWhen udfWhen = new GenericUDFWhen();
-      elseDesc = new ExprNodeGenericFuncDesc(returnType, udfWhen, udfWhen.getUdfName(),
-          childExpr.subList(2, childExpr.size()));
+    if (hiveVectorIfStmtMode == HiveVectorIfStmtMode.ADAPTOR) {
+      return null;
     }
 
-    if (isNullConst(thenDesc) && isNullConst(elseDesc)) {
+    // Align the THEN/ELSE types.
+    childExpr =
+        getChildExpressionsWithImplicitCast(
+            genericUDFIf,
+            childExpr,
+            returnType);
+
+    final ExprNodeDesc ifDesc = childExpr.get(0);
+    final ExprNodeDesc thenDesc = childExpr.get(1);
+    final ExprNodeDesc elseDesc = childExpr.get(2);
+
+    final boolean isThenNullConst = isNullConst(thenDesc);
+    final boolean isElseNullConst = isNullConst(elseDesc);
+    if (isThenNullConst && isElseNullConst) {
 
       // THEN NULL ELSE NULL: An unusual "case", but possible.
       final int outputColumnNum = ocm.allocateOutputColumn(returnType);
@@ -2956,17 +2993,32 @@ public class VectorizationContext {
 
       return resultExpr;
     }
-    if (isNullConst(thenDesc)) {
-      final VectorExpression whenExpr = getVectorExpression(whenDesc, mode);
+
+    final boolean isThenCondExpr = isCondExpr(thenDesc);
+    final boolean isElseCondExpr = isCondExpr(elseDesc);
+
+    final boolean isOnlyGood = (hiveVectorIfStmtMode == HiveVectorIfStmtMode.GOOD);
+
+    if (isThenNullConst) {
+      final VectorExpression whenExpr = getVectorExpression(ifDesc, mode);
       final VectorExpression elseExpr = getVectorExpression(elseDesc, mode);
 
       final int outputColumnNum = ocm.allocateOutputColumn(returnType);
 
-      final VectorExpression resultExpr =
-          new IfExprNullColumn(
-            whenExpr.getOutputColumnNum(),
-            elseExpr.getOutputColumnNum(),
-            outputColumnNum);
+      final VectorExpression resultExpr;
+      if (!isElseCondExpr || isOnlyGood) {
+        resultExpr =
+            new IfExprNullColumn(
+              whenExpr.getOutputColumnNum(),
+              elseExpr.getOutputColumnNum(),
+              outputColumnNum);
+      } else {
+        resultExpr =
+            new IfExprNullCondExpr(
+              whenExpr.getOutputColumnNum(),
+              elseExpr.getOutputColumnNum(),
+              outputColumnNum);
+      }
 
       resultExpr.setChildExpressions(new VectorExpression[] {whenExpr, elseExpr});
 
@@ -2984,17 +3036,27 @@ public class VectorizationContext {
 
       return resultExpr;
     }
-    if (isNullConst(elseDesc)) {
-      final VectorExpression whenExpr = getVectorExpression(whenDesc, mode);
+
+    if (isElseNullConst) {
+      final VectorExpression whenExpr = getVectorExpression(ifDesc, mode);
       final VectorExpression thenExpr = getVectorExpression(thenDesc, mode);
 
       final int outputColumnNum = ocm.allocateOutputColumn(returnType);
 
-      final VectorExpression resultExpr =
-          new IfExprColumnNull(
-            whenExpr.getOutputColumnNum(),
-            thenExpr.getOutputColumnNum(),
-            outputColumnNum);
+      final VectorExpression resultExpr;
+      if (!isThenCondExpr || isOnlyGood) {
+        resultExpr =
+            new IfExprColumnNull(
+              whenExpr.getOutputColumnNum(),
+              thenExpr.getOutputColumnNum(),
+              outputColumnNum);
+      } else {
+        resultExpr =
+            new IfExprCondExprNull(
+              whenExpr.getOutputColumnNum(),
+              thenExpr.getOutputColumnNum(),
+              outputColumnNum);
+      }
 
       resultExpr.setChildExpressions(new VectorExpression[] {whenExpr, thenExpr});
 
@@ -3012,11 +3074,91 @@ public class VectorizationContext {
 
       return resultExpr;
     }
+
+    if ((isThenCondExpr || isElseCondExpr) && !isOnlyGood) {
+      final VectorExpression whenExpr = getVectorExpression(ifDesc, mode);
+      final VectorExpression thenExpr = getVectorExpression(thenDesc, mode);
+      final VectorExpression elseExpr = getVectorExpression(elseDesc, mode);
+
+      // Only proceed if the THEN/ELSE types were aligned.
+      if (thenExpr.getOutputColumnVectorType() == elseExpr.getOutputColumnVectorType()) {
+
+        final int outputColumnNum = ocm.allocateOutputColumn(returnType);
+
+        final VectorExpression resultExpr;
+        if (isThenCondExpr && isElseCondExpr) {
+          resultExpr =
+              new IfExprCondExprCondExpr(
+                whenExpr.getOutputColumnNum(),
+                thenExpr.getOutputColumnNum(),
+                elseExpr.getOutputColumnNum(),
+                outputColumnNum);
+        } else if (isThenCondExpr) {
+          resultExpr =
+              new IfExprCondExprColumn(
+                whenExpr.getOutputColumnNum(),
+                thenExpr.getOutputColumnNum(),
+                elseExpr.getOutputColumnNum(),
+                outputColumnNum);
+        } else {
+          resultExpr =
+              new IfExprColumnCondExpr(
+                whenExpr.getOutputColumnNum(),
+                thenExpr.getOutputColumnNum(),
+                elseExpr.getOutputColumnNum(),
+                outputColumnNum);
+        }
+
+        resultExpr.setChildExpressions(new VectorExpression[] {whenExpr, thenExpr, elseExpr});
+
+        resultExpr.setInputTypeInfos(
+            whenExpr.getOutputTypeInfo(),
+            thenExpr.getOutputTypeInfo(),
+            elseExpr.getOutputTypeInfo());
+        resultExpr.setInputDataTypePhysicalVariations(
+            whenExpr.getOutputDataTypePhysicalVariation(),
+            thenExpr.getOutputDataTypePhysicalVariation(),
+            elseExpr.getOutputDataTypePhysicalVariation());
+
+        resultExpr.setOutputTypeInfo(returnType);
+        resultExpr.setOutputDataTypePhysicalVariation(DataTypePhysicalVariation.NONE);
+
+        return resultExpr;
+      }
+    }
+
+    Class<?> udfClass = genericUDFIf.getClass();
+    return getVectorExpressionForUdf(
+        genericUDFIf, udfClass, childExpr, mode, returnType);
+  }
+
+  private VectorExpression getWhenExpression(List<ExprNodeDesc> childExpr,
+      VectorExpressionDescriptor.Mode mode, TypeInfo returnType) throws HiveException {
+
+    if (mode != VectorExpressionDescriptor.Mode.PROJECTION) {
+      return null;
+    }
+    final int size = childExpr.size();
+
+    final ExprNodeDesc whenDesc = childExpr.get(0);
+    final ExprNodeDesc thenDesc = childExpr.get(1);
+    final ExprNodeDesc elseDesc;
+
+    if (size == 2) {
+      elseDesc = new ExprNodeConstantDesc(returnType, null);
+    } else if (size == 3) {
+      elseDesc = childExpr.get(2);
+    } else {
+      final GenericUDFWhen udfWhen = new GenericUDFWhen();
+      elseDesc = new ExprNodeGenericFuncDesc(returnType, udfWhen, udfWhen.getUdfName(),
+          childExpr.subList(2, childExpr.size()));
+    }
+
+    // Transform CASE WHEN with just a THEN/ELSE into an IF statement.
     final GenericUDFIf genericUDFIf = new GenericUDFIf();
-    final List<ExprNodeDesc> ifChildExpr = Arrays.<ExprNodeDesc>asList(whenDesc, thenDesc, elseDesc);
-    final ExprNodeGenericFuncDesc exprNodeDesc =
-        new ExprNodeGenericFuncDesc(returnType, genericUDFIf, "if", ifChildExpr);
-    return getVectorExpression(exprNodeDesc, mode);
+    final List<ExprNodeDesc> ifChildExpr =
+        Arrays.<ExprNodeDesc>asList(whenDesc, thenDesc, elseDesc);
+    return getIfExpression(genericUDFIf, ifChildExpr, mode, returnType);
   }
 
   /*

http://git-wip-us.apache.org/repos/asf/hive/blob/53980ba6/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/IfExprColumnCondExpr.java
----------------------------------------------------------------------
diff --git a/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/IfExprColumnCondExpr.java b/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/IfExprColumnCondExpr.java
new file mode 100644
index 0000000..94e5190
--- /dev/null
+++ b/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/IfExprColumnCondExpr.java
@@ -0,0 +1,125 @@
+/*
+ * 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.ql.exec.vector.ColumnVector;
+import org.apache.hadoop.hive.ql.exec.vector.VectorizedRowBatch;
+
+/**
+ * Do regular execution of the THEN vector expression (a column or scalar) and conditional execution
+ * of the ELSE vector expression of a SQL IF statement.
+ */
+public class IfExprColumnCondExpr extends IfExprCondExprBase {
+  private static final long serialVersionUID = 1L;
+
+  protected final int arg2Column;
+  protected final int arg3Column;
+
+  public IfExprColumnCondExpr(int arg1Column, int arg2Column, int arg3Column,
+      int outputColumnNum) {
+    super(arg1Column, outputColumnNum);
+    this.arg2Column = arg2Column;
+    this.arg3Column = arg3Column;
+  }
+
+  public IfExprColumnCondExpr() {
+    super();
+
+    // Dummy final assignments.
+    arg2Column = -1;
+    arg3Column = -1;
+  }
+
+  @Override
+  public void evaluate(VectorizedRowBatch batch) {
+
+    int n = batch.size;
+    if (n <= 0) {
+      // Nothing to do
+      return;
+    }
+
+    /*
+     * Do common analysis of the IF statement boolean expression.
+     *
+     * The following protected members can be examined afterwards:
+     *
+     *   boolean isIfStatementResultRepeated
+     *   boolean isIfStatementResultThen
+     *
+     *   int thenSelectedCount
+     *   int[] thenSelected
+     *   int elseSelectedCount
+     *   int[] elseSelected
+     */
+    super.evaluate(batch);
+
+    ColumnVector outputColVector = batch.cols[outputColumnNum];
+    boolean[] outputIsNull = outputColVector.isNull;
+
+    // We do not need to do a column reset since we are carefully changing the output.
+    outputColVector.isRepeating = false;
+
+    // CONSIDER: Should be do this for all vector expressions that can
+    //           work on BytesColumnVector output columns???
+    outputColVector.init();
+
+    ColumnVector thenColVector = batch.cols[arg2Column];
+    ColumnVector elseColVector = batch.cols[arg3Column];
+
+    final int thenCount = thenSelectedCount;
+    final int elseCount = elseSelectedCount;
+
+    if (isIfStatementResultRepeated) {
+      if (isIfStatementResultThen) {
+        // Evaluate THEN expression (only) and copy all its results.
+        childExpressions[1].evaluate(batch);
+        thenColVector.copySelected(batch.selectedInUse, batch.selected, n, outputColVector);
+      } else {
+        // Evaluate ELSE expression (only) and copy all its results.
+        childExpressions[2].evaluate(batch);
+        elseColVector.copySelected(batch.selectedInUse, batch.selected, n, outputColVector);
+      }
+      return;
+    }
+
+    // NOTE: We cannot use copySelected below since it is a whole column operation.
+
+    // The THEN expression is either IdentityExpression (a column) or a ConstantVectorExpression
+    // (a scalar) and trivial to evaluate.
+    childExpressions[1].evaluate(batch);
+    for (int i = 0; i < thenCount; i++) {
+      final int batchIndex = thenSelected[i];
+      outputIsNull[batchIndex] = false;
+      outputColVector.setElement(batchIndex, batchIndex, thenColVector);
+    }
+
+    conditionalEvaluate(batch, childExpressions[2], elseSelected, elseCount);
+    for (int i = 0; i < elseCount; i++) {
+      final int batchIndex = elseSelected[i];
+      outputIsNull[batchIndex] = false;
+      outputColVector.setElement(batchIndex, batchIndex, elseColVector);
+    }
+  }
+
+  @Override
+  public String vectorExpressionParameters() {
+    return getColumnParamString(0, arg1Column) + ", " + getColumnParamString(1, arg2Column) +
+        getColumnParamString(2, arg3Column);
+  }
+}

http://git-wip-us.apache.org/repos/asf/hive/blob/53980ba6/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/IfExprCondExprBase.java
----------------------------------------------------------------------
diff --git a/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/IfExprCondExprBase.java b/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/IfExprCondExprBase.java
new file mode 100644
index 0000000..abc1343
--- /dev/null
+++ b/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/IfExprCondExprBase.java
@@ -0,0 +1,171 @@
+/*
+ * 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.ql.exec.vector.LongColumnVector;
+import org.apache.hadoop.hive.ql.exec.vector.VectorExpressionDescriptor;
+import org.apache.hadoop.hive.ql.exec.vector.VectorizedRowBatch;
+
+/**
+ * Base class that supports conditional execution of the THEN/ELSE vector expressions of
+ * a SQL IF statement.
+ */
+public abstract class IfExprCondExprBase extends VectorExpression {
+  private static final long serialVersionUID = 1L;
+
+  protected final int arg1Column;
+
+  // Whether the IF statement boolean expression was repeating.
+  protected transient boolean isIfStatementResultRepeated;
+  protected transient boolean isIfStatementResultThen;
+
+  // The batchIndex for the rows that are for the THEN/ELSE rows respectively.
+  // Temporary work arrays.
+  protected transient int thenSelectedCount;
+  protected transient int[] thenSelected;
+  protected transient int elseSelectedCount;
+  protected transient int[] elseSelected;
+
+  public IfExprCondExprBase(int arg1Column, int outputColumnNum) {
+    super(outputColumnNum);
+    this.arg1Column = arg1Column;
+  }
+
+  public IfExprCondExprBase() {
+    super();
+
+    // Dummy final assignments.
+    arg1Column = -1;
+  }
+
+  public void conditionalEvaluate(VectorizedRowBatch batch, VectorExpression condVecExpr,
+      int[] condSelected, int condSize) {
+
+    int saveSize = batch.size;
+    boolean saveSelectedInUse = batch.selectedInUse;
+    int[] saveSelected = batch.selected;
+
+    batch.size = condSize;
+    batch.selectedInUse = true;
+    batch.selected = condSelected;
+
+    condVecExpr.evaluate(batch);
+
+    batch.size = saveSize;
+    batch.selectedInUse = saveSelectedInUse;
+    batch.selected = saveSelected;
+  }
+
+  @Override
+  public void evaluate(VectorizedRowBatch batch) {
+
+    // NOTE: We do conditional vector expression so we do not call super.evaluateChildren(batch).
+
+    thenSelectedCount = 0;
+    elseSelectedCount = 0;
+    isIfStatementResultRepeated = false;
+    isIfStatementResultThen = false;   // Give it a value.
+
+    int n = batch.size;
+    if (n <= 0) {
+      // Nothing to do
+      return;
+    }
+
+    // Child #1 is the IF boolean expression.
+    childExpressions[0].evaluate(batch);
+    LongColumnVector ifExprColVector = (LongColumnVector) batch.cols[arg1Column];
+    if (ifExprColVector.isRepeating) {
+      isIfStatementResultRepeated = true;
+      isIfStatementResultThen =
+          ((ifExprColVector.noNulls || !ifExprColVector.isNull[0]) &&
+              ifExprColVector.vector[0] == 1);
+      return;
+    }
+
+    if (thenSelected == null || n > thenSelected.length) {
+
+      // (Re)allocate larger to be a multiple of 1024 (DEFAULT_SIZE).
+      final int roundUpSize =
+          ((n + VectorizedRowBatch.DEFAULT_SIZE - 1) / VectorizedRowBatch.DEFAULT_SIZE)
+              * VectorizedRowBatch.DEFAULT_SIZE;
+      thenSelected = new int[roundUpSize];
+      elseSelected = new int[roundUpSize];
+    }
+
+    int[] sel = batch.selected;
+    long[] vector = ifExprColVector.vector;
+
+    if (ifExprColVector.noNulls) {
+      if (batch.selectedInUse) {
+        for (int j = 0; j < n; j++) {
+          final int i = sel[j];
+          if (vector[i] == 1) {
+            thenSelected[thenSelectedCount++] = i;
+          } else {
+            elseSelected[elseSelectedCount++] = i;
+          }
+        }
+      } else {
+        for (int i = 0; i < n; i++) {
+          if (vector[i] == 1) {
+            thenSelected[thenSelectedCount++] = i;
+          } else {
+            elseSelected[elseSelectedCount++] = i;
+          }
+        }
+      }
+    } else {
+      boolean[] isNull = ifExprColVector.isNull;
+      if (batch.selectedInUse) {
+        for (int j = 0; j < n; j++) {
+          final int i = sel[j];
+          if (!isNull[i] && vector[i] == 1) {
+            thenSelected[thenSelectedCount++] = i;
+          } else {
+            elseSelected[elseSelectedCount++] = i;
+          }
+        }
+      } else {
+        for (int i = 0; i < n; i++) {
+          if (!isNull[i] && vector[i] == 1) {
+            thenSelected[thenSelectedCount++] = i;
+          } else {
+            elseSelected[elseSelectedCount++] = i;
+          }
+        }
+      }
+    }
+
+    if (thenSelectedCount == 0) {
+      isIfStatementResultRepeated = true;
+      isIfStatementResultThen = false;
+    } else if (elseSelectedCount == 0) {
+      isIfStatementResultRepeated = true;
+      isIfStatementResultThen = true;
+    }
+  }
+
+  @Override
+  public VectorExpressionDescriptor.Descriptor getDescriptor() {
+
+    // Descriptor is not defined because it takes variable number of arguments with different
+    // data types.
+    throw new UnsupportedOperationException("Undefined descriptor");
+  }
+}

http://git-wip-us.apache.org/repos/asf/hive/blob/53980ba6/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/IfExprCondExprColumn.java
----------------------------------------------------------------------
diff --git a/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/IfExprCondExprColumn.java b/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/IfExprCondExprColumn.java
new file mode 100644
index 0000000..cc465c1
--- /dev/null
+++ b/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/IfExprCondExprColumn.java
@@ -0,0 +1,125 @@
+/*
+ * 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.ql.exec.vector.ColumnVector;
+import org.apache.hadoop.hive.ql.exec.vector.VectorizedRowBatch;
+
+/**
+ * Do conditional execution of the THEN/ vector expression and regular execution of the ELSE
+ * vector expression (a column or scalar) of a SQL IF statement.
+ */
+public class IfExprCondExprColumn extends IfExprCondExprBase {
+  private static final long serialVersionUID = 1L;
+
+  protected final int arg2Column;
+  protected final int arg3Column;
+
+  public IfExprCondExprColumn(int arg1Column, int arg2Column, int arg3Column,
+      int outputColumnNum) {
+    super(arg1Column, outputColumnNum);
+    this.arg2Column = arg2Column;
+    this.arg3Column = arg3Column;
+  }
+
+  public IfExprCondExprColumn() {
+    super();
+
+    // Dummy final assignments.
+    arg2Column = -1;
+    arg3Column = -1;
+  }
+
+  @Override
+  public void evaluate(VectorizedRowBatch batch) {
+
+    int n = batch.size;
+    if (n <= 0) {
+      // Nothing to do
+      return;
+    }
+
+    /*
+     * Do common analysis of the IF statement boolean expression.
+     *
+     * The following protected members can be examined afterwards:
+     *
+     *   boolean isIfStatementResultRepeated
+     *   boolean isIfStatementResultThen
+     *
+     *   int thenSelectedCount
+     *   int[] thenSelected
+     *   int elseSelectedCount
+     *   int[] elseSelected
+     */
+    super.evaluate(batch);
+
+    ColumnVector outputColVector = batch.cols[outputColumnNum];
+    boolean[] outputIsNull = outputColVector.isNull;
+
+    // We do not need to do a column reset since we are carefully changing the output.
+    outputColVector.isRepeating = false;
+
+    // CONSIDER: Should be do this for all vector expressions that can
+    //           work on BytesColumnVector output columns???
+    outputColVector.init();
+
+    ColumnVector thenColVector = batch.cols[arg2Column];
+    ColumnVector elseColVector = batch.cols[arg3Column];
+
+    final int thenCount = thenSelectedCount;
+    final int elseCount = elseSelectedCount;
+
+    if (isIfStatementResultRepeated) {
+      if (isIfStatementResultThen) {
+        // Evaluate THEN expression (only) and copy all its results.
+        childExpressions[1].evaluate(batch);
+        thenColVector.copySelected(batch.selectedInUse, batch.selected, n, outputColVector);
+      } else {
+        // Evaluate ELSE expression (only) and copy all its results.
+        childExpressions[2].evaluate(batch);
+        elseColVector.copySelected(batch.selectedInUse, batch.selected, n, outputColVector);
+      }
+      return;
+    }
+
+    // NOTE: We cannot use copySelected below since it is a whole column operation.
+
+    conditionalEvaluate(batch, childExpressions[1], thenSelected, thenCount);
+    for (int i = 0; i < thenCount; i++) {
+      final int batchIndex = thenSelected[i];
+      outputIsNull[batchIndex] = false;
+      outputColVector.setElement(batchIndex, batchIndex, thenColVector);
+    }
+
+    // The ELSE expression is either IdentityExpression (a column) or a ConstantVectorExpression
+    // (a scalar) and trivial to evaluate.
+    childExpressions[2].evaluate(batch);
+    for (int i = 0; i < elseCount; i++) {
+      final int batchIndex = elseSelected[i];
+      outputIsNull[batchIndex] = false;
+      outputColVector.setElement(batchIndex, batchIndex, elseColVector);
+    }
+  }
+
+  @Override
+  public String vectorExpressionParameters() {
+    return getColumnParamString(0, arg1Column) + ", " + getColumnParamString(1, arg2Column) +
+        ", " + getColumnParamString(2, arg3Column);
+  }
+}

http://git-wip-us.apache.org/repos/asf/hive/blob/53980ba6/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/IfExprCondExprCondExpr.java
----------------------------------------------------------------------
diff --git a/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/IfExprCondExprCondExpr.java b/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/IfExprCondExprCondExpr.java
new file mode 100644
index 0000000..7874d5c
--- /dev/null
+++ b/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/IfExprCondExprCondExpr.java
@@ -0,0 +1,122 @@
+/*
+ * 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.ql.exec.vector.ColumnVector;
+import org.apache.hadoop.hive.ql.exec.vector.VectorizedRowBatch;
+
+/**
+ * Do conditional execution of the THEN/ELSE vector expressions of a SQL IF statement.
+ */
+public class IfExprCondExprCondExpr extends IfExprCondExprBase {
+  private static final long serialVersionUID = 1L;
+
+  protected final int arg2Column;
+  protected final int arg3Column;
+
+  public IfExprCondExprCondExpr(int arg1Column, int arg2Column, int arg3Column,
+      int outputColumnNum) {
+    super(arg1Column, outputColumnNum);
+    this.arg2Column = arg2Column;
+    this.arg3Column = arg3Column;
+  }
+
+  public IfExprCondExprCondExpr() {
+    super();
+
+    // Dummy final assignments.
+    arg2Column = -1;
+    arg3Column = -1;
+  }
+
+  @Override
+  public void evaluate(VectorizedRowBatch batch) {
+
+    int n = batch.size;
+    if (n <= 0) {
+      // Nothing to do
+      return;
+    }
+
+    /*
+     * Do common analysis of the IF statement boolean expression.
+     *
+     * The following protected members can be examined afterwards:
+     *
+     *   boolean isIfStatementResultRepeated
+     *   boolean isIfStatementResultThen
+     *
+     *   int thenSelectedCount
+     *   int[] thenSelected
+     *   int elseSelectedCount
+     *   int[] elseSelected
+     */
+    super.evaluate(batch);
+
+    ColumnVector outputColVector = batch.cols[outputColumnNum];
+    boolean[] outputIsNull = outputColVector.isNull;
+
+    // We do not need to do a column reset since we are carefully changing the output.
+    outputColVector.isRepeating = false;
+
+    // CONSIDER: Should be do this for all vector expressions that can
+    //           work on BytesColumnVector output columns???
+    outputColVector.init();
+
+    ColumnVector thenColVector = batch.cols[arg2Column];
+    ColumnVector elseColVector = batch.cols[arg3Column];
+
+    final int thenCount = thenSelectedCount;
+    final int elseCount = elseSelectedCount;
+
+    if (isIfStatementResultRepeated) {
+      if (isIfStatementResultThen) {
+        // Evaluate THEN expression (only) and copy all its results.
+        childExpressions[1].evaluate(batch);
+        thenColVector.copySelected(batch.selectedInUse, batch.selected, n, outputColVector);
+      } else {
+        // Evaluate ELSE expression (only) and copy all its results.
+        childExpressions[2].evaluate(batch);
+        elseColVector.copySelected(batch.selectedInUse, batch.selected, n, outputColVector);
+      }
+      return;
+    }
+
+    // NOTE: We cannot use copySelected below since it is a whole column operation.
+
+    conditionalEvaluate(batch, childExpressions[1], thenSelected, thenCount);
+    for (int i = 0; i < thenCount; i++) {
+      final int batchIndex = thenSelected[i];
+      outputIsNull[batchIndex] = false;
+      outputColVector.setElement(batchIndex, batchIndex, thenColVector);
+    }
+
+    conditionalEvaluate(batch, childExpressions[2], elseSelected, elseCount);
+    for (int i = 0; i < elseCount; i++) {
+      final int batchIndex = elseSelected[i];
+      outputIsNull[batchIndex] = false;
+      outputColVector.setElement(batchIndex, batchIndex, elseColVector);
+    }
+  }
+
+  @Override
+  public String vectorExpressionParameters() {
+    return getColumnParamString(0, arg1Column) + ", " + getColumnParamString(1, arg2Column) +
+        getColumnParamString(2, arg3Column);
+  }
+}

http://git-wip-us.apache.org/repos/asf/hive/blob/53980ba6/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/IfExprCondExprNull.java
----------------------------------------------------------------------
diff --git a/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/IfExprCondExprNull.java b/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/IfExprCondExprNull.java
new file mode 100644
index 0000000..b2bf0e4
--- /dev/null
+++ b/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/IfExprCondExprNull.java
@@ -0,0 +1,115 @@
+/*
+ * 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.ql.exec.vector.ColumnVector;
+import org.apache.hadoop.hive.ql.exec.vector.VectorizedRowBatch;
+
+/**
+ * Do conditional execution of the THEN vector expression with NULL ELSE of a SQL IF statement.
+ */
+public class IfExprCondExprNull extends IfExprCondExprBase {
+  private static final long serialVersionUID = 1L;
+
+  protected final int arg2Column;
+
+  public IfExprCondExprNull(int arg1Column, int arg2Column, int outputColumnNum) {
+    super(arg1Column, outputColumnNum);
+    this.arg2Column = arg2Column;
+  }
+
+  public IfExprCondExprNull() {
+    super();
+
+    // Dummy final assignments.
+    arg2Column = -1;
+  }
+
+  @Override
+  public void evaluate(VectorizedRowBatch batch) {
+
+    int n = batch.size;
+    if (n <= 0) {
+      // Nothing to do
+      return;
+    }
+
+    /*
+     * Do common analysis of the IF statement boolean expression.
+     *
+     * The following protected members can be examined afterwards:
+     *
+     *   boolean isIfStatementResultRepeated
+     *   boolean isIfStatementResultThen
+     *
+     *   int thenSelectedCount
+     *   int[] thenSelected
+     *   int elseSelectedCount
+     *   int[] elseSelected
+     */
+    super.evaluate(batch);
+
+    ColumnVector outputColVector = batch.cols[outputColumnNum];
+    boolean[] outputIsNull = outputColVector.isNull;
+
+    // We do not need to do a column reset since we are carefully changing the output.
+    outputColVector.isRepeating = false;
+
+    // CONSIDER: Should be do this for all vector expressions that can
+    //           work on BytesColumnVector output columns???
+    outputColVector.init();
+
+    ColumnVector thenColVector = batch.cols[arg2Column];
+
+    final int thenCount = thenSelectedCount;
+    final int elseCount = elseSelectedCount;
+
+    if (isIfStatementResultRepeated) {
+      if (isIfStatementResultThen) {
+        // Evaluate THEN expression (only) and copy all its results.
+        childExpressions[1].evaluate(batch);
+        thenColVector.copySelected(batch.selectedInUse, batch.selected, n, outputColVector);
+      } else {
+        outputIsNull[0] = true;
+        outputColVector.noNulls = false;
+        outputColVector.isRepeating = true;
+      }
+      return;
+    }
+
+    // NOTE: We cannot use copySelected below since it is a whole column operation.
+
+    conditionalEvaluate(batch, childExpressions[1], thenSelected, thenCount);
+    for (int i = 0; i < thenCount; i++) {
+      final int batchIndex = thenSelected[i];
+      outputIsNull[batchIndex] = false;
+      outputColVector.setElement(batchIndex, batchIndex, thenColVector);
+    }
+
+    outputColVector.noNulls = false;
+    for (int i = 0; i < elseCount; i++) {
+      outputColVector.isNull[elseSelected[i]] = true;
+    }
+  }
+
+  @Override
+  public String vectorExpressionParameters() {
+    return getColumnParamString(0, arg1Column) + ", " + getColumnParamString(1, arg2Column) +
+        ", null";
+  }
+}

http://git-wip-us.apache.org/repos/asf/hive/blob/53980ba6/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/IfExprNullCondExpr.java
----------------------------------------------------------------------
diff --git a/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/IfExprNullCondExpr.java b/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/IfExprNullCondExpr.java
new file mode 100644
index 0000000..2ca3388
--- /dev/null
+++ b/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/IfExprNullCondExpr.java
@@ -0,0 +1,117 @@
+/*
+ * 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.ql.exec.vector.ColumnVector;
+import org.apache.hadoop.hive.ql.exec.vector.VectorizedRowBatch;
+
+/**
+ * Do conditional execution of a NULL THEN and a ELSE vector expression of a SQL IF statement.
+ */
+public class IfExprNullCondExpr extends IfExprCondExprBase {
+  private static final long serialVersionUID = 1L;
+
+  protected final int arg3Column;
+
+  public IfExprNullCondExpr(int arg1Column, int arg3Column, int outputColumnNum) {
+    super(arg1Column, outputColumnNum);
+    this.arg3Column = arg3Column;
+  }
+
+  public IfExprNullCondExpr() {
+    super();
+
+    // Dummy final assignments.
+    arg3Column = -1;
+  }
+
+  @Override
+  public void evaluate(VectorizedRowBatch batch) {
+
+    int n = batch.size;
+    if (n <= 0) {
+      // Nothing to do
+      return;
+    }
+
+    /*
+     * Do common analysis of the IF statement boolean expression.
+     *
+     * The following protected members can be examined afterwards:
+     *
+     *   boolean isIfStatementResultRepeated
+     *   boolean isIfStatementResultThen
+     *
+     *   int thenSelectedCount
+     *   int[] thenSelected
+     *   int elseSelectedCount
+     *   int[] elseSelected
+     */
+    super.evaluate(batch);
+
+    ColumnVector outputColVector = batch.cols[outputColumnNum];
+    boolean[] outputIsNull = outputColVector.isNull;
+
+    // We do not need to do a column reset since we are carefully changing the output.
+    outputColVector.isRepeating = false;
+
+    // CONSIDER: Should be do this for all vector expressions that can
+    //           work on BytesColumnVector output columns???
+    outputColVector.init();
+
+    ColumnVector elseColVector = batch.cols[arg3Column];
+
+    final int thenCount = thenSelectedCount;
+    final int elseCount = elseSelectedCount;
+
+    if (isIfStatementResultRepeated) {
+      if (isIfStatementResultThen) {
+        outputIsNull[0] = true;
+        outputColVector.noNulls = false;
+        outputColVector.isRepeating = true;
+      } else {
+        // Evaluate ELSE expression (only) and copy all its results.
+        // Second input parameter but 3rd column.
+        childExpressions[1].evaluate(batch);
+        elseColVector.copySelected(batch.selectedInUse, batch.selected, n, outputColVector);
+      }
+      return;
+    }
+
+    // NOTE: We cannot use copySelected below since it is a whole column operation.
+
+    outputColVector.noNulls = false;
+    for (int i = 0; i < thenCount; i++) {
+      outputColVector.isNull[thenSelected[i]] = true;
+    }
+
+    // Second input parameter but 3rd column.
+    conditionalEvaluate(batch, childExpressions[1], elseSelected, elseCount);
+    for (int i = 0; i < elseCount; i++) {
+      final int batchIndex = elseSelected[i];
+      outputIsNull[batchIndex] = false;
+      outputColVector.setElement(batchIndex, batchIndex, elseColVector);
+    }
+  }
+
+  @Override
+  public String vectorExpressionParameters() {
+    // Second input parameter but 3rd column.
+    return getColumnParamString(0, arg1Column) + ", null, " + getColumnParamString(2, arg3Column);
+  }
+}

http://git-wip-us.apache.org/repos/asf/hive/blob/53980ba6/ql/src/test/queries/clientpositive/vector_case_when_1.q
----------------------------------------------------------------------
diff --git a/ql/src/test/queries/clientpositive/vector_case_when_1.q b/ql/src/test/queries/clientpositive/vector_case_when_1.q
new file mode 100644
index 0000000..f081efb
--- /dev/null
+++ b/ql/src/test/queries/clientpositive/vector_case_when_1.q
@@ -0,0 +1,281 @@
+set hive.cli.print.header=true;
+set hive.mapred.mode=nonstrict;
+set hive.explain.user=false;
+set hive.fetch.task.conversion=none;
+set hive.vectorized.execution.enabled=true;
+
+CREATE TABLE lineitem_test_txt (L_ORDERKEY      INT,
+                                L_PARTKEY       INT,
+                                L_SUPPKEY       INT,
+                                L_LINENUMBER    INT,
+                                L_QUANTITY      INT,
+                                L_EXTENDEDPRICE DOUBLE,
+                                L_DISCOUNT      DOUBLE,
+                                L_TAX           DECIMAL(10,2),
+                                L_RETURNFLAG    CHAR(1),
+                                L_LINESTATUS    CHAR(1),
+                                l_shipdate      DATE,
+                                L_COMMITDATE    DATE,
+                                L_RECEIPTDATE   DATE,
+                                L_SHIPINSTRUCT  VARCHAR(20),
+                                L_SHIPMODE      CHAR(10),
+                                L_COMMENT       STRING)
+ROW FORMAT DELIMITED
+FIELDS TERMINATED BY '|';
+
+LOAD DATA LOCAL INPATH '../../data/files/lineitem.txt' OVERWRITE INTO TABLE lineitem_test_txt;
+CREATE TABLE lineitem_test STORED AS ORC AS SELECT * FROM lineitem_test_txt;
+INSERT INTO TABLE lineitem_test VALUES (NULL,NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+
+SET hive.vectorized.if.expr.mode=adaptor;
+
+EXPLAIN VECTORIZATION DETAIL
+SELECT
+   L_QUANTITY as Quantity,
+   CASE
+     WHEN L_QUANTITY = 1 THEN "Single"
+     WHEN L_QUANTITY = 2 THEN "Two"
+     WHEN L_QUANTITY < 10 THEN "Some"
+     WHEN L_QUANTITY < 100 THEN "Many"
+     ELSE "Huge number" END AS Quantity_Description,
+   CASE
+     WHEN L_QUANTITY = 1 THEN "Single"
+     WHEN L_QUANTITY = 2 THEN "Two"
+     WHEN L_QUANTITY < 10 THEN "Some"
+     WHEN L_QUANTITY < 100 THEN "Many"
+     ELSE NULL END AS Quantity_Description_2,
+   CASE
+     WHEN L_QUANTITY = 1 THEN "Single"
+     WHEN L_QUANTITY = 2 THEN "Two"
+     WHEN L_QUANTITY < 10 THEN "Some"
+     WHEN L_QUANTITY < 100 THEN NULL
+     ELSE NULL END AS Quantity_Description_3,
+   IF(L_SHIPMODE = "SHIP", DATE_ADD(l_shipdate, 10), DATE_ADD(l_shipdate, 5)) AS Expected_Date,
+   CASE WHEN L_RETURNFLAG = "N"
+            THEN l_extendedprice * (1 - l_discount)
+        ELSE 0 END AS Field_1,  -- The 0 will be an integer and requires implicit casting.
+   CASE WHEN L_RETURNFLAG = "N"
+            THEN l_extendedprice * (1 - l_discount)
+        ELSE CAST(0 AS DOUBLE) END AS Field_2,
+   IF(L_SHIPINSTRUCT = "DELIVER IN PERSON", NULL, L_TAX) AS Field_3,
+   IF(L_SHIPINSTRUCT = "TAKE BACK RETURN", L_TAX, NULL) AS Field_4,
+   -- For the next 2 IF stmts, the 0s are integer and require implicit casting to decimal.
+   IF(L_SHIPINSTRUCT = "DELIVER IN PERSON", 0, L_TAX) AS Field_5,
+   IF(L_SHIPINSTRUCT = "TAKE BACK RETURN", L_TAX, 0) AS Field_6,
+   IF(L_SHIPINSTRUCT = "DELIVER IN PERSON", 0BD, L_TAX) AS Field_7,
+   IF(L_SHIPINSTRUCT = "TAKE BACK RETURN", L_TAX, 0BD) AS Field_8,
+   IF(L_PARTKEY > 30, CAST(L_RECEIPTDATE AS TIMESTAMP), CAST(L_COMMITDATE AS TIMESTAMP)) AS Field_9,
+   IF(L_SUPPKEY > 10000, DATEDIFF(L_RECEIPTDATE, L_COMMITDATE), NULL) AS Field_10,
+   IF(L_SUPPKEY > 10000, NULL, DATEDIFF(L_RECEIPTDATE, L_COMMITDATE)) AS Field_11,
+   IF(L_SUPPKEY % 500 > 100, DATE_ADD('2008-12-31', 1), DATE_ADD('2008-12-31', 365)) AS Field_12
+FROM lineitem_test
+ORDER BY Quantity;
+SELECT
+   L_QUANTITY as Quantity,
+   CASE
+     WHEN L_QUANTITY = 1 THEN "Single"
+     WHEN L_QUANTITY = 2 THEN "Two"
+     WHEN L_QUANTITY < 10 THEN "Some"
+     WHEN L_QUANTITY < 100 THEN "Many"
+     ELSE "Huge number" END AS Quantity_Description,
+   CASE
+     WHEN L_QUANTITY = 1 THEN "Single"
+     WHEN L_QUANTITY = 2 THEN "Two"
+     WHEN L_QUANTITY < 10 THEN "Some"
+     WHEN L_QUANTITY < 100 THEN "Many"
+     ELSE NULL END AS Quantity_Description_2,
+   CASE
+     WHEN L_QUANTITY = 1 THEN "Single"
+     WHEN L_QUANTITY = 2 THEN "Two"
+     WHEN L_QUANTITY < 10 THEN "Some"
+     WHEN L_QUANTITY < 100 THEN NULL
+     ELSE NULL END AS Quantity_Description_3,
+   IF(L_SHIPMODE = "SHIP", DATE_ADD(l_shipdate, 10), DATE_ADD(l_shipdate, 5)) AS Expected_Date,
+   CASE WHEN L_RETURNFLAG = "N"
+            THEN l_extendedprice * (1 - l_discount)
+        ELSE 0 END AS Field_1,  -- The 0 will be an integer and requires implicit casting.
+   CASE WHEN L_RETURNFLAG = "N"
+            THEN l_extendedprice * (1 - l_discount)
+        ELSE CAST(0 AS DOUBLE) END AS Field_2,
+   IF(L_SHIPINSTRUCT = "DELIVER IN PERSON", NULL, L_TAX) AS Field_3,
+   IF(L_SHIPINSTRUCT = "TAKE BACK RETURN", L_TAX, NULL) AS Field_4,
+   -- For the next 2 IF stmts, the 0s are integer and require implicit casting to decimal.
+   IF(L_SHIPINSTRUCT = "DELIVER IN PERSON", 0, L_TAX) AS Field_5,
+   IF(L_SHIPINSTRUCT = "TAKE BACK RETURN", L_TAX, 0) AS Field_6,
+   IF(L_SHIPINSTRUCT = "DELIVER IN PERSON", 0BD, L_TAX) AS Field_7,
+   IF(L_SHIPINSTRUCT = "TAKE BACK RETURN", L_TAX, 0BD) AS Field_8,
+   IF(L_PARTKEY > 30, CAST(L_RECEIPTDATE AS TIMESTAMP), CAST(L_COMMITDATE AS TIMESTAMP)) AS Field_9,
+   IF(L_SUPPKEY > 10000, DATEDIFF(L_RECEIPTDATE, L_COMMITDATE), NULL) AS Field_10,
+   IF(L_SUPPKEY > 10000, NULL, DATEDIFF(L_RECEIPTDATE, L_COMMITDATE)) AS Field_11,
+   IF(L_SUPPKEY % 500 > 100, DATE_ADD('2008-12-31', 1), DATE_ADD('2008-12-31', 365)) AS Field_12
+FROM lineitem_test
+ORDER BY Quantity;
+
+SET hive.vectorized.if.expr.mode=good;
+
+EXPLAIN VECTORIZATION DETAIL
+SELECT
+   L_QUANTITY as Quantity,
+   CASE
+     WHEN L_QUANTITY = 1 THEN "Single"
+     WHEN L_QUANTITY = 2 THEN "Two"
+     WHEN L_QUANTITY < 10 THEN "Some"
+     WHEN L_QUANTITY < 100 THEN "Many"
+     ELSE "Huge number" END AS Quantity_Description,
+   CASE
+     WHEN L_QUANTITY = 1 THEN "Single"
+     WHEN L_QUANTITY = 2 THEN "Two"
+     WHEN L_QUANTITY < 10 THEN "Some"
+     WHEN L_QUANTITY < 100 THEN "Many"
+     ELSE NULL END AS Quantity_Description_2,
+   CASE
+     WHEN L_QUANTITY = 1 THEN "Single"
+     WHEN L_QUANTITY = 2 THEN "Two"
+     WHEN L_QUANTITY < 10 THEN "Some"
+     WHEN L_QUANTITY < 100 THEN NULL
+     ELSE NULL END AS Quantity_Description_3,
+   IF(L_SHIPMODE = "SHIP", DATE_ADD(l_shipdate, 10), DATE_ADD(l_shipdate, 5)) AS Expected_Date,
+   CASE WHEN L_RETURNFLAG = "N"
+            THEN l_extendedprice * (1 - l_discount)
+        ELSE 0 END AS Field_1,  -- The 0 will be an integer and requires implicit casting.
+   CASE WHEN L_RETURNFLAG = "N"
+            THEN l_extendedprice * (1 - l_discount)
+        ELSE CAST(0 AS DOUBLE) END AS Field_2,
+   IF(L_SHIPINSTRUCT = "DELIVER IN PERSON", NULL, L_TAX) AS Field_3,
+   IF(L_SHIPINSTRUCT = "TAKE BACK RETURN", L_TAX, NULL) AS Field_4,
+   -- For the next 2 IF stmts, the 0s are integer and require implicit casting to decimal.
+   IF(L_SHIPINSTRUCT = "DELIVER IN PERSON", 0, L_TAX) AS Field_5,
+   IF(L_SHIPINSTRUCT = "TAKE BACK RETURN", L_TAX, 0) AS Field_6,
+   IF(L_SHIPINSTRUCT = "DELIVER IN PERSON", 0BD, L_TAX) AS Field_7,
+   IF(L_SHIPINSTRUCT = "TAKE BACK RETURN", L_TAX, 0BD) AS Field_8,
+   IF(L_PARTKEY > 30, CAST(L_RECEIPTDATE AS TIMESTAMP), CAST(L_COMMITDATE AS TIMESTAMP)) AS Field_9,
+   IF(L_SUPPKEY > 10000, DATEDIFF(L_RECEIPTDATE, L_COMMITDATE), NULL) AS Field_10,
+   IF(L_SUPPKEY > 10000, NULL, DATEDIFF(L_RECEIPTDATE, L_COMMITDATE)) AS Field_11,
+   IF(L_SUPPKEY % 500 > 100, DATE_ADD('2008-12-31', 1), DATE_ADD('2008-12-31', 365)) AS Field_12
+FROM lineitem_test
+ORDER BY Quantity;
+SELECT
+   L_QUANTITY as Quantity,
+   CASE
+     WHEN L_QUANTITY = 1 THEN "Single"
+     WHEN L_QUANTITY = 2 THEN "Two"
+     WHEN L_QUANTITY < 10 THEN "Some"
+     WHEN L_QUANTITY < 100 THEN "Many"
+     ELSE "Huge number" END AS Quantity_Description,
+   CASE
+     WHEN L_QUANTITY = 1 THEN "Single"
+     WHEN L_QUANTITY = 2 THEN "Two"
+     WHEN L_QUANTITY < 10 THEN "Some"
+     WHEN L_QUANTITY < 100 THEN "Many"
+     ELSE NULL END AS Quantity_Description_2,
+   CASE
+     WHEN L_QUANTITY = 1 THEN "Single"
+     WHEN L_QUANTITY = 2 THEN "Two"
+     WHEN L_QUANTITY < 10 THEN "Some"
+     WHEN L_QUANTITY < 100 THEN NULL
+     ELSE NULL END AS Quantity_Description_3,
+   IF(L_SHIPMODE = "SHIP", DATE_ADD(l_shipdate, 10), DATE_ADD(l_shipdate, 5)) AS Expected_Date,
+   CASE WHEN L_RETURNFLAG = "N"
+            THEN l_extendedprice * (1 - l_discount)
+        ELSE 0 END AS Field_1,  -- The 0 will be an integer and requires implicit casting.
+   CASE WHEN L_RETURNFLAG = "N"
+            THEN l_extendedprice * (1 - l_discount)
+        ELSE CAST(0 AS DOUBLE) END AS Field_2,
+   IF(L_SHIPINSTRUCT = "DELIVER IN PERSON", NULL, L_TAX) AS Field_3,
+   IF(L_SHIPINSTRUCT = "TAKE BACK RETURN", L_TAX, NULL) AS Field_4,
+   -- For the next 2 IF stmts, the 0s are integer and require implicit casting to decimal.
+   IF(L_SHIPINSTRUCT = "DELIVER IN PERSON", 0, L_TAX) AS Field_5,
+   IF(L_SHIPINSTRUCT = "TAKE BACK RETURN", L_TAX, 0) AS Field_6,
+   IF(L_SHIPINSTRUCT = "DELIVER IN PERSON", 0BD, L_TAX) AS Field_7,
+   IF(L_SHIPINSTRUCT = "TAKE BACK RETURN", L_TAX, 0BD) AS Field_8,
+   IF(L_PARTKEY > 30, CAST(L_RECEIPTDATE AS TIMESTAMP), CAST(L_COMMITDATE AS TIMESTAMP)) AS Field_9,
+   IF(L_SUPPKEY > 10000, DATEDIFF(L_RECEIPTDATE, L_COMMITDATE), NULL) AS Field_10,
+   IF(L_SUPPKEY > 10000, NULL, DATEDIFF(L_RECEIPTDATE, L_COMMITDATE)) AS Field_11,
+   IF(L_SUPPKEY % 500 > 100, DATE_ADD('2008-12-31', 1), DATE_ADD('2008-12-31', 365)) AS Field_12
+FROM lineitem_test
+ORDER BY Quantity;
+
+SET hive.vectorized.if.expr.mode=better;
+
+EXPLAIN VECTORIZATION DETAIL
+SELECT
+   L_QUANTITY as Quantity,
+   CASE
+     WHEN L_QUANTITY = 1 THEN "Single"
+     WHEN L_QUANTITY = 2 THEN "Two"
+     WHEN L_QUANTITY < 10 THEN "Some"
+     WHEN L_QUANTITY < 100 THEN "Many"
+     ELSE "Huge number" END AS Quantity_Description,
+   CASE
+     WHEN L_QUANTITY = 1 THEN "Single"
+     WHEN L_QUANTITY = 2 THEN "Two"
+     WHEN L_QUANTITY < 10 THEN "Some"
+     WHEN L_QUANTITY < 100 THEN "Many"
+     ELSE NULL END AS Quantity_Description_2,
+   CASE
+     WHEN L_QUANTITY = 1 THEN "Single"
+     WHEN L_QUANTITY = 2 THEN "Two"
+     WHEN L_QUANTITY < 10 THEN "Some"
+     WHEN L_QUANTITY < 100 THEN NULL
+     ELSE NULL END AS Quantity_Description_3,
+   IF(L_SHIPMODE = "SHIP", DATE_ADD(l_shipdate, 10), DATE_ADD(l_shipdate, 5)) AS Expected_Date,
+   CASE WHEN L_RETURNFLAG = "N"
+            THEN l_extendedprice * (1 - l_discount)
+        ELSE 0 END AS Field_1,  -- The 0 will be an integer and requires implicit casting.
+   CASE WHEN L_RETURNFLAG = "N"
+            THEN l_extendedprice * (1 - l_discount)
+        ELSE CAST(0 AS DOUBLE) END AS Field_2,
+   IF(L_SHIPINSTRUCT = "DELIVER IN PERSON", NULL, L_TAX) AS Field_3,
+   IF(L_SHIPINSTRUCT = "TAKE BACK RETURN", L_TAX, NULL) AS Field_4,
+   -- For the next 2 IF stmts, the 0s are integer and require implicit casting to decimal.
+   IF(L_SHIPINSTRUCT = "DELIVER IN PERSON", 0, L_TAX) AS Field_5,
+   IF(L_SHIPINSTRUCT = "TAKE BACK RETURN", L_TAX, 0) AS Field_6,
+   IF(L_SHIPINSTRUCT = "DELIVER IN PERSON", 0BD, L_TAX) AS Field_7,
+   IF(L_SHIPINSTRUCT = "TAKE BACK RETURN", L_TAX, 0BD) AS Field_8,
+   IF(L_PARTKEY > 30, CAST(L_RECEIPTDATE AS TIMESTAMP), CAST(L_COMMITDATE AS TIMESTAMP)) AS Field_9,
+   IF(L_SUPPKEY > 10000, DATEDIFF(L_RECEIPTDATE, L_COMMITDATE), NULL) AS Field_10,
+   IF(L_SUPPKEY > 10000, NULL, DATEDIFF(L_RECEIPTDATE, L_COMMITDATE)) AS Field_11,
+   IF(L_SUPPKEY % 500 > 100, DATE_ADD('2008-12-31', 1), DATE_ADD('2008-12-31', 365)) AS Field_12
+FROM lineitem_test
+ORDER BY Quantity;
+SELECT
+   L_QUANTITY as Quantity,
+   CASE
+     WHEN L_QUANTITY = 1 THEN "Single"
+     WHEN L_QUANTITY = 2 THEN "Two"
+     WHEN L_QUANTITY < 10 THEN "Some"
+     WHEN L_QUANTITY < 100 THEN "Many"
+     ELSE "Huge number" END AS Quantity_Description,
+   CASE
+     WHEN L_QUANTITY = 1 THEN "Single"
+     WHEN L_QUANTITY = 2 THEN "Two"
+     WHEN L_QUANTITY < 10 THEN "Some"
+     WHEN L_QUANTITY < 100 THEN "Many"
+     ELSE NULL END AS Quantity_Description_2,
+   CASE
+     WHEN L_QUANTITY = 1 THEN "Single"
+     WHEN L_QUANTITY = 2 THEN "Two"
+     WHEN L_QUANTITY < 10 THEN "Some"
+     WHEN L_QUANTITY < 100 THEN NULL
+     ELSE NULL END AS Quantity_Description_3,
+   IF(L_SHIPMODE = "SHIP", DATE_ADD(l_shipdate, 10), DATE_ADD(l_shipdate, 5)) AS Expected_Date,
+   CASE WHEN L_RETURNFLAG = "N"
+            THEN l_extendedprice * (1 - l_discount)
+        ELSE 0 END AS Field_1,  -- The 0 will be an integer and requires implicit casting.
+   CASE WHEN L_RETURNFLAG = "N"
+            THEN l_extendedprice * (1 - l_discount)
+        ELSE CAST(0 AS DOUBLE) END AS Field_2,
+   IF(L_SHIPINSTRUCT = "DELIVER IN PERSON", NULL, L_TAX) AS Field_3,
+   IF(L_SHIPINSTRUCT = "TAKE BACK RETURN", L_TAX, NULL) AS Field_4,
+   -- For the next 2 IF stmts, the 0s are integer and require implicit casting to decimal.
+   IF(L_SHIPINSTRUCT = "DELIVER IN PERSON", 0, L_TAX) AS Field_5,
+   IF(L_SHIPINSTRUCT = "TAKE BACK RETURN", L_TAX, 0) AS Field_6,
+   IF(L_SHIPINSTRUCT = "DELIVER IN PERSON", 0BD, L_TAX) AS Field_7,
+   IF(L_SHIPINSTRUCT = "TAKE BACK RETURN", L_TAX, 0BD) AS Field_8,
+   IF(L_PARTKEY > 30, CAST(L_RECEIPTDATE AS TIMESTAMP), CAST(L_COMMITDATE AS TIMESTAMP)) AS Field_9,
+   IF(L_SUPPKEY > 10000, DATEDIFF(L_RECEIPTDATE, L_COMMITDATE), NULL) AS Field_10,
+   IF(L_SUPPKEY > 10000, NULL, DATEDIFF(L_RECEIPTDATE, L_COMMITDATE)) AS Field_11,
+   IF(L_SUPPKEY % 500 > 100, DATE_ADD('2008-12-31', 1), DATE_ADD('2008-12-31', 365)) AS Field_12
+FROM lineitem_test
+ORDER BY Quantity;
+ 
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/hive/blob/53980ba6/ql/src/test/queries/clientpositive/vector_case_when_2.q
----------------------------------------------------------------------
diff --git a/ql/src/test/queries/clientpositive/vector_case_when_2.q b/ql/src/test/queries/clientpositive/vector_case_when_2.q
new file mode 100644
index 0000000..6854fc0
--- /dev/null
+++ b/ql/src/test/queries/clientpositive/vector_case_when_2.q
@@ -0,0 +1,208 @@
+set hive.cli.print.header=true;
+set hive.mapred.mode=nonstrict;
+set hive.explain.user=false;
+set hive.fetch.task.conversion=none;
+set hive.vectorized.execution.enabled=true;
+
+create table timestamps_txt (tsval timestamp) STORED AS TEXTFILE;
+
+LOAD DATA LOCAL INPATH '../../data/files/timestamps.txt' OVERWRITE INTO TABLE timestamps_txt;
+
+create table timestamps (cdate date, ctimestamp1 timestamp,  stimestamp1 string,  ctimestamp2 timestamp) stored as orc;
+insert overwrite table timestamps
+  select cast(tsval as date), tsval, cast(tsval as string), tsval - '1 2:3:4' day to second from timestamps_txt;
+  
+INSERT INTO TABLE timestamps VALUES (NULL,NULL,NULL,NULL);
+
+SET hive.vectorized.if.expr.mode=adaptor;
+
+EXPLAIN VECTORIZATION DETAIL
+SELECT
+   ctimestamp1,
+   ctimestamp2,
+   CASE
+     WHEN ctimestamp2 <= date '1800-12-31' THEN "1800s or Earlier"
+     WHEN ctimestamp2 < date '1900-01-01' THEN "1900s"
+     WHEN ctimestamp2 between cast('2006-01-01 00:00:00.000' as timestamp) and cast('2010-12-31 23:59:59.999999999' as timestamp) THEN "Late 2000s"
+     WHEN ctimestamp2 <= timestamp '2015-12-31 23:59:59.999999999' THEN "Early 2010s"
+     ELSE "Unknown" END AS ctimestamp2_Description,
+   CASE
+     WHEN ctimestamp2 <= timestamp '2000-12-31 23:59:59.999999999' THEN "Old"
+     WHEN ctimestamp2 < timestamp '2006-01-01 00:00:00.000' THEN "Early 2000s"
+     WHEN ctimestamp2 between cast('2006-01-01 00:00:00.000' as timestamp) and cast('2010-12-31 23:59:59.999999999' as timestamp) THEN "Late 2000s"
+     WHEN ctimestamp2 <= timestamp '2015-12-31 23:59:59.999999999' THEN "Early 2010s"
+     ELSE NULL END AS ctimestamp2_Description_2,
+   CASE
+     WHEN ctimestamp2 <= timestamp '2000-12-31 23:59:59.999999999' THEN "Old"
+     WHEN ctimestamp2 < timestamp '2006-01-01 00:00:00.000' THEN "Early 2000s"
+     WHEN ctimestamp2 between timestamp '2006-01-01 00:00:00.000' and timestamp '2010-12-31 23:59:59.999999999' THEN "Late 2000s"
+     WHEN ctimestamp2 <= timestamp '2015-12-31 23:59:59.999999999' THEN NULL
+     ELSE NULL END AS ctimestamp2_Description_3,
+   IF(timestamp '1974-10-04 17:21:03.989' > ctimestamp1, year(ctimestamp1), year(ctimestamp2)) AS field1,
+   CASE WHEN stimestamp1 LIKE '%19%'
+            THEN stimestamp1
+        ELSE timestamp '2018-03-08 23:04:59' END AS Field_2,
+   IF(ctimestamp1 = timestamp '2021-09-24 03:18:32.413655165' , NULL, minute(ctimestamp1)) AS Field_3,
+   IF(ctimestamp2 >= timestamp '5344-10-04 18:40:08.165' and ctimestamp2 < timestamp '6631-11-13 16:31:29.702202248', minute(ctimestamp1), NULL) AS Field_4,
+   IF(cast(ctimestamp1 as double) % 500 > 100, DATE_ADD(cdate, 1), DATE_ADD(cdate, 365)) AS Field_5
+FROM timestamps
+ORDER BY ctimestamp1, stimestamp1, ctimestamp2;
+SELECT
+   ctimestamp1,
+   ctimestamp2,
+   CASE
+     WHEN ctimestamp2 <= date '1800-12-31' THEN "1800s or Earlier"
+     WHEN ctimestamp2 < date '1900-01-01' THEN "1900s"
+     WHEN ctimestamp2 between cast('2006-01-01 00:00:00.000' as timestamp) and cast('2010-12-31 23:59:59.999999999' as timestamp) THEN "Late 2000s"
+     WHEN ctimestamp2 <= timestamp '2015-12-31 23:59:59.999999999' THEN "Early 2010s"
+     ELSE "Unknown" END AS ctimestamp2_Description,
+   CASE
+     WHEN ctimestamp2 <= timestamp '2000-12-31 23:59:59.999999999' THEN "Old"
+     WHEN ctimestamp2 < timestamp '2006-01-01 00:00:00.000' THEN "Early 2000s"
+     WHEN ctimestamp2 between cast('2006-01-01 00:00:00.000' as timestamp) and cast('2010-12-31 23:59:59.999999999' as timestamp) THEN "Late 2000s"
+     WHEN ctimestamp2 <= timestamp '2015-12-31 23:59:59.999999999' THEN "Early 2010s"
+     ELSE NULL END AS ctimestamp2_Description_2,
+   CASE
+     WHEN ctimestamp2 <= timestamp '2000-12-31 23:59:59.999999999' THEN "Old"
+     WHEN ctimestamp2 < timestamp '2006-01-01 00:00:00.000' THEN "Early 2000s"
+     WHEN ctimestamp2 between timestamp '2006-01-01 00:00:00.000' and timestamp '2010-12-31 23:59:59.999999999' THEN "Late 2000s"
+     WHEN ctimestamp2 <= timestamp '2015-12-31 23:59:59.999999999' THEN NULL
+     ELSE NULL END AS ctimestamp2_Description_3,
+   IF(timestamp '1974-10-04 17:21:03.989' > ctimestamp1, year(ctimestamp1), year(ctimestamp2)) AS field1,
+   CASE WHEN stimestamp1 LIKE '%19%'
+            THEN stimestamp1
+        ELSE timestamp '2018-03-08 23:04:59' END AS Field_2,
+   IF(ctimestamp1 = timestamp '2021-09-24 03:18:32.413655165' , NULL, minute(ctimestamp1)) AS Field_3,
+   IF(ctimestamp2 >= timestamp '5344-10-04 18:40:08.165' and ctimestamp2 < timestamp '6631-11-13 16:31:29.702202248', minute(ctimestamp1), NULL) AS Field_4,
+   IF(cast(ctimestamp1 as double) % 500 > 100, DATE_ADD(cdate, 1), DATE_ADD(cdate, 365)) AS Field_5
+FROM timestamps
+ORDER BY ctimestamp1, stimestamp1, ctimestamp2;
+
+SET hive.vectorized.if.expr.mode=good;
+
+EXPLAIN VECTORIZATION DETAIL
+SELECT
+   ctimestamp1,
+   ctimestamp2,
+   CASE
+     WHEN ctimestamp2 <= date '1800-12-31' THEN "1800s or Earlier"
+     WHEN ctimestamp2 < date '1900-01-01' THEN "1900s"
+     WHEN ctimestamp2 between cast('2006-01-01 00:00:00.000' as timestamp) and cast('2010-12-31 23:59:59.999999999' as timestamp) THEN "Late 2000s"
+     WHEN ctimestamp2 <= timestamp '2015-12-31 23:59:59.999999999' THEN "Early 2010s"
+     ELSE "Unknown" END AS ctimestamp2_Description,
+   CASE
+     WHEN ctimestamp2 <= timestamp '2000-12-31 23:59:59.999999999' THEN "Old"
+     WHEN ctimestamp2 < timestamp '2006-01-01 00:00:00.000' THEN "Early 2000s"
+     WHEN ctimestamp2 between cast('2006-01-01 00:00:00.000' as timestamp) and cast('2010-12-31 23:59:59.999999999' as timestamp) THEN "Late 2000s"
+     WHEN ctimestamp2 <= timestamp '2015-12-31 23:59:59.999999999' THEN "Early 2010s"
+     ELSE NULL END AS ctimestamp2_Description_2,
+   CASE
+     WHEN ctimestamp2 <= timestamp '2000-12-31 23:59:59.999999999' THEN "Old"
+     WHEN ctimestamp2 < timestamp '2006-01-01 00:00:00.000' THEN "Early 2000s"
+     WHEN ctimestamp2 between timestamp '2006-01-01 00:00:00.000' and timestamp '2010-12-31 23:59:59.999999999' THEN "Late 2000s"
+     WHEN ctimestamp2 <= timestamp '2015-12-31 23:59:59.999999999' THEN NULL
+     ELSE NULL END AS ctimestamp2_Description_3,
+   IF(timestamp '1974-10-04 17:21:03.989' > ctimestamp1, year(ctimestamp1), year(ctimestamp2)) AS field1,
+   CASE WHEN stimestamp1 LIKE '%19%'
+            THEN stimestamp1
+        ELSE timestamp '2018-03-08 23:04:59' END AS Field_2,
+   IF(ctimestamp1 = timestamp '2021-09-24 03:18:32.413655165' , NULL, minute(ctimestamp1)) AS Field_3,
+   IF(ctimestamp2 >= timestamp '5344-10-04 18:40:08.165' and ctimestamp2 < timestamp '6631-11-13 16:31:29.702202248', minute(ctimestamp1), NULL) AS Field_4,
+   IF(cast(ctimestamp1 as double) % 500 > 100, DATE_ADD(cdate, 1), DATE_ADD(cdate, 365)) AS Field_5
+FROM timestamps
+ORDER BY ctimestamp1, stimestamp1, ctimestamp2;
+SELECT
+   ctimestamp1,
+   ctimestamp2,
+   CASE
+     WHEN ctimestamp2 <= date '1800-12-31' THEN "1800s or Earlier"
+     WHEN ctimestamp2 < date '1900-01-01' THEN "1900s"
+     WHEN ctimestamp2 between cast('2006-01-01 00:00:00.000' as timestamp) and cast('2010-12-31 23:59:59.999999999' as timestamp) THEN "Late 2000s"
+     WHEN ctimestamp2 <= timestamp '2015-12-31 23:59:59.999999999' THEN "Early 2010s"
+     ELSE "Unknown" END AS ctimestamp2_Description,
+   CASE
+     WHEN ctimestamp2 <= timestamp '2000-12-31 23:59:59.999999999' THEN "Old"
+     WHEN ctimestamp2 < timestamp '2006-01-01 00:00:00.000' THEN "Early 2000s"
+     WHEN ctimestamp2 between cast('2006-01-01 00:00:00.000' as timestamp) and cast('2010-12-31 23:59:59.999999999' as timestamp) THEN "Late 2000s"
+     WHEN ctimestamp2 <= timestamp '2015-12-31 23:59:59.999999999' THEN "Early 2010s"
+     ELSE NULL END AS ctimestamp2_Description_2,
+   CASE
+     WHEN ctimestamp2 <= timestamp '2000-12-31 23:59:59.999999999' THEN "Old"
+     WHEN ctimestamp2 < timestamp '2006-01-01 00:00:00.000' THEN "Early 2000s"
+     WHEN ctimestamp2 between timestamp '2006-01-01 00:00:00.000' and timestamp '2010-12-31 23:59:59.999999999' THEN "Late 2000s"
+     WHEN ctimestamp2 <= timestamp '2015-12-31 23:59:59.999999999' THEN NULL
+     ELSE NULL END AS ctimestamp2_Description_3,
+   IF(timestamp '1974-10-04 17:21:03.989' > ctimestamp1, year(ctimestamp1), year(ctimestamp2)) AS field1,
+   CASE WHEN stimestamp1 LIKE '%19%'
+            THEN stimestamp1
+        ELSE timestamp '2018-03-08 23:04:59' END AS Field_2,
+   IF(ctimestamp1 = timestamp '2021-09-24 03:18:32.413655165' , NULL, minute(ctimestamp1)) AS Field_3,
+   IF(ctimestamp2 >= timestamp '5344-10-04 18:40:08.165' and ctimestamp2 < timestamp '6631-11-13 16:31:29.702202248', minute(ctimestamp1), NULL) AS Field_4,
+   IF(cast(ctimestamp1 as double) % 500 > 100, DATE_ADD(cdate, 1), DATE_ADD(cdate, 365)) AS Field_5
+FROM timestamps
+ORDER BY ctimestamp1, stimestamp1, ctimestamp2;
+
+SET hive.vectorized.if.expr.mode=better;
+
+EXPLAIN VECTORIZATION DETAIL
+SELECT
+   ctimestamp1,
+   ctimestamp2,
+   CASE
+     WHEN ctimestamp2 <= date '1800-12-31' THEN "1800s or Earlier"
+     WHEN ctimestamp2 < date '1900-01-01' THEN "1900s"
+     WHEN ctimestamp2 between cast('2006-01-01 00:00:00.000' as timestamp) and cast('2010-12-31 23:59:59.999999999' as timestamp) THEN "Late 2000s"
+     WHEN ctimestamp2 <= timestamp '2015-12-31 23:59:59.999999999' THEN "Early 2010s"
+     ELSE "Unknown" END AS ctimestamp2_Description,
+   CASE
+     WHEN ctimestamp2 <= timestamp '2000-12-31 23:59:59.999999999' THEN "Old"
+     WHEN ctimestamp2 < timestamp '2006-01-01 00:00:00.000' THEN "Early 2000s"
+     WHEN ctimestamp2 between cast('2006-01-01 00:00:00.000' as timestamp) and cast('2010-12-31 23:59:59.999999999' as timestamp) THEN "Late 2000s"
+     WHEN ctimestamp2 <= timestamp '2015-12-31 23:59:59.999999999' THEN "Early 2010s"
+     ELSE NULL END AS ctimestamp2_Description_2,
+   CASE
+     WHEN ctimestamp2 <= timestamp '2000-12-31 23:59:59.999999999' THEN "Old"
+     WHEN ctimestamp2 < timestamp '2006-01-01 00:00:00.000' THEN "Early 2000s"
+     WHEN ctimestamp2 between timestamp '2006-01-01 00:00:00.000' and timestamp '2010-12-31 23:59:59.999999999' THEN "Late 2000s"
+     WHEN ctimestamp2 <= timestamp '2015-12-31 23:59:59.999999999' THEN NULL
+     ELSE NULL END AS ctimestamp2_Description_3,
+   IF(timestamp '1974-10-04 17:21:03.989' > ctimestamp1, year(ctimestamp1), year(ctimestamp2)) AS field1,
+   CASE WHEN stimestamp1 LIKE '%19%'
+            THEN stimestamp1
+        ELSE timestamp '2018-03-08 23:04:59' END AS Field_2,
+   IF(ctimestamp1 = timestamp '2021-09-24 03:18:32.413655165' , NULL, minute(ctimestamp1)) AS Field_3,
+   IF(ctimestamp2 >= timestamp '5344-10-04 18:40:08.165' and ctimestamp2 < timestamp '6631-11-13 16:31:29.702202248', minute(ctimestamp1), NULL) AS Field_4,
+   IF(cast(ctimestamp1 as double) % 500 > 100, DATE_ADD(cdate, 1), DATE_ADD(cdate, 365)) AS Field_5
+FROM timestamps
+ORDER BY ctimestamp1, stimestamp1, ctimestamp2;
+SELECT
+   ctimestamp1,
+   ctimestamp2,
+   CASE
+     WHEN ctimestamp2 <= date '1800-12-31' THEN "1800s or Earlier"
+     WHEN ctimestamp2 < date '1900-01-01' THEN "1900s"
+     WHEN ctimestamp2 between cast('2006-01-01 00:00:00.000' as timestamp) and cast('2010-12-31 23:59:59.999999999' as timestamp) THEN "Late 2000s"
+     WHEN ctimestamp2 <= timestamp '2015-12-31 23:59:59.999999999' THEN "Early 2010s"
+     ELSE "Unknown" END AS ctimestamp2_Description,
+   CASE
+     WHEN ctimestamp2 <= timestamp '2000-12-31 23:59:59.999999999' THEN "Old"
+     WHEN ctimestamp2 < timestamp '2006-01-01 00:00:00.000' THEN "Early 2000s"
+     WHEN ctimestamp2 between cast('2006-01-01 00:00:00.000' as timestamp) and cast('2010-12-31 23:59:59.999999999' as timestamp) THEN "Late 2000s"
+     WHEN ctimestamp2 <= timestamp '2015-12-31 23:59:59.999999999' THEN "Early 2010s"
+     ELSE NULL END AS ctimestamp2_Description_2,
+   CASE
+     WHEN ctimestamp2 <= timestamp '2000-12-31 23:59:59.999999999' THEN "Old"
+     WHEN ctimestamp2 < timestamp '2006-01-01 00:00:00.000' THEN "Early 2000s"
+     WHEN ctimestamp2 between timestamp '2006-01-01 00:00:00.000' and timestamp '2010-12-31 23:59:59.999999999' THEN "Late 2000s"
+     WHEN ctimestamp2 <= timestamp '2015-12-31 23:59:59.999999999' THEN NULL
+     ELSE NULL END AS ctimestamp2_Description_3,
+   IF(timestamp '1974-10-04 17:21:03.989' > ctimestamp1, year(ctimestamp1), year(ctimestamp2)) AS field1,
+   CASE WHEN stimestamp1 LIKE '%19%'
+            THEN stimestamp1
+        ELSE timestamp '2018-03-08 23:04:59' END AS Field_2,
+   IF(ctimestamp1 = timestamp '2021-09-24 03:18:32.413655165' , NULL, minute(ctimestamp1)) AS Field_3,
+   IF(ctimestamp2 >= timestamp '5344-10-04 18:40:08.165' and ctimestamp2 < timestamp '6631-11-13 16:31:29.702202248', minute(ctimestamp1), NULL) AS Field_4,
+   IF(cast(ctimestamp1 as double) % 500 > 100, DATE_ADD(cdate, 1), DATE_ADD(cdate, 365)) AS Field_5
+FROM timestamps
+ORDER BY ctimestamp1, stimestamp1, ctimestamp2;
+ 
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/hive/blob/53980ba6/ql/src/test/queries/clientpositive/vector_udf_adaptor_1.q
----------------------------------------------------------------------
diff --git a/ql/src/test/queries/clientpositive/vector_udf_adaptor_1.q b/ql/src/test/queries/clientpositive/vector_udf_adaptor_1.q
index 2eb0a0a..565edee 100644
--- a/ql/src/test/queries/clientpositive/vector_udf_adaptor_1.q
+++ b/ql/src/test/queries/clientpositive/vector_udf_adaptor_1.q
@@ -1,27 +1,209 @@
+set hive.cli.print.header=true;
 SET hive.vectorized.execution.enabled=true;
 set hive.fetch.task.conversion=none;
 set hive.stats.column.autogather=false;
 
-create table student_2_lines(
+-- SORT_QUERY_RESULTS
+
+create table student_10_lines_txt(
 name string,
 age int,
 gpa double)
 row format delimited
 fields terminated by '\001'
 stored as textfile;
-LOAD DATA LOCAL INPATH '../../data/files/student_2_lines' OVERWRITE INTO TABLE student_2_lines;
-analyze table student_2_lines compute statistics;
+LOAD DATA LOCAL INPATH '../../data/files/student_10_lines' OVERWRITE INTO TABLE student_10_lines_txt;
+CREATE TABLE student_10_lines STORED AS ORC AS SELECT * FROM student_10_lines_txt;
+INSERT INTO TABLE student_10_lines VALUES (NULL, NULL, NULL);
+INSERT INTO TABLE student_10_lines VALUES ("George", 22, 3.8);
+analyze table student_10_lines compute statistics;
+
+------------------------------------------------------------------------------------------
+
+SET hive.vectorized.if.expr.mode=adaptor;
+
+create table insert_a_adaptor (name string, age int, gpa double, a int, b timestamp, c string, d binary, e int, f double);
+
+explain vectorization detail
+insert overwrite table insert_a_adaptor
+    select
+      name,
+      age,
+      gpa,
+      IF(age<40, age, NULL),
+      IF(age>40, cast('2011-01-01 01:01:01' as timestamp), NULL),
+      IF(LENGTH(name)>8, name, NULL),
+      IF(LENGTH(name)<8, cast(name as binary), NULL),
+      IF(age>40, LENGTH(name), NULL),
+      IF(LENGTH(name)> 10, 2 * gpa, NULL)
+    from student_10_lines;
+insert overwrite table insert_a_adaptor
+    select
+      name,
+      age,
+      gpa,
+      IF(age<40, age, NULL),
+      IF(age>40, cast('2011-01-01 01:01:01' as timestamp), NULL),
+      IF(LENGTH(name)>8, name, NULL),
+      IF(LENGTH(name)<8, cast(name as binary), NULL),
+      IF(age>40, LENGTH(name), NULL),
+      IF(LENGTH(name)> 10, 2 * gpa, NULL)
+    from student_10_lines;
+select * from insert_a_adaptor;
+
+SET hive.vectorized.if.expr.mode=good;
+
+create table insert_a_good (name string, age int, gpa double, a int, b timestamp, c string, d binary, e int, f double);
+
+explain vectorization detail
+insert overwrite table insert_a_good
+    select
+      name,
+      age,
+      gpa,
+      IF(age<40, age, NULL),
+      IF(age>40, cast('2011-01-01 01:01:01' as timestamp), NULL),
+      IF(LENGTH(name)>8, name, NULL),
+      IF(LENGTH(name)<8, cast(name as binary), NULL),
+      IF(age>40, LENGTH(name), NULL),
+      IF(LENGTH(name)> 10, 2 * gpa, NULL)
+    from student_10_lines;
+insert overwrite table insert_a_good
+    select
+      name,
+      age,
+      gpa,
+      IF(age<40, age, NULL),
+      IF(age>40, cast('2011-01-01 01:01:01' as timestamp), NULL),
+      IF(LENGTH(name)>8, name, NULL),
+      IF(LENGTH(name)<8, cast(name as binary), NULL),
+      IF(age>40, LENGTH(name), NULL),
+      IF(LENGTH(name)> 10, 2 * gpa, NULL)
+    from student_10_lines;
+select * from insert_a_good;
+
+SET hive.vectorized.if.expr.mode=better;
+
+create table insert_a_better (name string, age int, gpa double, a int, b timestamp, c string, d binary, e int, f double);
+
+explain vectorization detail
+insert overwrite table insert_a_better
+    select
+      name,
+      age,
+      gpa,
+      IF(age<40, age, NULL),
+      IF(age>40, cast('2011-01-01 01:01:01' as timestamp), NULL),
+      IF(LENGTH(name)>8, name, NULL),
+      IF(LENGTH(name)<8, cast(name as binary), NULL),
+      IF(age>40, LENGTH(name), NULL),
+      IF(LENGTH(name)> 10, 2 * gpa, NULL)
+    from student_10_lines;
+insert overwrite table insert_a_better
+    select
+      name,
+      age,
+      gpa,
+      IF(age<40, age, NULL),
+      IF(age>40, cast('2011-01-01 01:01:01' as timestamp), NULL),
+      IF(LENGTH(name)>8, name, NULL),
+      IF(LENGTH(name)<8, cast(name as binary), NULL),
+      IF(age>40, LENGTH(name), NULL),
+      IF(LENGTH(name)> 10, 2 * gpa, NULL)
+    from student_10_lines;
+select * from insert_a_better;
+
+------------------------------------------------------------------------------------------
+
+SET hive.vectorized.if.expr.mode=adaptor;
+
+create table insert_b_adaptor (name string, age int, gpa double, a int, b timestamp, c string, d binary, e int, f double);
+
+explain vectorization detail
+insert overwrite table insert_b_adaptor
+    select
+      name,
+      age,
+      gpa,
+      IF(age<40, NULL, age),
+      IF(age>40, NULL, cast('2011-01-01 01:01:01' as timestamp)),
+      IF(LENGTH(name)>8, NULL, name),
+      IF(LENGTH(name)<8, NULL, cast(name as binary)),
+      IF(age>40, NULL, LENGTH(name)),
+      IF(LENGTH(name)> 10, NULL, 2 * gpa)
+    from student_10_lines;
+insert overwrite table insert_b_adaptor
+    select
+      name,
+      age,
+      gpa,
+      IF(age<40, NULL, age),
+      IF(age>40, NULL, cast('2011-01-01 01:01:01' as timestamp)),
+      IF(LENGTH(name)>8, NULL, name),
+      IF(LENGTH(name)<8, NULL, cast(name as binary)),
+      IF(age>40, NULL, LENGTH(name)),
+      IF(LENGTH(name)> 10, NULL, 2 * gpa)
+    from student_10_lines;
+select * from insert_b_adaptor;
+
+SET hive.vectorized.if.expr.mode=good;
+
+create table insert_b_good (name string, age int, gpa double, a int, b timestamp, c string, d binary, e int, f double);
+
+explain vectorization detail
+insert overwrite table insert_b_good
+    select
+      name,
+      age,
+      gpa,
+      IF(age<40, NULL, age),
+      IF(age>40, NULL, cast('2011-01-01 01:01:01' as timestamp)),
+      IF(LENGTH(name)>8, NULL, name),
+      IF(LENGTH(name)<8, NULL, cast(name as binary)),
+      IF(age>40, NULL, LENGTH(name)),
+      IF(LENGTH(name)> 10, NULL, 2 * gpa)
+    from student_10_lines;
+insert overwrite table insert_b_good
+    select
+      name,
+      age,
+      gpa,
+      IF(age<40, NULL, age),
+      IF(age>40, NULL, cast('2011-01-01 01:01:01' as timestamp)),
+      IF(LENGTH(name)>8, NULL, name),
+      IF(LENGTH(name)<8, NULL, cast(name as binary)),
+      IF(age>40, NULL, LENGTH(name)),
+      IF(LENGTH(name)> 10, NULL, 2 * gpa)
+    from student_10_lines;
+select * from insert_b_good;
+
+SET hive.vectorized.if.expr.mode=better;
 
-create table insert_10_1 (a float, b int, c timestamp, d binary);
+create table insert_b_better (name string, age int, gpa double, a int, b timestamp, c string, d binary, e int, f double);
 
 explain vectorization detail
-insert overwrite table insert_10_1
-    select cast(gpa as float),
-    age,
-    IF(age>40,cast('2011-01-01 01:01:01' as timestamp),NULL),
-    IF(LENGTH(name)>10,cast(name as binary),NULL) from student_2_lines;
-insert overwrite table insert_10_1
-    select cast(gpa as float),
-    age,
-    IF(age>40,cast('2011-01-01 01:01:01' as timestamp),NULL),
-    IF(LENGTH(name)>10,cast(name as binary),NULL) from student_2_lines;
\ No newline at end of file
+insert overwrite table insert_b_better
+    select
+      name,
+      age,
+      gpa,
+      IF(age<40, NULL, age),
+      IF(age>40, NULL, cast('2011-01-01 01:01:01' as timestamp)),
+      IF(LENGTH(name)>8, NULL, name),
+      IF(LENGTH(name)<8, NULL, cast(name as binary)),
+      IF(age>40, NULL, LENGTH(name)),
+      IF(LENGTH(name)> 10, NULL, 2 * gpa)
+    from student_10_lines;
+insert overwrite table insert_b_better
+    select
+      name,
+      age,
+      gpa,
+      IF(age<40, NULL, age),
+      IF(age>40, NULL, cast('2011-01-01 01:01:01' as timestamp)),
+      IF(LENGTH(name)>8, NULL, name),
+      IF(LENGTH(name)<8, NULL, cast(name as binary)),
+      IF(age>40, NULL, LENGTH(name)),
+      IF(LENGTH(name)> 10, NULL, 2 * gpa)
+    from student_10_lines;
+select * from insert_b_better;
\ No newline at end of file