fixed issue #5474 , scaled_float -> BigDecimal

This commit is contained in:
jianghang.loujh
2026-02-12 17:33:39 +08:00
parent 24877fdf03
commit 1a265c8960
2 changed files with 87 additions and 1 deletions

View File

@@ -2,6 +2,7 @@ package com.alibaba.otter.canal.client.adapter.es.core.support;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.sql.Blob; import java.sql.Blob;
import java.sql.SQLException; import java.sql.SQLException;
@@ -101,13 +102,22 @@ public class ESSyncUtil {
break; break;
case "float": case "float":
case "half_float": case "half_float":
case "scaled_float":
if (val instanceof Number) { if (val instanceof Number) {
res = ((Number) val).floatValue(); res = ((Number) val).floatValue();
} else { } else {
res = Float.parseFloat(val.toString()); res = Float.parseFloat(val.toString());
} }
break; break;
case "scaled_float":
// scaled_float 需要保持高精度,使用 BigDecimal 进行处理
if (val instanceof BigDecimal) {
res = val; // 保持 BigDecimal 精度
} else if (val instanceof Number) {
res = new BigDecimal(val.toString());
} else {
res = new BigDecimal(val.toString());
}
break;
case "boolean": case "boolean":
if (val instanceof Boolean) { if (val instanceof Boolean) {
res = val; res = val;

View File

@@ -0,0 +1,76 @@
package com.alibaba.otter.canal.client.adapter.es.core.support;
import java.math.BigDecimal;
import org.junit.Assert;
import org.junit.Test;
/**
* ESSyncUtil 测试类
*
* @author jianghang
*/
public class ESSyncUtilTest {
@Test
public void testScaledFloatPrecision() {
// 测试高精度 decimal 转换为 scaled_float
BigDecimal originalValue = new BigDecimal("1234567890.12345678901234567890");
// 转换为 scaled_float
Object result = ESSyncUtil.typeConvert(originalValue, "scaled_float");
// 验证结果仍然是 BigDecimal,保持精度
Assert.assertTrue("scaled_float 转换结果应该是 BigDecimal 类型", result instanceof BigDecimal);
Assert.assertEquals("scaled_float 转换应该保持原始精度", originalValue, result);
// 验证 toString 表示
Assert.assertEquals("scaled_float 精度应该保持完整", "1234567890.12345678901234567890", result.toString());
}
@Test
public void testScaledFloatFromString() {
// 测试字符串转换为 scaled_float
String originalString = "9876543210.98765432109876543210";
// 转换为 scaled_float
Object result = ESSyncUtil.typeConvert(originalString, "scaled_float");
// 验证结果是 BigDecimal
Assert.assertTrue("scaled_float 字符串转换结果应该是 BigDecimal 类型", result instanceof BigDecimal);
// 验证值正确
BigDecimal expected = new BigDecimal(originalString);
Assert.assertEquals("scaled_float 字符串转换应该正确解析", expected, result);
}
@Test
public void testScaledFloatFromDouble() {
// 测试 double 转换为 scaled_float(注意:double 本身有精度限制)
Double originalDouble = 1234567890.1234567890;
// 转换为 scaled_float
Object result = ESSyncUtil.typeConvert(originalDouble, "scaled_float");
// 验证结果是 BigDecimal
Assert.assertTrue("scaled_float double 转换结果应该是 BigDecimal 类型", result instanceof BigDecimal);
// 验证值正确(由于 double 精度限制,这里验证转换过程正确)
BigDecimal expected = new BigDecimal(originalDouble.toString());
Assert.assertEquals("scaled_float double 转换应该正确处理", expected, result);
}
@Test
public void testOtherFloatTypes() {
// 测试其他浮点类型仍然正常工作
BigDecimal value = new BigDecimal("123.45");
// 测试 float 类型
Object floatResult = ESSyncUtil.typeConvert(value, "float");
Assert.assertTrue("float 转换结果应该是 Float 类型", floatResult instanceof Float);
// 测试 half_float 类型
Object halfFloatResult = ESSyncUtil.typeConvert(value, "half_float");
Assert.assertTrue("half_float 转换结果应该是 Float 类型", halfFloatResult instanceof Float);
}
}