Skip to content
This repository was archived by the owner on Mar 1, 2026. It is now read-only.

Commit 16f92ae

Browse files
committed
Merge branch 'mysql-8.0' into mysql-trunk
Change-Id: I08a02ff0c04d52afa03448699829977af2bab6a4
2 parents 92fe951 + 339e3da commit 16f92ae

3 files changed

Lines changed: 88 additions & 1 deletion

File tree

‎libmysql/libmysql.cc‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1760,8 +1760,12 @@ static bool execute(MYSQL_STMT *stmt, char *packet, ulong length,
17601760
(the reset of the result set will be read in prepare_to_fetch_result).
17611761
*/
17621762

1763-
if ((pkt_len = cli_safe_read(mysql, &is_data_packet)) == packet_error)
1763+
if ((pkt_len = cli_safe_read(mysql, &is_data_packet)) == packet_error) {
1764+
set_stmt_errmsg(stmt, net);
1765+
mysql->status = MYSQL_STATUS_READY;
1766+
stmt->read_row_func = stmt_read_row_no_data;
17641767
return true;
1768+
}
17651769

17661770
if (is_data_packet) {
17671771
assert(stmt->result.rows == 0);

‎sql/sql_prepare.cc‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3467,6 +3467,15 @@ bool Prepared_statement::execute(THD *thd, String *expanded_query,
34673467
stmt_backup.save_rlb(thd);
34683468

34693469
auto execute_guard = create_scope_guard([&]() {
3470+
// In an error situation, cursor may have been left open, close it:
3471+
if (status && open_cursor) {
3472+
if (m_cursor == nullptr && m_cursor_result != nullptr) {
3473+
m_cursor = m_cursor_result->cursor();
3474+
}
3475+
if (m_cursor != nullptr && m_cursor->is_open()) {
3476+
close_cursor();
3477+
}
3478+
}
34703479
/*
34713480
Restore the current database (if changed).
34723481

‎testclients/mysql_client_test.cc‎

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,10 @@
3636
#include <stdio.h>
3737
#include <stdlib.h>
3838
#include <sys/types.h>
39+
#include <condition_variable>
3940
#include <memory>
41+
#include <mutex>
42+
#include <thread>
4043

4144
#include "my_byteorder.h"
4245
#include "my_compiler.h"
@@ -23309,6 +23312,76 @@ static void test_wl13128() {
2330923312
mysql_close(lmysql);
2331023313
}
2331123314

23315+
static void test_bug25584097() {
23316+
DBUG_TRACE;
23317+
myheader("test_bug25584097");
23318+
int rc;
23319+
23320+
class test_bug25584097_thd {
23321+
unsigned long thread_id{0};
23322+
std::condition_variable cnd;
23323+
std::mutex mtx;
23324+
23325+
public:
23326+
void run() {
23327+
int rc;
23328+
MYSQL *lmysql;
23329+
MYSQL_STMT *stmt;
23330+
const char *sqlstmt = "select sleep(300)";
23331+
unsigned long ct = (unsigned long)CURSOR_TYPE_READ_ONLY;
23332+
23333+
printf("child thread start\n");
23334+
lmysql = mysql_client_init(nullptr);
23335+
DIE_UNLESS(lmysql);
23336+
23337+
if (!mysql_real_connect(lmysql, opt_host, opt_user, opt_password,
23338+
current_db, opt_port, opt_unix_socket, 0)) {
23339+
fprintf(stderr, "Failed to connect to the database\n");
23340+
DIE_UNLESS(0);
23341+
}
23342+
23343+
{
23344+
std::unique_lock lk(mtx);
23345+
thread_id = mysql_thread_id(lmysql);
23346+
}
23347+
stmt = mysql_stmt_init(lmysql);
23348+
DIE_UNLESS(stmt != nullptr);
23349+
rc = mysql_stmt_prepare(stmt, sqlstmt, (unsigned long)strlen(sqlstmt));
23350+
DIE_UNLESS(rc == 0);
23351+
rc = mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (const void *)&ct);
23352+
DIE_UNLESS(rc == 0);
23353+
printf("child thread ready to exec\n");
23354+
cnd.notify_one();
23355+
rc = mysql_stmt_execute(stmt);
23356+
DIE_UNLESS(rc != 0);
23357+
printf("child thread cleaning up\n");
23358+
rc = mysql_stmt_close(stmt);
23359+
DIE_UNLESS(rc == 0);
23360+
mysql_close(lmysql);
23361+
printf("child thread ending\n");
23362+
}
23363+
23364+
unsigned long wait_to_kill() {
23365+
std::unique_lock lk(mtx);
23366+
cnd.wait(lk, [this] { return thread_id != 0; });
23367+
return thread_id;
23368+
}
23369+
} foo;
23370+
23371+
std::thread thd(&test_bug25584097_thd::run, &foo);
23372+
printf("Waiting for the child thread\n");
23373+
unsigned long thd_to_kill = foo.wait_to_kill();
23374+
sleep(2);
23375+
23376+
printf("Killing the child thread\n");
23377+
char cmd[50];
23378+
sprintf(cmd, "KILL %lu", thd_to_kill);
23379+
rc = mysql_query(mysql, cmd);
23380+
myquery(rc);
23381+
printf("Wating for the child thread to finish\n");
23382+
thd.join();
23383+
}
23384+
2331223385
static struct my_tests_st my_tests[] = {
2331323386
{"test_bug5194", test_bug5194},
2331423387
{"disable_query_logs", disable_query_logs},
@@ -23623,6 +23696,7 @@ static struct my_tests_st my_tests[] = {
2362323696
{"test_bug34007830", test_bug34007830},
2362423697
{"test_bug33535746", test_bug33535746},
2362523698
{"test_wl13128", test_wl13128},
23699+
{"test_bug25584097", test_bug25584097},
2362623700
{nullptr, nullptr}};
2362723701

2362823702
static struct my_tests_st *get_my_tests() { return my_tests; }

0 commit comments

Comments
 (0)