diff --git a/client/mysqltest.c b/client/mysqltest.c
index 6f212f784efdd2144dca4376f4551def9617b7fb..4fb97334ddf50db257825453d1092b77059b0e22 100644
--- a/client/mysqltest.c
+++ b/client/mysqltest.c
@@ -3157,7 +3157,7 @@ static void append_stmt_result(DYNAMIC_STRING *ds, MYSQL_STMT *stmt,
 
   if (mysql_stmt_fetch(stmt) != MYSQL_NO_DATA)
     die("fetch didn't end with MYSQL_NO_DATA from statement: %d %s",
-	mysql_stmt_error(stmt), mysql_stmt_errno(stmt));
+	mysql_stmt_errno(stmt), mysql_stmt_error(stmt));
 
   free_replace_column();
 
@@ -3622,7 +3622,7 @@ static void run_query_stmt(MYSQL *mysql, struct st_query *command,
   if (mysql_stmt_prepare(stmt, query, query_len))
   {
     handle_error(query, command,  mysql_stmt_errno(stmt),
-		 mysql_stmt_error(stmt), mysql_stmt_sqlstate(stmt), ds);
+                 mysql_stmt_error(stmt), mysql_stmt_sqlstate(stmt), ds);
     goto end;
   }
 
@@ -3638,29 +3638,34 @@ static void run_query_stmt(MYSQL *mysql, struct st_query *command,
     parameter markers.
   */
 
-#ifdef BUG14013_FIXED
-  /*
-    Use cursor when retrieving result
-  */
   if (cursor_protocol_enabled)
   {
+    /*
+      Use cursor when retrieving result
+    */
     ulong type= CURSOR_TYPE_READ_ONLY;
     if (mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*) &type))
       die("mysql_stmt_attr_set(STMT_ATTR_CURSOR_TYPE) failed': %d %s",
-	  mysql_stmt_errno(stmt), mysql_stmt_error(stmt));
+          mysql_stmt_errno(stmt), mysql_stmt_error(stmt));
   }
