mysql> select name from users;\n+--------------------------------------------------------+\n| name |\n+--------------------------------------------------------+\n| {\"hoge1\": {\"fuga1\": 100000}} |\n| {\"hoge2\": {\"fuga2\": 1000000}} |\n+--------------------------------------------------------+
In Go, I'm executing the following SQL queries and scanning the results into int64 variables:
\nimport (\n ...\n \"github.com/volatiletech/sqlboiler/queries\"\n \"database/sql\"\n)\n...\nvar ( \n v1 v2 int64\n db *sql.DB\n)\n...\nrow1 := queries.Raw(`\n select sum(JSON_EXTRACT(name, '$.hoge1.fuga1')) as piyo from users;\n`).QueryRow(db)\n\nerr := row1.Scan(&v1)\nfmt.Printf(\"%v, err\\n\", v1, err) // output: 100000, nil\n\nrow2 := queries.Raw(`\n select sum(JSON_EXTRACT(name, '$.hoge2.fuga2')) as piyo from users;\n`).QueryRow(db)\n\nerr = row2.Scan(&v2)\nfmt.Printf(\"%v, err\\n\", v2, err) // output: 0, Scan error on column index 0, name \"piyo\": converting driver.Value type float64 (\"1e+06\") to a int64: invalid syntax
The first query works as expected, but the second query returns the following error:
\nScan error on column index 0, name \"piyo\": converting driver.Value type float64 (\"1e+06\") to a int64: invalid syntax
I thought that 1,000,000 is expected to be of type int64, but for some reason, it was retrieved as float64.
\nSo what criteria determine whether a value is sent as int64 or double.
\nSpecifically, for values like 100,000 and 1,000,000 which data type (int64 or double) would be used?
I managed to run your code and I can reproduce it.
\nhttps://gist.github.com/methane/8f7bf5c84705246ab7c8da3eb5889820
I confirm that MySQL returns DOUBLE (float64) for both queries.
\n$ mysql -h 127.0.0.1 -u root test --column-type-info\n\nmysql> select sum(JSON_EXTRACT(name, '$.hoge1.fuga1')) as piyo from users;\nField 1: `piyo`\nCatalog: `def`\nDatabase: ``\nTable: ``\nOrg_table: ``\nType: DOUBLE\nCollation: binary (63)\nLength: 23\nMax_length: 6\nDecimals: 31\nFlags: BINARY NUM\n\n\n+--------+\n| piyo |\n+--------+\n| 100000 |\n+--------+\n1 row in set (0.00 sec)\n\nmysql> select sum(JSON_EXTRACT(name, '$.hoge2.fuga2')) as piyo from users;\nField 1: `piyo`\nCatalog: `def`\nDatabase: ``\nTable: ``\nOrg_table: ``\nType: DOUBLE\nCollation: binary (63)\nLength: 23\nMax_length: 7\nDecimals: 31\nFlags: BINARY NUM\n\n\n+---------+\n| piyo |\n+---------+\n| 1000000 |\n+---------+\n1 row in set (0.01 sec)\n
The difference is came from here.
\n\nWhen dest type (scanning into) is int and source type (the driver returns) is not int, database/sql stringify source value and use ParseInt() to get integer.
\nSee and run this sample code. https://go.dev/play/p/-raUl94MbZW
\nfmt.Println(100000.0)
becomes 100000
so ParseInt succeeds.
\nfmt.Println(1000000.0)
becomes 1e+06
so ParseInt fails.
That's why two queries have different results.
","upvoteCount":1,"url":"https://github.com/go-sql-driver/mysql/discussions/1627#discussioncomment-10436091"}}}-
I've been working with go-sql-driver/mysql and recently upgraded to version 1.8.1. I noticed in the release notes that as of this version, integer/float values are now converted into int64 or double even when using the text protocol:
I would appreciate some clarification on the following points: What criteria determine whether a value is sent as int64 or double. Context: Here's a simplified version of my setup: CREATE TABLE users {
name json NOT NULL
} mysql> select name from users;
+--------------------------------------------------------+
| name |
+--------------------------------------------------------+
| {"hoge1": {"fuga1": 100000}} |
| {"hoge2": {"fuga2": 1000000}} |
+--------------------------------------------------------+ In Go, I'm executing the following SQL queries and scanning the results into int64 variables: import (
...
"github.com/volatiletech/sqlboiler/queries"
"database/sql"
)
...
var (
v1 v2 int64
db *sql.DB
)
...
row1 := queries.Raw(`
select sum(JSON_EXTRACT(name, '$.hoge1.fuga1')) as piyo from users;
`).QueryRow(db)
err := row1.Scan(&v1)
fmt.Printf("%v, err\n", v1, err) // output: 100000, nil
row2 := queries.Raw(`
select sum(JSON_EXTRACT(name, '$.hoge2.fuga2')) as piyo from users;
`).QueryRow(db)
err = row2.Scan(&v2)
fmt.Printf("%v, err\n", v2, err) // output: 0, Scan error on column index 0, name "piyo": converting driver.Value type float64 ("1e+06") to a int64: invalid syntax The first query works as expected, but the second query returns the following error: Scan error on column index 0, name "piyo": converting driver.Value type float64 ("1e+06") to a int64: invalid syntax I thought that 1,000,000 is expected to be of type int64, but for some reason, it was retrieved as float64. So what criteria determine whether a value is sent as int64 or double. |
Beta Was this translation helpful? Give feedback.
-
It is question about behavior of the MySQL, not a driver. |
Beta Was this translation helpful? Give feedback.
-
I managed to run your code and I can reproduce it. I confirm that MySQL returns DOUBLE (float64) for both queries.
The difference is came from here. When dest type (scanning into) is int and source type (the driver returns) is not int, database/sql stringify source value and use ParseInt() to get integer. See and run this sample code. https://go.dev/play/p/-raUl94MbZW
That's why two queries have different results. |
Beta Was this translation helpful? Give feedback.
I managed to run your code and I can reproduce it.
https://gist.github.com/methane/8f7bf5c84705246ab7c8da3eb5889820
I confirm that MySQL returns DOUBLE (float64) for both queries.