5.0-bugteam->5.1-bugteam merge

This commit is contained in:
Sergey Glukhov 2008-12-10 18:16:21 +04:00
commit 1ca1439270
3 changed files with 72 additions and 7 deletions

View File

@ -85,6 +85,7 @@ class Materialized_cursor: public Server_side_cursor
List<Item> item_list; List<Item> item_list;
ulong fetch_limit; ulong fetch_limit;
ulong fetch_count; ulong fetch_count;
bool is_rnd_inited;
public: public:
Materialized_cursor(select_result *result, TABLE *table); Materialized_cursor(select_result *result, TABLE *table);
@ -190,7 +191,11 @@ int mysql_open_cursor(THD *thd, uint flags, select_result *result,
such command is SHOW VARIABLES or SHOW STATUS. such command is SHOW VARIABLES or SHOW STATUS.
*/ */
if (rc) if (rc)
{
if (result_materialize->materialized_cursor)
delete result_materialize->materialized_cursor;
goto err_open; goto err_open;
}
if (sensitive_cursor->is_open()) if (sensitive_cursor->is_open())
{ {
@ -542,7 +547,8 @@ Materialized_cursor::Materialized_cursor(select_result *result_arg,
:Server_side_cursor(&table_arg->mem_root, result_arg), :Server_side_cursor(&table_arg->mem_root, result_arg),
table(table_arg), table(table_arg),
fetch_limit(0), fetch_limit(0),
fetch_count(0) fetch_count(0),
is_rnd_inited(0)
{ {
fake_unit.init_query(); fake_unit.init_query();
fake_unit.thd= table->in_use; fake_unit.thd= table->in_use;
@ -599,11 +605,12 @@ int Materialized_cursor::open(JOIN *join __attribute__((unused)))
THD *thd= fake_unit.thd; THD *thd= fake_unit.thd;
int rc; int rc;
Query_arena backup_arena; Query_arena backup_arena;
thd->set_n_backup_active_arena(this, &backup_arena); thd->set_n_backup_active_arena(this, &backup_arena);
/* Create a list of fields and start sequential scan */ /* Create a list of fields and start sequential scan */
rc= (result->prepare(item_list, &fake_unit) || rc= result->prepare(item_list, &fake_unit);
table->file->ha_rnd_init(TRUE)); if (!rc && !(rc= table->file->ha_rnd_init(TRUE)))
is_rnd_inited= 1;
thd->restore_active_arena(this, &backup_arena); thd->restore_active_arena(this, &backup_arena);
if (rc == 0) if (rc == 0)
{ {
@ -678,6 +685,7 @@ void Materialized_cursor::close()
{ {
/* Free item_list items */ /* Free item_list items */
free_items(); free_items();
if (is_rnd_inited)
(void) table->file->ha_rnd_end(); (void) table->file->ha_rnd_end();
/* /*
We need to grab table->mem_root to prevent free_tmp_table from freeing: We need to grab table->mem_root to prevent free_tmp_table from freeing:

View File

@ -1667,8 +1667,11 @@ JOIN::exec()
(zero_result_cause?zero_result_cause:"No tables used")); (zero_result_cause?zero_result_cause:"No tables used"));
else else
{ {
result->send_fields(*columns_list, if (result->send_fields(*columns_list,
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF); Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
{
DBUG_VOID_RETURN;
}
/* /*
We have to test for 'conds' here as the WHERE may not be constant We have to test for 'conds' here as the WHERE may not be constant
even if we don't have any tables for prepared statements or if even if we don't have any tables for prepared statements or if

View File

@ -16552,6 +16552,59 @@ static void test_change_user()
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
/**
Bug#37956 memory leak and / or crash with geometry and prepared statements!
*/
static void test_bug37956(void)
{
const char *query="select point(?,?)";
MYSQL_STMT *stmt=NULL;
unsigned int val=0;
MYSQL_BIND bind_param[2];
unsigned char buff[2]= { 134, 211 };
DBUG_ENTER("test_bug37956");
myheader("test_bug37956");
stmt= mysql_simple_prepare(mysql, query);
check_stmt(stmt);
val=1;
mysql_stmt_attr_set(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, (void *)&val);
val=CURSOR_TYPE_READ_ONLY;
mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void *)&val);
val=0;
mysql_stmt_attr_set(stmt, STMT_ATTR_PREFETCH_ROWS, (void *)&val);
memset(bind_param, 0, sizeof(bind_param));
bind_param[0].buffer_type=MYSQL_TYPE_TINY;
bind_param[0].buffer= (void *)buff;
bind_param[0].is_null=NULL;
bind_param[0].error=NULL;
bind_param[0].is_unsigned=1;
bind_param[1].buffer_type=MYSQL_TYPE_TINY;
bind_param[1].buffer= (void *)(buff+1);
bind_param[1].is_null=NULL;
bind_param[1].error=NULL;
bind_param[1].is_unsigned=1;
if (mysql_stmt_bind_param(stmt, bind_param))
{
mysql_stmt_close(stmt);
DIE_UNLESS(0);
}
if (mysql_stmt_execute(stmt))
{
mysql_stmt_close(stmt);
DBUG_VOID_RETURN;
}
/* Should never reach here: execution returns an error. */
mysql_stmt_close(stmt);
DIE_UNLESS(0);
DBUG_VOID_RETURN;
}
/* /*
Bug#27592 (stack overrun when storing datetime value using prepared statements) Bug#27592 (stack overrun when storing datetime value using prepared statements)
*/ */
@ -17967,6 +18020,7 @@ static struct my_tests_st my_tests[]= {
{ "test_wl4166_2", test_wl4166_2 }, { "test_wl4166_2", test_wl4166_2 },
{ "test_bug38486", test_bug38486 }, { "test_bug38486", test_bug38486 },
{ "test_bug40365", test_bug40365 }, { "test_bug40365", test_bug40365 },
{ "test_bug37956", test_bug37956 },
{ 0, 0 } { 0, 0 }
}; };