private static Type getCommonSuperTypeForDecimal(DecimalType firstType, DecimalType secondType) { int targetScale = Math.max(firstType.getScale(), secondType.getScale()); int targetPrecision = Math.max(firstType.getPrecision() - firstType.getScale(), secondType.getPrecision() - secondType.getScale()) + targetScale; //we allow potential loss of precision here. Overflow checking is done in operators. targetPrecision = Math.min(38, targetPrecision); return createDecimalType(targetPrecision, targetScale); }
public static BigDecimal readBigDecimal(DecimalType type, Block block, int position) { BigInteger unscaledValue = type.isShort() ? BigInteger.valueOf(type.getLong(block, position)) : decodeUnscaledValue(type.getSlice(block, position)); return new BigDecimal(unscaledValue, type.getScale(), new MathContext(type.getPrecision())); }
@Override public void append(JsonParser parser, BlockBuilder blockBuilder) throws IOException { Slice result = currentTokenAsLongDecimal(parser, type.getPrecision(), type.getScale()); if (result == null) { blockBuilder.appendNull(); } else { type.writeSlice(blockBuilder, result); } } }
public static BigDecimal rescale(BigDecimal value, DecimalType type) { value = value.setScale(type.getScale(), UNNECESSARY); if (value.precision() > type.getPrecision()) { throw new IllegalArgumentException("decimal precision larger than column precision"); } return value; }
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)); }
private static Type getDecimalType(BigDecimal decimal) { if (decimal == null) { return createDecimalType(1, 0); } return createDecimalType(decimal.precision(), decimal.scale()); }
protected static SqlDecimal decimal(String decimalString) { DecimalParseResult parseResult = Decimals.parseIncludeLeadingZerosInPrecision(decimalString); BigInteger unscaledValue; if (parseResult.getType().isShort()) { unscaledValue = BigInteger.valueOf((Long) parseResult.getObject()); } else { unscaledValue = Decimals.decodeUnscaledValue((Slice) parseResult.getObject()); } return new SqlDecimal(unscaledValue, parseResult.getType().getPrecision(), parseResult.getType().getScale()); }
@Override public void append(JsonParser parser, BlockBuilder blockBuilder) throws IOException { Long result = currentTokenAsShortDecimal(parser, type.getPrecision(), type.getScale()); if (result == null) { blockBuilder.appendNull(); } else { type.writeLong(blockBuilder, result); } } }
private static BigDecimal decimalPartitionKey(String value, DecimalType type, String name) { try { if (value.endsWith(BIG_DECIMAL_POSTFIX)) { value = value.substring(0, value.length() - BIG_DECIMAL_POSTFIX.length()); } BigDecimal decimal = new BigDecimal(value); decimal = decimal.setScale(type.getScale(), ROUND_UNNECESSARY); if (decimal.precision() > type.getPrecision()) { throw new PrestoException(HIVE_INVALID_PARTITION_VALUE, format("Invalid partition value '%s' for %s partition key: %s", value, type.toString(), name)); } return decimal; } catch (NumberFormatException e) { throw new PrestoException(HIVE_INVALID_PARTITION_VALUE, format("Invalid partition value '%s' for %s partition key: %s", value, type.toString(), name)); } }
@Override public void writeJsonValue(JsonGenerator jsonGenerator, Block block, int position, ConnectorSession session) throws IOException { if (block.isNull(position)) { jsonGenerator.writeNull(); } else { BigDecimal value = BigDecimal.valueOf(type.getLong(block, position), type.getScale()); jsonGenerator.writeNumber(value); } } }
public void nextShortDecimalVector(int items, BlockBuilder builder, DecimalType targetType, long[] sourceScale) throws IOException { for (int i = 0; i < items; i++) { long value = nextLong(); long rescaledDecimal = Decimals.rescale(value, (int) sourceScale[i], targetType.getScale()); targetType.writeLong(builder, rescaledDecimal); } }
public static PrimitiveColumnReader createReader(RichColumnDescriptor descriptor, int precision, int scale) { DecimalType decimalType = DecimalType.createDecimalType(precision, scale); if (decimalType.isShort()) { return new ShortDecimalColumnReader(descriptor); } else { return new LongDecimalColumnReader(descriptor); } } }
private void encodeValue(Block block, int position, SliceOutput output) { if (isShortDecimal(type)) { output.writeBytes(utf8Slice(Decimals.toString(type.getLong(block, position), type.getScale()))); } else { output.writeBytes(utf8Slice(Decimals.toString(type.getSlice(block, position), type.getScale()))); } }
private static Integer decimalDigits(Type type) { if (type instanceof DecimalType) { return ((DecimalType) type).getScale(); } return null; }
public static Block createLongDecimalSequenceBlock(int start, int end, DecimalType type) { BlockBuilder builder = type.createFixedSizeBlockBuilder(end - start); BigInteger base = BigInteger.TEN.pow(type.getScale()); for (int i = start; i < end; ++i) { type.writeSlice(builder, encodeUnscaledValue(BigInteger.valueOf(i).multiply(base))); } return builder.build(); }
public static Block createShortDecimalSequenceBlock(int start, int end, DecimalType type) { BlockBuilder builder = type.createFixedSizeBlockBuilder(end - start); long base = BigInteger.TEN.pow(type.getScale()).longValue(); for (int i = start; i < end; ++i) { type.writeLong(builder, base * i); } return builder.build(); }
@Override public void writeJsonValue(JsonGenerator jsonGenerator, Block block, int position, ConnectorSession session) throws IOException { if (block.isNull(position)) { jsonGenerator.writeNull(); } else { BigDecimal value = new BigDecimal( decodeUnscaledValue(type.getSlice(block, position)), type.getScale()); jsonGenerator.writeNumber(value); } } }
public static Block createShortDecimalsBlock(Iterable<String> values) { DecimalType shortDecimalType = DecimalType.createDecimalType(1); BlockBuilder builder = shortDecimalType.createBlockBuilder(null, 100); for (String value : values) { if (value == null) { builder.appendNull(); } else { shortDecimalType.writeLong(builder, new BigDecimal(value).unscaledValue().longValue()); } } return builder.build(); }
public static Block decimalArrayBlockOf(DecimalType type, BigDecimal decimal) { if (type.isShort()) { long longDecimal = decimal.unscaledValue().longValue(); return arrayBlockOf(type, longDecimal); } else { Slice sliceDecimal = Decimals.encodeUnscaledValue(decimal.unscaledValue()); return arrayBlockOf(type, sliceDecimal); } }