List:Commits« Previous MessageNext Message »
From:ramil Date:May 24 2006 1:14pm
Subject:bk commit into 4.1 tree (ramil:1.2485)
View as plain text  
Below is the list of changes that have just been committed into a local
4.1 repository of rkalimullin. When rkalimullin does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet
  1.2485 06/05/24 15:14:00 ramil@stripped +1 -0
  Merge rkalimullin@stripped:/home/bk/mysql-4.1
  into  production.mysql.com:/usersnfs/rkalimullin/4.1.b16900

  sql/sql_class.cc
    1.206 06/05/24 15:13:52 ramil@stripped +0 -0
    Auto merged

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	ramil
# Host:	production.mysql.com
# Root:	/usersnfs/rkalimullin/4.1.b16900/RESYNC

--- 1.205/sql/sql_class.cc	2006-02-02 07:27:34 +01:00
+++ 1.206/sql/sql_class.cc	2006-05-24 15:13:52 +02:00
@@ -1617,26 +1617,127 @@
             NULL,MYF(0));
 }
 
-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 rc= my_hash_insert(&st_hash, (byte *) statement);
-  if (rc == 0)
-    last_found_statement= statement;
+  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 there is a statement with the same name, remove it. It is ok to 
+      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 ((rc= my_hash_insert(&names_hash, (byte*)statement)))
-      hash_delete(&st_hash, (byte*)statement);
+      erase(old_stmt);
+    if (my_hash_insert(&names_hash, (byte*) statement))
+    {
+      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 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:
+  send_error(thd);
+  return 1;
+}
+
+
+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);
   }
-  return rc;
+  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)
 {
Thread
bk commit into 4.1 tree (ramil:1.2485)ramil24 May