Gaea icon indicating copy to clipboard operation
Gaea copied to clipboard

prepare,exec方式代理导致decimal精度丢失

Open andyblog opened this issue 2 years ago • 0 comments

客户端通过gaea代理访问后端数据库进行查询操作,如果使用prepare,exec方式进行操作,会导致精度丢失问题


后端数据库版本:5.7.38 gaea版本:latest 客户端:go+gorm进行操作 数据库字段类型:decimal(58,18)


通过gorm进行直接查询,结果符合预期


type TestModel struct {
	Amount decimal.Decimal `gorm:"type:decimal(58,18);"`
}

func (t TestModel) TableName() string {
	return "table1"
}

func Test_GORM(t *testing.T) {
	dsn := "user:123456@tcp(127.0.0.1:13306)/db1?charset=utf8mb4&parseTime=True&loc=Local"
	db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
	if err != nil {
		panic("failed to connect database")
	}

	tm := TestModel{}

	db.Select("amount").Where("id = 10001").First(&tm)

	fmt.Println(tm.Amount.String())
}


客户端打印的结果为

11773175730.545026930000000051

下面是通过gorm+prepare,exec方式进行查询


func Test_GORMPrepare(t *testing.T) {
	dsn := "user:123456@tcp(127.0.0.1:13306)/db1?charset=utf8mb4&parseTime=True&loc=Local"
	db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
	if err != nil {
		panic("failed to connect database")
	}

	tm := TestModel{}

	db.Raw("select amount from table1 where id = ?", 10001).Scan(&tm)

	fmt.Println(tm.Amount.String())
}

客户端打印的结果为

11773175730.545027

第二种方式使用prepare,exec方式进行执行查询,经过抓包和测试,发现后端返回给gaea是精确的,但是gaea对数据进行拼接的时候,转换为float,导致精度丢失

导致问题的具体代码位置为 https://github.com/XiaoMi/Gaea/blob/master/mysql/result.go#L81

大佬们帮忙解答下,是代码问题,还是使用方式不正确导致此问题

andyblog avatar Nov 24 '22 13:11 andyblog