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