Bug #101284 | Problem with prepared statements | ||
---|---|---|---|
Submitted: | 23 Oct 2020 10:48 | Modified: | 17 Nov 2020 16:42 |
Reporter: | Damjan Vujnovic | Email Updates: | |
Status: | Closed | Impact on me: | |
Category: | MySQL Server: JSON | Severity: | S2 (Serious) |
Version: | 8.0.22 | OS: | CentOS |
Assigned to: | CPU Architecture: | x86 | |
Tags: | json, prepared statements, regression, WL#9384 |
[23 Oct 2020 10:48]
Damjan Vujnovic
[23 Oct 2020 10:55]
Damjan Vujnovic
Also, it's worth pointing out that changing the invocation to: set @x = '"a"'; execute s1 using @x; makes it work, but we would like some clarity on the change of behavior (the release notes do mention changes in prepared statements and potentially having to use CAST, but we would like to know if this is a regression or indeed a new behavior).
[23 Oct 2020 11:17]
MySQL Verification Team
Hello Damjan Vujnovic, Thank you for the report and test case. regards, Umesh
[17 Nov 2020 16:42]
Jon Stephens
Documented fix in the MySQL 8.0.23 changelog, as follows: Work done in MySQL 8.0.22 to cause prepared statements to be prepared only once introduced a regression in the handling of dynamic parameters to JSON functions. All JSON arguments were classified as data type MYSQL_TYPE_JSON, which overlooked the fact that JSON functions take two kinds of JSON parameters—JSON values and JSON documents—and this distinction cannot be made with the data type only. For Bug #31667405 this problem was solved for comparison operators and the IN() operator by making it possible to tag a JSON argument as being a scalar value, while letting arguments to other JSON functions be treated as JSON documents. The present fix restores for a number of JSON functions their treatment of certain arguments as JSON values, as listed here: ·The first argument to MEMBER OF() ·The third, fifth, seventh, and subsequent odd-numbered arguments to the functions JSON_INSERT(), JSON_REPLACE(), JSON_SET(), JSON_ARRAY_APPEND(), and JSON_ARRAY_INSERT(). Closed.
[17 Dec 2020 22:50]
Rodrigo Pedra Brum
It is not clear to me if the 8.0.23 changelog from the last comment would fix this scenario. But when using prepared statements and mixing `JSON_SET()` it affects all other parameters. For example, this test script fails in 8.0.22: ~~~sql select @@version; -- 8.0.22 select @@sql_mode; -- ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION drop schema if exists `dummy`; create schema `dummy`; use `dummy`; create table `dummy`.`table` ( `id` bigint unsigned not null, `properties` json null ); insert into `dummy`.`table` (`id`, `properties`) VALUES (1, '{}'); insert into `dummy`.`table` (`id`, `properties`) VALUES (2, '{}'); prepare stmt from 'update `dummy`.`table` set `properties` = json_set(`properties`, ''$."foo"'', ?), `properties` = json_set(`properties`, ''$."bar"'', ?) where `id` in (?, ?)'; set @foo = 'foo'; set @bar = 'bar'; set @id = '1'; -- works with 1 (as an integer) set @other = '2'; -- works with 2 (as an integer) execute stmt using @foo, @bar, @id, @other; deallocate prepare stmt; select * from `dummy`.`table`; ~~~ I also tested with `where id = ?` and using only one parameter, and it fails if the bound value is a string. I also tested dropping the `unsigned` from the `id` column, or using the `int` datatype. This worked fine in previous versions. If this would be a different bug, let me know and I will open another bug report.
[18 Dec 2020 8:04]
Roy Lyseng
Hi Rodrigo, I think your problem will be fixed in the next release.
[18 Dec 2020 15:19]
Rodrigo Pedra Brum
Thanks for the quick response Roy. Have a nice day =)