Bug #74796 mysql_stmt_execute hangs if cursor type was specified and server is not 5.7
Submitted: 11 Nov 2014 15:18 Modified: 10 Feb 2015 15:37
Reporter: Igor Solodovnikov Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: C API (client library) Severity:S2 (Serious)
Version:5.7.5 OS:Any
Assigned to: CPU Architecture:Any

[11 Nov 2014 15:18] Igor Solodovnikov
Description:
The issue appears only when new client code (libmysql from mysql-trunk) connects to old servers (5.5 or 5.6).

If client code specifies prepared statement's cursor type CURSOR_TYPE_READ_ONLY with mysql_stmt_attr_set() then subsequent call to mysql_stmt_execute() hangs.

If cursor type is not specified then mysql_stmt_execute() works as expected.

How to repeat:
1. Build attached client application with trunk version of libmysql
2. Run application against 5.5 or 5.6 version of server
3. application will hang inside mysql_stmt_execute()

Suggested fix:
Below is the patch which solves this issue. Existing code in mysql_execute() unconditionally clears SERVER_STATUS_CURSOR_EXISTS flag from server_status. This is wrong for 5.5 and 5.6 servers which return this flag but does not specify CLIENT_DEPRECATE_EOF capability (thus old server returns cursor but new client code ignores it). After this patch mysql_execute() will clear SERVER_STATUS_CURSOR_EXISTS flag only when server specifies CLIENT_DEPRECATE_EOF capability.

=== modified file 'libmysql/libmysql.c'
--- libmysql/libmysql.c 2014-10-06 13:25:09 +0000
+++ libmysql/libmysql.c 2014-11-11 14:44:23 +0000
@@ -2047,12 +2047,12 @@
                                     (uchar*) packet, length, 1, stmt) ||
                (*mysql->methods->read_query_result)(mysql));
 
-  if (mysql->server_status & SERVER_STATUS_CURSOR_EXISTS)
-     mysql->server_status&= ~SERVER_STATUS_CURSOR_EXISTS;
-
   if (!res && (stmt->flags & CURSOR_TYPE_READ_ONLY) &&
       (mysql->server_capabilities & CLIENT_DEPRECATE_EOF))
   {
+    if (mysql->server_status & SERVER_STATUS_CURSOR_EXISTS)
+      mysql->server_status&= ~SERVER_STATUS_CURSOR_EXISTS;
+
     /*
       if server responds with a cursor then COM_STMT_EXECUTE response format
       will be <Metadata><OK>. Hence read the OK packet to get the server status
[10 Feb 2015 15:37] Paul DuBois
Fixed in 5.7.6. No released version affected. No changelog entry needed.