1
0
mirror of https://github.com/mariadb-corporation/mariadb-connector-c.git synced 2025-08-07 02:42:49 +03:00

Fix for CONC-198: can't use two statements per connection

If we have multiple open cursors we need to check the server_status per statement (not per connection)
This commit is contained in:
Georg Richter
2016-08-18 08:04:46 +02:00
parent b68843a93d
commit 405bb926e9
2 changed files with 193 additions and 110 deletions

View File

@@ -242,7 +242,7 @@ int mthd_stmt_read_all_rows(MYSQL_STMT *stmt)
p++;
stmt->upsert_status.warning_count= stmt->mysql->warning_count= uint2korr(p);
p+=2;
stmt->mysql->server_status= uint2korr(p);
stmt->upsert_status.server_status= stmt->mysql->server_status= uint2korr(p);
stmt->result_cursor= result->data;
return(0);
}
@@ -269,7 +269,7 @@ static int stmt_cursor_fetch(MYSQL_STMT *stmt, uchar **row)
return(stmt_buffered_fetch(stmt, row));
if (stmt->mysql->server_status & SERVER_STATUS_LAST_ROW_SENT)
stmt->mysql->server_status&= ~SERVER_STATUS_LAST_ROW_SENT;
else
if (!(stmt->upsert_status.server_status & SERVER_STATUS_LAST_ROW_SENT))
{
int4store(buf, stmt->stmt_id);
int4store(buf + STMT_ID_LENGTH, stmt->prefetch_rows);
@@ -1089,7 +1089,7 @@ static my_bool net_stmt_close(MYSQL_STMT *stmt, my_bool remove)
my_bool STDCALL mysql_stmt_close(MYSQL_STMT *stmt)
{
if (stmt && stmt->mysql && stmt->mysql->net.pvio)
if (stmt && stmt->mysql && stmt->mysql->net.vio)
mysql_stmt_internal_reset(stmt, 1);
net_stmt_close(stmt, 1);
@@ -1791,7 +1791,7 @@ static my_bool madb_reset_stmt(MYSQL_STMT *stmt, unsigned int flags)
{
/* reset statement on server side */
if (stmt->mysql && stmt->mysql->status == MYSQL_STATUS_READY &&
stmt->mysql->net.pvio)
stmt->mysql->net.vio)
{
unsigned char cmd_buf[STMT_ID_LENGTH];
int4store(cmd_buf, stmt->stmt_id);

View File

@@ -4332,8 +4332,91 @@ static int test_conc181(MYSQL *mysql)
return OK;
}
static int test_conc198(MYSQL *mysql)
{
MYSQL_STMT *stmt1, *stmt2;
MYSQL_BIND my_bind[1];
int32 a;
int rc;
const char *stmt_text;
int num_rows= 0;
ulong type;
ulong prefetch_rows= 3;
mysql_query(mysql, "drop table if exists t1");
mysql_query(mysql, "create table t1 (id integer not null primary key)");
rc= mysql_query(mysql, "insert into t1 (id) values "
" (1), (2), (3), (4), (5), (6), (7), (8), (9)");
check_mysql_rc(rc, mysql);
stmt1= mysql_stmt_init(mysql);
stmt2= mysql_stmt_init(mysql);
/* Not implemented in 5.0 */
type= (ulong) CURSOR_TYPE_SCROLLABLE;
rc= mysql_stmt_attr_set(stmt1, STMT_ATTR_CURSOR_TYPE, (void*) &type);
FAIL_UNLESS(rc, "Error expected");
rc= mysql_stmt_attr_set(stmt2, STMT_ATTR_CURSOR_TYPE, (void*) &type);
FAIL_UNLESS(rc, "Error expected");
type= (ulong) CURSOR_TYPE_READ_ONLY;
rc= mysql_stmt_attr_set(stmt1, STMT_ATTR_CURSOR_TYPE, (void*) &type);
check_stmt_rc(rc, stmt1);
rc= mysql_stmt_attr_set(stmt2, STMT_ATTR_CURSOR_TYPE, (void*) &type);
check_stmt_rc(rc, stmt2);
rc= mysql_stmt_attr_set(stmt1, STMT_ATTR_PREFETCH_ROWS,
(void*) &prefetch_rows);
check_stmt_rc(rc, stmt1);
rc= mysql_stmt_attr_set(stmt2, STMT_ATTR_PREFETCH_ROWS,
(void*) &prefetch_rows);
check_stmt_rc(rc, stmt2);
stmt_text= "select * from t1";
rc= mysql_stmt_prepare(stmt1, "SELECT * FROM t1 ORDER by id ASC" , -1);
check_stmt_rc(rc, stmt1);
rc= mysql_stmt_prepare(stmt2, "SELECT * FROM t1 ORDER by id DESC", -1);
check_stmt_rc(rc, stmt2);
rc= mysql_stmt_execute(stmt1);
check_stmt_rc(rc, stmt1);
rc= mysql_stmt_execute(stmt2);
check_stmt_rc(rc, stmt2);
memset(my_bind, '\0', sizeof(my_bind));
my_bind[0].buffer_type= MYSQL_TYPE_LONG;
my_bind[0].buffer= (void*) &a;
my_bind[0].buffer_length= sizeof(a);
mysql_stmt_bind_result(stmt1, my_bind);
mysql_stmt_bind_result(stmt2, my_bind);
while ((rc= mysql_stmt_fetch(stmt1)) == 0)
{
diag("a=%d", a);
++num_rows;
}
FAIL_UNLESS(num_rows == 9, "num_rows != 9");
diag("---------------");
num_rows= 0;
while ((rc= mysql_stmt_fetch(stmt2)) == 0)
{
diag("a=%d", a);
++num_rows;
}
FAIL_UNLESS(num_rows == 9, "num_rows != 9");
rc= mysql_stmt_close(stmt1);
rc= mysql_stmt_close(stmt2);
FAIL_UNLESS(rc == 0, "");
rc= mysql_query(mysql, "drop table t1");
check_mysql_rc(rc, mysql);
return OK;
}
struct my_tests_st my_tests[] = {
{"test_conc198", test_conc198, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
{"test_conc182", test_conc182, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
{"test_conc181", test_conc181, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
{"test_conc179", test_conc179, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},