private VectorExpression doGetIfExpression(GenericUDFIf genericUDFIf, List<ExprNodeDesc> childExpr,
      TypeInfo returnType) throws HiveException {

    // 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 (hiveVectorIfStmtMode == HiveVectorIfStmtMode.ADAPTOR) {
      return null;
    }

    // Align the THEN/ELSE types.
    childExpr =
        getChildExpressionsWithImplicitCast(
            genericUDFIf,
            childExpr,
            returnType);

    final ExprNodeDesc ifDesc = Objects.requireNonNull(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);

      final VectorExpression resultExpr =
          new IfExprNullNull(
            outputColumnNum);

      resultExpr.setOutputTypeInfo(returnType);
      resultExpr.setOutputDataTypePhysicalVariation(DataTypePhysicalVariation.NONE);

      return resultExpr;
    }

    final boolean isThenCondExpr = isCondExpr(thenDesc);
    final boolean isElseCondExpr = isCondExpr(elseDesc);

    final boolean isOnlyGood = (hiveVectorIfStmtMode == HiveVectorIfStmtMode.GOOD);

    if (isThenNullConst) {
      final VectorExpression whenExpr =
          getVectorExpression(ifDesc, VectorExpressionDescriptor.Mode.PROJECTION);
      final VectorExpression elseExpr =
          getVectorExpression(elseDesc, VectorExpressionDescriptor.Mode.PROJECTION);
      DataTypePhysicalVariation outputDataTypePhysicalVariation =
          (elseExpr.getOutputDataTypePhysicalVariation() == null)
              ? DataTypePhysicalVariation.NONE
              : elseExpr.getOutputDataTypePhysicalVariation();

      final int outputColumnNum = ocm.allocateOutputColumn(returnType, outputDataTypePhysicalVariation);

      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});

      resultExpr.setInputTypeInfos(
          whenExpr.getOutputTypeInfo(),
          TypeInfoFactory.voidTypeInfo,
          elseExpr.getOutputTypeInfo());
      resultExpr.setInputDataTypePhysicalVariations(
          whenExpr.getOutputDataTypePhysicalVariation(),
          outputDataTypePhysicalVariation,
          elseExpr.getOutputDataTypePhysicalVariation());

      resultExpr.setOutputTypeInfo(returnType);
      resultExpr.setOutputDataTypePhysicalVariation(outputDataTypePhysicalVariation);

      return resultExpr;
    }

    if (isElseNullConst) {
      final VectorExpression whenExpr =
          getVectorExpression(ifDesc, VectorExpressionDescriptor.Mode.PROJECTION);
      final VectorExpression thenExpr =
          getVectorExpression(thenDesc, VectorExpressionDescriptor.Mode.PROJECTION);
      DataTypePhysicalVariation outputDataTypePhysicalVariation =
          (thenExpr.getOutputDataTypePhysicalVariation() == null)
              ? DataTypePhysicalVariation.NONE
              : thenExpr.getOutputDataTypePhysicalVariation();

      final int outputColumnNum = ocm.allocateOutputColumn(returnType, outputDataTypePhysicalVariation);

      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});

      resultExpr.setInputTypeInfos(
          whenExpr.getOutputTypeInfo(),
          thenExpr.getOutputTypeInfo(),
          TypeInfoFactory.voidTypeInfo);
      resultExpr.setInputDataTypePhysicalVariations(
          whenExpr.getOutputDataTypePhysicalVariation(),
          thenExpr.getOutputDataTypePhysicalVariation(),
          outputDataTypePhysicalVariation);

      resultExpr.setOutputTypeInfo(returnType);
      resultExpr.setOutputDataTypePhysicalVariation(outputDataTypePhysicalVariation);

      return resultExpr;
    }

    if ((isThenCondExpr || isElseCondExpr) && !isOnlyGood) {
      final VectorExpression whenExpr =
          getVectorExpression(ifDesc, VectorExpressionDescriptor.Mode.PROJECTION);
      final VectorExpression thenExpr =
          getVectorExpression(thenDesc, VectorExpressionDescriptor.Mode.PROJECTION);
      final VectorExpression elseExpr =
          getVectorExpression(elseDesc, VectorExpressionDescriptor.Mode.PROJECTION);

      // Only proceed if the THEN/ELSE types were aligned.
      if (thenExpr.getOutputColumnVectorType() == elseExpr.getOutputColumnVectorType()) {
        DataTypePhysicalVariation outputDataTypePhysicalVariation =
            (thenExpr.getOutputDataTypePhysicalVariation() == elseExpr.getOutputDataTypePhysicalVariation()
                && thenExpr.getOutputDataTypePhysicalVariation() != null)
                ? thenExpr.getOutputDataTypePhysicalVariation()
                : DataTypePhysicalVariation.NONE;

        final int outputColumnNum = ocm.allocateOutputColumn(returnType, outputDataTypePhysicalVariation);

        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(outputDataTypePhysicalVariation);

        return resultExpr;
      }
    }

    Class<?> udfClass = genericUDFIf.getClass();
    return getVectorExpressionForUdf(
        genericUDFIf, udfClass, childExpr, VectorExpressionDescriptor.Mode.PROJECTION, returnType);
  }
Invoke special handling for expressions that can't be vectorized by regular
descriptor based lookup.
ql/src/java/org/apache/hadoop/hive/ql/exec/vector/VectorizationContext.java