Search in sources :

Example 56 with DecimalType

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);
}
Also used : PrimitiveType(org.apache.parquet.schema.PrimitiveType) DateTimeZone(org.joda.time.DateTimeZone) FilterPredicate(org.apache.parquet.filter2.predicate.FilterPredicate) ColumnIndex(org.apache.parquet.internal.column.columnindex.ColumnIndex) FilterApi(org.apache.parquet.filter2.predicate.FilterApi) ByteBuffer(java.nio.ByteBuffer) INT96(org.apache.parquet.schema.PrimitiveType.PrimitiveTypeName.INT96) TrinoTimestampEncoderFactory.createTimestampEncoder(io.trino.plugin.base.type.TrinoTimestampEncoderFactory.createTimestampEncoder) ParquetDataSourceId(io.trino.parquet.ParquetDataSourceId) Preconditions.checkArgument(com.google.common.base.Preconditions.checkArgument) Slices(io.airlift.slice.Slices) Map(java.util.Map) INTEGER(io.trino.spi.type.IntegerType.INTEGER) UserDefinedPredicate(org.apache.parquet.filter2.predicate.UserDefinedPredicate) SMALLINT(io.trino.spi.type.SmallintType.SMALLINT) PredicateUtils.isStatisticsOverflow(io.trino.parquet.predicate.PredicateUtils.isStatisticsOverflow) Range(io.trino.spi.predicate.Range) TimestampLogicalTypeAnnotation(org.apache.parquet.schema.LogicalTypeAnnotation.TimestampLogicalTypeAnnotation) Domain(io.trino.spi.predicate.Domain) ParquetTimestampUtils.decodeInt96Timestamp(io.trino.parquet.ParquetTimestampUtils.decodeInt96Timestamp) Dictionary(io.trino.parquet.dictionary.Dictionary) ColumnIndexStore(org.apache.parquet.internal.filter2.columnindex.ColumnIndexStore) String.format(java.lang.String.format) ValueSet(io.trino.spi.predicate.ValueSet) Binary(org.apache.parquet.io.api.Binary) Serializable(java.io.Serializable) INT64(org.apache.parquet.schema.PrimitiveType.PrimitiveTypeName.INT64) List(java.util.List) TrinoTimestampEncoder(io.trino.plugin.base.type.TrinoTimestampEncoder) BIGINT(io.trino.spi.type.BigintType.BIGINT) LITTLE_ENDIAN(java.nio.ByteOrder.LITTLE_ENDIAN) ColumnDescriptor(org.apache.parquet.column.ColumnDescriptor) Optional(java.util.Optional) Operators(org.apache.parquet.filter2.predicate.Operators) DecimalType(io.trino.spi.type.DecimalType) DATE(io.trino.spi.type.DateType.DATE) REAL(io.trino.spi.type.RealType.REAL) ParquetCorruptionException(io.trino.parquet.ParquetCorruptionException) ColumnPath(org.apache.parquet.hadoop.metadata.ColumnPath) Slice(io.airlift.slice.Slice) Type(io.trino.spi.type.Type) BOOLEAN(io.trino.spi.type.BooleanType.BOOLEAN) LogicalTypeAnnotation(org.apache.parquet.schema.LogicalTypeAnnotation) Function(java.util.function.Function) TimestampType(io.trino.spi.type.TimestampType) ArrayList(java.util.ArrayList) VarcharType(io.trino.spi.type.VarcharType) Float.floatToRawIntBits(java.lang.Float.floatToRawIntBits) ImmutableList(com.google.common.collect.ImmutableList) Objects.requireNonNull(java.util.Objects.requireNonNull) RichColumnDescriptor(io.trino.parquet.RichColumnDescriptor) VerifyException(com.google.common.base.VerifyException) Int128(io.trino.spi.type.Int128) Statistics(org.apache.parquet.column.statistics.Statistics) DictionaryPage(io.trino.parquet.DictionaryPage) ParquetTimestampUtils.decodeInt64Timestamp(io.trino.parquet.ParquetTimestampUtils.decodeInt64Timestamp) ParquetTypeUtils.getShortDecimalValue(io.trino.parquet.ParquetTypeUtils.getShortDecimalValue) TupleDomain(io.trino.spi.predicate.TupleDomain) DOUBLE(io.trino.spi.type.DoubleType.DOUBLE) VisibleForTesting(com.google.common.annotations.VisibleForTesting) TINYINT(io.trino.spi.type.TinyintType.TINYINT) VarcharType(io.trino.spi.type.VarcharType) ArrayList(java.util.ArrayList) Range(io.trino.spi.predicate.Range) VerifyException(com.google.common.base.VerifyException) TimestampLogicalTypeAnnotation(org.apache.parquet.schema.LogicalTypeAnnotation.TimestampLogicalTypeAnnotation) LogicalTypeAnnotation(org.apache.parquet.schema.LogicalTypeAnnotation) Slice(io.airlift.slice.Slice) TimestampLogicalTypeAnnotation(org.apache.parquet.schema.LogicalTypeAnnotation.TimestampLogicalTypeAnnotation) DecimalType(io.trino.spi.type.DecimalType) TimestampType(io.trino.spi.type.TimestampType) Binary(org.apache.parquet.io.api.Binary) Int128(io.trino.spi.type.Int128)

