public static Slice encodeScaledValue(BigDecimal value, int scale) { checkArgument(scale >= 0); return encodeScaledValue(value.setScale(scale, UNNECESSARY)); }
public static void writeBigDecimal(DecimalType decimalType, BlockBuilder blockBuilder, BigDecimal value) { decimalType.writeSlice(blockBuilder, encodeScaledValue(value)); }
private static Slice longDecimal(String value) { return encodeScaledValue(new BigDecimal(value)); } }
public static Slice longDecimal(String value) { return encodeScaledValue(new BigDecimal(value)); } }
private static Slice longDecimal(String value) { return encodeScaledValue(new BigDecimal(value)); }
private static Slice internalDoubleToLongDecimal(double value, long precision, long scale) { if (Double.isInfinite(value) || Double.isNaN(value)) { throw new PrestoException(INVALID_CAST_ARGUMENT, format("Cannot cast DOUBLE '%s' to DECIMAL(%s, %s)", value, precision, scale)); } try { // todo consider changing this implementation to more performant one which does not use intermediate String objects BigDecimal bigDecimal = BigDecimal.valueOf(value).setScale(intScale(scale), HALF_UP); Slice decimal = Decimals.encodeScaledValue(bigDecimal); if (overflows(decimal, intScale(precision))) { throw new PrestoException(INVALID_CAST_ARGUMENT, format("Cannot cast DOUBLE '%s' to DECIMAL(%s, %s)", value, precision, scale)); } return decimal; } catch (ArithmeticException e) { throw new PrestoException(INVALID_CAST_ARGUMENT, format("Cannot cast DOUBLE '%s' to DECIMAL(%s, %s)", value, precision, scale)); } }
private static Slice realToLongDecimal(long value, long precision, long scale) { float floatValue = intBitsToFloat(intScale(value)); if (Float.isInfinite(floatValue) || Float.isNaN(floatValue)) { throw new PrestoException(INVALID_CAST_ARGUMENT, format("Cannot cast REAL '%s' to DECIMAL(%s, %s)", floatValue, precision, scale)); } try { // todo consider changing this implementation to more performant one which does not use intermediate String objects BigDecimal bigDecimal = new BigDecimal(String.valueOf(floatValue)).setScale(intScale(scale), HALF_UP); Slice decimal = Decimals.encodeScaledValue(bigDecimal); if (overflows(decimal, intScale(precision))) { throw new PrestoException(INVALID_CAST_ARGUMENT, format("Cannot cast REAL '%s' to DECIMAL(%s, %s)", floatValue, precision, scale)); } return decimal; } catch (ArithmeticException e) { throw new PrestoException(INVALID_CAST_ARGUMENT, format("Cannot cast REAL '%s' to DECIMAL(%s, %s)", floatValue, precision, scale)); } }
public static ReadMapping decimalReadMapping(DecimalType decimalType) { // JDBC driver can return BigDecimal with lower scale than column's scale when there are trailing zeroes int scale = decimalType.getScale(); if (decimalType.isShort()) { return longReadMapping(decimalType, (resultSet, columnIndex) -> encodeShortScaledValue(resultSet.getBigDecimal(columnIndex), scale)); } return sliceReadMapping(decimalType, (resultSet, columnIndex) -> encodeScaledValue(resultSet.getBigDecimal(columnIndex), scale)); }
@Override protected void writeDecimalToBlock(BigDecimal decimal, BlockBuilder blockBuilder) { longDecimalType.writeSlice(blockBuilder, encodeScaledValue(decimal)); }
@Override protected Object getGreaterValue(Object value) { Slice slice = (Slice) value; BigDecimal decimal = toBigDecimal(slice, 10); BigDecimal greaterDecimal = decimal.add(BigDecimal.ONE); return encodeScaledValue(greaterDecimal); }
@Override protected void writeDecimalToBlock(BigDecimal decimal, BlockBuilder blockBuilder) { LONG_DECIMAL_TYPE.writeSlice(blockBuilder, encodeScaledValue(decimal)); }
@Test public void testEncodeScaledValue() { assertEquals(encodeScaledValue(new BigDecimal("2.00"), 2), sliceFromBytes(200, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); assertEquals(encodeScaledValue(new BigDecimal("2.13"), 2), sliceFromBytes(213, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); assertEquals(encodeScaledValue(new BigDecimal("172.60"), 2), sliceFromBytes(108, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); assertEquals(encodeScaledValue(new BigDecimal("2"), 2), sliceFromBytes(200, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); assertEquals(encodeScaledValue(new BigDecimal("172.6"), 2), sliceFromBytes(108, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); int minus = 0x80; assertEquals(encodeScaledValue(new BigDecimal("-2.00"), 2), sliceFromBytes(200, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, minus)); assertEquals(encodeScaledValue(new BigDecimal("-2.13"), 2), sliceFromBytes(213, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, minus)); assertEquals(encodeScaledValue(new BigDecimal("-2"), 2), sliceFromBytes(200, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, minus)); assertEquals(encodeScaledValue(new BigDecimal("-172.60"), 2), sliceFromBytes(108, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, minus)); }
public static Slice getSlice(Type type, RowResult row, int field) { if (type instanceof VarcharType) { return Slices.utf8Slice(row.getString(field)); } else if (type instanceof VarbinaryType) { return Slices.wrappedBuffer(row.getBinary(field)); } else if (type instanceof DecimalType) { BigDecimal dec = row.getDecimal(field); return Decimals.encodeScaledValue(dec); } else { throw new IllegalStateException("getSlice not implemented for " + type); } } }
private Block decimalAsBlock(String value) { Slice slice = encodeScaledValue(new BigDecimal(value)); BlockBuilder blockBuilder = new VariableWidthBlockBuilder(null, 1, slice.length()); TYPE.writeSlice(blockBuilder, slice); return blockBuilder.build(); } }
slice = encodeScaledValue(ZERO);
@Test public void testOptimizeDecimalLiteral() { // Short decimal assertEquals(translateAndOptimize(expression("CAST(NULL AS DECIMAL(7,2))")), constant(null, createDecimalType(7, 2))); assertEquals(translateAndOptimize(expression("DECIMAL '42'")), constant(42L, createDecimalType(2, 0))); assertEquals(translateAndOptimize(expression("CAST(42 AS DECIMAL(7,2))")), constant(4200L, createDecimalType(7, 2))); assertEquals(translateAndOptimize(simplifyExpression(expression("CAST(42 AS DECIMAL(7,2))"))), constant(4200L, createDecimalType(7, 2))); // Long decimal assertEquals(translateAndOptimize(expression("CAST(NULL AS DECIMAL(35,2))")), constant(null, createDecimalType(35, 2))); assertEquals( translateAndOptimize(expression("DECIMAL '123456789012345678901234567890'")), constant(encodeScaledValue(new BigDecimal("123456789012345678901234567890")), createDecimalType(30, 0))); assertEquals( translateAndOptimize(expression("CAST(DECIMAL '123456789012345678901234567890' AS DECIMAL(35,2))")), constant(encodeScaledValue(new BigDecimal("123456789012345678901234567890.00")), createDecimalType(35, 2))); assertEquals( translateAndOptimize(simplifyExpression(expression("CAST(DECIMAL '123456789012345678901234567890' AS DECIMAL(35,2))"))), constant(encodeScaledValue(new BigDecimal("123456789012345678901234567890.00")), createDecimalType(35, 2))); }
public static void writeBigDecimal(DecimalType decimalType, BlockBuilder blockBuilder, BigDecimal value) { decimalType.writeSlice(blockBuilder, encodeScaledValue(value)); }
public static Slice encodeScaledValue(BigDecimal value, int scale) { checkArgument(scale >= 0); return encodeScaledValue(value.setScale(scale, UNNECESSARY)); }
private static Slice longDecimal(String value) { return encodeScaledValue(new BigDecimal(value)); } }
public static Slice longDecimal(String value) { return encodeScaledValue(new BigDecimal(value)); } }