public static ExprEval ofType()

in processing/src/main/java/org/apache/druid/math/expr/ExprEval.java [499:599]


  public static ExprEval ofType(@Nullable ExpressionType type, @Nullable Object value)
  {
    if (type == null) {
      return bestEffortOf(value);
    }
    switch (type.getType()) {
      case STRING:
        // not all who claim to be "STRING" are always a String, prepare ourselves...
        if (value instanceof String[]) {
          final String[] inputArray = (String[]) value;
          final Object[] array = new Object[inputArray.length];
          for (int i = 0; i < inputArray.length; i++) {
            array[i] = inputArray[i];
          }
          return new ArrayExprEval(ExpressionType.STRING_ARRAY, array);
        }
        if (value instanceof Object[]) {
          return bestEffortOf(value);
        }
        if (value instanceof List) {
          return bestEffortOf(value);
        }
        if (value instanceof byte[]) {
          return new StringExprEval(StringUtils.encodeBase64String((byte[]) value));
        }
        return of(Evals.asString(value));
      case LONG:
        if (value instanceof Number) {
          return ofLong((Number) value);
        }
        if (value instanceof Boolean) {
          return ofLongBoolean((Boolean) value);
        }
        if (value instanceof String) {
          return ofLong(ExprEval.computeNumber((String) value));
        }
        return ofLong(null);
      case DOUBLE:
        if (value instanceof Number) {
          return ofDouble((Number) value);
        }
        if (value instanceof Boolean) {
          return ofDouble(Evals.asDouble((Boolean) value));
        }
        if (value instanceof String) {
          return ofDouble(ExprEval.computeNumber((String) value));
        }
        return ofDouble(null);
      case COMPLEX:
        if (ExpressionType.NESTED_DATA.equals(type)) {
          return ofComplex(type, StructuredData.unwrap(value));
        }
        byte[] bytes = null;
        if (value instanceof String) {
          try {
            bytes = StringUtils.decodeBase64String((String) value);
          }
          catch (IllegalArgumentException ignored) {
          }
        } else if (value instanceof byte[]) {
          bytes = (byte[]) value;
        }

        if (bytes != null) {
          TypeStrategy<?> strategy = type.getStrategy();
          ByteBuffer bb = ByteBuffer.wrap(bytes);
          return ofComplex(type, strategy.read(bb));
        }

        return ofComplex(type, value);
      case ARRAY:
        ExpressionType elementType = (ExpressionType) type.getElementType();
        if (value == null) {
          return ofArray(type, null);
        }
        if (value instanceof List) {
          List<?> theList = (List<?>) value;
          Object[] array = new Object[theList.size()];
          int i = 0;
          for (Object o : theList) {
            array[i++] = ExprEval.ofType(elementType, o).value();
          }
          return ofArray(type, array);
        }

        if (value instanceof Object[]) {
          Object[] inputArray = (Object[]) value;
          Object[] array = new Object[inputArray.length];
          int i = 0;
          for (Object o : inputArray) {
            array[i++] = ExprEval.ofType(elementType, o).value();
          }
          return ofArray(type, array);
        }
        // in a better world, we might get an object that matches the type signature for arrays and could do a switch
        // statement here, but this is not that world yet, and things that are array typed might also be non-arrays,
        // e.g. we might get a String instead of String[], so just fallback to bestEffortOf
        return bestEffortOf(value).castTo(type);
    }
    throw new IAE("Cannot create type [%s]", type);
  }