in athena-elasticsearch/src/main/java/com/amazonaws/athena/connectors/elasticsearch/ElasticsearchFieldResolver.java [149:247]
private Object coerceField(Field field, Object fieldValue)
{
Types.MinorType fieldType = Types.getMinorTypeForArrowType(field.getType());
if (fieldType != Types.MinorType.LIST && fieldValue instanceof List) {
// This is an abnormal case where the field was not defined as a list in the schema,
// however, fieldValue returns a list => return first item in list only applying coercion
// where necessary in order to match the type of the field being mapped into.
return coerceField(field, ((List) fieldValue).get(0));
}
switch (fieldType) {
case LIST:
return coerceListField(field, fieldValue);
case BIGINT:
if (!field.getMetadata().isEmpty() && field.getMetadata().containsKey("scaling_factor")) {
// scaled_float w/scaling_factor - a float represented as a long.
double scalingFactor = new Double(field.getMetadata().get("scaling_factor"));
if (fieldValue instanceof String) {
return Math.round(new Double((String) fieldValue) * scalingFactor);
}
else if (fieldValue instanceof Number) {
return Math.round(((Number) fieldValue).doubleValue() * scalingFactor);
}
break;
}
else if (fieldValue instanceof String) {
return new Double((String) fieldValue).longValue();
}
else if (fieldValue instanceof Number) {
return ((Number) fieldValue).longValue();
}
break;
case INT:
if (fieldValue instanceof String) {
return new Double((String) fieldValue).intValue();
}
else if (fieldValue instanceof Number) {
return ((Number) fieldValue).intValue();
}
break;
case SMALLINT:
if (fieldValue instanceof String) {
return new Double((String) fieldValue).shortValue();
}
else if (fieldValue instanceof Number) {
return ((Number) fieldValue).shortValue();
}
break;
case TINYINT:
if (fieldValue instanceof String) {
return new Double((String) fieldValue).byteValue();
}
else if (fieldValue instanceof Number) {
return ((Number) fieldValue).byteValue();
}
break;
case FLOAT8:
if (fieldValue instanceof String) {
return new Double((String) fieldValue);
}
else if (fieldValue instanceof Number) {
return ((Number) fieldValue).doubleValue();
}
break;
case FLOAT4:
if (fieldValue instanceof String) {
return new Float((String) fieldValue);
}
else if (fieldValue instanceof Number) {
return ((Number) fieldValue).floatValue();
}
break;
case DATEMILLI:
if (fieldValue instanceof String) {
try {
return toEpochMillis((String) fieldValue);
}
catch (DateTimeParseException error) {
logger.warn("Error parsing localDateTime: {}.", error.getMessage());
return null;
}
}
if (fieldValue instanceof Number) {
// Date should be a long numeric value representing epoch milliseconds (e.g. 1589525370001).
return ((Number) fieldValue).longValue();
}
break;
case BIT:
if (fieldValue instanceof String) {
return new Boolean((String) fieldValue);
}
break;
default:
break;
}
return fieldValue;
}