use of io.trino.spi.type.DecimalType in project trino by trinodb.
the class TestTupleDomainParquetPredicate method testLongDecimal.
@Test
public void testLongDecimal() throws Exception {
ColumnDescriptor columnDescriptor = createColumnDescriptor(FIXED_LEN_BYTE_ARRAY, "LongDecimalColumn");
DecimalType type = createDecimalType(20, 5);
BigInteger maximum = new BigInteger("12345678901234512345");
Int128 zero = Int128.ZERO;
Int128 hundred = Int128.valueOf(100L);
Int128 max = Int128.valueOf(maximum);
assertEquals(getDomain(columnDescriptor, type, 0, null, ID, UTC), all(type));
assertEquals(getDomain(columnDescriptor, type, 10, binaryColumnStats(maximum, maximum), ID, UTC), singleValue(type, max));
assertEquals(getDomain(columnDescriptor, type, 10, binaryColumnStats(0L, 100L), ID, UTC), create(ValueSet.ofRanges(range(type, zero, true, hundred, true)), false));
// fail on corrupted statistics
assertThatExceptionOfType(ParquetCorruptionException.class).isThrownBy(() -> getDomain(columnDescriptor, type, 10, binaryColumnStats(100L, 10L), ID, UTC)).withMessage("Corrupted statistics for column \"[] required fixed_len_byte_array(0) LongDecimalColumn\" in Parquet file \"testFile\": [min: 0x64, max: 0x0A, num_nulls: 0]");
}
use of io.trino.spi.type.DecimalType in project trino by trinodb.
the class DruidJdbcClient method legacyToWriteMapping.
private WriteMapping legacyToWriteMapping(Type type) {
// This method is copied from deprecated BaseJdbcClient.legacyToWriteMapping()
if (type == BOOLEAN) {
return WriteMapping.booleanMapping("boolean", booleanWriteFunction());
}
if (type == TINYINT) {
return WriteMapping.longMapping("tinyint", tinyintWriteFunction());
}
if (type == SMALLINT) {
return WriteMapping.longMapping("smallint", smallintWriteFunction());
}
if (type == INTEGER) {
return WriteMapping.longMapping("integer", integerWriteFunction());
}
if (type == BIGINT) {
return WriteMapping.longMapping("bigint", bigintWriteFunction());
}
if (type == REAL) {
return WriteMapping.longMapping("real", realWriteFunction());
}
if (type == DOUBLE) {
return WriteMapping.doubleMapping("double precision", doubleWriteFunction());
}
if (type instanceof DecimalType) {
DecimalType decimalType = (DecimalType) type;
String dataType = format("decimal(%s, %s)", decimalType.getPrecision(), decimalType.getScale());
if (decimalType.isShort()) {
return WriteMapping.longMapping(dataType, shortDecimalWriteFunction(decimalType));
}
return WriteMapping.objectMapping(dataType, longDecimalWriteFunction(decimalType));
}
if (type instanceof CharType) {
return WriteMapping.sliceMapping("char(" + ((CharType) type).getLength() + ")", charWriteFunction());
}
if (type instanceof VarcharType) {
VarcharType varcharType = (VarcharType) type;
String dataType;
if (varcharType.isUnbounded()) {
dataType = "varchar";
} else {
dataType = "varchar(" + varcharType.getBoundedLength() + ")";
}
return WriteMapping.sliceMapping(dataType, varcharWriteFunction());
}
if (type == VARBINARY) {
return WriteMapping.sliceMapping("varbinary", varbinaryWriteFunction());
}
if (type == DATE) {
return WriteMapping.longMapping("date", dateWriteFunctionUsingSqlDate());
}
throw new TrinoException(NOT_SUPPORTED, "Unsupported column type: " + type.getDisplayName());
}
use of io.trino.spi.type.DecimalType in project trino by trinodb.
the class FormatFunction method valueConverter.
private static BiFunction<ConnectorSession, Block, Object> valueConverter(FunctionDependencies functionDependencies, Type type, int position) {
if (type.equals(UNKNOWN)) {
return (session, block) -> null;
}
if (type.equals(BOOLEAN)) {
return (session, block) -> type.getBoolean(block, position);
}
if (type.equals(TINYINT) || type.equals(SMALLINT) || type.equals(INTEGER) || type.equals(BIGINT)) {
return (session, block) -> type.getLong(block, position);
}
if (type.equals(REAL)) {
return (session, block) -> intBitsToFloat(toIntExact(type.getLong(block, position)));
}
if (type.equals(DOUBLE)) {
return (session, block) -> type.getDouble(block, position);
}
if (type.equals(DATE)) {
return (session, block) -> LocalDate.ofEpochDay(type.getLong(block, position));
}
if (type instanceof TimestampWithTimeZoneType) {
return (session, block) -> toZonedDateTime(((TimestampWithTimeZoneType) type), block, position);
}
if (type instanceof TimestampType) {
return (session, block) -> toLocalDateTime(((TimestampType) type), block, position);
}
if (type instanceof TimeType) {
return (session, block) -> toLocalTime(type.getLong(block, position));
}
// TODO: support TIME WITH TIME ZONE by https://github.com/trinodb/trino/issues/191 + mapping to java.time.OffsetTime
if (type.equals(JSON)) {
MethodHandle handle = functionDependencies.getFunctionInvoker(QualifiedName.of("json_format"), ImmutableList.of(JSON), simpleConvention(FAIL_ON_NULL, NEVER_NULL)).getMethodHandle();
return (session, block) -> convertToString(handle, type.getSlice(block, position));
}
if (isShortDecimal(type)) {
int scale = ((DecimalType) type).getScale();
return (session, block) -> BigDecimal.valueOf(type.getLong(block, position), scale);
}
if (isLongDecimal(type)) {
int scale = ((DecimalType) type).getScale();
return (session, block) -> new BigDecimal(((Int128) type.getObject(block, position)).toBigInteger(), scale);
}
if (type instanceof VarcharType) {
return (session, block) -> type.getSlice(block, position).toStringUtf8();
}
if (type instanceof CharType) {
CharType charType = (CharType) type;
return (session, block) -> padSpaces(type.getSlice(block, position), charType).toStringUtf8();
}
BiFunction<ConnectorSession, Block, Object> function;
if (type.getJavaType() == long.class) {
function = (session, block) -> type.getLong(block, position);
} else if (type.getJavaType() == double.class) {
function = (session, block) -> type.getDouble(block, position);
} else if (type.getJavaType() == boolean.class) {
function = (session, block) -> type.getBoolean(block, position);
} else if (type.getJavaType() == Slice.class) {
function = (session, block) -> type.getSlice(block, position);
} else {
function = (session, block) -> type.getObject(block, position);
}
MethodHandle handle = functionDependencies.getCastInvoker(type, VARCHAR, simpleConvention(FAIL_ON_NULL, NEVER_NULL)).getMethodHandle();
return (session, block) -> convertToString(handle, function.apply(session, block));
}
use of io.trino.spi.type.DecimalType in project trino by trinodb.
the class TypeCoercion method isTypeOnlyCoercion.
public boolean isTypeOnlyCoercion(Type source, Type result) {
if (source.equals(result)) {
return true;
}
if (!canCoerce(source, result)) {
return false;
}
if (source instanceof VarcharType && result instanceof VarcharType) {
return true;
}
if (source instanceof DecimalType && result instanceof DecimalType) {
DecimalType sourceDecimal = (DecimalType) source;
DecimalType resultDecimal = (DecimalType) result;
boolean sameDecimalSubtype = (sourceDecimal.isShort() && resultDecimal.isShort()) || (!sourceDecimal.isShort() && !resultDecimal.isShort());
boolean sameScale = sourceDecimal.getScale() == resultDecimal.getScale();
boolean sourcePrecisionIsLessOrEqualToResultPrecision = sourceDecimal.getPrecision() <= resultDecimal.getPrecision();
return sameDecimalSubtype && sameScale && sourcePrecisionIsLessOrEqualToResultPrecision;
}
if (source instanceof RowType && result instanceof RowType) {
RowType sourceType = (RowType) source;
RowType resultType = (RowType) result;
List<Field> sourceFields = sourceType.getFields();
List<Field> resultFields = resultType.getFields();
if (sourceFields.size() != resultFields.size()) {
return false;
}
for (int i = 0; i < sourceFields.size(); i++) {
if (!isTypeOnlyCoercion(sourceFields.get(i).getType(), resultFields.get(i).getType())) {
return false;
}
}
return true;
}
String sourceTypeBase = source.getBaseName();
String resultTypeBase = result.getBaseName();
if (sourceTypeBase.equals(resultTypeBase) && isCovariantParametrizedType(source)) {
List<Type> sourceTypeParameters = source.getTypeParameters();
List<Type> resultTypeParameters = result.getTypeParameters();
checkState(sourceTypeParameters.size() == resultTypeParameters.size());
for (int i = 0; i < sourceTypeParameters.size(); i++) {
if (!isTypeOnlyCoercion(sourceTypeParameters.get(i), resultTypeParameters.get(i))) {
return false;
}
}
return true;
}
return false;
}
use of io.trino.spi.type.DecimalType in project trino by trinodb.
the class OrcTester method decodeRecordReaderValue.
private static Object decodeRecordReaderValue(Type type, Object actualValue) {
if (actualValue instanceof BooleanWritable) {
actualValue = ((BooleanWritable) actualValue).get();
} else if (actualValue instanceof ByteWritable) {
actualValue = ((ByteWritable) actualValue).get();
} else if (actualValue instanceof BytesWritable) {
actualValue = new SqlVarbinary(((BytesWritable) actualValue).copyBytes());
} else if (actualValue instanceof DateWritableV2) {
actualValue = new SqlDate(((DateWritableV2) actualValue).getDays());
} else if (actualValue instanceof DoubleWritable) {
actualValue = ((DoubleWritable) actualValue).get();
} else if (actualValue instanceof FloatWritable) {
actualValue = ((FloatWritable) actualValue).get();
} else if (actualValue instanceof IntWritable) {
actualValue = ((IntWritable) actualValue).get();
} else if (actualValue instanceof HiveCharWritable) {
actualValue = ((HiveCharWritable) actualValue).getPaddedValue().toString();
} else if (actualValue instanceof LongWritable) {
actualValue = ((LongWritable) actualValue).get();
} else if (actualValue instanceof ShortWritable) {
actualValue = ((ShortWritable) actualValue).get();
} else if (actualValue instanceof HiveDecimalWritable) {
DecimalType decimalType = (DecimalType) type;
HiveDecimalWritable writable = (HiveDecimalWritable) actualValue;
// writable messes with the scale so rescale the values to the Trino type
BigInteger rescaledValue = rescale(writable.getHiveDecimal().unscaledValue(), writable.getScale(), decimalType.getScale());
actualValue = new SqlDecimal(rescaledValue, decimalType.getPrecision(), decimalType.getScale());
} else if (actualValue instanceof Text) {
actualValue = actualValue.toString();
} else if (actualValue instanceof TimestampWritableV2) {
Timestamp timestamp = ((TimestampWritableV2) actualValue).getTimestamp();
if (type.equals(TIMESTAMP_MILLIS)) {
actualValue = sqlTimestampOf(3, timestamp.toEpochMilli());
} else if (type.equals(TIMESTAMP_MICROS)) {
long micros = timestamp.toEpochSecond() * MICROSECONDS_PER_SECOND;
micros += roundDiv(timestamp.getNanos(), NANOSECONDS_PER_MICROSECOND);
actualValue = SqlTimestamp.newInstance(6, micros, 0);
} else if (type.equals(TIMESTAMP_NANOS)) {
long micros = timestamp.toEpochSecond() * MICROSECONDS_PER_SECOND;
micros += timestamp.getNanos() / NANOSECONDS_PER_MICROSECOND;
int picosOfMicro = (timestamp.getNanos() % NANOSECONDS_PER_MICROSECOND) * PICOSECONDS_PER_NANOSECOND;
actualValue = SqlTimestamp.newInstance(9, micros, picosOfMicro);
} else if (type.equals(TIMESTAMP_TZ_MILLIS)) {
actualValue = SqlTimestampWithTimeZone.newInstance(3, timestamp.toEpochMilli(), 0, UTC_KEY);
} else if (type.equals(TIMESTAMP_TZ_MICROS)) {
int picosOfMilli = roundDiv(timestamp.getNanos(), NANOSECONDS_PER_MICROSECOND) * PICOSECONDS_PER_MICROSECOND;
actualValue = SqlTimestampWithTimeZone.newInstance(3, timestamp.toEpochMilli(), picosOfMilli, UTC_KEY);
} else if (type.equals(TIMESTAMP_TZ_NANOS)) {
int picosOfMilli = (timestamp.getNanos() % NANOSECONDS_PER_MILLISECOND) * PICOSECONDS_PER_NANOSECOND;
actualValue = SqlTimestampWithTimeZone.newInstance(3, timestamp.toEpochMilli(), picosOfMilli, UTC_KEY);
} else {
throw new IllegalArgumentException("Unsupported timestamp type: " + type);
}
} else if (actualValue instanceof OrcStruct) {
List<Object> fields = new ArrayList<>();
OrcStruct structObject = (OrcStruct) actualValue;
for (int fieldId = 0; fieldId < structObject.getNumFields(); fieldId++) {
fields.add(OrcUtil.getFieldValue(structObject, fieldId));
}
actualValue = decodeRecordReaderStruct(type, fields);
} else if (actualValue instanceof List) {
actualValue = decodeRecordReaderList(type, ((List<?>) actualValue));
} else if (actualValue instanceof Map) {
actualValue = decodeRecordReaderMap(type, (Map<?, ?>) actualValue);
}
return actualValue;
}
Aggregations