use of io.trino.spi.type.DecimalType in project trino by trinodb.
the class TupleDomainParquetPredicate method getDomain.
/**
* Get a domain for the ranges defined by each pair of elements from {@code minimums} and {@code maximums}.
* Both arrays must have the same length.
*/
private static Domain getDomain(ColumnDescriptor column, Type type, List<Object> minimums, List<Object> maximums, boolean hasNullValue, DateTimeZone timeZone) {
checkArgument(minimums.size() == maximums.size(), "Expected minimums and maximums to have the same size");
if (type.equals(BOOLEAN)) {
boolean hasTrueValues = minimums.stream().anyMatch(value -> (boolean) value) || maximums.stream().anyMatch(value -> (boolean) value);
boolean hasFalseValues = minimums.stream().anyMatch(value -> !(boolean) value) || maximums.stream().anyMatch(value -> !(boolean) value);
if (hasTrueValues && hasFalseValues) {
return Domain.all(type);
}
if (hasTrueValues) {
return Domain.create(ValueSet.of(type, true), hasNullValue);
}
if (hasFalseValues) {
return Domain.create(ValueSet.of(type, false), hasNullValue);
}
// All nulls case is handled earlier
throw new VerifyException("Impossible boolean statistics");
}
if (type.equals(BIGINT) || type.equals(INTEGER) || type.equals(DATE) || type.equals(SMALLINT) || type.equals(TINYINT)) {
List<Range> ranges = new ArrayList<>();
for (int i = 0; i < minimums.size(); i++) {
long min = asLong(minimums.get(i));
long max = asLong(maximums.get(i));
if (isStatisticsOverflow(type, min, max)) {
return Domain.create(ValueSet.all(type), hasNullValue);
}
ranges.add(Range.range(type, min, true, max, true));
}
return Domain.create(ValueSet.ofRanges(ranges), hasNullValue);
}
if (type instanceof DecimalType) {
DecimalType decimalType = (DecimalType) type;
List<Range> ranges = new ArrayList<>();
if (decimalType.isShort()) {
for (int i = 0; i < minimums.size(); i++) {
Object min = minimums.get(i);
Object max = maximums.get(i);
long minValue = min instanceof Binary ? getShortDecimalValue(((Binary) min).getBytes()) : asLong(min);
long maxValue = min instanceof Binary ? getShortDecimalValue(((Binary) max).getBytes()) : asLong(max);
if (isStatisticsOverflow(type, minValue, maxValue)) {
return Domain.create(ValueSet.all(type), hasNullValue);
}
ranges.add(Range.range(type, minValue, true, maxValue, true));
}
} else {
for (int i = 0; i < minimums.size(); i++) {
Int128 min = Int128.fromBigEndian(((Binary) minimums.get(i)).getBytes());
Int128 max = Int128.fromBigEndian(((Binary) maximums.get(i)).getBytes());
ranges.add(Range.range(type, min, true, max, true));
}
}
return Domain.create(ValueSet.ofRanges(ranges), hasNullValue);
}
if (type.equals(REAL)) {
List<Range> ranges = new ArrayList<>();
for (int i = 0; i < minimums.size(); i++) {
Float min = (Float) minimums.get(i);
Float max = (Float) maximums.get(i);
if (min.isNaN() || max.isNaN()) {
return Domain.create(ValueSet.all(type), hasNullValue);
}
ranges.add(Range.range(type, (long) floatToRawIntBits(min), true, (long) floatToRawIntBits(max), true));
}
return Domain.create(ValueSet.ofRanges(ranges), hasNullValue);
}
if (type.equals(DOUBLE)) {
List<Range> ranges = new ArrayList<>();
for (int i = 0; i < minimums.size(); i++) {
Double min = (Double) minimums.get(i);
Double max = (Double) maximums.get(i);
if (min.isNaN() || max.isNaN()) {
return Domain.create(ValueSet.all(type), hasNullValue);
}
ranges.add(Range.range(type, min, true, max, true));
}
return Domain.create(ValueSet.ofRanges(ranges), hasNullValue);
}
if (type instanceof VarcharType) {
List<Range> ranges = new ArrayList<>();
for (int i = 0; i < minimums.size(); i++) {
Slice min = Slices.wrappedBuffer(((Binary) minimums.get(i)).toByteBuffer());
Slice max = Slices.wrappedBuffer(((Binary) maximums.get(i)).toByteBuffer());
ranges.add(Range.range(type, min, true, max, true));
}
return Domain.create(ValueSet.ofRanges(ranges), hasNullValue);
}
if (type instanceof TimestampType) {
if (column.getPrimitiveType().getPrimitiveTypeName().equals(INT96)) {
TrinoTimestampEncoder<?> timestampEncoder = createTimestampEncoder((TimestampType) type, timeZone);
List<Object> values = new ArrayList<>();
for (int i = 0; i < minimums.size(); i++) {
Object min = minimums.get(i);
Object max = maximums.get(i);
// available and valid in that special case
if (!(min instanceof Binary) || !(max instanceof Binary) || !min.equals(max)) {
return Domain.create(ValueSet.all(type), hasNullValue);
}
values.add(timestampEncoder.getTimestamp(decodeInt96Timestamp((Binary) min)));
}
return Domain.multipleValues(type, values, hasNullValue);
}
if (column.getPrimitiveType().getPrimitiveTypeName().equals(INT64)) {
LogicalTypeAnnotation logicalTypeAnnotation = column.getPrimitiveType().getLogicalTypeAnnotation();
if (!(logicalTypeAnnotation instanceof TimestampLogicalTypeAnnotation)) {
// Invalid statistics. Unit and UTC adjustment are not known
return Domain.create(ValueSet.all(type), hasNullValue);
}
TimestampLogicalTypeAnnotation timestampTypeAnnotation = (TimestampLogicalTypeAnnotation) logicalTypeAnnotation;
// Bail out if the precision is not known
if (timestampTypeAnnotation.getUnit() == null) {
return Domain.create(ValueSet.all(type), hasNullValue);
}
TrinoTimestampEncoder<?> timestampEncoder = createTimestampEncoder((TimestampType) type, DateTimeZone.UTC);
List<Range> ranges = new ArrayList<>();
for (int i = 0; i < minimums.size(); i++) {
long min = (long) minimums.get(i);
long max = (long) maximums.get(i);
ranges.add(Range.range(type, timestampEncoder.getTimestamp(decodeInt64Timestamp(min, timestampTypeAnnotation.getUnit())), true, timestampEncoder.getTimestamp(decodeInt64Timestamp(max, timestampTypeAnnotation.getUnit())), true));
}
return Domain.create(ValueSet.ofRanges(ranges), hasNullValue);
}
}
return Domain.create(ValueSet.all(type), hasNullValue);
}
use of io.trino.spi.type.DecimalType in project trino by trinodb.
the class ParquetSchemaConverter method getPrimitiveType.
private org.apache.parquet.schema.Type getPrimitiveType(Type type, String name, List<String> parent) {
List<String> fullName = ImmutableList.<String>builder().addAll(parent).add(name).build();
primitiveTypes.put(fullName, type);
if (BOOLEAN.equals(type)) {
return Types.primitive(PrimitiveType.PrimitiveTypeName.BOOLEAN, OPTIONAL).named(name);
}
if (INTEGER.equals(type) || SMALLINT.equals(type) || TINYINT.equals(type)) {
return Types.primitive(PrimitiveType.PrimitiveTypeName.INT32, OPTIONAL).named(name);
}
if (type instanceof DecimalType) {
DecimalType decimalType = (DecimalType) type;
if (decimalType.getPrecision() <= 9) {
return Types.optional(PrimitiveType.PrimitiveTypeName.INT32).as(OriginalType.DECIMAL).precision(decimalType.getPrecision()).scale(decimalType.getScale()).named(name);
} else if (decimalType.isShort()) {
return Types.optional(PrimitiveType.PrimitiveTypeName.INT64).as(OriginalType.DECIMAL).precision(decimalType.getPrecision()).scale(decimalType.getScale()).named(name);
} else {
return Types.optional(PrimitiveType.PrimitiveTypeName.FIXED_LEN_BYTE_ARRAY).length(16).as(OriginalType.DECIMAL).precision(decimalType.getPrecision()).scale(decimalType.getScale()).named(name);
}
}
if (DATE.equals(type)) {
return Types.optional(PrimitiveType.PrimitiveTypeName.INT32).as(OriginalType.DATE).named(name);
}
if (BIGINT.equals(type)) {
return Types.primitive(PrimitiveType.PrimitiveTypeName.INT64, OPTIONAL).named(name);
}
if (type instanceof TimestampType) {
TimestampType timestampType = (TimestampType) type;
if (timestampType.getPrecision() <= 3) {
return Types.primitive(PrimitiveType.PrimitiveTypeName.INT64, OPTIONAL).as(LogicalTypeAnnotation.timestampType(false, LogicalTypeAnnotation.TimeUnit.MILLIS)).named(name);
}
if (timestampType.getPrecision() <= 6) {
return Types.primitive(PrimitiveType.PrimitiveTypeName.INT64, OPTIONAL).as(LogicalTypeAnnotation.timestampType(false, LogicalTypeAnnotation.TimeUnit.MICROS)).named(name);
}
if (timestampType.getPrecision() <= 9) {
// even though it can only hold values within 1677-09-21 00:12:43 and 2262-04-11 23:47:16 range.
return Types.primitive(PrimitiveType.PrimitiveTypeName.INT64, OPTIONAL).as(LogicalTypeAnnotation.timestampType(false, LogicalTypeAnnotation.TimeUnit.NANOS)).named(name);
}
}
if (DOUBLE.equals(type)) {
return Types.primitive(PrimitiveType.PrimitiveTypeName.DOUBLE, OPTIONAL).named(name);
}
if (RealType.REAL.equals(type)) {
return Types.primitive(PrimitiveType.PrimitiveTypeName.FLOAT, OPTIONAL).named(name);
}
if (type instanceof VarcharType || type instanceof CharType) {
return Types.primitive(PrimitiveType.PrimitiveTypeName.BINARY, OPTIONAL).as(LogicalTypeAnnotation.stringType()).named(name);
}
if (type instanceof VarbinaryType) {
return Types.primitive(PrimitiveType.PrimitiveTypeName.BINARY, OPTIONAL).named(name);
}
throw new TrinoException(NOT_SUPPORTED, format("Unsupported primitive type: %s", type));
}
use of io.trino.spi.type.DecimalType in project trino by trinodb.
the class ImplementSum method rewrite.
@Override
public Optional<JdbcExpression> rewrite(AggregateFunction aggregateFunction, Captures captures, RewriteContext<String> context) {
Variable argument = captures.get(ARGUMENT);
JdbcColumnHandle columnHandle = (JdbcColumnHandle) context.getAssignment(argument.getName());
JdbcTypeHandle resultTypeHandle;
if (columnHandle.getColumnType().equals(aggregateFunction.getOutputType())) {
resultTypeHandle = columnHandle.getJdbcTypeHandle();
} else if (aggregateFunction.getOutputType() instanceof DecimalType) {
Optional<JdbcTypeHandle> decimalTypeHandle = this.decimalTypeHandle.apply(((DecimalType) aggregateFunction.getOutputType()));
if (decimalTypeHandle.isEmpty()) {
return Optional.empty();
}
resultTypeHandle = decimalTypeHandle.get();
} else {
return Optional.empty();
}
return Optional.of(new JdbcExpression(format("sum(%s)", context.rewriteExpression(argument).orElseThrow()), resultTypeHandle));
}
use of io.trino.spi.type.DecimalType in project trino by trinodb.
the class IcebergTypes method convertIcebergValueToTrino.
/**
* Convert value from Iceberg representation to Trino representation.
*/
public static Object convertIcebergValueToTrino(Type icebergType, Object value) {
if (value == null) {
return null;
}
if (icebergType instanceof Types.BooleanType) {
// noinspection RedundantCast
return (Boolean) value;
}
if (icebergType instanceof Types.IntegerType) {
return ((Integer) value).longValue();
}
if (icebergType instanceof Types.LongType) {
// noinspection RedundantCast
return (Long) value;
}
if (icebergType instanceof Types.FloatType) {
return (long) Float.floatToIntBits((Float) value);
}
if (icebergType instanceof Types.DoubleType) {
// noinspection RedundantCast
return (Double) value;
}
if (icebergType instanceof Types.DecimalType) {
Types.DecimalType icebergDecimalType = (Types.DecimalType) icebergType;
DecimalType trinoDecimalType = DecimalType.createDecimalType(icebergDecimalType.precision(), icebergDecimalType.scale());
if (isShortDecimal(trinoDecimalType)) {
return Decimals.encodeShortScaledValue((BigDecimal) value, trinoDecimalType.getScale());
}
return Decimals.encodeScaledValue((BigDecimal) value, trinoDecimalType.getScale());
}
if (icebergType instanceof Types.StringType) {
// Partition values are passed as String, but min/max values are passed as a CharBuffer
if (value instanceof CharBuffer) {
value = new String(((CharBuffer) value).array());
}
return utf8Slice(((String) value));
}
if (icebergType instanceof Types.BinaryType) {
return Slices.wrappedBuffer(((ByteBuffer) value).array().clone());
}
if (icebergType instanceof Types.DateType) {
return ((Integer) value).longValue();
}
if (icebergType instanceof Types.TimeType) {
return Math.multiplyExact((Long) value, PICOSECONDS_PER_MICROSECOND);
}
if (icebergType instanceof Types.TimestampType) {
long epochMicros = (long) value;
if (((Types.TimestampType) icebergType).shouldAdjustToUTC()) {
return timestampTzFromMicros(epochMicros);
}
return epochMicros;
}
if (icebergType instanceof Types.UUIDType) {
return UuidType.javaUuidToTrinoUuid((UUID) value);
}
throw new UnsupportedOperationException("Unsupported iceberg type: " + icebergType);
}
use of io.trino.spi.type.DecimalType in project trino by trinodb.
the class TestChecksumAggregation method testShortDecimal.
@Test
public void testShortDecimal() {
Block block = createShortDecimalsBlock("11.11", "22.22", null, "33.33", "44.44");
DecimalType shortDecimalType = createDecimalType(1);
assertAggregation(FUNCTION_RESOLUTION, QualifiedName.of("checksum"), fromTypes(createDecimalType(10, 2)), expectedChecksum(shortDecimalType, block), block);
}
Aggregations