static HiveType pickType()

in java/tools/src/java/org/apache/orc/tools/json/JsonSchemaFinder.java [77:155]


  static HiveType pickType(JsonElement json) {
    if (json.isJsonPrimitive()) {
      JsonPrimitive prim = (JsonPrimitive) json;
      if (prim.isBoolean()) {
        return new BooleanType();
      } else if (prim.isNumber()) {
        Matcher matcher = DECIMAL_PATTERN.matcher(prim.getAsString());
        if (matcher.matches()) {
          int intDigits = matcher.group("int").length();
          String fraction = matcher.group("fraction");
          int scale = fraction == null ? 0 : fraction.length();
          if (scale == 0) {
            if (intDigits < 19) {
              long value = prim.getAsLong();
              if (value >= -128 && value < 128) {
                return new NumericType(HiveType.Kind.BYTE, intDigits, scale);
              } else if (value >= -32768 && value < 32768) {
                return new NumericType(HiveType.Kind.SHORT, intDigits, scale);
              } else if (value >= -2147483648 && value < 2147483648L) {
                return new NumericType(HiveType.Kind.INT, intDigits, scale);
              } else {
                return new NumericType(HiveType.Kind.LONG, intDigits, scale);
              }
            } else if (intDigits == 19) {
              // at 19 digits, it may fit inside a long, but we need to check
              BigInteger val = prim.getAsBigInteger();
              if (val.compareTo(MIN_LONG) >= 0 && val.compareTo(MAX_LONG) <= 0) {
                return new NumericType(HiveType.Kind.LONG, intDigits, scale);
              }
            }
          }
          if (intDigits + scale <= MAX_DECIMAL_DIGITS) {
            return new NumericType(HiveType.Kind.DECIMAL, intDigits, scale);
          }
        }
        double value = prim.getAsDouble();
        if (value >= Float.MIN_VALUE && value <= Float.MAX_VALUE) {
          return new NumericType(HiveType.Kind.FLOAT, 0, 0);
        } else {
          return new NumericType(HiveType.Kind.DOUBLE, 0, 0);
        }
      } else {
        String str = prim.getAsString();
        if (TIMESTAMP_PATTERN.matcher(str).matches()) {
          return new StringType(HiveType.Kind.TIMESTAMP);
        } else if (HEX_PATTERN.matcher(str).matches()) {
          return new StringType(HiveType.Kind.BINARY);
        } else {
          return new StringType(HiveType.Kind.STRING);
        }
      }
    } else if (json.isJsonNull()) {
      return new NullType();
    } else if (json.isJsonArray()) {
      ListType result = new ListType();
      result.elementType = new NullType();
      for(JsonElement child: ((JsonArray) json)) {
        HiveType sub = pickType(child);
        if (result.elementType.subsumes(sub)) {
          result.elementType.merge(sub);
        } else if (sub.subsumes(result.elementType)) {
          sub.merge(result.elementType);
          result.elementType = sub;
        } else {
          result.elementType = new UnionType(result.elementType, sub);
        }
      }
      return result;
    } else {
      JsonObject obj = (JsonObject) json;
      StructType result = new StructType();
      for(Map.Entry<String,JsonElement> field: obj.entrySet()) {
        String fieldName = field.getKey();
        HiveType type = pickType(field.getValue());
        result.fields.put(fieldName, type);
      }
      return result;
    }
  }