[MDEV-28041] Invalid resulset received for prepared statement Created: 2022-03-11  Updated: 2022-03-14  Resolved: 2022-03-14

Status: Closed
Project: MariaDB Server
Component/s: Prepared Statements
Affects Version/s: 10.7.3
Fix Version/s: N/A

Type: Bug Priority: Major
Reporter: Javier Jaramago Fernández Assignee: Unassigned
Resolution: Duplicate Votes: 0
Labels: None

Attachments: File libmariadb_invalid_stmt_response.pcapng     File libmariadb_valid_stmt_response.pcapng     File libmysql_invalid_stmt_response.pcapng     File libmysql_valid_stmt_response.pcapng     File test_stmt_large_param_num.cpp    
Issue Links:
Duplicate
duplicates MDEV-27937 Assertion failure when executing prep... Closed

 Description   

Issue Description

When a prepared statement is issued with a high enough number of parameters an invalid resulset (no resulset) is received from server side. Both client libraries `libmysqlclient` and `libmariadbclient` has been tested against a MariaDB backend, leading to the same result. A minimal test case that can be compiled against both of these libraries, together with traffic captures is provided for reproducing the issue.

Errors reported by client libraries

libmysqlclient:

error: 'Attempt to read a row while there is no result set associated with the statement'

libmariadbclient:

error: 'Commands out of sync; you can't run this command now'

Error reported in MariaDB error log

2022-03-11 12:27:00 1708 [Warning] Aborted connection 1708 to db: 'unconnected' user: 'root' host: '127.0.0.1' (Got an error reading communication packets)
2022-03-11 12:27:03 1709 [Warning] Aborted connection 1709 to db: 'unconnected' user: 'root' host: '127.0.0.1' (Got an error reading communication packets)

Traffic captures showing the issue:

In the following traffic captures it can be seen valid requests (COM_STMT_EXECUTE) and the responses from MariaDB.

Valid request - COM_STMT_EXECUTE - libmariadb_valid_stmt_response.pcapng:

Frame 16: 2006 bytes on wire (16048 bits), 2006 bytes captured (16048 bits) on interface any, id 0
Linux cooked capture v1
Internet Protocol Version 4, Src: 127.0.0.1, Dst: 127.0.0.1
Transmission Control Protocol, Src Port: 49516, Dst Port: 3306, Seq: 10703, Ack: 28346, Len: 1938
[2 Reassembled TCP Segments (10130 bytes): #15(8192), #16(1938)]
MySQL Protocol
    Packet Length: 10126
    Packet Number: 0
    Request Command Execute Statement

Valid response - BinaryProtocolResulset - libmariadb_valid_stmt_response.pcapng:

Frame 17: 286 bytes on wire (2288 bits), 286 bytes captured (2288 bits) on interface any, id 0
Linux cooked capture v1
Internet Protocol Version 4, Src: 127.0.0.1, Dst: 127.0.0.1
Transmission Control Protocol, Src Port: 3306, Dst Port: 49516, Seq: 28346, Ack: 12641, Len: 218
MySQL Protocol
... { More packets } ...
MySQL Protocol
    Packet Length: 5
    Packet Number: 7
    Response Code: EOF Packet (0xfe)
    EOF marker: 254
    Warnings: 0
    Server Status: 0x0000
    Payload: 2200

Offending request - COM_STMT_EXECUTE - libmariadb_invalid_stmt_response.pcapng:

Frame 16: 2016 bytes on wire (16128 bits), 2016 bytes captured (16128 bits) on interface any, id 0
Linux cooked capture v1
Internet Protocol Version 4, Src: 127.0.0.1, Dst: 127.0.0.1
Transmission Control Protocol, Src Port: 49514, Dst Port: 3306, Seq: 10705, Ack: 28374, Len: 1948
[2 Reassembled TCP Segments (10140 bytes): #15(8192), #16(1948)]
MySQL Protocol
    Packet Length: 10136
    Packet Number: 0
    Request Command Execute Statement

Invalid Response - libmariadb_invalid_stmt_response.pcapng:

Expected BinaryProtocolResulset, received just OK packet:

Frame 17: 79 bytes on wire (632 bits), 79 bytes captured (632 bits) on interface any, id 0
Linux cooked capture v1
Internet Protocol Version 4, Src: 127.0.0.1, Dst: 127.0.0.1
Transmission Control Protocol, Src Port: 3306, Dst Port: 49514, Seq: 28374, Ack: 12653, Len: 11
MySQL Protocol
    Packet Length: 7
    Packet Number: 1
    Response Code: OK Packet (0x00)
    Prefix: 0
    Length: 0
    Prefix: 0
    Length: 0
    Affected Rows: 0
    Prefix: 0
    Length: 0
    Server Status: 0x0002
    Warnings: 0

Issue Reproduction

Script compilation

Against `libmysqlclient`:

g++ -DLIBMYSQLCLIENT test_stmt_large_param_num.cpp -I/usr/include/mysql -ldl -std=c++11 -lmysqlclient -o libmysql_test_stmt_large_param_num

Against `libmariadbclient`:

g++ test_stmt_large_param_num.cpp -I/usr/include/mysql -ldl -std=c++11 -lmariadbclient -o libmariadb_test_stmt_large_param_num

Script usage

Using the provided test script it's just enough to use it against a MariaDB, and the issue will be reproduce, script usage is the following:

test_stmt_large_param_num -h <mysql host> -u <mysql user> -p <mysql password> -P <mysql port> -N <stmt_param_num>

Where '-N' specifies the number of parameters to be created for the stmt to be issued. Simple testing using the script via:

for i in {500..2000}; do ./libmariadb_test_stmt_large_param_num -h '127.0.0.1' -u root -p root -P 3306 -N $i; if [ $? -ne 0 ]; then echo ArgNum: $i - $(date); break; fi; done

Revealed that `1000` appears to be the offending number of parameters that triggers the issue, at least in the used testing environment.



 Comments   
Comment by Alice Sherepa [ 2022-03-11 ]

It seems to be the same problem as MDEV-27937. Could you please try a temporary workaround, that is suggested in MDEV-27937 - (setting in_predicate_conversion_threshold to a higher value)?

Comment by Javier Jaramago Fernández [ 2022-03-11 ]

@Alice Sherepa thanks for the fast reply. I can confirm that the suggestion of in_predicate_conversion_threshold to either '0' or a value higher than the number of parameters of the statement seems to solve the issue.

Generated at Thu Feb 08 09:57:36 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.