DBZ-287 Corrected scale representation for Postgres NUMERIC/DECIMAL

This commit is contained in:
Matteo Capitanio 2017-06-20 12:12:39 +02:00 committed by Gunnar Morling
parent a1e68d413f
commit 7fb8829cb1
4 changed files with 22 additions and 5 deletions

View File

@ -8,6 +8,7 @@
import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.MathContext;
import java.sql.SQLException;
import java.time.Instant;
import java.time.LocalDateTime;
@ -115,11 +116,26 @@ public ValueConverter converter(Column column, Field fieldDefn) {
return data -> convertPoint(column, fieldDefn, data);
case PgOid.MONEY:
return data -> convertMoney(column, fieldDefn, data);
case PgOid.NUMERIC:
return data -> convertDecimal(column, fieldDefn, data);
default:
return super.converter(column, fieldDefn);
}
}
@Override
protected Object convertDecimal(Column column, Field fieldDefn, Object data) {
BigDecimal newDecimal = (BigDecimal) super.convertDecimal(column, fieldDefn, data);
if (newDecimal == null) {
return newDecimal;
}
if (column.scale() > newDecimal.scale()) {
MathContext mc = new MathContext((newDecimal.precision() - newDecimal.scale()) + column.scale());
newDecimal = new BigDecimal(newDecimal.doubleValue(), mc);
}
return newDecimal;
}
@Override
protected Object convertBit(Column column, Field fieldDefn, Object data) {
if (data instanceof String) {
@ -288,4 +304,4 @@ protected Object convertPoint(Column column, Field fieldDefn, Object data) {
}
return handleUnknownData(column, fieldDefn, data);
}
}
}

View File

@ -14,6 +14,7 @@
import static org.junit.Assert.fail;
import java.math.BigDecimal;
import java.math.MathContext;
import java.nio.ByteBuffer;
import java.time.Instant;
import java.time.LocalDate;
@ -90,8 +91,8 @@ protected List<SchemaAndValueField> schemasAndValuesForNumericType() {
return Arrays.asList(new SchemaAndValueField("si", SchemaBuilder.OPTIONAL_INT16_SCHEMA, (short) 1),
new SchemaAndValueField("i", SchemaBuilder.OPTIONAL_INT32_SCHEMA, 123456),
new SchemaAndValueField("bi", SchemaBuilder.OPTIONAL_INT64_SCHEMA, 1234567890123L),
new SchemaAndValueField("d", Decimal.builder(1).optional().build(), BigDecimal.valueOf(1.1d)),
new SchemaAndValueField("n", Decimal.builder(2).optional().build(), BigDecimal.valueOf(22.22d)),
new SchemaAndValueField("d", Decimal.builder(2).optional().build(), new BigDecimal(1.10, new MathContext(3))),
new SchemaAndValueField("n", Decimal.builder(3).optional().build(), new BigDecimal(22.220, new MathContext(5))),
new SchemaAndValueField("r", Schema.OPTIONAL_FLOAT32_SCHEMA, 3.3f),
new SchemaAndValueField("db", Schema.OPTIONAL_FLOAT64_SCHEMA, 4.44d),
new SchemaAndValueField("ss", Schema.INT16_SCHEMA, (short) 1),

View File

@ -66,7 +66,7 @@ public void shouldLoadSchemaForBuiltinPostgresTypes() throws Exception {
Arrays.stream(TEST_TABLES).forEach(tableId -> assertKeySchema(tableId, "pk", Schema.INT32_SCHEMA));
assertTableSchema("public.numeric_table", "si, i, bi, d, n, r, db, ss, bs, b",
Schema.OPTIONAL_INT16_SCHEMA, Schema.OPTIONAL_INT32_SCHEMA, Schema.OPTIONAL_INT64_SCHEMA,
Decimal.builder(1).optional().build(), Decimal.builder(2).optional().build(), Schema.OPTIONAL_FLOAT32_SCHEMA,
Decimal.builder(2).optional().build(), Decimal.builder(3).optional().build(), Schema.OPTIONAL_FLOAT32_SCHEMA,
Schema.OPTIONAL_FLOAT64_SCHEMA, Schema.INT16_SCHEMA, Schema.INT64_SCHEMA, Schema.OPTIONAL_BOOLEAN_SCHEMA);
assertTableSchema("public.string_table", "vc, vcv, ch, c, t",
Schema.OPTIONAL_STRING_SCHEMA, Schema.OPTIONAL_STRING_SCHEMA, Schema.OPTIONAL_STRING_SCHEMA,

View File

@ -1,7 +1,7 @@
-- Generate a number of tables to cover as many of the PG types as possible
DROP SCHEMA IF EXISTS public CASCADE;
CREATE SCHEMA public;
CREATE TABLE numeric_table (pk SERIAL, si SMALLINT, i INTEGER, bi BIGINT, d DECIMAL(2,1), n NUMERIC(4,2), r REAL, db DOUBLE PRECISION, ss SMALLSERIAL, bs BIGSERIAL, b BOOLEAN, PRIMARY KEY(pk));
CREATE TABLE numeric_table (pk SERIAL, si SMALLINT, i INTEGER, bi BIGINT, d DECIMAL(3,2), n NUMERIC(5,3), r REAL, db DOUBLE PRECISION, ss SMALLSERIAL, bs BIGSERIAL, b BOOLEAN, PRIMARY KEY(pk));
CREATE TABLE string_table (pk SERIAL, vc VARCHAR(2), vcv CHARACTER VARYING(2), ch CHARACTER(4), c CHAR(3), t TEXT, PRIMARY KEY(pk));
CREATE TABLE cash_table (pk SERIAL, csh MONEY, PRIMARY KEY(pk));
CREATE TABLE bitbin_table (pk SERIAL, ba BYTEA, bol BIT(1), bs BIT(2), bv BIT VARYING(2) , PRIMARY KEY(pk));