Skip to content

Commit 76c358b

Browse files
nokiaMSgithubgxll
authored andcommitted
[fix][sdk] Support decimal rounding to be compatible with mysql.
1 parent 2343869 commit 76c358b

File tree

2 files changed

+99
-0
lines changed

2 files changed

+99
-0
lines changed

java/dingo-sdk/src/main/java/io/dingodb/sdk/common/serial/MyDecimal.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,15 @@ public MyDecimal(String string, int prec, int scal) {
434434
throw new IllegalArgumentException("Decimal type: No digits in string.");
435435
}
436436

437+
//To be compatible with MySQL rounding for decimal.
438+
if(digitsFracLocal != 0 && scal < digitsFracLocal) {
439+
int lastDigitPos = 1 - ((negative) ? 1 : 0);
440+
int lastDigit = Integer.parseInt(String.valueOf(string.charAt(digitsIntLocal + digitsFracLocal - lastDigitPos)));
441+
lastDigit = lastDigit < 5 ? lastDigit : lastDigit + 1;
442+
string = string.substring(0, digitsIntLocal + digitsFracLocal - lastDigitPos) + lastDigit;
443+
digitsFracLocal = scal;
444+
}
445+
437446
int wordsInt = digitsToWords(digitsIntLocal);
438447
int wordsFrac = digitsToWords(digitsFracLocal);
439448

java/dingo-sdk/src/test/java/sdk/common/serial/CodecTest.java

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,96 @@ public void testDecimal1() throws IOException {
6767
Assertions.assertArrayEquals(expected, codec.decode(codec.encode(record)));
6868
}
6969

70+
@Test
71+
public void testDecimal1_1() throws IOException {
72+
73+
ColumnDefinition c1 = ColumnDefinition.builder().name("col1").type("DECIMAL").primary(0).precision(10).scale(2).build();
74+
ColumnDefinition c2 = ColumnDefinition.builder().name("col2").type("INT").primary(-1).build();
75+
76+
TableDefinition tableDefinition = TableDefinition.builder()
77+
.name("TEST_ENCODE")
78+
.columns(Arrays.asList(c1, c2))
79+
.version(1).codecVersion(2)
80+
.build();
81+
82+
DingoKeyValueCodec codec = DingoKeyValueCodec.of(1, 1L, tableDefinition);
83+
Object[] record = {"1.231234e2", 1};
84+
Object[] expected = {"123.12", 1};
85+
Assertions.assertArrayEquals(expected, codec.decode(codec.encode(record)));
86+
}
87+
88+
@Test
89+
public void testDecimal1_2() throws IOException {
90+
91+
ColumnDefinition c1 = ColumnDefinition.builder().name("col1").type("DECIMAL").primary(0).precision(10).scale(2).build();
92+
ColumnDefinition c2 = ColumnDefinition.builder().name("col2").type("INT").primary(-1).build();
93+
94+
TableDefinition tableDefinition = TableDefinition.builder()
95+
.name("TEST_ENCODE")
96+
.columns(Arrays.asList(c1, c2))
97+
.version(1).codecVersion(2)
98+
.build();
99+
100+
DingoKeyValueCodec codec = DingoKeyValueCodec.of(1, 1L, tableDefinition);
101+
Object[] record = {"2345.678", 1};
102+
Object[] expected = {"2345.68", 1};
103+
Assertions.assertArrayEquals(expected, codec.decode(codec.encode(record)));
104+
}
105+
106+
@Test
107+
public void testDecimal1_3() throws IOException {
108+
109+
ColumnDefinition c1 = ColumnDefinition.builder().name("col1").type("DECIMAL").primary(0).precision(10).scale(2).build();
110+
ColumnDefinition c2 = ColumnDefinition.builder().name("col2").type("INT").primary(-1).build();
111+
112+
TableDefinition tableDefinition = TableDefinition.builder()
113+
.name("TEST_ENCODE")
114+
.columns(Arrays.asList(c1, c2))
115+
.version(1).codecVersion(2)
116+
.build();
117+
118+
DingoKeyValueCodec codec = DingoKeyValueCodec.of(1, 1L, tableDefinition);
119+
Object[] record = {"2345.6", 1};
120+
Object[] expected = {"2345.60", 1};
121+
Assertions.assertArrayEquals(expected, codec.decode(codec.encode(record)));
122+
}
123+
124+
@Test
125+
public void testDecimal1_4() throws IOException {
126+
127+
ColumnDefinition c1 = ColumnDefinition.builder().name("col1").type("DECIMAL").primary(0).precision(10).scale(2).build();
128+
ColumnDefinition c2 = ColumnDefinition.builder().name("col2").type("INT").primary(-1).build();
129+
130+
TableDefinition tableDefinition = TableDefinition.builder()
131+
.name("TEST_ENCODE")
132+
.columns(Arrays.asList(c1, c2))
133+
.version(1).codecVersion(2)
134+
.build();
135+
136+
DingoKeyValueCodec codec = DingoKeyValueCodec.of(1, 1L, tableDefinition);
137+
Object[] record = {"2345", 1};
138+
Object[] expected = {"2345.00", 1};
139+
Assertions.assertArrayEquals(expected, codec.decode(codec.encode(record)));
140+
}
141+
142+
@Test
143+
public void testDecimal1_5() throws IOException {
144+
145+
ColumnDefinition c1 = ColumnDefinition.builder().name("col1").type("DECIMAL").primary(0).precision(10).scale(2).build();
146+
ColumnDefinition c2 = ColumnDefinition.builder().name("col2").type("INT").primary(-1).build();
147+
148+
TableDefinition tableDefinition = TableDefinition.builder()
149+
.name("TEST_ENCODE")
150+
.columns(Arrays.asList(c1, c2))
151+
.version(1).codecVersion(2)
152+
.build();
153+
154+
DingoKeyValueCodec codec = DingoKeyValueCodec.of(1, 1L, tableDefinition);
155+
Object[] record = {"-2345.678", 1};
156+
Object[] expected = {"-2345.68", 1};
157+
Assertions.assertArrayEquals(expected, codec.decode(codec.encode(record)));
158+
}
159+
70160
@Test
71161
public void testDecimal2() throws IOException {
72162

0 commit comments

Comments
 (0)