Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
andyblog opened this issue Nov 24, 2022 · 0 comments
Open

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

andyblog opened this issue Nov 24, 2022 · 0 comments

Comments

@andyblog
Copy link

客户端通过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

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant