~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_base.cc

  • Committer: Brian Aker
  • Date: 2010-10-20 20:26:18 UTC
  • mfrom: (1859.2.13 refactor)
  • Revision ID: brian@tangent.org-20101020202618-9222n39lm329urv5
Merge for Brian 

Show diffs side-by-side

added added

removed removed

Lines of Context:
70
70
  return open_cache;
71
71
}
72
72
 
73
 
static void free_cache_entry(Table *entry);
 
73
static void free_cache_entry(table::Concurrent *entry);
74
74
 
75
 
void remove_table(Table *arg)
 
75
void remove_table(table::Concurrent *arg)
76
76
{
77
77
  TableOpenCacheRange ppp;
78
78
  ppp= get_open_cache().equal_range(arg->getShare()->getCacheKey());
80
80
  for (TableOpenCache::const_iterator iter= ppp.first;
81
81
         iter != ppp.second; ++iter)
82
82
  {
83
 
    Table *found_table= (*iter).second;
 
83
    table::Concurrent *found_table= (*iter).second;
84
84
 
85
85
    if (found_table == arg)
86
86
    {
91
91
  }
92
92
}
93
93
 
94
 
static bool add_table(Table *arg)
 
94
static bool add_table(table::Concurrent *arg)
95
95
{
96
96
  TableOpenCache &open_cache(get_open_cache());
97
97
 
101
101
}
102
102
 
103
103
class UnusedTables {
104
 
  Table *tables;                                /* Used by mysql_test */
 
104
  table::Concurrent *tables;                            /* Used by mysql_test */
105
105
 
106
 
  Table *getTable() const
 
106
  table::Concurrent *getTable() const
107
107
  {
108
108
    return tables;
109
109
  }
110
110
 
111
 
  Table *setTable(Table *arg)
 
111
  table::Concurrent *setTable(Table *arg)
112
112
  {
113
 
    return tables= arg;
 
113
    return tables= dynamic_cast<table::Concurrent *>(arg);
114
114
  }
115
115
 
116
116
public:
128
128
      remove_table(getTable());
129
129
  }
130
130
  
131
 
  void link(Table *table)
 
131
  void link(table::Concurrent *table)
132
132
  {
133
133
    if (getTable())
134
134
    {
146
146
  }
147
147
 
148
148
 
149
 
  void unlink(Table *table)
 
149
  void unlink(table::Concurrent *table)
150
150
  {
151
151
    table->unlink();
152
152
 
161
161
 
162
162
/* move table first in unused links */
163
163
 
164
 
  void relink(Table *table)
 
164
  void relink(table::Concurrent *table)
165
165
  {
166
166
    if (table != getTable())
167
167
    {
295
295
  We need to have a lock on LOCK_open when calling this
296
296
*/
297
297
 
298
 
void free_cache_entry(Table *table)
 
298
void free_cache_entry(table::Concurrent *table)
299
299
{
300
300
  table->intern_close_table();
301
301
  if (not table->in_use)
504
504
bool Session::free_cached_table()
505
505
{
506
506
  bool found_old_table= false;
507
 
  Table *table= open_tables;
 
507
  table::Concurrent *table= dynamic_cast<table::Concurrent *>(open_tables);
508
508
 
509
509
  safe_mutex_assert_owner(LOCK_open.native_handle());
510
510
  assert(table->key_read == 0);
849
849
 
850
850
  @param  session     Thread context
851
851
  @param  find    Table to remove
 
852
 
 
853
  @note because we risk the chance of deleting the share, we can't assume that it will exist past, this should be modified once we can use a TableSharePtr here.
852
854
*/
853
855
 
854
856
void Session::unlink_open_table(Table *find)
855
857
{
856
 
  char key[MAX_DBKEY_LENGTH];
857
 
  uint32_t key_length= find->getShare()->getCacheKeySize();
858
 
  Table *list, **prev;
 
858
  const TableIdentifier::Key find_key(find->getShare()->getCacheKey());
 
859
  Table **prev;
859
860
  safe_mutex_assert_owner(LOCK_open.native_handle());
860
861
 
861
 
  memcpy(key, &find->getShare()->getCacheKey()[0], key_length);
862
862
  /*
863
863
    Note that we need to hold LOCK_open while changing the
864
864
    open_tables list. Another thread may work on it.
868
868
  */
869
869
  for (prev= &open_tables; *prev; )
870
870
  {
871
 
    list= *prev;
 
871
    Table *list= *prev;
872
872
 
873
 
    if (list->getShare()->getCacheKeySize() == key_length &&
874
 
        not memcmp(&list->getShare()->getCacheKey()[0], key, key_length))
 
873
    if (list->getShare()->getCacheKey() == find_key)
875
874
    {
876
875
      /* Remove table from open_tables list. */
877
876
      *prev= list->getNext();
878
877
 
879
878
      /* Close table. */
880
 
      remove_table(list);
 
879
      remove_table(dynamic_cast<table::Concurrent *>(list));
881
880
    }
882
881
    else
883
882
    {
995
994
  true  - Error
996
995
*/
997
996
 
998
 
bool Session::reopen_name_locked_table(TableList* table_list, bool link_in)
 
997
bool Session::reopen_name_locked_table(TableList* table_list)
999
998
{
1000
999
  Table *table= table_list->table;
1001
1000
  char *table_name= table_list->table_name;
1002
 
  Table orig_table;
1003
1001
 
1004
1002
  safe_mutex_assert_owner(LOCK_open.native_handle());
1005
1003
 
1006
 
  if (killed || !table)
 
1004
  if (killed || not table)
1007
1005
    return true;
1008
1006
 
1009
 
  orig_table= *table;
1010
 
 
1011
1007
  TableIdentifier identifier(table_list->db, table_list->table_name);
1012
1008
  if (open_unireg_entry(this, table, table_name, identifier))
1013
1009
  {
1014
1010
    table->intern_close_table();
1015
 
    /*
1016
 
      If there was an error during opening of table (for example if it
1017
 
      does not exist) '*table' object can be wiped out. To be able
1018
 
      properly release name-lock in this case we should restore this
1019
 
      object to its original state.
1020
 
    */
1021
 
    *table= orig_table;
1022
1011
    return true;
1023
1012
  }
1024
1013
 
1033
1022
  table->getMutableShare()->resetVersion();
1034
1023
  table->in_use = this;
1035
1024
 
1036
 
  if (link_in)
1037
 
  {
1038
 
    table->setNext(open_tables);
1039
 
    open_tables= table;
1040
 
  }
1041
 
  else
1042
 
  {
1043
 
    /*
1044
 
      Table object should be already in Session::open_tables list so we just
1045
 
      need to set Table::next correctly.
1046
 
    */
1047
 
    table->setNext(orig_table.getNext());
1048
 
  }
1049
 
 
1050
1025
  table->tablenr= current_tablenr++;
1051
1026
  table->used_fields= 0;
1052
1027
  table->const_table= 0;
1384
1359
      }
1385
1360
      if (table)
1386
1361
      {
1387
 
        unused_tables.unlink(table);
 
1362
        unused_tables.unlink(dynamic_cast<table::Concurrent *>(table));
1388
1363
        table->in_use= this;
1389
1364
      }
1390
1365
      else
1424
1399
        }
1425
1400
 
1426
1401
        /* make a new table */
1427
 
        table= new Table;
1428
 
        if (table == NULL)
1429
1402
        {
1430
 
          LOCK_open.unlock();
1431
 
          return NULL;
1432
 
        }
 
1403
          table::Concurrent *new_table= new table::Concurrent;
 
1404
          table= new_table;
 
1405
          if (new_table == NULL)
 
1406
          {
 
1407
            LOCK_open.unlock();
 
1408
            return NULL;
 
1409
          }
1433
1410
 
1434
 
        error= open_unireg_entry(this, table, alias, identifier);
1435
 
        if (error != 0)
1436
 
        {
1437
 
          delete table;
1438
 
          LOCK_open.unlock();
1439
 
          return NULL;
 
1411
          error= open_unireg_entry(this, new_table, alias, identifier);
 
1412
          if (error != 0)
 
1413
          {
 
1414
            delete new_table;
 
1415
            LOCK_open.unlock();
 
1416
            return NULL;
 
1417
          }
 
1418
          (void)add_table(new_table);
1440
1419
        }
1441
 
        (void)add_table(table);
1442
1420
      }
1443
1421
 
1444
1422
      LOCK_open.unlock();
1591
1569
    next= table->getNext();
1592
1570
 
1593
1571
    my_error(ER_CANT_REOPEN_TABLE, MYF(0), table->getAlias());
1594
 
    remove_table(table);
 
1572
    remove_table(dynamic_cast<table::Concurrent *>(table));
1595
1573
    error= 1;
1596
1574
  }
1597
1575
  *prev=0;
1843
1821
      else
1844
1822
      {
1845
1823
        /* We already have a name lock, remove copy */
1846
 
        remove_table(table);
 
1824
        remove_table(dynamic_cast<table::Concurrent *>(table));
1847
1825
      }
1848
1826
    }
1849
1827
    else
1930
1908
    {
1931
1909
      share->resetVersion();                        // Mark share as old
1932
1910
      if (discover_retry_count++)               // Retry once
1933
 
        goto err;
 
1911
      {
 
1912
        TableShare::release(share);
 
1913
        return 1;
 
1914
      }
1934
1915
 
1935
1916
      /*
1936
1917
        TODO->
1952
1933
        using the share.
1953
1934
      */
1954
1935
      if (share->getTableCount() != 1)
1955
 
        goto err;
 
1936
      {
 
1937
        TableShare::release(share);
 
1938
        return 1;
 
1939
      }
1956
1940
      /* Free share and wait until it's released by all threads */
1957
1941
      TableShare::release(share);
1958
1942
 
1965
1949
      return 1;
1966
1950
    }
1967
1951
 
1968
 
    goto err;
 
1952
    TableShare::release(share);
 
1953
 
 
1954
    return 1;
1969
1955
  }
1970
1956
 
1971
1957
  return 0;
1972
 
 
1973
 
err:
1974
 
  TableShare::release(share);
1975
 
 
1976
 
  return 1;
1977
1958
}
1978
1959
 
1979
1960
 
3202
3183
    /* true if field_name_1 is a member of using_fields */
3203
3184
    bool is_using_column_1;
3204
3185
    if (!(nj_col_1= it_1.get_or_create_column_ref(leaf_1)))
3205
 
      goto err;
 
3186
      return(result);
3206
3187
    field_name_1= nj_col_1->name();
3207
3188
    is_using_column_1= using_fields &&
3208
3189
      test_if_string_in_list(field_name_1, using_fields);
3220
3201
      Natural_join_column *cur_nj_col_2;
3221
3202
      const char *cur_field_name_2;
3222
3203
      if (!(cur_nj_col_2= it_2.get_or_create_column_ref(leaf_2)))
3223
 
        goto err;
 
3204
        return(result);
3224
3205
      cur_field_name_2= cur_nj_col_2->name();
3225
3206
 
3226
3207
      /*
3240
3221
            (found && (!using_fields || is_using_column_1)))
3241
3222
        {
3242
3223
          my_error(ER_NON_UNIQ_ERROR, MYF(0), field_name_1, session->where);
3243
 
          goto err;
 
3224
          return(result);
3244
3225
        }
3245
3226
        nj_col_2= cur_nj_col_2;
3246
3227
        found= true;
3273
3254
      Item_func_eq *eq_cond;
3274
3255
 
3275
3256
      if (!item_1 || !item_2)
3276
 
        goto err;                               // out of memory
 
3257
        return(result); // out of memory
3277
3258
 
3278
3259
      /*
3279
3260
        In the case of no_wrap_view_item == 0, the created items must be
3298
3279
      */
3299
3280
      if (set_new_item_local_context(session, item_ident_1, nj_col_1->table_ref) ||
3300
3281
          set_new_item_local_context(session, item_ident_2, nj_col_2->table_ref))
3301
 
        goto err;
 
3282
        return(result);
3302
3283
 
3303
3284
      if (!(eq_cond= new Item_func_eq(item_ident_1, item_ident_2)))
3304
 
        goto err;                               /* Out of memory. */
 
3285
        return(result);                               /* Out of memory. */
3305
3286
 
3306
3287
      /*
3307
3288
        Add the new equi-join condition to the ON clause. Notice that
3347
3328
  */
3348
3329
  result= false;
3349
3330
 
3350
 
err:
3351
3331
  return(result);
3352
3332
}
3353
3333
 
3405
3385
 
3406
3386
  if (!(non_join_columns= new List<Natural_join_column>) ||
3407
3387
      !(natural_using_join->join_columns= new List<Natural_join_column>))
3408
 
    goto err;
 
3388
  {
 
3389
    return(result);
 
3390
  }
3409
3391
 
3410
3392
  /* Append the columns of the first join operand. */
3411
3393
  for (it_1.set(table_ref_1); !it_1.end_of_fields(); it_1.next())
3444
3426
        {
3445
3427
          my_error(ER_BAD_FIELD_ERROR, MYF(0), using_field_name_ptr,
3446
3428
                   session->where);
3447
 
          goto err;
 
3429
          return(result);
3448
3430
        }
3449
3431
        if (!my_strcasecmp(system_charset_info,
3450
3432
                           common_field->name(), using_field_name_ptr))
3472
3454
 
3473
3455
  result= false;
3474
3456
 
3475
 
err:
3476
3457
  return(result);
3477
3458
}
3478
3459
 
3558
3539
      if (cur_table_ref->getNestedJoin() &&
3559
3540
          store_top_level_join_columns(session, cur_table_ref,
3560
3541
                                       real_left_neighbor, real_right_neighbor))
3561
 
        goto err;
 
3542
        return(result);
3562
3543
      same_level_right_neighbor= cur_table_ref;
3563
3544
    }
3564
3545
  }
