[CONC-519] mariadb client library doesn't handle server_status and warnign_count fields received in the packet COM_STMT_EXECUTE_RESPONSE. Created: 2020-12-17  Updated: 2021-06-17  Resolved: 2021-02-07

Status: Closed
Project: MariaDB Connector/C
Component/s: None
Affects Version/s: 3.1.11
Fix Version/s: 3.2.0

Type: Bug Priority: Major
Reporter: Dmitry Shulga Assignee: Georg Richter
Resolution: Fixed Votes: 0
Labels: None

Attachments: File conc519.diff    

 Description   

While working on implementation of the task MDEV-16708 I've got stumble with the following issue: warnings generated during execution of the CALL is not displayed in case the binary protocol is used for communication between client and server.

I pushed the branch 10.6-MDEV-16708 that adds support for execution of some formerly missed statements in prepared statement mode including the CALL statement. If run a server built with this patch then the following test case will reproduce the issue.

$ cat mysql-test/main/ps_ps.test
create procedure proc_1() checksum table xyz;
call proc_1();
SHOW WARNINGS;
drop procedure proc_1;

$ ./mtr --ps-protocol main.ps_ps

create procedure proc_1() checksum table xyz;
call proc_1();
Table Checksum
test.xyz NULL
SHOW WARNINGS;
Level Code Message
Error 1146 Table 'test.xyz' doesn't exist
drop procedure proc_1;

If the same test is run without the option --ps-protocol
the test output is the following:

$ ./mtr main.ps_ps
create procedure proc_1() checksum table xyz;
call proc_1();
Table Checksum
test.xyz NULL
Warnings:
Error 1146 Table 'test.xyz' doesn't exist
SHOW WARNINGS;
Level Code Message
Error 1146 Table 'test.xyz' doesn't exist
drop procedure proc_1;

As you can seen the warning message
Error 1146 Table 'test.xyz' doesn't exist
is not output as a result of the statement execution in case the CALL statement
is run via PS protocol although explicit execution of the SHOW WARNING statement
results in displaying warning details.



 Comments   
Comment by Dmitry Shulga [ 2020-12-17 ]

Debugging of the client mysqltest shows that the data member MYSQL->warning_count has value 0. In result mysqltest is not run the statement
SHOW WARNINGS in order to display warning details.

See the code snippet below
```
int append_warnings(DYNAMIC_STRING ds, MYSQL mysql)
{
uint count;
MYSQL_RES *warn_res;
DYNAMIC_STRING res;
DBUG_ENTER("append_warnings");

DBUG_PRINT("info",("mysql_warning_count: %d",
mysql_warning_count(mysql)));
if (!(count= mysql_warning_count(mysql))) <<==== Here, the value of count variable equals 0 so append_warnings() returns control flow without execution of the "SHOW WARNINGS" statement a few lines below
DBUG_RETURN(0);

/*
If one day we will support execution of multi-statements
through PS API we should not issue SHOW WARNINGS until
we have not read all results...
*/
DBUG_ASSERT(!mysql_more_results(mysql));

if (mysql_real_query(mysql, "SHOW WARNINGS", 13))
die("Error running query \"SHOW WARNINGS\": %s", mysql_error(mysql));

```

Comment by Dmitry Shulga [ 2020-12-18 ]

I did the following experiment:
ran mysqltest under debugger and set a break point on the function run_query_stmt
when the break point hit with query="call proc_1()" I stepped-over every statement in the function until reached the line
next right after the following statement block
/*
Execute the query
*/
if (do_stmt_execute(cn))

{ handle_error(command, mysql_stmt_errno(stmt), mysql_stmt_error(stmt), mysql_stmt_sqlstate(stmt), ds); goto end; }

/*
When running in cursor_protocol get the warnings from execute here
and keep them in a separate string for later.
*/
if (cursor_protocol_enabled && !disable_warnings) <<=== Stopped at this line
append_warnings(&ds_execute_warnings, mysql);

and then I printed warning count and error number for the prepared statement just executed.

(lldb) p mysql_stmt_errno(stmt)
(unsigned int) $10 = 0
(lldb) p mysql_stmt_warning_count(stmt)
(int) $11 = 0

As you can see these data fields also have zero values.

Comment by Georg Richter [ 2020-12-18 ]

The problem is, that mysqltest always uses mysql_warning_count instead of mysql_stmt_warning_count for prepared statements. See attached quick and dirty hack.

Comment by Dmitry Shulga [ 2021-02-07 ]

Fix is the same as for he bug report MDEV-24460.
Actual reason of this failure is that the OK packet received from server wasn't processed
by mysqltest utility in case mysqltest started in ps-protocol mode.

Enclosing of statements for processing of COM_STMT_EXECUTE response
in the construct like
do

{ ... }

while (!mysql_stmt_next_result());
fixes this issue.

Generated at Thu Feb 08 03:05:54 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.