1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-29 05:21:33 +03:00

Merge mysql.com:/opt/local/work/mysql-4.1-16365

into  mysql.com:/opt/local/work/mysql-5.0-merge
This commit is contained in:
konstantin@mysql.com
2006-04-12 18:30:54 +04:00
10 changed files with 397 additions and 51 deletions

View File

@ -1724,21 +1724,81 @@ Statement_map::Statement_map() :
}
int Statement_map::insert(Statement *statement)
/*
Insert a new statement to the thread-local statement map.
DESCRIPTION
If there was an old statement with the same name, replace it with the
new one. Otherwise, check if max_prepared_stmt_count is not reached yet,
increase prepared_stmt_count, and insert the new statement. It's okay
to delete an old statement and fail to insert the new one.
POSTCONDITIONS
All named prepared statements are also present in names_hash.
Statement names in names_hash are unique.
The statement is added only if prepared_stmt_count < max_prepard_stmt_count
last_found_statement always points to a valid statement or is 0
RETURN VALUE
0 success
1 error: out of resources or max_prepared_stmt_count limit has been
reached. An error is sent to the client, the statement is deleted.
*/
int Statement_map::insert(THD *thd, Statement *statement)
{
int res= my_hash_insert(&st_hash, (byte *) statement);
if (res)
return res;
if (my_hash_insert(&st_hash, (byte*) statement))
{
/*
Delete is needed only in case of an insert failure. In all other
cases hash_delete will also delete the statement.
*/
delete statement;
my_error(ER_OUT_OF_RESOURCES, MYF(0));
goto err_st_hash;
}
if (statement->name.str)
{
if ((res= my_hash_insert(&names_hash, (byte*)statement)))
/*
If there is a statement with the same name, remove it. It is ok to
remove old and fail to insert new one at the same time.
*/
Statement *old_stmt;
if ((old_stmt= find_by_name(&statement->name)))
erase(old_stmt);
if (my_hash_insert(&names_hash, (byte*) statement))
{
hash_delete(&st_hash, (byte*)statement);
return res;
my_error(ER_OUT_OF_RESOURCES, MYF(0));
goto err_names_hash;
}
}
pthread_mutex_lock(&LOCK_prepared_stmt_count);
/*
We don't check that prepared_stmt_count is <= max_prepared_stmt_count
because we would like to allow to lower the total limit
of prepared statements below the current count. In that case
no new statements can be added until prepared_stmt_count drops below
the limit.
*/
if (prepared_stmt_count >= max_prepared_stmt_count)
{
pthread_mutex_unlock(&LOCK_prepared_stmt_count);
my_error(ER_UNKNOWN_ERROR, MYF(0));
goto err_max;
}
prepared_stmt_count++;
pthread_mutex_unlock(&LOCK_prepared_stmt_count);
last_found_statement= statement;
return res;
return 0;
err_max:
if (statement->name.str)
hash_delete(&names_hash, (byte*) statement);
err_names_hash:
hash_delete(&st_hash, (byte*) statement);
err_st_hash:
return 1;
}
@ -1752,6 +1812,49 @@ void Statement_map::close_transient_cursors()
}
void Statement_map::erase(Statement *statement)
{
if (statement == last_found_statement)
last_found_statement= 0;
if (statement->name.str)
{
hash_delete(&names_hash, (byte *) statement);
}
hash_delete(&st_hash, (byte *) statement);
pthread_mutex_lock(&LOCK_prepared_stmt_count);
DBUG_ASSERT(prepared_stmt_count > 0);
prepared_stmt_count--;
pthread_mutex_unlock(&LOCK_prepared_stmt_count);
}
void Statement_map::reset()
{
/* Must be first, hash_free will reset st_hash.records */
pthread_mutex_lock(&LOCK_prepared_stmt_count);
DBUG_ASSERT(prepared_stmt_count >= st_hash.records);
prepared_stmt_count-= st_hash.records;
pthread_mutex_unlock(&LOCK_prepared_stmt_count);
my_hash_reset(&names_hash);
my_hash_reset(&st_hash);
last_found_statement= 0;
}
Statement_map::~Statement_map()
{
/* Must go first, hash_free will reset st_hash.records */
pthread_mutex_lock(&LOCK_prepared_stmt_count);
DBUG_ASSERT(prepared_stmt_count >= st_hash.records);
prepared_stmt_count-= st_hash.records;
pthread_mutex_unlock(&LOCK_prepared_stmt_count);
hash_free(&names_hash);
hash_free(&st_hash);
}
bool select_dumpvar::send_data(List<Item> &items)
{
List_iterator_fast<Item_func_set_user_var> li(vars);