Bug #106352 | Binary resultset for `SELECT ?` with date/time gives wrong type for the column | ||
---|---|---|---|
Submitted: | 2 Feb 2022 0:00 | Modified: | 9 Feb 2022 19:00 |
Reporter: | Austin Bonander | Email Updates: | |
Status: | Closed | Impact on me: | |
Category: | MySQL Server: Prepared statements | Severity: | S3 (Non-critical) |
Version: | 8.0.28, 5.7.37 | OS: | Any |
Assigned to: | CPU Architecture: | Any |
[2 Feb 2022 0:00]
Austin Bonander
[2 Feb 2022 0:02]
Austin Bonander
Wireshark capture: DATE
Attachment: mysql-8.0.28-regression-date.pcapng (application/x-pcapng, text), 6.00 KiB.
[2 Feb 2022 0:02]
Austin Bonander
Wireshark capture: TIME
Attachment: mysql-8.0.28-regression-time.pcapng (application/x-pcapng, text), 5.38 KiB.
[2 Feb 2022 0:02]
Austin Bonander
Wireshark capture: DATETIME
Attachment: mysql-8.0.28-regression-datetime.pcapng (application/x-pcapng, text), 5.41 KiB.
[2 Feb 2022 0:03]
Austin Bonander
Wireshark capture: TIMESTAMP
Attachment: mysql-8.0.28-regression-timestamp.pcapng (application/x-pcapng, text), 5.48 KiB.
[2 Feb 2022 8:07]
MySQL Verification Team
Hello Austin Bonander, Thank you for the report and feedback. Imho this is seen in even earlier versions(5.6,5.7,8.0). regards, Umesh
[2 Feb 2022 9:25]
Roy Lyseng
Hi Austin, can you please add the actual SQL statements for the various temporal data types? The problem you are facing is most likely related to now detecting parameter types from the context, in accordance with the SQL standard. It probably means that some CAST clauses must be inserted in the SQL statements.
[2 Feb 2022 21:11]
Austin Bonander
Roy: SQLx is telling MySQL what the type of that bind argument is, e.g. MYSQL_TYPE_TIMESTAMP, and passing it in the binary encoding. There shouldn't be any inference necessary. Additionally, MySQL appears to be returning returning the value as a string instead of in the binary encoding as expected, which explains why the type is MYSQL_TYPE_VAR_STRING. The same test passes for all the other types we cover, and passes for these types with 8.0.27. It is almost certainly a regression introduced in 8.0.28. I can simplify the query to just `SELECT ?` and reproduce the issue. I will attach the Wireshark capture for the simplified test if it makes the issue clearer. For simplicity, it's just going to be the capture from testing with TIMESTAMP, but I do want to reiterate that this also affects DATE, TIME and DATETIME.
[2 Feb 2022 21:13]
Austin Bonander
Wireshark capture: TIMESTAMP by itself
Attachment: mysql-8.0.28-regression-timestamp-simplified.pcapng (application/x-pcapng, text), 5.54 KiB.
[4 Feb 2022 11:27]
Roy Lyseng
MySQL will always derive a data type for dynamic parameters based on the context. However, for a query like "SELECT ?", there is no context to look into, so by default, the type VARCHAR is assumed. On execution, we check whether the actual type is compatible with the derived type, and if these are incompatible, an implicit repreparation is performed, where the parameter type is reassigned according to the actual type. This is assumed to happen here, but doesn't. It is however always good to avoid such repreparations, this is why we recommend to rewrite the query with an explicit cast, such as SELECT CAST(? AS DATETIME); Anyway, we'll fix this regression as soon as possible.
[9 Feb 2022 19:00]
Christine Cole
Posted by developer: Fixed as of the upcoming MySQL 8.0.29 release, and here's the proposed changelog entry from the documentation team: A prepared and executed query like ‘SELECT ?’ with a DATE, TIME, DATETIME or TIMESTAMP as the bound argument could return the wrong column type. The issue is fixed by restoring the previous logic that reprepared such queries to give each dynamic parameter its literal value. Thank you for the bug report.