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:
119
sql/sql_class.cc
119
sql/sql_class.cc
@ -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);
|
||||
|
Reference in New Issue
Block a user