Bug #113269 Prepared statements executed with numbers can no longer be executed with strings
Submitted: 28 Nov 2023 21:41 Modified: 29 Nov 2023 11:36
Reporter: Kent Ross Email Updates:
Status: Duplicate Impact on me:
None 
Category:MySQL Server Severity:S3 (Non-critical)
Version:8.0+ OS:Any
Assigned to: CPU Architecture:Any
Tags: json, prepared statements

[28 Nov 2023 21:41] Kent Ross
Description:
When a prepared statement is first created, it can successfully be executed as expected with its arguments bound with either numeric or string typed values.

After the first time a prepared statement is executed with a numeric value bound to an argument, string values can no longer be used. At that time, when the prepared statement is executed with a string value bound it emits a conversion warning with code 1292 for each row evaluated.

This bug is new in mysql version 8, and is/was not present in mysql server 5.7.

How to repeat:
mysql> create table t (
    ->   id integer primary key,
    ->   val json
    -> );
Query OK, 0 rows affected (0.01 sec)

mysql> insert into t(id, val) values (1, '1'), (2, '"two"'), (3, '"three"');
Query OK, 3 rows affected (0.00 sec)
Records: 3  Duplicates: 0  Warnings: 0

mysql> prepare stmt from 'select *, val = ? from t';
Query OK, 0 rows affected (0.00 sec)
Statement prepared

mysql> set @one = 1;
Query OK, 0 rows affected (0.00 sec)

mysql> set @two = 'two';
Query OK, 0 rows affected (0.00 sec)

mysql> set @three = 'three';
Query OK, 0 rows affected (0.00 sec)

mysql> execute stmt using @three;
+----+---------+---------+
| id | val     | val = ? |
+----+---------+---------+
|  1 | 1       |       0 |
|  2 | "two"   |       0 |
|  3 | "three" |       1 |
+----+---------+---------+
3 rows in set (0.00 sec)

mysql> execute stmt using @two;
+----+---------+---------+
| id | val     | val = ? |
+----+---------+---------+
|  1 | 1       |       0 |
|  2 | "two"   |       1 |
|  3 | "three" |       0 |
+----+---------+---------+
3 rows in set (0.00 sec)

mysql> execute stmt using @one;
+----+---------+---------+
| id | val     | val = ? |
+----+---------+---------+
|  1 | 1       |       1 |
|  2 | "two"   |       0 |
|  3 | "three" |       0 |
+----+---------+---------+
3 rows in set (0.00 sec)

mysql> execute stmt using @two;
+----+---------+---------+
| id | val     | val = ? |
+----+---------+---------+
|  1 | 1       |       0 |
|  2 | "two"   |       0 |
|  3 | "three" |       0 |
+----+---------+---------+
3 rows in set, 3 warnings (0.00 sec)

mysql> show warnings;
+---------+------+------------------------------------------+
| Level   | Code | Message                                  |
+---------+------+------------------------------------------+
| Warning | 1292 | Truncated incorrect INTEGER value: 'two' |
| Warning | 1292 | Truncated incorrect INTEGER value: 'two' |
| Warning | 1292 | Truncated incorrect INTEGER value: 'two' |
+---------+------+------------------------------------------+
3 rows in set (0.00 sec)

mysql> select version();
+-----------+
| version() |
+-----------+
| 8.2.0     |
+-----------+
1 row in set (0.00 sec)

mysql>

Suggested fix:
Executing a prepared statement with a numeric value bound to its arguments should not permanently change the state of the prepared statement. It should be possible to execute the prepared statement with string values bound after that.
[29 Nov 2023 11:36] MySQL Verification Team
Please do not submit the same bug more than once. An existing bug report already describes this very problem. Even if you feel that your issue is somewhat different, the resolution is likely
to be the same. Because of this, we hope you add your comments to the original bug instead.

The original bug that you filed is:

https://bugs.mysql.com/bug.php?id=113240

Thank you for your interest in MySQL.