3590
3571
      std::swap(table_ref_1, table_ref_2);
3591
3572
    if (mark_common_columns(session, table_ref_1, table_ref_2,
3592
3573
                            using_fields, &found_using_fields))
3593
 
      goto err;
 
3574
      return(result);
3594
3575
 
3595
3576
    /*
3596
3577
      Swap the join operands back, so that we pick the columns of the second
3602
3583
    if (store_natural_using_join_columns(session, table_ref, table_ref_1,
3603
3584
                                         table_ref_2, using_fields,
3604
3585
                                         found_using_fields))
3605
 
      goto err;
 
3586
      return(result);
3606
3587
 
3607
3588
    /*
3608
3589
      Change NATURAL JOIN to JOIN ... ON. We do this for both operands
3635
3616
  }
3636
3617
  result= false; /* All is OK. */
3637
3618
 
3638
 
err:
3639
3619
  return(result);
3640
3620
}
3641
3621
 
4280
4260
    if ((value->save_in_field(rfield, 0) < 0) && !ignore_errors)
4281
4261
    {
4282
4262
      my_message(ER_UNKNOWN_ERROR, ER(ER_UNKNOWN_ERROR), MYF(0));
4283
 
      goto err;
 
4263
      if (table)
 
4264
        table->auto_increment_field_not_null= false;
 
4265
 
 
4266
      return true;
4284
4267
    }
