/** * Updates the decimal column. * * <p>Note: In order to support update a decimal with precision > 18, CAN NOT call setNullAt() for * this column. */ @Override public void setDecimal(int ordinal, Decimal value, int precision) { assertIndexIsValid(ordinal); if (precision <= Decimal.MAX_LONG_DIGITS()) { // compact format if (value == null) { setNullAt(ordinal); } else { setLong(ordinal, value.toUnscaledLong()); } } else { // fixed length long cursor = getLong(ordinal) >>> 32; assert cursor > 0 : "invalid cursor " + cursor; // zero-out the bytes Platform.putLong(baseObject, baseOffset + cursor, 0L); Platform.putLong(baseObject, baseOffset + cursor + 8, 0L); if (value == null) { setNullAt(ordinal); // keep the offset for future update Platform.putLong(baseObject, getFieldOffset(ordinal), cursor << 32); } else { final BigInteger integer = value.toJavaBigDecimal().unscaledValue(); byte[] bytes = integer.toByteArray(); assert (bytes.length <= 16); // Write the bytes to the variable length portion. Platform.copyMemory( bytes, Platform.BYTE_ARRAY_OFFSET, baseObject, baseOffset + cursor, bytes.length); setLong(ordinal, (cursor << 32) | ((long) bytes.length)); } } }
@Override public Decimal getDecimal(int ordinal, int precision, int scale) { if (isNullAt(ordinal)) { return null; } if (precision <= Decimal.MAX_LONG_DIGITS()) { return Decimal.apply(getLong(ordinal), precision, scale); } else { byte[] bytes = getBinary(ordinal); BigInteger bigInteger = new BigInteger(bytes); BigDecimal javaDecimal = new BigDecimal(bigInteger, scale); return Decimal.apply(javaDecimal, precision, scale); } }
public static boolean isFixedLength(DataType dt) { if (dt instanceof DecimalType) { return ((DecimalType) dt).precision() <= Decimal.MAX_LONG_DIGITS(); } else { return mutableFieldTypes.contains(dt); } }