mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
A fix and a test case for Bug#10736 "mysql_stmt_attr_set
CURSOR_TYPE_READ_ONLY select within select". The bug was caused by the reset of thd->mem_root to thd->main_mem_root in Item_subselect::exec, which in turn triggered too early free_root() for data which was needed on subsequent fetches from a cursor. This reset also caused a memory leak in stored procedures, as subsequent executions of instructions containing a subselect were allocating memory in thd->main_mem_root, which is not freed until the end of the entire SP, instead of the per-call mem_root, which is freed in the end of execution of the instruction.
This commit is contained in:
@ -13332,6 +13332,64 @@ static void test_bug9992()
|
||||
mysql_close(mysql1);
|
||||
}
|
||||
|
||||
|
||||
/* Bug#10736: cursors and subqueries, memroot management */
|
||||
|
||||
static void test_bug10736()
|
||||
{
|
||||
MYSQL_STMT *stmt;
|
||||
MYSQL_BIND bind[1];
|
||||
char a[21];
|
||||
int rc;
|
||||
const char *stmt_text;
|
||||
int i= 0;
|
||||
ulong type;
|
||||
|
||||
myheader("test_bug10736");
|
||||
|
||||
mysql_query(mysql, "drop table if exists t1");
|
||||
mysql_query(mysql, "create table t1 (id integer not null primary key,"
|
||||
"name VARCHAR(20) NOT NULL)");
|
||||
rc= mysql_query(mysql, "insert into t1 (id, name) values "
|
||||
"(1, 'aaa'), (2, 'bbb'), (3, 'ccc')");
|
||||
myquery(rc);
|
||||
|
||||
stmt= mysql_stmt_init(mysql);
|
||||
|
||||
type= (ulong) CURSOR_TYPE_READ_ONLY;
|
||||
rc= mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*) &type);
|
||||
check_execute(stmt, rc);
|
||||
stmt_text= "select name from t1 where name=(select name from t1 where id=2)";
|
||||
rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
|
||||
check_execute(stmt, rc);
|
||||
|
||||
bzero(bind, sizeof(bind));
|
||||
bind[0].buffer_type= MYSQL_TYPE_STRING;
|
||||
bind[0].buffer= (void*) a;
|
||||
bind[0].buffer_length= sizeof(a);
|
||||
mysql_stmt_bind_result(stmt, bind);
|
||||
|
||||
for (i= 0; i < 3; i++)
|
||||
{
|
||||
int row_no= 0;
|
||||
rc= mysql_stmt_execute(stmt);
|
||||
check_execute(stmt, rc);
|
||||
while ((rc= mysql_stmt_fetch(stmt)) == 0)
|
||||
{
|
||||
if (!opt_silent)
|
||||
printf("%d: %s\n", row_no, a);
|
||||
++row_no;
|
||||
}
|
||||
DIE_UNLESS(rc == MYSQL_NO_DATA);
|
||||
}
|
||||
rc= mysql_stmt_close(stmt);
|
||||
DIE_UNLESS(rc == 0);
|
||||
|
||||
rc= mysql_query(mysql, "drop table t1");
|
||||
myquery(rc);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Read and parse arguments and MySQL options from my.cnf
|
||||
*/
|
||||
@ -13567,6 +13625,7 @@ static struct my_tests_st my_tests[]= {
|
||||
{ "test_bug10729", test_bug10729 },
|
||||
{ "test_bug11111", test_bug11111 },
|
||||
{ "test_bug9992", test_bug9992 },
|
||||
{ "test_bug10736", test_bug10736 },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
|
Reference in New Issue
Block a user