4285
4268
  }
4286
4269
 
4287
4270
  return session->is_error();
4288
 
 
4289
 
err:
4290
 
  if (table)
4291
 
    table->auto_increment_field_not_null= false;
4292
 
 
4293
 
  return true;
4294
4271
}
4295
4272
 
4296
4273
 
4340
4317
    if (field == table->next_number_field)
4341
4318
      table->auto_increment_field_not_null= true;
4342
4319
    if (value->save_in_field(field, 0) < 0)
4343
 
      goto err;
 
4320
    {
 
4321
      if (table)
 
4322
        table->auto_increment_field_not_null= false;
 
4323
 
 
4324
      return true;
 
4325
    }
4344
4326
  }
4345
4327
 
4346
4328
  return(session->is_error());
4347
 
 
4348
 
err:
4349
 
  if (table)
4350
 
    table->auto_increment_field_not_null= false;
4351
 
 
4352
 
  return true;
4353
4329
}
4354
4330
 
4355
4331
 
4399
4375
       iter != get_open_cache().end();
4400
4376
       iter++)
4401
4377
  {
4402
 
    Table *table= (*iter).second;
 
4378
    table::Concurrent *table= (*iter).second;
4403
4379
 
4404
4380
    if (not schema_identifier.getPath().compare(table->getShare()->getSchemaName()))
4405
4381
    {
4444
4420
    for (TableOpenCache::const_iterator iter= ppp.first;
4445
4421
         iter != ppp.second; ++iter)
4446
4422
    {
4447
 
      Table *table= (*iter).second;
 
4423
      table::Concurrent *table= (*iter).second;
4448
4424
      Session *in_use;
4449
4425
 
4450
4426
      table->getMutableShare()->resetVersion();         /* Free when thread is ready */
4451
 
      if (!(in_use=table->in_use))
 
4427
      if (not (in_use= table->in_use))
4452
4428
      {
4453
4429
        unused_tables.relink(table);
4454
4430
      }
4483
4459
        }
4484
4460
      }
4485
4461
      else
 
4462
      {
4486
4463
        result= result || (flags & RTFC_OWNED_BY_Session_FLAG);
 
4464
      }
4487
4465
    }
4488
4466
 
4489
4467
    unused_tables.cullByVersion();