in paimon-format/src/main/java/org/apache/orc/impl/RecordReaderImpl.java [1082:1201]
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) {
ChronoLocalDate date = (ChronoLocalDate) obj;
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));
}