Details
-
Bug
-
Status: Closed (View Workflow)
-
Trivial
-
Resolution: Cannot Reproduce
-
2.0.0, N/A
-
None
-
None
Description
Function mysql_stmt_execute can hang up under the following conditions.
1. Call mysql_stmt_bind_result in advance.
2. Call mysql_stmt_execute (It is OK)
3. Do NOT call mysql_stmt_fetch
4. Call mysql_stmt_execute again (hang up)
In case of the following sample code, function good_select can be called twice. On the other hand, bad_select works only once.
#include <cstring>
|
#include <iostream>
|
#include <mariadb/mysql.h>
|
#include <new>
|
|
using namespace std; |
|
static const char create_table_sql[] = |
"CREATE TABLE IF NOT EXISTS test.ids (id INT AUTO_INCREMENT PRIMARY KEY)"; |
|
static const char select_sql[] = "SELECT * from test.ids"; |
|
void show_mysql_error(MYSQL *mysql) { |
cerr << "Error(" << mysql_errno(mysql) << ") [" << mysql_sqlstate(mysql) |
<< "] " << mysql_error(mysql) << endl; |
exit(-1); |
}
|
|
void show_mysql_error(MYSQL_STMT *stmt) { |
cerr << "Error(" << mysql_stmt_errno(stmt) << ") [" |
<< mysql_stmt_sqlstate(stmt) << "] " << mysql_stmt_error(stmt) << endl; |
exit(-1); |
}
|
|
void create_table(MYSQL *mysql) { |
|
if (mysql_query(mysql, create_table_sql)) |
show_mysql_error(mysql);
|
}
|
|
void bad_select(MYSQL_STMT *stmt) { |
|
if (mysql_stmt_execute(stmt)) |
show_mysql_error(stmt);
|
|
if (mysql_stmt_store_result(stmt)) |
show_mysql_error(stmt);
|
}
|
|
void good_select(MYSQL_STMT *stmt) { |
|
if (mysql_stmt_execute(stmt)) |
show_mysql_error(stmt);
|
|
if (mysql_stmt_store_result(stmt)) |
show_mysql_error(stmt);
|
|
if (mysql_stmt_fetch(stmt) != MYSQL_NO_DATA) |
show_mysql_error(stmt);
|
}
|
|
int main() { |
|
MYSQL *mysql = mysql_init(nullptr);
|
if (!mysql) |
throw bad_alloc(); |
|
if (!mysql_real_connect(mysql, "127.0.0.1", "test_user", "", "test", 3306, |
nullptr, CLIENT_REMEMBER_OPTIONS))
|
show_mysql_error(mysql);
|
|
create_table(mysql);
|
|
MYSQL_STMT *stmt = mysql_stmt_init(mysql);
|
if (!stmt) |
show_mysql_error(mysql);
|
|
if (mysql_stmt_prepare(stmt, select_sql, strlen(select_sql))) |
show_mysql_error(stmt);
|
|
MYSQL_BIND result;
|
memset(&result, 0, sizeof(result)); |
|
int id; |
result.buffer = &id;
|
result.buffer_length = sizeof(id); |
result.buffer_type = MYSQL_TYPE_LONG;
|
|
if (mysql_stmt_bind_result(stmt, &result)) |
show_mysql_error(stmt);
|
|
good_select(stmt);
|
cout << "good_select done (1st time)" << endl; |
|
good_select(stmt);
|
cout << "good_select done (2nd time)" << endl; |
|
bad_select(stmt);
|
cout << "bad_select done (1st time)" << endl; |
|
bad_select(stmt);
|
cout << "bad_select done (2nd time)" << endl; |
|
return 0; |
}
|