/** * Converts a value from its logical format to its encoded format - a struct containing * the scale of the number and a binary representation of the number. * * @param schema of the encoded value * @param value the value or the decimal * * @return the encoded value */ public static Struct fromLogical(Schema schema, SpecialValueDecimal value) { return fromLogical(schema, value.getDecimalValue().orElse(null)); }
protected Object convertDecimal(Column column, Field fieldDefn, Object data, DecimalMode mode) { SpecialValueDecimal value; BigDecimal newDecimal; if (data instanceof SpecialValueDecimal) { value = (SpecialValueDecimal)data; if (!value.getDecimalValue().isPresent()) { return SpecialValueDecimal.fromLogical(value, mode, column.name()); } } else { final Object o = toBigDecimal(column, fieldDefn, data); if (o == null || !(o instanceof BigDecimal)) { return o; } value = new SpecialValueDecimal((BigDecimal)o); } newDecimal = value.getDecimalValue().get(); if (column.scale().get() > newDecimal.scale()) { newDecimal = newDecimal.setScale(column.scale().get()); } if (isVariableScaleDecimal(column) && mode == DecimalMode.PRECISE) { newDecimal = newDecimal.stripTrailingZeros(); if (newDecimal.scale() < 0) { newDecimal = newDecimal.setScale(0); } return VariableScaleDecimal.fromLogical(fieldDefn.schema(), new SpecialValueDecimal(newDecimal)); } return SpecialValueDecimal.fromLogical(new SpecialValueDecimal(newDecimal), mode, column.name()); }
@Test public void testVariableScaleDecimal() { final BigDecimal testValue = new BigDecimal("138.456"); final Struct struct = VariableScaleDecimal.fromLogical(VariableScaleDecimal.schema(), new SpecialValueDecimal(testValue)); final BigDecimal decodedValue = VariableScaleDecimal.toLogical(struct).getDecimalValue().get(); assertEquals("Number should be same after serde", testValue, decodedValue); } }
/** * Converts a value from its logical format to its encoded format - a struct containing * the scale of the number and a binary representation of the number. * * @param schema of the encoded value * @param value the value or the decimal * * @return the encoded value */ public static Struct fromLogical(Schema schema, SpecialValueDecimal value) { return fromLogical(schema, value.getDecimalValue().orElse(null)); }
protected Object convertVariableScale(Column column, Field fieldDefn, Object data) { data = convertNumeric(column, fieldDefn, data); // provides default value if (data == null) { return null; } // TODO Need to handle special values, it is not supported in variable scale decimal else if (data instanceof SpecialValueDecimal) { return VariableScaleDecimal.fromLogical(fieldDefn.schema(), (SpecialValueDecimal)data); } else if (data instanceof BigDecimal) { return VariableScaleDecimal.fromLogical(fieldDefn.schema(), new SpecialValueDecimal((BigDecimal)data)); } return handleUnknownData(column, fieldDefn, data); }
protected Object convertDecimal(Column column, Field fieldDefn, Object data, DecimalMode mode) { SpecialValueDecimal value; BigDecimal newDecimal; if (data instanceof SpecialValueDecimal) { value = (SpecialValueDecimal)data; if (!value.getDecimalValue().isPresent()) { return SpecialValueDecimal.fromLogical(value, mode, column.name()); } } else { final Object o = toBigDecimal(column, fieldDefn, data); if (o == null || !(o instanceof BigDecimal)) { return o; } value = new SpecialValueDecimal((BigDecimal)o); } newDecimal = value.getDecimalValue().get(); if (column.scale().get() > newDecimal.scale()) { newDecimal = newDecimal.setScale(column.scale().get()); } if (isVariableScaleDecimal(column) && mode == DecimalMode.PRECISE) { newDecimal = newDecimal.stripTrailingZeros(); if (newDecimal.scale() < 0) { newDecimal = newDecimal.setScale(0); } return VariableScaleDecimal.fromLogical(fieldDefn.schema(), new SpecialValueDecimal(newDecimal)); } return SpecialValueDecimal.fromLogical(new SpecialValueDecimal(newDecimal), mode, column.name()); }
@Test public void testVariableScaleDecimal() { final BigDecimal testValue = new BigDecimal("138.456"); final Struct struct = VariableScaleDecimal.fromLogical(VariableScaleDecimal.schema(), new SpecialValueDecimal(testValue)); final BigDecimal decodedValue = VariableScaleDecimal.toLogical(struct).getDecimalValue().get(); assertEquals("Number should be same after serde", testValue, decodedValue); } }