public static PrimitiveCategory getPrimitiveCommonCategory(TypeInfo a, TypeInfo b) {
    if (a.getCategory() != Category.PRIMITIVE || b.getCategory() != Category.PRIMITIVE) {
      return null;
    }

    PrimitiveCategory pcA = ((PrimitiveTypeInfo)a).getPrimitiveCategory();
    PrimitiveCategory pcB = ((PrimitiveTypeInfo)b).getPrimitiveCategory();

    if (pcA == pcB) {
      // Same primitive category
      return pcA;
    }

    if (pcA == PrimitiveCategory.VOID) {
      // Handle NULL, we return the type of pcB
      return pcB;
    }
    if (pcB == PrimitiveCategory.VOID) {
      // Handle NULL, we return the type of pcA
      return pcA;
    }

    PrimitiveGrouping pgA = PrimitiveObjectInspectorUtils.getPrimitiveGrouping(pcA);
    PrimitiveGrouping pgB = PrimitiveObjectInspectorUtils.getPrimitiveGrouping(pcB);

    if (pgA == pgB) {
      // Equal groups, return what we can handle
      switch (pgA) {
        case NUMERIC_GROUP: {
          Integer ai = TypeInfoUtils.numericTypes.get(pcA);
          Integer bi = TypeInfoUtils.numericTypes.get(pcB);
          return (ai > bi) ? pcA : pcB;
        }
        case DATE_GROUP: {
          Integer ai = TypeInfoUtils.dateTypes.get(pcA);
          Integer bi = TypeInfoUtils.dateTypes.get(pcB);
          return (ai > bi) ? pcA : pcB;
        }
        case STRING_GROUP: {
          // handle string types properly
          return PrimitiveCategory.STRING;
        }
        default:
          break;
      }
    }

    // Handle common category for date-string, numeric-string, and boolean-string types
    if (pgA == PrimitiveGrouping.STRING_GROUP && STRING_FRIENDLY_GROUPS.contains(pgB)) {
      return pcA;
    }
    if (pgB == PrimitiveGrouping.STRING_GROUP && STRING_FRIENDLY_GROUPS.contains(pgA)) {
      return pcB;
    }

    // We could not find a common category, return null
    return null;
  }
Find a common class that objects of both TypeInfo a and TypeInfo b can
convert to. This is used for comparing objects of type a and type b.

When we are comparing string and double, we will always convert both of
them to double and then compare.

@return null if no common class could be found.
ql/src/java/org/apache/hadoop/hive/ql/exec/FunctionRegistry.java