~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_base.cc

Merged Drizzle's Trunk.

Show diffs side-by-side

added added

removed removed

Lines of Context:
141
141
 
142
142
void close_handle_and_leave_table_as_lock(Table *table)
143
143
{
144
 
  TableShare *share, *old_share= table->s;
 
144
  TableShare *share, *old_share= table->getMutableShare();
145
145
 
146
146
  assert(table->db_stat);
147
147
 
155
155
 
156
156
  table->cursor->close();
157
157
  table->db_stat= 0;                            // Mark cursor closed
158
 
  TableShare::release(table->s);
159
 
  table->s= share;
160
 
  table->cursor->change_table_ptr(table, table->s);
 
158
  TableShare::release(table->getMutableShare());
 
159
  table->setShare(share);
 
160
  table->cursor->change_table_ptr(table, table->getMutableShare());
161
161
}
162
162
 
163
163
 
377
377
        global read lock won't sneak in.
378
378
      */
379
379
      if (table->reginfo.lock_type < TL_WRITE_ALLOW_WRITE)
380
 
        table->s->version= refresh_version;
 
380
        table->getMutableShare()->refreshVersion();
381
381
    }
382
382
  }
383
383
 
662
662
    {
663
663
      if (identifier.compare(table->getShare()->getSchemaName(), table->getShare()->getTableName()))
664
664
      {
665
 
        table_proto.CopyFrom(*(table->s->getTableProto()));
 
665
        table_proto.CopyFrom(*(table->getShare()->getTableProto()));
666
666
 
667
667
        return EEXIST;
668
668
      }
847
847
 
848
848
void Session::drop_open_table(Table *table, TableIdentifier &identifier)
849
849
{
850
 
  if (table->s->tmp_table)
 
850
  if (table->getShare()->tmp_table)
851
851
  {
852
852
    close_temporary_table(table);
853
853
  }
945
945
  orig_table= *table;
946
946
 
947
947
  if (open_unireg_entry(this, table, table_name,
948
 
                        const_cast<char *>(table->s->getCacheKey()),
949
 
                        table->s->getCacheKeySize()))
 
948
                        const_cast<char *>(table->getMutableShare()->getCacheKey()),
 
949
                        table->getShare()->getCacheKeySize()))