Example 57 with DecimalType

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));
}
Also used : VarbinaryType(io.trino.spi.type.VarbinaryType) VarcharType(io.trino.spi.type.VarcharType) DecimalType(io.trino.spi.type.DecimalType) TimestampType(io.trino.spi.type.TimestampType) TrinoException(io.trino.spi.TrinoException) CharType(io.trino.spi.type.CharType)

Example 58 with DecimalType

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));
}
Also used : JdbcTypeHandle(io.trino.plugin.jdbc.JdbcTypeHandle) Variable(io.trino.spi.expression.Variable) Optional(java.util.Optional) JdbcColumnHandle(io.trino.plugin.jdbc.JdbcColumnHandle) DecimalType(io.trino.spi.type.DecimalType) JdbcExpression(io.trino.plugin.jdbc.JdbcExpression)

Example 59 with DecimalType

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);
}
Also used : Types(org.apache.iceberg.types.Types) CharBuffer(java.nio.CharBuffer) ByteBuffer(java.nio.ByteBuffer) DecimalType(io.trino.spi.type.DecimalType)

Example 60 with DecimalType

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);
}
Also used : Block(io.trino.spi.block.Block) BlockAssertions.createShortDecimalsBlock(io.trino.block.BlockAssertions.createShortDecimalsBlock) BlockAssertions.createStringsBlock(io.trino.block.BlockAssertions.createStringsBlock) BlockAssertions.createDoublesBlock(io.trino.block.BlockAssertions.createDoublesBlock) BlockAssertions.createBooleansBlock(io.trino.block.BlockAssertions.createBooleansBlock) BlockAssertions.createLongDecimalsBlock(io.trino.block.BlockAssertions.createLongDecimalsBlock) BlockAssertions.createLongsBlock(io.trino.block.BlockAssertions.createLongsBlock) BlockAssertions.createArrayBigintBlock(io.trino.block.BlockAssertions.createArrayBigintBlock) DecimalType.createDecimalType(io.trino.spi.type.DecimalType.createDecimalType) DecimalType(io.trino.spi.type.DecimalType) Test(org.testng.annotations.Test)

Aggregations

DecimalType (io.trino.spi.type.DecimalType)79 VarcharType (io.trino.spi.type.VarcharType)50 CharType (io.trino.spi.type.CharType)39 TrinoException (io.trino.spi.TrinoException)31 Type (io.trino.spi.type.Type)29 TimestampType (io.trino.spi.type.TimestampType)23 DecimalType.createDecimalType (io.trino.spi.type.DecimalType.createDecimalType)22 ArrayType (io.trino.spi.type.ArrayType)21 BigDecimal (java.math.BigDecimal)19 Int128 (io.trino.spi.type.Int128)16 BigInteger (java.math.BigInteger)15 Block (io.trino.spi.block.Block)14 Slice (io.airlift.slice.Slice)13 TimeType (io.trino.spi.type.TimeType)13 TimestampWithTimeZoneType (io.trino.spi.type.TimestampWithTimeZoneType)13 VarcharType.createUnboundedVarcharType (io.trino.spi.type.VarcharType.createUnboundedVarcharType)13 MapType (io.trino.spi.type.MapType)12 ArrayList (java.util.ArrayList)12 ImmutableList (com.google.common.collect.ImmutableList)11 RowType (io.trino.spi.type.RowType)11