~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/session.cc

This patch significantly reworks the way that
savepoints are handled:

1) Memory management

   Removes the trans_prealloc_size and trans_block_size
   variables which set up a separate mem_root for storing
   "savepoint data".  Without the binlog, this separate
   memory root, which by default allocated 1M *for every
   single transaction regardless of whether savepoints
   were used*, was not useful any more.

2) No more DIY linked lists of SAVEPOINT pointers

   The Session::transaction struct used to contain a 
   member "savepoints" which was of type pointer to
   SAVEPOINT.  This has been replaced with an STL
   std::deque<drizzled::NamedSavepoint> and the pointeri and
   linked-list fiddling is gone, replaced with STL conventions.

3) SAVEPOINT struct is now drizzled::NamedSavepoint

   The SAVEPOINT struct has been converted to an STL container-
   safe class called drizzled::NamedSavepoint.

4) RollbackToSavepoint, Savepoint, and ReleaseSavepoint

   RollbackToSavepoint, Savepoint, and ReleaseSavepoint classes
   have had their logic revamped and documented.

5) The innodb.test case had (has?) an error in it

   The innodb.test case was testing a wrong assertion that
   a ROLLBACK TO SAVEPOINT x; should result in an error if
   called twice in a row.  This is incorrect behaviour.  If
   a ROLLBACK TO SAVEPOINT x; is executed, the savepoint x
   should stay on the top of the savepoint stack.

6) XID and XID_STATE classes made STL-container-safe

   Places proper initializer lists and constructors for
   the XID and XID_STATE classes and removes use of the
   horrible memset(this, 0, sizeof(*this)); usage.

7) The various savepoint-handling routines use references

   A switch was made to the various savepoint-handling routines
   of TransactionServices to ensure only references to a 
   drizzled::NamedSavepoint were being passed, and not void pointers.

Show diffs side-by-side

added added

removed removed

Lines of Context:
231
231
  query_length= 0;
232
232
  warn_query_id= 0;
233
233
  memset(ha_data, 0, sizeof(ha_data));
234
 
  replication_data= 0;
235
234
  mysys_var= 0;
236
235
  dbug_sentry=Session_SENTRY_MAGIC;
237
236
  cleanup_done= abort_on_warning= no_warnings_for_error= false;
408
407
  plugin_sessionvar_cleanup(this);
409
408
 
410
409
  free_root(&warn_root,MYF(0));
411
 
  free_root(&transaction.mem_root,MYF(0));
412
410
  mysys_var=0;                                  // Safety (shouldn't be needed)
413
411
  dbug_sentry= Session_SENTRY_GONE;
414
412
 
563
561
 
564
562
  reset_root_defaults(mem_root, variables.query_alloc_block_size,
565
563
                      variables.query_prealloc_size);
566
 
  reset_root_defaults(&transaction.mem_root,
567
 
                      variables.trans_alloc_block_size,
568
 
                      variables.trans_prealloc_size);
569
564
  transaction.xid_state.xid.null();
570
565
  transaction.xid_state.in_session=1;
571
566
}
928
923
  return lex_str;
929
924
}
930
925
 
931
 
/* routings to adding tables to list of changed in transaction tables */
932
 
inline static void list_include(CHANGED_TableList** prev,
933
 
                                CHANGED_TableList* curr,
934
 
                                CHANGED_TableList* new_table)
935
 
{
936
 
  if (new_table)
937
 
  {
938
 
    *prev = new_table;
939
 
    (*prev)->next = curr;
940
 
  }
941
 
}
942
 
 
943
 
/* add table to list of changed in transaction tables */
944
 
 
945
 
void Session::add_changed_table(Table *table)
946
 
{
947
 
  assert((options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) &&
948
 
              table->cursor->has_transactions());
949
 
  add_changed_table(table->s->table_cache_key.str,
950
 
                    (long) table->s->table_cache_key.length);
951
 
}
952
 
 
953
 
 
954
 
void Session::add_changed_table(const char *key, long key_length)
955
 
{
956
 
  CHANGED_TableList **prev_changed = &transaction.changed_tables;
957
 
  CHANGED_TableList *curr = transaction.changed_tables;
958
 
 
959
 
  for (; curr; prev_changed = &(curr->next), curr = curr->next)
960
 
  {
961
 
    int cmp =  (long)curr->key_length - (long)key_length;
962
 
    if (cmp < 0)
963
 
    {
964
 
      list_include(prev_changed, curr, changed_table_dup(key, key_length));
965
 
      return;
966
 
    }
967
 
    else if (cmp == 0)
968
 
    {
969
 
      cmp = memcmp(curr->key, key, curr->key_length);
970
 
      if (cmp < 0)
971
 
      {
972
 
        list_include(prev_changed, curr, changed_table_dup(key, key_length));
973
 
        return;
974
 
      }
975
 
      else if (cmp == 0)
976
 
      {
977
 
        return;
978
 
      }
979
 
    }
980
 
  }
981
 
  *prev_changed = changed_table_dup(key, key_length);
982
 
}
983
 
 
984
 
 
985
 
CHANGED_TableList* Session::changed_table_dup(const char *key, long key_length)
986
 
{
987
 
  CHANGED_TableList* new_table =
988
 
    (CHANGED_TableList*) trans_alloc(ALIGN_SIZE(sizeof(CHANGED_TableList))+
989
 
                                      key_length + 1);
990
 
  if (!new_table)
991
 
  {
992
 
    my_error(EE_OUTOFMEMORY, MYF(ME_BELL),
993
 
             ALIGN_SIZE(sizeof(TableList)) + key_length + 1);
994
 
    killed= KILL_CONNECTION;
995
 
    return 0;
996
 
  }
997
 
 
998
 
  new_table->key= ((char*)new_table)+ ALIGN_SIZE(sizeof(CHANGED_TableList));
999
 
  new_table->next = 0;
1000
 
  new_table->key_length = key_length;
1001
 
  ::memcpy(new_table->key, key, key_length);
1002
 
  return new_table;
1003
 
}
1004
 
 
1005
 
 
1006
926
int Session::send_explain_fields(select_result *result)
1007
927
{
1008
928
  List<Item> field_list;