950
950
  {
951
951
    table->intern_close_table();
952
952
    /*
959
959
    return true;
960
960
  }
961
961
 
962
 
  share= table->s;
 
962
  share= table->getMutableShare();
963
963
  /*
964
964
    We want to prevent other connections from opening this table until end
965
965
    of statement as it is likely that modifications of table's metadata are
968
968
    This also allows us to assume that no other connection will sneak in
969
969
    before we will get table-level lock on this table.
970
970
  */
971
 
  share->version=0;
 
971
  share->resetVersion();
972
972
  table->in_use = this;
973
973
 
974
974
  if (link_in)
1158
1158
  */
1159
1159
  for (table= temporary_tables; table ; table=table->next)
1160
1160
  {
1161
 
    if (table->s->getCacheKeySize() == key_length && !memcmp(table->s->getCacheKey(), key, key_length))
 
1161
    if (table->getShare()->getCacheKeySize() == key_length && !memcmp(table->getMutableShare()->getCacheKey(), key, key_length))
1162
1162
    {
1163
1163
      /*
1164
1164
        We're trying to use the same temporary table twice in a query.
1219
1219
    Now we should:
1220
1220
    - try to find the table in the table cache.
1221
1221
    - if one of the discovered Table instances is name-locked
1222
 
    (table->s->version == 0) back off -- we have to wait
 
1222
    (table->getShare()->version == 0) back off -- we have to wait
1223
1223
    until no one holds a name lock on the table.
1224
1224
    - if there is no such Table in the name cache, read the table definition
1225
1225
    and insert it into the cache.
1248
1248
  {
1249
1249
    /*
1250
1250
      Here we flush tables marked for flush.
1251
 
      Normally, table->s->version contains the value of
 
1251
      Normally, table->getShare()->version contains the value of
1252
1252
      refresh_version from the moment when this table was
1253
1253
      (re-)opened and added to the cache.
1254
1254
      If since then we did (or just started) FLUSH TABLES
1255
1255
      statement, refresh_version has been increased.
1256
 
      For "name-locked" Table instances, table->s->version is set
 
1256
      For "name-locked" Table instances, table->getShare()->version is set
1257
1257
      to 0 (see lock_table_name for details).
1258
1258
      In case there is a pending FLUSH TABLES or a name lock, we
1259
1259
      need to back off and re-start opening tables.
1269
1269
      if (flags & DRIZZLE_LOCK_IGNORE_FLUSH)
1270
1270
      {
1271
1271
        /* Force close at once after usage */
1272
 
        version= table->s->version;
 
1272
        version= table->getShare()->getVersion();
1273
1273
        continue;
1274
1274
      }
1275
1275
 
1277
1277
      if (table->open_placeholder && table->in_use == this)
1278
1278
      {
1279
1279
        pthread_mutex_unlock(&LOCK_open);
1280
 
        my_error(ER_UPDATE_TABLE_USED, MYF(0), table->s->getTableName());
 
1280
        my_error(ER_UPDATE_TABLE_USED, MYF(0), table->getMutableShare()->getTableName());
1281
1281
        return NULL;
1282
1282
      }
1283
1283
 
1285
1285
        Back off, part 1: mark the table as "unused" for the
1286
1286
        purpose of name-locking by setting table->db_stat to 0. Do
1287
1287
        that only for the tables in this thread that have an old
1288
 
        table->s->version (this is an optimization (?)).
 
1288
        table->getShare()->version (this is an optimization (?)).
1289
1289
        table->db_stat == 0 signals wait_for_locked_table_names
1290
1290
        that the tables in question are not used any more. See
1291
1291
        table_is_used call for details.
1296
1296
        Back-off part 2: try to avoid "busy waiting" on the table:
1297
1297
        if the table is in use by some other thread, we suspend
1298
1298
        and wait till the operation is complete: when any
1299
 
        operation that juggles with table->s->version completes,
 
1299
        operation that juggles with table->getShare()->version completes,
1300
1300
        it broadcasts COND_refresh condition variable.
1301
1301
        If 'old' table we met is in use by current thread we return
1302
1302
        without waiting since in this situation it's this thread
1403
1403
  table->reginfo.lock_type= TL_READ; /* Assume read */
1404
1404
 
1405
1405
reset:
1406
 
  assert(table->s->ref_count > 0 || table->s->tmp_table != message::Table::STANDARD);
 
1406
  assert(table->getShare()->getTableCount() > 0 || table->getShare()->tmp_table != message::Table::STANDARD);
1407
1407
 
1408
1408
  if (lex->need_correct_ident())
1409
1409
    table->alias_name_used= my_strcasecmp(table_alias_charset,
1410
 
                                          table->s->getTableName(), alias);
 
1410
                                          table->getMutableShare()->getTableName(), alias);
1411
1411
  /* Fix alias if table name changes */
1412
1412
  if (strcmp(table->alias, alias))
1413
1413
  {
1464
1464
  TableList table_list;
1465
1465
  Session *session= table->in_use;
1466
1466
 
1467
 
  assert(table->s->ref_count == 0);
 
1467
  assert(table->getShare()->ref_count == 0);
1468
1468
  assert(!table->sort.io_cache);
1469
1469
 
1470
1470
#ifdef EXTRA_DEBUG
1472
1472
    errmsg_printf(ERRMSG_LVL_ERROR, _("Table %s had a open data Cursor in reopen_table"),
1473
1473
                  table->alias);
1474
1474
#endif
1475
 
  table_list.db=         const_cast<char *>(table->s->getSchemaName());
1476
 
  table_list.table_name= table->s->getTableName();
 
1475
  table_list.db=         const_cast<char *>(table->getShare()->getSchemaName());
 
1476
  table_list.table_name= table->getShare()->getTableName();
1477
1477
  table_list.table=      table;
1478
1478
 
1479
1479
  if (wait_for_locked_table_names(session, &table_list))
1481
1481
 
1482
1482
  if (open_unireg_entry(session, &tmp, &table_list,
1483
1483
                        table->alias,
1484
 
                        table->s->getCacheKey(),
1485
 
                        table->s->getCacheKeySize()))
 
1484
                        table->getShare()->getCacheKey(),
 
1485
                        table->getShare()->getCacheKeySize()))
1486
1486
    goto end;
1487
1487
 
1488
1488
  /* This list copies variables set by open_table */
1514
1514
    (*field)->table= (*field)->orig_table= table;
1515
1515
    (*field)->table_name= &table->alias;
1516
1516
  }
1517
 
  for (key=0 ; key < table->s->keys ; key++)
 
1517
  for (key=0 ; key < table->getShare()->keys ; key++)
