-
Notifications
You must be signed in to change notification settings - Fork 141
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
向 varchar字段保存中文中会被截断 #182
Comments
所以应该改动哪里呢 |
我个人的处理办法是在param.go的67行下增加
个人能力有限。你要好好测试一下。 |
@dotqi 好奇请教一下 UTF16 和 UTF8 在中文长度上有区别么? |
package main import ( func main() { func StringToUTF16(s string) []uint16 { return utf16.Encode([]rune(s + "\x00")) } |
@dotqi 你这个实验,我做了,感觉你这个不对
但实际上,u16 可以转回成 []rune,他们的长度是一模一样的 val := "你好𠀾" rune 实际是 int32,比 uint16 表示的多,131134 和 55360 56382 都表示 “𠀾”,它实际占 4 个字节 [240 160 128 190] |
分析:
错误的点: 按照 case string:
ctype = api.SQL_C_WCHAR
// b := api.StringToUTF16(d)
// p.Data = b
// buf = unsafe.Pointer(&b[0])
// l := len(b)
// l -= 1 // remove terminating 0
// size = api.SQLULEN(l)
// if size < 1 {
// // size cannot be less then 1 even for empty fields
// size = 1
// }
// l *= 2 // every char takes 2 bytes
// buflen = api.SQLLEN(l)
// plen = p.StoreStrLen_or_IndPtr(buflen)
b := []byte(d)
p.Data = append(b, byte(0))
buf = unsafe.Pointer(&b[0])
buflen = api.SQLLEN(len(b))
plen = p.StoreStrLen_or_IndPtr(buflen)
size = api.SQLULEN(len(b))
if size < 1 {
// size cannot be less then 1 even for empty fields
size = 1
} 大胆点:因为使用了 append 所以不用再判断 size < 1 了,我不太明白为什么 buflen 不能包含 \0 的长度,所以参照原来减 1 了 b := append([]byte(d), byte(0))
p.Data = b
buf = unsafe.Pointer(&b[0])
buflen = api.SQLLEN(len(b) - 1)
plen = p.StoreStrLen_or_IndPtr(buflen)
size = api.SQLULEN(len(b)) |
谢谢,回头按你的方式测试一下。 |
增加一个PR:#195 |
可以合并吗? |
I don't understand Chinese. If you want help, you should explain in English. Alex |
When saving non ASCII characters to varchar fields, they will be truncated. The reason is that the length calculation is based on the length of the UTF-16 encoding, and if the actual data is in UTF-8, the calculated length will be smaller than the actual length, resulting in the actual data stored in the database being truncated. |
@zhangyongding thanks for explaining. I assume you are suggesting that your PR #195 is fixing the issue. If you want me to review your PR, you should add a test that demonstrate the problem, test that demonstrate the problem is fixed by your PR. Alex |
向 varchar字段保存中文中会被截断。
测试发现。文件param.go绑定strinig时。size取的是转为UTF16后的长度。
但一个中文在UTF8时占用3个字节。size应该取UTF8的长度。
这样才可以保证向varchar字段保存中文时不会被截断。
The text was updated successfully, but these errors were encountered: