use of com.facebook.presto.common.type.DecimalType in project presto by prestodb.
the class LiteralEncoder method toExpression.
@Deprecated
public Expression toExpression(Object object, Type type, boolean typeOnly) {
requireNonNull(type, "type is null");
if (object instanceof Expression) {
return (Expression) object;
}
if (object == null) {
if (type.equals(UNKNOWN)) {
return new NullLiteral();
}
return new Cast(new NullLiteral(), type.getTypeSignature().toString(), false, typeOnly);
}
if (type.equals(TINYINT)) {
return new GenericLiteral("TINYINT", object.toString());
}
if (type.equals(SMALLINT)) {
return new GenericLiteral("SMALLINT", object.toString());
}
if (type.equals(INTEGER)) {
return new LongLiteral(object.toString());
}
if (type.equals(BIGINT)) {
LongLiteral expression = new LongLiteral(object.toString());
if (expression.getValue() >= Integer.MIN_VALUE && expression.getValue() <= Integer.MAX_VALUE) {
return new GenericLiteral("BIGINT", object.toString());
}
return new LongLiteral(object.toString());
}
checkArgument(Primitives.wrap(type.getJavaType()).isInstance(object), "object.getClass (%s) and type.getJavaType (%s) do not agree", object.getClass(), type.getJavaType());
if (type.equals(DOUBLE)) {
Double value = (Double) object;
// When changing this, don't forget about similar code for REAL below
if (value.isNaN()) {
return new FunctionCall(QualifiedName.of("nan"), ImmutableList.of());
}
if (value.equals(Double.NEGATIVE_INFINITY)) {
return ArithmeticUnaryExpression.negative(new FunctionCall(QualifiedName.of("infinity"), ImmutableList.of()));
}
if (value.equals(Double.POSITIVE_INFINITY)) {
return new FunctionCall(QualifiedName.of("infinity"), ImmutableList.of());
}
return new DoubleLiteral(object.toString());
}
if (type.equals(REAL)) {
Float value = intBitsToFloat(((Long) object).intValue());
// WARNING for ORC predicate code as above (for double)
if (value.isNaN()) {
return new Cast(new FunctionCall(QualifiedName.of("nan"), ImmutableList.of()), StandardTypes.REAL);
}
if (value.equals(Float.NEGATIVE_INFINITY)) {
return ArithmeticUnaryExpression.negative(new Cast(new FunctionCall(QualifiedName.of("infinity"), ImmutableList.of()), StandardTypes.REAL));
}
if (value.equals(Float.POSITIVE_INFINITY)) {
return new Cast(new FunctionCall(QualifiedName.of("infinity"), ImmutableList.of()), StandardTypes.REAL);
}
return new GenericLiteral("REAL", value.toString());
}
if (type instanceof DecimalType) {
String string;
if (isShortDecimal(type)) {
string = Decimals.toString((long) object, ((DecimalType) type).getScale());
} else {
string = Decimals.toString((Slice) object, ((DecimalType) type).getScale());
}
return new Cast(new DecimalLiteral(string), type.getDisplayName());
}
if (type instanceof VarcharType) {
VarcharType varcharType = (VarcharType) type;
Slice value = (Slice) object;
StringLiteral stringLiteral = new StringLiteral(value.toStringUtf8());
if (!varcharType.isUnbounded() && varcharType.getLengthSafe() == SliceUtf8.countCodePoints(value)) {
return stringLiteral;
}
return new Cast(stringLiteral, type.getDisplayName(), false, typeOnly);
}
if (type instanceof CharType) {
StringLiteral stringLiteral = new StringLiteral(((Slice) object).toStringUtf8());
return new Cast(stringLiteral, type.getDisplayName(), false, typeOnly);
}
if (type.equals(BOOLEAN)) {
return new BooleanLiteral(object.toString());
}
if (type.equals(DATE)) {
return new GenericLiteral("DATE", new SqlDate(toIntExact((Long) object)).toString());
}
if (object instanceof Block) {
SliceOutput output = new DynamicSliceOutput(toIntExact(((Block) object).getSizeInBytes()));
BlockSerdeUtil.writeBlock(blockEncodingSerde, output, (Block) object);
object = output.slice();
// This if condition will evaluate to true: object instanceof Slice && !type.equals(VARCHAR)
}
if (type instanceof EnumType) {
return new EnumLiteral(type.getTypeSignature().toString(), object);
}
Signature signature = getMagicLiteralFunctionSignature(type);
if (object instanceof Slice) {
// HACK: we need to serialize VARBINARY in a format that can be embedded in an expression to be
// able to encode it in the plan that gets sent to workers.
// We do this by transforming the in-memory varbinary into a call to from_base64(<base64-encoded value>)
FunctionCall fromBase64 = new FunctionCall(QualifiedName.of("from_base64"), ImmutableList.of(new StringLiteral(VarbinaryFunctions.toBase64((Slice) object).toStringUtf8())));
return new FunctionCall(QualifiedName.of(signature.getNameSuffix()), ImmutableList.of(fromBase64));
}
Expression rawLiteral = toExpression(object, typeForMagicLiteral(type), typeOnly);
return new FunctionCall(QualifiedName.of(signature.getNameSuffix()), ImmutableList.of(rawLiteral));
}
use of com.facebook.presto.common.type.DecimalType in project presto by prestodb.
the class LiteralInterpreter method evaluate.
public static Object evaluate(ConnectorSession session, ConstantExpression node) {
Type type = node.getType();
SqlFunctionProperties properties = session.getSqlFunctionProperties();
if (node.getValue() == null) {
return null;
}
if (type instanceof BooleanType) {
return node.getValue();
}
if (type instanceof BigintType || type instanceof TinyintType || type instanceof SmallintType || type instanceof IntegerType) {
return node.getValue();
}
if (type instanceof DoubleType) {
return node.getValue();
}
if (type instanceof RealType) {
Long number = (Long) node.getValue();
return intBitsToFloat(number.intValue());
}
if (type instanceof DecimalType) {
DecimalType decimalType = (DecimalType) type;
if (decimalType.isShort()) {
checkState(node.getValue() instanceof Long);
return decodeDecimal(BigInteger.valueOf((long) node.getValue()), decimalType);
}
checkState(node.getValue() instanceof Slice);
Slice value = (Slice) node.getValue();
return decodeDecimal(decodeUnscaledValue(value), decimalType);
}
if (type instanceof VarcharType || type instanceof CharType) {
return ((Slice) node.getValue()).toStringUtf8();
}
if (type instanceof VarbinaryType) {
return new SqlVarbinary(((Slice) node.getValue()).getBytes());
}
if (type instanceof DateType) {
return new SqlDate(((Long) node.getValue()).intValue());
}
if (type instanceof TimeType) {
if (properties.isLegacyTimestamp()) {
return new SqlTime((long) node.getValue(), properties.getTimeZoneKey());
}
return new SqlTime((long) node.getValue());
}
if (type instanceof TimestampType) {
try {
if (properties.isLegacyTimestamp()) {
return new SqlTimestamp((long) node.getValue(), properties.getTimeZoneKey());
}
return new SqlTimestamp((long) node.getValue());
} catch (RuntimeException e) {
throw new PrestoException(GENERIC_USER_ERROR, format("'%s' is not a valid timestamp literal", (String) node.getValue()));
}
}
if (type instanceof IntervalDayTimeType) {
return new SqlIntervalDayTime((long) node.getValue());
}
if (type instanceof IntervalYearMonthType) {
return new SqlIntervalYearMonth(((Long) node.getValue()).intValue());
}
if (type.getJavaType().equals(Slice.class)) {
// DO NOT ever remove toBase64. Calling toString directly on Slice whose base is not byte[] will cause JVM to crash.
return "'" + VarbinaryFunctions.toBase64((Slice) node.getValue()).toStringUtf8() + "'";
}
// We should not fail at the moment; just return the raw value (block, regex, etc) to the user
return node.getValue();
}
use of com.facebook.presto.common.type.DecimalType in project presto by prestodb.
the class IcebergPageSource method deserializePartitionValue.
private static Object deserializePartitionValue(Type type, String valueString, String name, TimeZoneKey timeZoneKey) {
if (valueString == null) {
return null;
}
try {
if (type.equals(BOOLEAN)) {
if (valueString.equalsIgnoreCase("true")) {
return true;
}
if (valueString.equalsIgnoreCase("false")) {
return false;
}
throw new IllegalArgumentException();
}
if (type.equals(INTEGER)) {
return parseLong(valueString);
}
if (type.equals(BIGINT)) {
return parseLong(valueString);
}
if (type.equals(REAL)) {
return (long) floatToRawIntBits(parseFloat(valueString));
}
if (type.equals(DOUBLE)) {
return parseDouble(valueString);
}
if (type.equals(DATE) || type.equals(TIME) || type.equals(TIMESTAMP)) {
return parseLong(valueString);
}
if (type instanceof VarcharType) {
Slice value = utf8Slice(valueString);
return value;
}
if (type.equals(VarbinaryType.VARBINARY)) {
return utf8Slice(valueString);
}
if (isShortDecimal(type) || isLongDecimal(type)) {
DecimalType decimalType = (DecimalType) type;
BigDecimal decimal = new BigDecimal(valueString);
decimal = decimal.setScale(decimalType.getScale(), BigDecimal.ROUND_UNNECESSARY);
if (decimal.precision() > decimalType.getPrecision()) {
throw new IllegalArgumentException();
}
BigInteger unscaledValue = decimal.unscaledValue();
return isShortDecimal(type) ? unscaledValue.longValue() : Decimals.encodeUnscaledValue(unscaledValue);
}
} catch (IllegalArgumentException e) {
throw new PrestoException(ICEBERG_INVALID_PARTITION_VALUE, format("Invalid partition value '%s' for %s partition key: %s", valueString, type.getDisplayName(), name));
}
// Iceberg tables don't partition by non-primitive-type columns.
throw new PrestoException(GENERIC_INTERNAL_ERROR, "Invalid partition type " + type.toString());
}
use of com.facebook.presto.common.type.DecimalType in project presto by prestodb.
the class TypeCoercer 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;
}
String sourceTypeBase = source.getTypeSignature().getBase();
String resultTypeBase = result.getTypeSignature().getBase();
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 com.facebook.presto.common.type.DecimalType in project presto by prestodb.
the class TestIonSqlQueryBuilder method testDecimalColumns.
@Test
public void testDecimalColumns() {
TypeManager typeManager = createTestFunctionAndTypeManager();
IonSqlQueryBuilder queryBuilder = new IonSqlQueryBuilder(typeManager);
List<HiveColumnHandle> columns = ImmutableList.of(new HiveColumnHandle("quantity", HiveType.valueOf("decimal(20,0)"), parseTypeSignature(DECIMAL), 0, REGULAR, Optional.empty(), Optional.empty()), new HiveColumnHandle("extendedprice", HiveType.valueOf("decimal(20,2)"), parseTypeSignature(DECIMAL), 1, REGULAR, Optional.empty(), Optional.empty()), new HiveColumnHandle("discount", HiveType.valueOf("decimal(10,2)"), parseTypeSignature(DECIMAL), 2, REGULAR, Optional.empty(), Optional.empty()));
DecimalType decimalType = DecimalType.createDecimalType(10, 2);
TupleDomain<HiveColumnHandle> tupleDomain = withColumnDomains(ImmutableMap.of(columns.get(0), Domain.create(ofRanges(Range.lessThan(DecimalType.createDecimalType(20, 0), longDecimal("50"))), false), columns.get(1), Domain.create(ofRanges(Range.equal(HiveType.valueOf("decimal(20,2)").getType(typeManager), longDecimal("0.05"))), false), columns.get(2), Domain.create(ofRanges(Range.range(decimalType, shortDecimal("0.0"), true, shortDecimal("0.02"), true)), false)));
assertEquals("SELECT s._1, s._2, s._3 FROM S3Object s WHERE ((case s._1 when '' then null else CAST(s._1 AS DECIMAL(20,0)) end < 50)) AND " + "(case s._2 when '' then null else CAST(s._2 AS DECIMAL(20,2)) end = 0.05) AND ((case s._3 when '' then null else CAST(s._3 AS DECIMAL(10,2)) " + "end >= 0.00 AND case s._3 when '' then null else CAST(s._3 AS DECIMAL(10,2)) end <= 0.02))", queryBuilder.buildSql(columns, tupleDomain));
}
Aggregations