1518
1518
  {
1519
1519
    for (part=0 ; part < table->key_info[key].usable_key_parts ; part++)
1520
1520
      table->key_info[key].key_part[part].field->table= table;
1569
1569
  */
1570
1570
  for (table= open_tables; table ; table=table->next)
1571
1571
  {
1572
 
    if (!strcmp(table->s->getTableName(), identifier.getTableName().c_str()) &&
1573
 
        !strcasecmp(table->s->getSchemaName(), identifier.getSchemaName().c_str()))
 
1572
    if (!strcmp(table->getMutableShare()->getTableName(), identifier.getTableName().c_str()) &&
 
1573
        !strcasecmp(table->getMutableShare()->getSchemaName(), identifier.getSchemaName().c_str()))
1574
1574
    {
1575
1575
      table->open_placeholder= true;
1576
1576
      close_handle_and_leave_table_as_lock(table);
1774
1774
{
1775
1775
  do
1776
1776
  {
1777
 
    char *key= const_cast<char *>(table->s->getCacheKey());
1778
 
    uint32_t key_length= table->s->getCacheKeySize();
 
1777
    char *key= const_cast<char *>(table->getMutableShare()->getCacheKey());
 
1778
    uint32_t key_length= table->getShare()->getCacheKeySize();
1779
1779
 
1780
1780
    HASH_SEARCH_STATE state;
1781
1781
    for (Table *search= (Table*) hash_first(&open_cache, (unsigned char*) key,
1858
1858
*/
1859
1859
 
1860
1860
 
1861
 
Table *drop_locked_tables(Session *session,const char *db, const char *table_name)
 
1861
Table *drop_locked_tables(Session *session, const char *db, const char *table_name)
1862
1862
{
1863
1863
  Table *table,*next,**prev, *found= 0;
1864
1864
  prev= &session->open_tables;
1873
1873
  for (table= session->open_tables; table ; table=next)
1874
1874
  {
1875
1875
    next=table->next;
1876
 
    if (!strcmp(table->s->getTableName(), table_name) &&
1877
 
        !strcasecmp(table->s->getSchemaName(), db))
 
1876
    if (!strcmp(table->getMutableShare()->getTableName(), table_name) &&
 
1877
        !strcasecmp(table->getMutableShare()->getSchemaName(), db))
1878
1878
    {
1879
1879
      mysql_lock_remove(session, table);
1880
1880
 
1919
1919
  Table *table;
1920
1920
  for (table= session->open_tables; table ; table= table->next)
1921
1921
  {
1922
 
    if (!strcmp(table->s->getTableName(), table_name) &&
1923
 
        !strcmp(table->s->getSchemaName(), db))
 
1922
    if (!strcmp(table->getMutableShare()->getTableName(), table_name) &&
 
1923
        !strcmp(table->getMutableShare()->getSchemaName(), db))
1924
1924
    {
1925
1925
      /* If MERGE child, forward lock handling to parent. */
1926
1926
      mysql_lock_abort(session, table);
1975
1975
  {
1976
1976
    if (error == 7)                             // Table def changed
1977
1977
    {
1978
 
      share->version= 0;                        // Mark share as old
 
1978
      share->resetVersion();                        // Mark share as old
1979
1979
      if (discover_retry_count++)               // Retry once
1980
1980
        goto err;
1981
1981
 
1998
1998
        To avoid deadlock, only wait for release if no one else is
1999
1999
        using the share.
2000
2000
      */
2001
 
      if (share->ref_count != 1)
 
2001
      if (share->getTableCount() != 1)
2002
2002
        goto err;
2003
2003
      /* Free share and wait until it's released by all threads */
2004
2004
      TableShare::release(share);
2138
2138
    {
2139
2139
      if (tables->lock_type == TL_WRITE_DEFAULT)
2140
2140
        tables->table->reginfo.lock_type= update_lock_default;
2141
 
      else if (tables->table->s->tmp_table == message::Table::STANDARD)
 
2141
      else if (tables->table->getShare()->tmp_table == message::Table::STANDARD)
2142
2142
        tables->table->reginfo.lock_type= tables->lock_type;
2143
2143
    }
2144
2144
  }
2493
2493
  uint32_t cached_field_index= *cached_field_index_ptr;
2494
2494
 
2495
2495
  /* We assume here that table->field < NO_CACHED_FIELD_INDEX = UINT_MAX */
2496
 
  if (cached_field_index < table->s->fields &&
 
2496
  if (cached_field_index < table->getShare()->sizeFields() &&
2497
2497
      !my_strcasecmp(system_charset_info,
2498
 
                     table->field[cached_field_index]->field_name, name))
2499
 
    field_ptr= table->field + cached_field_index;
2500
 
  else if (table->s->name_hash.records)
2501
 
  {
2502
 
    field_ptr= (Field**) hash_search(&table->s->name_hash, (unsigned char*) name,
 
2498
                     table->getField(cached_field_index)->field_name, name))
 
2499
  {
 
2500
    field_ptr= table->getFields() + cached_field_index;
 
2501
  }
 
2502
  else if (table->getShare()->name_hash.records)
 
2503
  {
 
2504
    field_ptr= (Field**) hash_search(&table->getShare()->name_hash, (unsigned char*) name,
2503
2505
                                     length);
2504
2506
    if (field_ptr)
2505
2507
    {
2507
2509
        field_ptr points to field in TableShare. Convert it to the matching
2508
2510
        field in table
2509
2511
      */
2510
 
      field_ptr= (table->field + (field_ptr - table->s->getFields()));
 
2512
      field_ptr= (table->getFields() + table->getShare()->positionFields(field_ptr));
2511
2513
    }
2512
2514
  }
2513
2515
  else
2514
2516
  {
2515
 
    if (!(field_ptr= table->field))
 
2517
    if (!(field_ptr= table->getFields()))
2516
2518
      return((Field *)0);
2517
2519
    for (; *field_ptr; ++field_ptr)
2518
2520
      if (!my_strcasecmp(system_charset_info, (*field_ptr)->field_name, name))
2521
2523
 
2522
2524
  if (field_ptr && *field_ptr)
2523
2525
  {
2524
 
    *cached_field_index_ptr= field_ptr - table->field;
 
2526
    *cached_field_index_ptr= field_ptr - table->getFields();
2525
2527
    field= *field_ptr;
2526
2528
  }
2527
2529
  else
2528
2530
  {
2529
2531
    if (!allow_rowid ||
2530
2532
        my_strcasecmp(system_charset_info, name, "_rowid") ||
2531
 
        table->s->rowid_field_offset == 0)
 
2533
        table->getShare()->rowid_field_offset == 0)
2532
2534
      return((Field*) 0);
2533
 
    field= table->field[table->s->rowid_field_offset-1];
 
2535
    field= table->getField(table->getShare()->rowid_field_offset-1);
2534
2536
  }
2535
2537
 
2536
2538
  update_field_dependencies(session, field, table);
4162
4164
      For NATURAL joins, used_tables is updated in the IF above.
4163
4165
    */
4164
4166
    if (table)
4165
 
      table->used_fields= table->s->fields;
 
4167
      table->used_fields= table->getShare()->sizeFields();
4166
4168
  }
4167
4169
  if (found)
4168
4170
    return false;
4448
4450
  for (uint32_t idx=0 ; idx < open_cache.records ; idx++)
4449
4451
  {
4450
4452
    Table *table=(Table*) hash_element(&open_cache,idx);
4451
 
    if (not schema_identifier.getPath().compare(table->s->getSchemaName()))
 
4453
    if (not schema_identifier.getPath().compare(table->getMutableShare()->getSchemaName()))
4452
4454
    {
4453
 
      table->s->version= 0L;                    /* Free when thread is ready */
 
4455
      table->getMutableShare()->resetVersion();                 /* Free when thread is ready */
4454
4456
      if (not table->in_use)
4455
4457
        relink_unused(table);
4456
4458
    }
4457
4459
  }
4458
 
  while (unused_tables && !unused_tables->s->version)
 
4460
  while (unused_tables && !unused_tables->getShare()->getVersion())
4459
4461
    hash_delete(&open_cache,(unsigned char*) unused_tables);
4460
4462
}
4461
4463
 
4502
4504
    {
4503
4505
      Session *in_use;
4504
4506
 
4505
 
      table->s->version=0L;             /* Free when thread is ready */
 
4507
      table->getMutableShare()->resetVersion();         /* Free when thread is ready */
4506
4508
      if (!(in_use=table->in_use))
4507
4509
      {
4508
4510
        relink_unused(table);
4540
4542
      else
4541
4543
        result= result || (flags & RTFC_OWNED_BY_Session_FLAG);
4542
4544
    }
4543
 
    while (unused_tables && !unused_tables->s->version)
 
4545
    while (unused_tables && !unused_tables->getShare()->getVersion())
4544
4546
      hash_delete(&open_cache,(unsigned char*) unused_tables);
4545
4547
 
4546
4548
    /* Remove table from table definition cache if it's not in use */