-#endif
 
   /*
     Execute the query
-   */
+  */
   if (mysql_stmt_execute(stmt))
   {
     handle_error(query, command, mysql_stmt_errno(stmt),
-		 mysql_stmt_error(stmt), mysql_stmt_sqlstate(stmt), ds);
+                 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)
+    append_warnings(&ds_execute_warnings, mysql);
+
   /*
     We instruct that we want to update the "max_length" field in
      mysql_stmt_store_result(), this is our only way to know how much
@@ -3670,7 +3675,7 @@ static void run_query_stmt(MYSQL *mysql, struct st_query *command,
     my_bool one= 1;
     if (mysql_stmt_attr_set(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, (void*) &one))
       die("mysql_stmt_attr_set(STMT_ATTR_UPDATE_MAX_LENGTH) failed': %d %s",
-	  mysql_stmt_errno(stmt), mysql_stmt_error(stmt));
+          mysql_stmt_errno(stmt), mysql_stmt_error(stmt));
   }
 
   /*
@@ -3680,7 +3685,7 @@ static void run_query_stmt(MYSQL *mysql, struct st_query *command,
   if (mysql_stmt_store_result(stmt))
   {
     handle_error(query, command, mysql_stmt_errno(stmt),
-		 mysql_stmt_error(stmt), mysql_stmt_sqlstate(stmt), ds);
+                 mysql_stmt_error(stmt), mysql_stmt_sqlstate(stmt), ds);
     goto end;
   }
 
@@ -3701,10 +3706,10 @@ static void run_query_stmt(MYSQL *mysql, struct st_query *command,
       uint num_fields= mysql_num_fields(res);
 
       if (display_metadata)
-	append_metadata(ds, fields, num_fields);
+        append_metadata(ds, fields, num_fields);
 
       if (!display_result_vertically)
-	append_table_headings(ds, fields, num_fields);
+        append_table_headings(ds, fields, num_fields);
 
       append_stmt_result(ds, stmt, fields, num_fields);
 
@@ -3726,10 +3731,11 @@ static void run_query_stmt(MYSQL *mysql, struct st_query *command,
 
       /* Append warnings to ds - if there are any */
       if (append_warnings(&ds_execute_warnings, mysql) ||
-	  ds_prepare_warnings.length ||
-	  ds_warnings->length)
+          ds_execute_warnings.length ||
+          ds_prepare_warnings.length ||
+          ds_warnings->length)
       {
-	dynstr_append_mem(ds, "Warnings:\n", 10);
+        dynstr_append_mem(ds, "Warnings:\n", 10);
 	if (ds_warnings->length)
 	  dynstr_append_mem(ds, ds_warnings->str,
 			    ds_warnings->length);
diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c
index 9825f1ecdfaaf919125124366add7b8ade208d5b..7a492e5003439471ec71e30a8c8c233713b630c5 100644
--- a/libmysql/libmysql.c
+++ b/libmysql/libmysql.c
@@ -4757,12 +4757,39 @@ int STDCALL mysql_stmt_store_result(MYSQL_STMT *stmt)
 
   if (!stmt->field_count)
     DBUG_RETURN(0);
-  if ((int) stmt->state < (int) MYSQL_STMT_EXECUTE_DONE ||
-      mysql->status != MYSQL_STATUS_GET_RESULT)
+
+  if ((int) stmt->state < (int) MYSQL_STMT_EXECUTE_DONE)
+  {
+    set_stmt_error(stmt, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate);
+    DBUG_RETURN(1);
+  }
+
+  if (mysql->status == MYSQL_STATUS_READY &&
+      stmt->server_status & SERVER_STATUS_CURSOR_EXISTS)
+  {
+    /*
+      Server side cursor exist, tell server to start sending the rows
+    */
+    NET *net= &mysql->net;
+    char buff[4 /* statement id */ +
+              4 /* number of rows to fetch */];
+
+    /* Send row request to the server */
+    int4store(buff, stmt->stmt_id);
+    int4store(buff + 4, (int)~0); /* number of rows to fetch */
+    if (cli_advanced_command(mysql, COM_STMT_FETCH, buff, sizeof(buff),
+                             NullS, 0, 1))
+    {
+      set_stmt_errmsg(stmt, net->last_error, net->last_errno, net->sqlstate);
+      DBUG_RETURN(1);
+    }
+  }
+  else if (mysql->status != MYSQL_STATUS_GET_RESULT)
   {
     set_stmt_error(stmt, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate);
     DBUG_RETURN(1);
   }
+
   if (result->data)
   {
     free_root(&result->alloc, MYF(MY_KEEP_PREALLOC));
@@ -4803,6 +4830,10 @@ int STDCALL mysql_stmt_store_result(MYSQL_STMT *stmt)
     DBUG_RETURN(1);
   }
 
+  /* Assert that if there was a cursor, all rows have been fetched */
+  DBUG_ASSERT(mysql->status != MYSQL_STATUS_READY ||
+              (mysql->server_status & SERVER_STATUS_LAST_ROW_SENT));
+
   if (stmt->update_max_length)
   {
     MYSQL_ROWS *cur= result->data;
diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c
index 666c60391da4d4cf59e37e6ffabca9675f8c6140..f4016f4368e91b72e58949f6a40c999b718835e7 100644
--- a/tests/mysql_client_test.c
+++ b/tests/mysql_client_test.c
@@ -1049,7 +1049,10 @@ void stmt_fetch_close(Stmt_fetch *fetch)
   reading from the rest.
 */
 
-my_bool fetch_n(const char **query_list, unsigned query_count)
+enum fetch_type { USE_ROW_BY_ROW_FETCH= 0, USE_STORE_RESULT= 1 };
+
+my_bool fetch_n(const char **query_list, unsigned query_count,
+                enum fetch_type fetch_type)
 {
   unsigned open_statements= query_count;
   int rc, error_count= 0;
@@ -1065,6 +1068,15 @@ my_bool fetch_n(const char **query_list, unsigned query_count)
                     query_list[fetch - fetch_array]);
   }
 
+  if (fetch_type == USE_STORE_RESULT)
+  {
+    for (fetch= fetch_array; fetch < fetch_array + query_count; ++fetch)
+    {
+      rc= mysql_stmt_store_result(fetch->handle);
+      check_execute(fetch->handle, rc);
+    }
+  }
+
   while (open_statements)
   {
     for (fetch= fetch_array; fetch < fetch_array + query_count; ++fetch)
@@ -11867,7 +11879,8 @@ static void test_basic_cursors()
 
   fill_tables(basic_tables, sizeof(basic_tables)/sizeof(*basic_tables));
 
-  fetch_n(queries, sizeof(queries)/sizeof(*queries));
+  fetch_n(queries, sizeof(queries)/sizeof(*queries), USE_ROW_BY_ROW_FETCH);
+  fetch_n(queries, sizeof(queries)/sizeof(*queries), USE_STORE_RESULT);
   DBUG_VOID_RETURN;
 }
 
@@ -11880,7 +11893,8 @@ static void test_cursors_with_union()
     "SELECT t1.id FROM t1 WHERE t1.id < 5"
   };
   myheader("test_cursors_with_union");
-  fetch_n(queries, sizeof(queries)/sizeof(*queries));
+  fetch_n(queries, sizeof(queries)/sizeof(*queries), USE_ROW_BY_ROW_FETCH);
+  fetch_n(queries, sizeof(queries)/sizeof(*queries), USE_STORE_RESULT);
 }
 
 /*