in java/core/src/java/org/apache/orc/impl/RecordReaderImpl.java [984:1094]
private static Comparable getBaseObjectForComparison(PredicateLeaf.Type type,
Comparable obj) {
if (obj == null) {
return null;
}
switch (type) {
case BOOLEAN:
if (obj instanceof Boolean) {
return obj;
} else {
// will only be true if the string conversion yields "true", all other values are
// considered false
return Boolean.valueOf(obj.toString());
}
case DATE:
if (obj instanceof ChronoLocalDate) {
return obj;
} else if (obj instanceof java.sql.Date) {
return ((java.sql.Date) obj).toLocalDate();
} else if (obj instanceof Date) {
return LocalDateTime.ofInstant(((Date) obj).toInstant(),
ZoneOffset.UTC).toLocalDate();
} else if (obj instanceof String) {
return LocalDate.parse((String) obj);
} else if (obj instanceof Timestamp) {
return ((Timestamp) obj).toLocalDateTime().toLocalDate();
}
// always string, but prevent the comparison to numbers (are they days/seconds/milliseconds?)
break;
case DECIMAL:
if (obj instanceof Boolean) {
return new HiveDecimalWritable((Boolean) obj ?
HiveDecimal.ONE : HiveDecimal.ZERO);
} else if (obj instanceof Integer) {
return new HiveDecimalWritable((Integer) obj);
} else if (obj instanceof Long) {
return new HiveDecimalWritable(((Long) obj));
} else if (obj instanceof Float || obj instanceof Double ||
obj instanceof String) {
return new HiveDecimalWritable(obj.toString());
} else if (obj instanceof BigDecimal) {
return new HiveDecimalWritable(HiveDecimal.create((BigDecimal) obj));
} else if (obj instanceof HiveDecimal) {
return new HiveDecimalWritable((HiveDecimal) obj);
} else if (obj instanceof HiveDecimalWritable) {
return obj;
} else if (obj instanceof Timestamp) {
return new HiveDecimalWritable(Double.toString(
TimestampUtils.getDouble((Timestamp) obj)));
}
break;
case FLOAT:
if (obj instanceof Number) {
// widening conversion
return ((Number) obj).doubleValue();
} else if (obj instanceof HiveDecimal) {
return ((HiveDecimal) obj).doubleValue();
} else if (obj instanceof String) {
return Double.valueOf(obj.toString());
} else if (obj instanceof Timestamp) {
return TimestampUtils.getDouble((Timestamp) obj);
}
break;
case LONG:
if (obj instanceof Number) {
// widening conversion
return ((Number) obj).longValue();
} else if (obj instanceof HiveDecimal) {
return ((HiveDecimal) obj).longValue();
} else if (obj instanceof String) {
return Long.valueOf(obj.toString());
}
break;
case STRING:
if (obj instanceof ChronoLocalDate date) {
return date.format(DateTimeFormatter.ISO_LOCAL_DATE
.withChronology(date.getChronology()));
}
return (obj.toString());
case TIMESTAMP:
if (obj instanceof Timestamp) {
return obj;
} else if (obj instanceof Integer) {
return new Timestamp(((Number) obj).longValue());
} else if (obj instanceof Float) {
return TimestampUtils.doubleToTimestamp(((Float) obj).doubleValue());
} else if (obj instanceof Double) {
return TimestampUtils.doubleToTimestamp((Double) obj);
} else if (obj instanceof HiveDecimal) {
return TimestampUtils.decimalToTimestamp((HiveDecimal) obj);
} else if (obj instanceof HiveDecimalWritable) {
return TimestampUtils.decimalToTimestamp(((HiveDecimalWritable) obj).getHiveDecimal());
} else if (obj instanceof Date) {
return new Timestamp(((Date) obj).getTime());
} else if (obj instanceof ChronoLocalDate) {
return new Timestamp(((ChronoLocalDate) obj).atTime(LocalTime.MIDNIGHT)
.toInstant(ZoneOffset.UTC).getEpochSecond() * 1000L);
}
// float/double conversion to timestamp is interpreted as seconds whereas integer conversion
// to timestamp is interpreted as milliseconds by default. The integer to timestamp casting
// is also config driven. The filter operator changes its promotion based on config:
// "int.timestamp.conversion.in.seconds". Disable PPD for integer cases.
break;
default:
break;
}
throw new SargCastException(String.format(
"ORC SARGS could not convert from %s to %s", obj.getClass()
.getSimpleName(), type));
}