~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_base.cc

  • Committer: Brian Aker
  • Date: 2010-06-15 13:37:26 UTC
  • Revision ID: brian@gaz-20100615133726-160z0ql8gxi8s3rg
This is a rollup set of patches for modifications to TableIdentifier to have
a getKey() which is now used for open_cache and table_share_def cache. This
also includes additional unittests on TableIdentifier, and makes use of some
cleanup, though not perfect, to TableShare for its contructors.

Show diffs side-by-side

added added

removed removed

Lines of Context:
71
71
static int open_unireg_entry(Session *session,
72
72
                             Table *entry,
73
73
                             const char *alias,
74
 
                             char *cache_key, uint32_t cache_key_length);
 
74
                             TableIdentifier &identifier);
75
75
void free_cache_entry(void *entry);
76
76
unsigned char *table_cache_key(const unsigned char *record,
77
77
                               size_t *length,
150
150
    This has to be done to ensure that the table share is removed from
151
151
    the table defintion cache as soon as the last instance is removed
152
152
  */
153
 
  share= new TableShare(message::Table::INTERNAL, const_cast<char *>(old_share->getCacheKey()),  static_cast<uint32_t>(old_share->getCacheKeySize()));
 
153
  TableIdentifier identifier(table->getShare()->getSchemaName(), table->getShare()->getTableName(), message::Table::INTERNAL);
 
154
  share= new TableShare(identifier.getType(),
 
155
                        identifier,
 
156
                        const_cast<char *>(old_share->getCacheKey()),  static_cast<uint32_t>(old_share->getCacheKeySize()));
154
157
 
155
158
  table->cursor->close();
156
159
  table->db_stat= 0;                            // Mark cursor closed
307
310
    bool found= false;
308
311
    for (TableList *table= tables; table; table= table->next_local)
309
312
    {
310
 
      if (remove_table_from_cache(session, table->db, table->table_name,
 
313
      TableIdentifier identifier(table->db, table->table_name);
 
314
      if (remove_table_from_cache(session, identifier,
311
315
                                  RTFC_OWNED_BY_Session_FLAG))
 
316
      {
312
317
        found= true;
 
318
      }
313
319
    }
314
320
    if (!found)
315
321
      wait_for_refresh= false;                  // Nothing to wait for
677
683
  char  key[MAX_DBKEY_LENGTH];
678
684
  uint  key_length;
679
685
 
680
 
  key_length= TableShare::createKey(key, new_db, table_name);
 
686
  key_length= TableIdentifier::createKey(key, new_db, table_name);
681
687
 
682
688
  for (Table *table= temporary_tables ; table ; table= table->getNext())
683
689
  {
697
703
 
698
704
Table *Session::find_temporary_table(TableIdentifier &identifier)
699
705
{
700
 
  char  key[MAX_DBKEY_LENGTH];
701
 
  uint  key_length;
702
 
 
703
 
  key_length= TableShare::createKey(key, identifier);
 
706
  const TableIdentifier::Key &key(identifier.getKey());
704
707
 
705
708
  for (Table *table= temporary_tables ; table ; table= table->getNext())
706
709
  {
707
 
    if (table->getShare()->getCacheKeySize() == key_length &&
708
 
        not memcmp(table->getMutableShare()->getCacheKey(), key, key_length))
 
710
    if (table->getShare()->getCacheKeySize() == key.size() &&
 
711
        not memcmp(table->getMutableShare()->getCacheKey(), &key[0], key.size()))
709
712
 
710
713
      return table;
711
714
  }
944
947
 
945
948
  orig_table= *table;
946
949
 
947
 
  if (open_unireg_entry(this, table, table_name,
948
 
                        const_cast<char *>(table->getMutableShare()->getCacheKey()),
949
 
                        table->getShare()->getCacheKeySize()))
 
950
  TableIdentifier identifier(table_list->db, table_list->table_name);
 
951
  if (open_unireg_entry(this, table, table_name, identifier))
950
952
  {
951
953
    table->intern_close_table();
952
954
    /*
1010
1012
  case of failure.
1011
1013
*/
1012
1014
 
1013
 
Table *Session::table_cache_insert_placeholder(const char *key, uint32_t key_length)
 
1015
Table *Session::table_cache_insert_placeholder(const char *db_name, const char *table_name, const char *, uint32_t)
1014
1016
{
1015
1017
  safe_mutex_assert_owner(&LOCK_open);
1016
1018
 
1019
1021
    Note that we must use multi_malloc() here as this is freed by the
1020
1022
    table cache
1021
1023
  */
1022
 
  TablePlaceholder *table= new TablePlaceholder(key, key_length);
1023
 
  table->in_use= this;
 
1024
  TableIdentifier identifier(db_name, table_name, message::Table::INTERNAL);
 
1025
  TablePlaceholder *table= new TablePlaceholder(this, identifier);
1024
1026
 
1025
1027
  if (my_hash_insert(&open_cache, (unsigned char*)table))
1026
1028
  {
1063
1065
                                            const char *table_name, Table **table)
1064
1066
{
1065
1067
  char key[MAX_DBKEY_LENGTH];
1066
 
  char *key_pos= key;
1067
1068
  uint32_t key_length;
1068
1069
 
1069
 
  key_pos= strcpy(key_pos, new_db) + strlen(new_db);
1070
 
  key_pos= strcpy(key_pos+1, table_name) + strlen(table_name);
1071
 
  key_length= (uint32_t) (key_pos-key)+1;
 
1070
  key_length= TableIdentifier::createKey(key, new_db, table_name);
1072
1071
 
1073
1072
  pthread_mutex_lock(&LOCK_open); /* Obtain a name lock even though table is not in cache (like for create table)  */
1074
1073
 
1079
1078
    return false;
1080
1079
  }
1081
1080
 
1082
 
  if (not (*table= table_cache_insert_placeholder(key, key_length)))
 
1081
  if (not (*table= table_cache_insert_placeholder(new_db, table_name, key, key_length)))
1083
1082
  {
1084
1083
    pthread_mutex_unlock(&LOCK_open);
1085
1084
    return true;
1128
1127
Table *Session::openTable(TableList *table_list, bool *refresh, uint32_t flags)
1129
1128
{
1130
1129
  Table *table;
1131
 
  char key[MAX_DBKEY_LENGTH];
1132
1130
  unsigned int key_length;
1133
1131
  const char *alias= table_list->alias;
1134
1132
  HASH_SEARCH_STATE state;
1147
1145
  if (killed)
1148
1146
    return NULL;
1149
1147
 
1150
 
  key_length= table_list->create_table_def_key(key);
 
1148
  TableIdentifier identifier(table_list->db, table_list->table_name);
 
1149
  const TableIdentifier::Key &key(identifier.getKey());
 
1150
  key_length= key.size();
1151
1151
 
1152
1152
  /*
1153
1153
    Unless requested otherwise, try to resolve this table in the list
1158
1158
  */
1159
1159
  for (table= temporary_tables; table ; table=table->getNext())
1160
1160
  {
1161
 
    if (table->getShare()->getCacheKeySize() == key_length && !memcmp(table->getMutableShare()->getCacheKey(), key, key_length))
 
1161
    if (table->getShare()->getCacheKeySize() == key_length && !memcmp(table->getMutableShare()->getCacheKey(), &key[0], key_length))
1162
1162
    {
1163
1163
      /*
1164
1164
        We're trying to use the same temporary table twice in a query.
1240
1240
    an implicit "pending locks queue" - see
1241
1241
    wait_for_locked_table_names for details.
1242
1242
  */
1243
 
  for (table= (Table*) hash_first(&open_cache, (unsigned char*) key, key_length,
 
1243
  for (table= (Table*) hash_first(&open_cache, (unsigned char*) &key[0], key_length,
1244
1244
                                  &state);
1245
1245
       table && table->in_use ;
1246
 
       table= (Table*) hash_next(&open_cache, (unsigned char*) key, key_length,
 
1246
       table= (Table*) hash_next(&open_cache, (unsigned char*) &key[0], key_length,
1247
1247
                                 &state))
1248
1248
  {
1249
1249
    /*
1355
1355
        /*
1356
1356
          Table to be created, so we need to create placeholder in table-cache.
1357
1357
        */
1358
 
        if (!(table= table_cache_insert_placeholder(key, key_length)))
 
1358
        if (!(table= table_cache_insert_placeholder(table_list->db, table_list->table_name, &key[0], key_length)))
1359
1359
        {
1360
1360
          pthread_mutex_unlock(&LOCK_open);
1361
1361
          return NULL;
1384
1384
      return NULL;
1385
1385
    }
1386
1386
 
1387
 
    error= open_unireg_entry(this, table, alias, key, key_length);
 
1387
    error= open_unireg_entry(this, table, alias, identifier);
1388
1388
    if (error != 0)
1389
1389
    {
1390
1390
      free(table);
1955
1955
static int open_unireg_entry(Session *session,
1956
1956
                             Table *entry,
1957
1957
                             const char *alias,
1958
 
                             char *cache_key, uint32_t cache_key_length)
 
1958
                             TableIdentifier &identifier)
1959
1959
{
1960
1960
  int error;
1961
1961
  TableShare *share;
1963
1963
 
1964
1964
  safe_mutex_assert_owner(&LOCK_open);
1965
1965
retry:
1966
 
  if (not (share= TableShare::getShare(session, cache_key,
1967
 
                                       cache_key_length,
1968
 
                                       &error)))
 
1966
  if (not (share= TableShare::getShareCreate(session,
 
1967
                                             identifier,
 
1968
                                             &error)))
1969
1969
    return 1;
1970
1970
 
1971
1971
  while ((error= share->open_table_from_share(session, alias,
2300
2300
{
2301
2301
  Table *new_tmp_table;
2302
2302
  TableShare *share;
2303
 
  char cache_key[MAX_DBKEY_LENGTH];
2304
 
  uint32_t key_length;
2305
 
 
2306
 
  /* Create the cache_key for temporary tables */
2307
 
  key_length= TableShare::createKey(cache_key, const_cast<char*>(identifier.getSchemaName().c_str()),
2308
 
                                    const_cast<char*>(identifier.getTableName().c_str()));
2309
 
 
2310
 
  share= new TableShare(message::Table::TEMPORARY, cache_key, key_length,
 
2303
 
 
2304
  assert(identifier.isTmp());
 
2305
  share= new TableShare(identifier.getType(),
 
2306
                        identifier,
2311
2307
                        const_cast<char *>(identifier.getPath().c_str()), static_cast<uint32_t>(identifier.getPath().length()));
2312
2308
 
 
2309
 
2313
2310
  if (!(new_tmp_table= (Table*) malloc(sizeof(*new_tmp_table))))
2314
2311
    return NULL;
2315
2312
 
4481
4478
  1  Table is in use by another thread
4482
4479
*/
4483
4480
 
4484
 
bool remove_table_from_cache(Session *session, const char *db, const char *table_name,
4485
 
                             uint32_t flags)
 
4481
bool remove_table_from_cache(Session *session, TableIdentifier &identifier, uint32_t flags)
4486
4482
{
4487
 
  char key[MAX_DBKEY_LENGTH];
4488
 
  char *key_pos= key;
4489
 
  uint32_t key_length;
4490
 
  Table *table;
 
4483
  const TableIdentifier::Key &key(identifier.getKey());
4491
4484
  bool result= false; 
4492
4485
  bool signalled= false;
4493
4486
 
4494
 
  key_pos= strcpy(key_pos, db) + strlen(db);
4495
 
  key_pos= strcpy(key_pos+1, table_name) + strlen(table_name);
4496
 
  key_length= (uint32_t) (key_pos-key)+1;
 
4487
  uint32_t key_length= key.size();
4497
4488
 
4498
4489
  for (;;)
4499
4490
  {
4500
4491
    HASH_SEARCH_STATE state;
 
4492
    Table *table;
4501
4493
    result= signalled= false;
4502
4494
 
4503
 
    for (table= (Table*) hash_first(&open_cache, (unsigned char*) key, key_length,
 
4495
    for (table= (Table*) hash_first(&open_cache, (unsigned char*) &key[0], key_length,
4504
4496
                                    &state);
4505
4497
         table;
4506
 
         table= (Table*) hash_next(&open_cache, (unsigned char*) key, key_length,
 
4498
         table= (Table*) hash_next(&open_cache, (unsigned char*) &key[0], key_length,
4507
4499
                                   &state))
4508
4500
    {
4509
4501
      Session *in_use;
4550
4542
      hash_delete(&open_cache,(unsigned char*) unused_tables);
4551
4543
 
4552
4544
    /* Remove table from table definition cache if it's not in use */
4553
 
    TableShare::release(key, key_length);
 
4545
    TableShare::release(identifier);
4554
4546
 
4555
4547
    if (result && (flags & RTFC_WAIT_OTHER_THREAD_FLAG))
4556
4548
    {
4586
4578
    }
4587
4579
    break;
4588
4580
  }
 
4581
 
4589
4582
  return result;
4590
4583
}
4591
4584