use of io.trino.spi.type.TimestampType in project trino by trinodb.
the class DeltaHiveTypeTranslator method translate.
// Copy from HiveTypeTranslator with a custom mapping for TimestampWithTimeZone
public static TypeInfo translate(Type type) {
requireNonNull(type, "type is null");
if (BOOLEAN.equals(type)) {
return HIVE_BOOLEAN.getTypeInfo();
}
if (BIGINT.equals(type)) {
return HIVE_LONG.getTypeInfo();
}
if (INTEGER.equals(type)) {
return HIVE_INT.getTypeInfo();
}
if (SMALLINT.equals(type)) {
return HIVE_SHORT.getTypeInfo();
}
if (TINYINT.equals(type)) {
return HIVE_BYTE.getTypeInfo();
}
if (REAL.equals(type)) {
return HIVE_FLOAT.getTypeInfo();
}
if (DOUBLE.equals(type)) {
return HIVE_DOUBLE.getTypeInfo();
}
if (type instanceof VarcharType) {
VarcharType varcharType = (VarcharType) type;
if (varcharType.isUnbounded()) {
return HIVE_STRING.getTypeInfo();
}
if (varcharType.getBoundedLength() <= HiveVarchar.MAX_VARCHAR_LENGTH) {
return getVarcharTypeInfo(varcharType.getBoundedLength());
}
throw new TrinoException(NOT_SUPPORTED, format("Unsupported Hive type: %s. Supported VARCHAR types: VARCHAR(<=%d), VARCHAR.", type, HiveVarchar.MAX_VARCHAR_LENGTH));
}
if (type instanceof CharType) {
CharType charType = (CharType) type;
int charLength = charType.getLength();
if (charLength <= HiveChar.MAX_CHAR_LENGTH) {
return getCharTypeInfo(charLength);
}
throw new TrinoException(NOT_SUPPORTED, format("Unsupported Hive type: %s. Supported CHAR types: CHAR(<=%d).", type, HiveChar.MAX_CHAR_LENGTH));
}
if (VARBINARY.equals(type)) {
return HIVE_BINARY.getTypeInfo();
}
if (DATE.equals(type)) {
return HIVE_DATE.getTypeInfo();
}
if (type instanceof TimestampWithTimeZoneType) {
verify(((TimestampWithTimeZoneType) type).getPrecision() == 3, "Unsupported type: %s", type);
return HIVE_TIMESTAMP.getTypeInfo();
}
if (type instanceof TimestampType) {
verify(((TimestampType) type).getPrecision() == 3, "Unsupported type: %s", type);
return HIVE_TIMESTAMP.getTypeInfo();
}
if (type instanceof DecimalType) {
DecimalType decimalType = (DecimalType) type;
return new DecimalTypeInfo(decimalType.getPrecision(), decimalType.getScale());
}
if (isArrayType(type)) {
TypeInfo elementType = translate(type.getTypeParameters().get(0));
return getListTypeInfo(elementType);
}
if (isMapType(type)) {
TypeInfo keyType = translate(type.getTypeParameters().get(0));
TypeInfo valueType = translate(type.getTypeParameters().get(1));
return getMapTypeInfo(keyType, valueType);
}
if (isRowType(type)) {
ImmutableList.Builder<String> fieldNames = ImmutableList.builder();
for (TypeSignatureParameter parameter : type.getTypeSignature().getParameters()) {
if (!parameter.isNamedTypeSignature()) {
throw new IllegalArgumentException(format("Expected all parameters to be named type, but got %s", parameter));
}
NamedTypeSignature namedTypeSignature = parameter.getNamedTypeSignature();
if (namedTypeSignature.getName().isEmpty()) {
throw new TrinoException(NOT_SUPPORTED, format("Anonymous row type is not supported in Hive. Please give each field a name: %s", type));
}
fieldNames.add(namedTypeSignature.getName().get());
}
return getStructTypeInfo(fieldNames.build(), type.getTypeParameters().stream().map(DeltaHiveTypeTranslator::translate).collect(toImmutableList()));
}
throw new TrinoException(NOT_SUPPORTED, format("Unsupported Delta Lake type: %s", type));
}
use of io.trino.spi.type.TimestampType in project trino by trinodb.
the class AbstractRowEncoder method appendColumnValue.
@Override
public void appendColumnValue(Block block, int position) {
checkArgument(currentColumnIndex < columnHandles.size(), format("currentColumnIndex '%d' is greater than number of columns '%d'", currentColumnIndex, columnHandles.size()));
Type type = columnHandles.get(currentColumnIndex).getType();
if (block.isNull(position)) {
appendNullValue();
} else if (type == BOOLEAN) {
appendBoolean(type.getBoolean(block, position));
} else if (type == BIGINT) {
appendLong(type.getLong(block, position));
} else if (type == INTEGER) {
appendInt(toIntExact(type.getLong(block, position)));
} else if (type == SMALLINT) {
appendShort(Shorts.checkedCast(type.getLong(block, position)));
} else if (type == TINYINT) {
appendByte(SignedBytes.checkedCast(type.getLong(block, position)));
} else if (type == DOUBLE) {
appendDouble(type.getDouble(block, position));
} else if (type == REAL) {
appendFloat(intBitsToFloat(toIntExact(type.getLong(block, position))));
} else if (type instanceof VarcharType) {
appendString(type.getSlice(block, position).toStringUtf8());
} else if (type instanceof VarbinaryType) {
appendByteBuffer(type.getSlice(block, position).toByteBuffer());
} else if (type == DATE) {
appendSqlDate((SqlDate) type.getObjectValue(session, block, position));
} else if (type instanceof TimeType) {
appendSqlTime((SqlTime) type.getObjectValue(session, block, position));
} else if (type instanceof TimeWithTimeZoneType) {
appendSqlTimeWithTimeZone((SqlTimeWithTimeZone) type.getObjectValue(session, block, position));
} else if (type instanceof TimestampType) {
appendSqlTimestamp((SqlTimestamp) type.getObjectValue(session, block, position));
} else if (type instanceof TimestampWithTimeZoneType) {
appendSqlTimestampWithTimeZone((SqlTimestampWithTimeZone) type.getObjectValue(session, block, position));
} else if (type instanceof ArrayType) {
appendArray((List<Object>) type.getObjectValue(session, block, position));
} else if (type instanceof MapType) {
appendMap((Map<Object, Object>) type.getObjectValue(session, block, position));
} else if (type instanceof RowType) {
appendRow((List<Object>) type.getObjectValue(session, block, position));
} else {
throw new UnsupportedOperationException(format("Unsupported type '%s' for column '%s'", type, columnHandles.get(currentColumnIndex).getName()));
}
currentColumnIndex++;
}
use of io.trino.spi.type.TimestampType in project trino by trinodb.
the class H2QueryRunner method rowMapper.
private static RowMapper<MaterializedRow> rowMapper(List<? extends Type> types) {
return (resultSet, context) -> {
int count = resultSet.getMetaData().getColumnCount();
checkArgument(types.size() == count, "expected types count (%s) does not match actual column count (%s)", types.size(), count);
List<Object> row = new ArrayList<>(count);
for (int i = 1; i <= count; i++) {
Type type = types.get(i - 1);
if (BOOLEAN.equals(type)) {
boolean booleanValue = resultSet.getBoolean(i);
if (resultSet.wasNull()) {
row.add(null);
} else {
row.add(booleanValue);
}
} else if (TINYINT.equals(type)) {
byte byteValue = resultSet.getByte(i);
if (resultSet.wasNull()) {
row.add(null);
} else {
row.add(byteValue);
}
} else if (SMALLINT.equals(type)) {
short shortValue = resultSet.getShort(i);
if (resultSet.wasNull()) {
row.add(null);
} else {
row.add(shortValue);
}
} else if (INTEGER.equals(type)) {
int intValue = resultSet.getInt(i);
if (resultSet.wasNull()) {
row.add(null);
} else {
row.add(intValue);
}
} else if (BIGINT.equals(type)) {
long longValue = resultSet.getLong(i);
if (resultSet.wasNull()) {
row.add(null);
} else {
row.add(longValue);
}
} else if (REAL.equals(type)) {
float floatValue = resultSet.getFloat(i);
if (resultSet.wasNull()) {
row.add(null);
} else {
row.add(floatValue);
}
} else if (DOUBLE.equals(type)) {
double doubleValue = resultSet.getDouble(i);
if (resultSet.wasNull()) {
row.add(null);
} else {
row.add(doubleValue);
}
} else if (JSON.equals(type)) {
String stringValue = resultSet.getString(i);
if (resultSet.wasNull()) {
row.add(null);
} else {
row.add(jsonParse(utf8Slice(stringValue)).toStringUtf8());
}
} else if (type instanceof VarcharType) {
String stringValue = resultSet.getString(i);
if (resultSet.wasNull()) {
row.add(null);
} else {
row.add(stringValue);
}
} else if (type instanceof CharType) {
String stringValue = resultSet.getString(i);
if (resultSet.wasNull()) {
row.add(null);
} else {
row.add(padSpaces(stringValue, (CharType) type));
}
} else if (VARBINARY.equals(type)) {
byte[] bytes = resultSet.getBytes(i);
if (resultSet.wasNull()) {
row.add(null);
} else {
row.add(bytes);
}
} else if (DATE.equals(type)) {
// resultSet.getDate(i) doesn't work if JVM's zone skipped day being retrieved (e.g. 2011-12-30 and Pacific/Apia zone)
LocalDate dateValue = resultSet.getObject(i, LocalDate.class);
if (resultSet.wasNull()) {
row.add(null);
} else {
row.add(dateValue);
}
} else if (type instanceof TimeType) {
// resultSet.getTime(i) doesn't work if JVM's zone had forward offset change during 1970-01-01 (e.g. America/Hermosillo zone)
LocalTime timeValue = resultSet.getObject(i, LocalTime.class);
if (resultSet.wasNull()) {
row.add(null);
} else {
row.add(timeValue);
}
} else if (TIME_WITH_TIME_ZONE.equals(type)) {
throw new UnsupportedOperationException("H2 does not support TIME WITH TIME ZONE");
} else if (type instanceof TimestampType) {
// resultSet.getTimestamp(i) doesn't work if JVM's zone had forward offset at the date/time being retrieved
LocalDateTime timestampValue;
try {
timestampValue = resultSet.getObject(i, LocalDateTime.class);
} catch (SQLException first) {
// H2 cannot convert DATE to LocalDateTime in their JDBC driver (even though it can convert to java.sql.Timestamp), we need to do this manually
try {
timestampValue = Optional.ofNullable(resultSet.getObject(i, LocalDate.class)).map(LocalDate::atStartOfDay).orElse(null);
} catch (RuntimeException e) {
first.addSuppressed(e);
throw first;
}
}
if (resultSet.wasNull()) {
row.add(null);
} else {
row.add(timestampValue);
}
} else if (TIMESTAMP_WITH_TIME_ZONE.equals(type)) {
// This means H2 is unsuitable for testing TIMESTAMP WITH TIME ZONE-bearing queries. Those need to be tested manually.
throw new UnsupportedOperationException();
} else if (UUID.equals(type)) {
java.util.UUID value = (java.util.UUID) resultSet.getObject(i);
row.add(value);
} else if (UNKNOWN.equals(type)) {
Object objectValue = resultSet.getObject(i);
checkState(resultSet.wasNull(), "Expected a null value, but got %s", objectValue);
row.add(null);
} else if (type instanceof DecimalType) {
DecimalType decimalType = (DecimalType) type;
BigDecimal decimalValue = resultSet.getBigDecimal(i);
if (resultSet.wasNull()) {
row.add(null);
} else {
row.add(decimalValue.setScale(decimalType.getScale(), BigDecimal.ROUND_HALF_UP).round(new MathContext(decimalType.getPrecision())));
}
} else if (type instanceof ArrayType) {
Array array = resultSet.getArray(i);
if (resultSet.wasNull()) {
row.add(null);
} else {
row.add(newArrayList((Object[]) array.getArray()));
}
} else {
throw new AssertionError("unhandled type: " + type);
}
}
return new MaterializedRow(MaterializedResult.DEFAULT_PRECISION, row);
};
}
use of io.trino.spi.type.TimestampType in project trino by trinodb.
the class PostgreSqlClient method toColumnMapping.
@Override
public Optional<ColumnMapping> toColumnMapping(ConnectorSession session, Connection connection, JdbcTypeHandle typeHandle) {
String jdbcTypeName = typeHandle.getJdbcTypeName().orElseThrow(() -> new TrinoException(JDBC_ERROR, "Type name is missing: " + typeHandle));
Optional<ColumnMapping> mapping = getForcedMappingToVarchar(typeHandle);
if (mapping.isPresent()) {
return mapping;
}
switch(jdbcTypeName) {
case "money":
return Optional.of(moneyColumnMapping());
case "uuid":
return Optional.of(uuidColumnMapping());
case "jsonb":
case "json":
return Optional.of(jsonColumnMapping());
case "timestamptz":
// PostgreSQL's "timestamp with time zone" is reported as Types.TIMESTAMP rather than Types.TIMESTAMP_WITH_TIMEZONE
int decimalDigits = typeHandle.getRequiredDecimalDigits();
return Optional.of(timestampWithTimeZoneColumnMapping(decimalDigits));
case "hstore":
return Optional.of(hstoreColumnMapping(session));
}
switch(typeHandle.getJdbcType()) {
case Types.BIT:
return Optional.of(booleanColumnMapping());
case Types.SMALLINT:
return Optional.of(smallintColumnMapping());
case Types.INTEGER:
return Optional.of(integerColumnMapping());
case Types.BIGINT:
return Optional.of(bigintColumnMapping());
case Types.REAL:
return Optional.of(realColumnMapping());
case Types.DOUBLE:
return Optional.of(doubleColumnMapping());
case Types.NUMERIC:
{
int columnSize = typeHandle.getRequiredColumnSize();
int precision;
int decimalDigits = typeHandle.getDecimalDigits().orElse(0);
if (getDecimalRounding(session) == ALLOW_OVERFLOW) {
if (columnSize == PRECISION_OF_UNSPECIFIED_DECIMAL) {
// decimal type with unspecified scale - up to 131072 digits before the decimal point; up to 16383 digits after the decimal point)
return Optional.of(decimalColumnMapping(createDecimalType(Decimals.MAX_PRECISION, getDecimalDefaultScale(session)), getDecimalRoundingMode(session)));
}
precision = columnSize;
if (precision > Decimals.MAX_PRECISION) {
int scale = min(decimalDigits, getDecimalDefaultScale(session));
return Optional.of(decimalColumnMapping(createDecimalType(Decimals.MAX_PRECISION, scale), getDecimalRoundingMode(session)));
}
}
// Map decimal(p, -s) (negative scale) to decimal(p+s, 0).
precision = columnSize + max(-decimalDigits, 0);
if (columnSize == PRECISION_OF_UNSPECIFIED_DECIMAL || precision > Decimals.MAX_PRECISION) {
break;
}
return Optional.of(decimalColumnMapping(createDecimalType(precision, max(decimalDigits, 0)), UNNECESSARY));
}
case Types.CHAR:
return Optional.of(charColumnMapping(typeHandle.getRequiredColumnSize()));
case Types.VARCHAR:
if (!jdbcTypeName.equals("varchar")) {
// This can be e.g. an ENUM
return Optional.of(typedVarcharColumnMapping(jdbcTypeName));
}
return Optional.of(varcharColumnMapping(typeHandle.getRequiredColumnSize()));
case Types.BINARY:
return Optional.of(varbinaryColumnMapping());
case Types.DATE:
return Optional.of(ColumnMapping.longMapping(DATE, (resultSet, index) -> LocalDate.parse(resultSet.getString(index), DATE_FORMATTER).toEpochDay(), dateWriteFunctionUsingLocalDate()));
case Types.TIME:
return Optional.of(timeColumnMapping(typeHandle.getRequiredDecimalDigits()));
case Types.TIMESTAMP:
TimestampType timestampType = createTimestampType(typeHandle.getRequiredDecimalDigits());
return Optional.of(ColumnMapping.longMapping(timestampType, timestampReadFunction(timestampType), PostgreSqlClient::shortTimestampWriteFunction));
case Types.ARRAY:
Optional<ColumnMapping> columnMapping = arrayToTrinoType(session, connection, typeHandle);
if (columnMapping.isPresent()) {
return columnMapping;
}
break;
}
if (getUnsupportedTypeHandling(session) == CONVERT_TO_VARCHAR) {
return mapToUnboundedVarchar(typeHandle);
}
return Optional.empty();
}
use of io.trino.spi.type.TimestampType in project trino by trinodb.
the class PostgreSqlClient method toWriteMapping.
@Override
public WriteMapping toWriteMapping(ConnectorSession session, Type type) {
if (type == BOOLEAN) {
return WriteMapping.booleanMapping("boolean", booleanWriteFunction());
}
if (type == TINYINT) {
// PostgreSQL has no type corresponding to tinyint
return WriteMapping.longMapping("smallint", 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 (VARBINARY.equals(type)) {
return WriteMapping.sliceMapping("bytea", varbinaryWriteFunction());
}
if (type == DATE) {
return WriteMapping.longMapping("date", dateWriteFunctionUsingLocalDate());
}
if (type instanceof TimeType) {
TimeType timeType = (TimeType) type;
if (timeType.getPrecision() <= POSTGRESQL_MAX_SUPPORTED_TIMESTAMP_PRECISION) {
return WriteMapping.longMapping(format("time(%s)", timeType.getPrecision()), timeWriteFunction(timeType.getPrecision()));
}
return WriteMapping.longMapping(format("time(%s)", POSTGRESQL_MAX_SUPPORTED_TIMESTAMP_PRECISION), timeWriteFunction(POSTGRESQL_MAX_SUPPORTED_TIMESTAMP_PRECISION));
}
if (type instanceof TimestampType) {
TimestampType timestampType = (TimestampType) type;
if (timestampType.getPrecision() <= POSTGRESQL_MAX_SUPPORTED_TIMESTAMP_PRECISION) {
verify(timestampType.getPrecision() <= TimestampType.MAX_SHORT_PRECISION);
return WriteMapping.longMapping(format("timestamp(%s)", timestampType.getPrecision()), PostgreSqlClient::shortTimestampWriteFunction);
}
verify(timestampType.getPrecision() > TimestampType.MAX_SHORT_PRECISION);
return WriteMapping.objectMapping(format("timestamp(%s)", POSTGRESQL_MAX_SUPPORTED_TIMESTAMP_PRECISION), longTimestampWriteFunction());
}
if (type instanceof TimestampWithTimeZoneType) {
TimestampWithTimeZoneType timestampWithTimeZoneType = (TimestampWithTimeZoneType) type;
if (timestampWithTimeZoneType.getPrecision() <= POSTGRESQL_MAX_SUPPORTED_TIMESTAMP_PRECISION) {
String dataType = format("timestamptz(%d)", timestampWithTimeZoneType.getPrecision());
if (timestampWithTimeZoneType.getPrecision() <= TimestampWithTimeZoneType.MAX_SHORT_PRECISION) {
return WriteMapping.longMapping(dataType, shortTimestampWithTimeZoneWriteFunction());
}
return WriteMapping.objectMapping(dataType, longTimestampWithTimeZoneWriteFunction());
}
return WriteMapping.objectMapping(format("timestamptz(%d)", POSTGRESQL_MAX_SUPPORTED_TIMESTAMP_PRECISION), longTimestampWithTimeZoneWriteFunction());
}
if (type.equals(jsonType)) {
return WriteMapping.sliceMapping("jsonb", typedVarcharWriteFunction("json"));
}
if (type.equals(uuidType)) {
return WriteMapping.sliceMapping("uuid", uuidWriteFunction());
}
if (type instanceof ArrayType && getArrayMapping(session) == AS_ARRAY) {
Type elementType = ((ArrayType) type).getElementType();
String elementDataType = toWriteMapping(session, elementType).getDataType();
return WriteMapping.objectMapping(elementDataType + "[]", arrayWriteFunction(session, elementType, getArrayElementPgTypeName(session, this, elementType)));
}
throw new TrinoException(NOT_SUPPORTED, "Unsupported column type: " + type.getDisplayName());
}
Aggregations