You've already forked mariadb-connector-c
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:
@@ -242,7 +242,7 @@ int mthd_stmt_read_all_rows(MYSQL_STMT *stmt)
|
|||||||
p++;
|
p++;
|
||||||
stmt->upsert_status.warning_count= stmt->mysql->warning_count= uint2korr(p);
|
stmt->upsert_status.warning_count= stmt->mysql->warning_count= uint2korr(p);
|
||||||
p+=2;
|
p+=2;
|
||||||
stmt->mysql->server_status= uint2korr(p);
|
stmt->upsert_status.server_status= stmt->mysql->server_status= uint2korr(p);
|
||||||
stmt->result_cursor= result->data;
|
stmt->result_cursor= result->data;
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
@@ -269,7 +269,7 @@ static int stmt_cursor_fetch(MYSQL_STMT *stmt, uchar **row)
|
|||||||
return(stmt_buffered_fetch(stmt, row));
|
return(stmt_buffered_fetch(stmt, row));
|
||||||
if (stmt->mysql->server_status & SERVER_STATUS_LAST_ROW_SENT)
|
if (stmt->mysql->server_status & SERVER_STATUS_LAST_ROW_SENT)
|
||||||
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->stmt_id);
|
||||||
int4store(buf + STMT_ID_LENGTH, stmt->prefetch_rows);
|
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)
|
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);
|
mysql_stmt_internal_reset(stmt, 1);
|
||||||
|
|
||||||
net_stmt_close(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 */
|
/* reset statement on server side */
|
||||||
if (stmt->mysql && stmt->mysql->status == MYSQL_STATUS_READY &&
|
if (stmt->mysql && stmt->mysql->status == MYSQL_STATUS_READY &&
|
||||||
stmt->mysql->net.pvio)
|
stmt->mysql->net.vio)
|
||||||
{
|
{
|
||||||
unsigned char cmd_buf[STMT_ID_LENGTH];
|
unsigned char cmd_buf[STMT_ID_LENGTH];
|
||||||
int4store(cmd_buf, stmt->stmt_id);
|
int4store(cmd_buf, stmt->stmt_id);
|
||||||
|
@@ -4332,8 +4332,91 @@ static int test_conc181(MYSQL *mysql)
|
|||||||
return OK;
|
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[] = {
|
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_conc182", test_conc182, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
|
||||||
{"test_conc181", test_conc181, 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},
|
{"test_conc179", test_conc179, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
|
||||||
|
Reference in New Issue
Block a user