private static Integer decimalDigits(Type type) { if (type instanceof DecimalType) { return ((DecimalType) type).getScale(); } return null; }
public static BigDecimal parseHiveDecimal(byte[] bytes, int start, int length, DecimalType columnType) { BigDecimal parsed = new BigDecimal(new String(bytes, start, length, UTF_8)); if (parsed.scale() > columnType.getScale()) { // Hive rounds HALF_UP too parsed = parsed.setScale(columnType.getScale(), HALF_UP); } return rescale(parsed, columnType); } }
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 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 boolean isFractional() { return type == DOUBLE || type == REAL || (type instanceof DecimalType && ((DecimalType) type).getScale() > 0); } }
@VisibleForTesting public static BigDecimal average(LongDecimalWithOverflowAndLongState state, DecimalType type) { BigDecimal sum = new BigDecimal(Decimals.decodeUnscaledValue(state.getLongDecimal()), type.getScale()); BigDecimal count = BigDecimal.valueOf(state.getLong()); if (state.getOverflow() != 0) { BigInteger overflowMultiplier = TWO.shiftLeft(UNSCALED_DECIMAL_128_SLICE_LENGTH * 8 - 2); BigInteger overflow = overflowMultiplier.multiply(BigInteger.valueOf(state.getOverflow())); sum = sum.add(new BigDecimal(overflow)); } return sum.divide(count, type.getScale(), ROUND_HALF_UP); }
private static List<Object> divideRescaleFactor(PolymorphicScalarFunctionBuilder.SpecializeContext context) { DecimalType returnType = (DecimalType) context.getReturnType(); int dividendScale = toIntExact(requireNonNull(context.getLiteral("a_scale"), "a_scale is null")); int divisorScale = toIntExact(requireNonNull(context.getLiteral("b_scale"), "b_scale is null")); int resultScale = returnType.getScale(); int rescaleFactor = resultScale - dividendScale + divisorScale; return ImmutableList.of(rescaleFactor); }
private static Optional<PrimitiveColumnReader> createDecimalColumnReader(RichColumnDescriptor descriptor) { Optional<Type> type = createDecimalType(descriptor); if (type.isPresent()) { DecimalType decimalType = (DecimalType) type.get(); return Optional.of(DecimalColumnReaderFactory.createReader(descriptor, decimalType.getPrecision(), decimalType.getScale())); } return Optional.empty(); }
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())); }
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)); }
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); } }
private static HiveDecimal getHiveDecimal(DecimalType decimalType, Block block, int position) { BigInteger unscaledValue; if (decimalType.isShort()) { unscaledValue = BigInteger.valueOf(decimalType.getLong(block, position)); } else { unscaledValue = Decimals.decodeUnscaledValue(decimalType.getSlice(block, position)); } return HiveDecimal.create(unscaledValue, decimalType.getScale()); }
@Override public void reset() { closed = false; dataStream.reset(); scaleStream.reset(); presentStream.reset(); rowGroupColumnStatistics.clear(); shortDecimalStatisticsBuilder = new ShortDecimalStatisticsBuilder(this.type.getScale()); longDecimalStatisticsBuilder = new LongDecimalStatisticsBuilder(); } }
@Override public void addBlock(Type type, Block block) { int scale = ((DecimalType) type).getScale(); for (int position = 0; position < block.getPositionCount(); position++) { if (!block.isNull(position)) { Slice value = type.getSlice(block, position); addValue(new BigDecimal(Decimals.decodeUnscaledValue(value), scale)); } } }
private void writeLong(SliceOutput output, long value) { // first vint is scale writeVInt(output, type.getScale()); // second vint is length int length = getWriteByteCount(value); writeVInt(output, length); // write value (big endian) for (int i = length - 1; i >= 0; i--) { output.writeByte((int) (value >> (i * 8))); } }
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()))); } }
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(); }
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(); }
private void setTypeAttributes(ColumnMetadata columnMetadata, ColumnSchema.ColumnSchemaBuilder builder) { if (columnMetadata.getType() instanceof DecimalType) { DecimalType type = (DecimalType) columnMetadata.getType(); ColumnTypeAttributes attributes = new ColumnTypeAttributes.ColumnTypeAttributesBuilder() .precision(type.getPrecision()) .scale(type.getScale()).build(); builder.typeAttributes(attributes); } }
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()); }