private VectorExpression getCoalesceExpression(List<ExprNodeDesc> childExpr,
      VectorExpressionDescriptor.Mode mode, TypeInfo returnType)
      throws HiveException {
    int[] inputColumns = new int[childExpr.size()];
    VectorExpression[] vectorChildren =
        getVectorExpressions(childExpr, VectorExpressionDescriptor.Mode.PROJECTION);

    final int size = vectorChildren.length;
    TypeInfo[] inputTypeInfos = new TypeInfo[size];
    DataTypePhysicalVariation[] inputDataTypePhysicalVariations = new DataTypePhysicalVariation[size];
    DataTypePhysicalVariation outputDataTypePhysicalVariation = DataTypePhysicalVariation.DECIMAL_64;
    boolean fixConstants = false;
    for (int i = 0; i < vectorChildren.length; ++i) {
      VectorExpression ve = vectorChildren[i];
      inputColumns[i] = ve.getOutputColumnNum();
      inputTypeInfos[i] = ve.getOutputTypeInfo();
      inputDataTypePhysicalVariations[i] = ve.getOutputDataTypePhysicalVariation();
      if (inputDataTypePhysicalVariations[i] == DataTypePhysicalVariation.NONE ||
          inputDataTypePhysicalVariations[i] == null) {
        if (childExpr.get(i) instanceof ExprNodeConstantDesc && inputTypeInfos[i] instanceof DecimalTypeInfo &&
            ((DecimalTypeInfo)inputTypeInfos[i]).precision() <= 18) {
          fixConstants = true;
        } else {
          outputDataTypePhysicalVariation = DataTypePhysicalVariation.NONE;
        }
      }
    }

    if (outputDataTypePhysicalVariation == DataTypePhysicalVariation.DECIMAL_64 && fixConstants) {
      for (int i = 0; i < vectorChildren.length; ++i) {
        if ((inputDataTypePhysicalVariations[i] == DataTypePhysicalVariation.NONE ||
            inputDataTypePhysicalVariations[i] == null) && vectorChildren[i] instanceof ConstantVectorExpression) {
          ConstantVectorExpression cve = ((ConstantVectorExpression)vectorChildren[i]);
          HiveDecimal hd = cve.getDecimalValue();
          Long longValue = new HiveDecimalWritable(hd).serialize64(((DecimalTypeInfo)cve.getOutputTypeInfo()).getScale());
          ((ConstantVectorExpression)vectorChildren[i]).setLongValue(longValue);
          vectorChildren[i].setOutputDataTypePhysicalVariation(DataTypePhysicalVariation.DECIMAL_64);
          int scratchColIndex = vectorChildren[i].getOutputColumnNum() - ocm.initialOutputCol;
          ocm.scratchDataTypePhysicalVariations[scratchColIndex] = DataTypePhysicalVariation.DECIMAL_64;
        }
      }
    }

    final int outputColumnNum = ocm.allocateOutputColumn(returnType, outputDataTypePhysicalVariation);
    VectorCoalesce vectorCoalesce = new VectorCoalesce(inputColumns, outputColumnNum);

    vectorCoalesce.setChildExpressions(vectorChildren);

    vectorCoalesce.setInputTypeInfos(inputTypeInfos);
    vectorCoalesce.setInputDataTypePhysicalVariations(inputDataTypePhysicalVariations);

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

    freeNonColumns(vectorChildren);

    boolean isFilter = false;    // Assume.
    if (mode == VectorExpressionDescriptor.Mode.FILTER) {

      // Is output type a BOOLEAN?
      if (returnType.getCategory() == Category.PRIMITIVE &&
          ((PrimitiveTypeInfo) returnType).getPrimitiveCategory() == PrimitiveCategory.BOOLEAN) {
        isFilter = true;
      } else {
        return null;
      }
    }

    if (isFilter) {

      // Wrap the PROJECTION IF expression output with a filter.
      SelectColumnIsTrue filterVectorExpr = new SelectColumnIsTrue(vectorCoalesce.getOutputColumnNum());

      filterVectorExpr.setChildExpressions(new VectorExpression[] {vectorCoalesce});

      filterVectorExpr.setInputTypeInfos(vectorCoalesce.getOutputTypeInfo());
      filterVectorExpr.setInputDataTypePhysicalVariations(vectorCoalesce.getOutputDataTypePhysicalVariation());

      return filterVectorExpr;
    } else {
      return vectorCoalesce;
    }
  }
Used as a fast path for operations that don't modify their input, like unary +
and casting boolean to long. IdentityExpression and its children are always
projections.
ql/src/java/org/apache/hadoop/hive/ql/exec/vector/VectorizationContext.java