~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_base.cc

  • Committer: Padraig O'Sullivan
  • Date: 2009-08-07 14:14:58 UTC
  • mfrom: (1112 staging)
  • mto: (1115.3.4 captain)
  • mto: This revision was merged to the branch mainline in revision 1117.
  • Revision ID: osullivan.padraig@gmail.com-20090807141458-qrc3don58s304ore
Merge from trunk.

Show diffs side-by-side

added added

removed removed

Lines of Context:
93
93
 
94
94
void table_cache_free(void)
95
95
{
96
 
  close_cached_tables(NULL, NULL, false, false);
 
96
  refresh_version++;                            // Force close of open tables
 
97
 
 
98
  while (unused_tables)
 
99
    hash_delete(&open_cache,(unsigned char*) unused_tables);
 
100
 
97
101
  if (!open_cache.records)                      // Safety first
98
102
    hash_free(&open_cache);
99
103
}
234
238
 ****************************************************************************/
235
239
 
236
240
 
237
 
void intern_close_table(Table *table)
 
241
void Table::intern_close_table()
238
242
{                                               // Free all structures
239
 
  free_io_cache(table);
240
 
  if (table->file)                              // Not true if name lock
241
 
    table->closefrm(true);                      // close file
 
243
  free_io_cache();
 
244
  if (file)                              // Not true if name lock
 
245
    closefrm(true);                     // close file
242
246
}
243
247
 
244
248
/*
255
259
void free_cache_entry(void *entry)
256
260
{
257
261
  Table *table= static_cast<Table *>(entry);
258
 
  intern_close_table(table);
 
262
  table->intern_close_table();
259
263
  if (!table->in_use)
260
264
  {
261
265
    table->next->prev=table->prev;              /* remove from used chain */
272
276
 
273
277
/* Free resources allocated by filesort() and read_record() */
274
278
 
275
 
void free_io_cache(Table *table)
 
279
void Table::free_io_cache()
276
280
{
277
 
  if (table->sort.io_cache)
 
281
  if (sort.io_cache)
278
282
  {
279
 
    close_cached_file(table->sort.io_cache);
280
 
    delete table->sort.io_cache;
281
 
    table->sort.io_cache= 0;
 
283
    close_cached_file(sort.io_cache);
 
284
    delete sort.io_cache;
 
285
    sort.io_cache= 0;
282
286
  }
283
287
}
284
288
 
298
302
  and tables must be NULL.
299
303
*/
300
304
 
301
 
bool close_cached_tables(Session *session, TableList *tables,
302
 
                         bool wait_for_refresh, bool wait_for_placeholders)
 
305
bool Session::close_cached_tables(TableList *tables, bool wait_for_refresh, bool wait_for_placeholders)
303
306
{
304
307
  bool result= false;
305
 
  assert(session || (!wait_for_refresh && !tables));
 
308
  Session *session= this;
306
309
 
307
310
  pthread_mutex_lock(&LOCK_open); /* Optionally lock for remove tables from open_cahe if not in use */
308
311
 
310
313
  {
311
314
    refresh_version++;                          // Force close of open tables
312
315
    while (unused_tables)
313
 
    {
314
 
#ifdef EXTRA_DEBUG
315
 
      if (hash_delete(&open_cache,(unsigned char*) unused_tables))
316
 
        printf("Warning: Couldn't delete open table from hash\n");
317
 
#else
318
316
      hash_delete(&open_cache,(unsigned char*) unused_tables);
319
 
#endif
320
 
    }
 
317
 
321
318
    if (wait_for_refresh)
322
319
    {
323
320
      /*
328
325
        request is aborted. They loop in open_and_lock_tables() and
329
326
        enter open_table(). Here they notice the table is refreshed and
330
327
        wait for COND_refresh. Then they loop again in
331
 
        open_and_lock_tables() and this time open_table() succeeds. At
 
328
        openTablesLock() and this time open_table() succeeds. At
332
329
        this moment, if we (the FLUSH TABLES thread) are scheduled and
333
330
        on another FLUSH TABLES enter close_cached_tables(), they could
334
331
        awake while we sleep below, waiting for others threads (us) to
343
340
        The fix for this problem is to set some_tables_deleted for all
344
341
        threads with open tables. These threads can still get their
345
342
        locks, but will immediately release them again after checking
346
 
        this variable. They will then loop in open_and_lock_tables()
 
343
        this variable. They will then loop in openTablesLock()
347
344
        again. There they will wait until we update all tables version
348
345
        below.
349
346
 
380
377
 
381
378
  if (wait_for_refresh)
382
379
  {
383
 
    assert(session);
384
380
    /*
385
381
      If there is any table that has a lower refresh_version, wait until
386
382
      this is closed (or this thread is killed) before returning
433
429
    result= session->reopen_tables(true, true);
434
430
 
435
431
    /* Set version for table */
436
 
    for (Table *table=session->open_tables; table ; table= table->next)
 
432
    for (Table *table= session->open_tables; table ; table= table->next)
437
433
    {
438
434
      /*
439
435
        Preserve the version (0) of write locked tables so that a impending
448
444
 
449
445
  if (wait_for_refresh)
450
446
  {
451
 
    assert(session);
452
 
 
453
447
    pthread_mutex_lock(&session->mysys_var->mutex);
454
448
    session->mysys_var->current_mutex= 0;
455
449
    session->mysys_var->current_cond= 0;
549
543
  table_name            Table name
550
544
 
551
545
NOTES:
552
 
This is called by find_table_in_local_list() and
553
 
find_table_in_global_list().
 
546
This is called by find_table_in_global_list().
554
547
 
555
548
RETURN VALUES
556
549
NULL    Table not found
728
721
  return 0;
729
722
}
730
723
 
731
 
/*
732
 
  unlink from session->temporary tables and close temporary table
733
 
*/
734
 
 
735
 
void Session::close_temporary_table(Table *table,
736
 
                                    bool free_share, bool delete_table)
737
 
{
738
 
  if (table->prev)
739
 
  {
740
 
    table->prev->next= table->next;
741
 
    if (table->prev->next)
742
 
      table->next->prev= table->prev;
743
 
  }
744
 
  else
745
 
  {
746
 
    /* removing the item from the list */
747
 
    assert(table == temporary_tables);
748
 
    /*
749
 
      slave must reset its temporary list pointer to zero to exclude
750
 
      passing non-zero value to end_slave via rli->save_temporary_tables
751
 
      when no temp tables opened, see an invariant below.
752
 
    */
753
 
    temporary_tables= table->next;
754
 
    if (temporary_tables)
755
 
      table->next->prev= NULL;
756
 
  }
757
 
  close_temporary(table, free_share, delete_table);
758
 
}
759
 
 
760
 
 
761
 
/*
762
 
  Close and delete a temporary table
763
 
 
764
 
  NOTE
765
 
  This dosn't unlink table from session->temporary
766
 
  If this is needed, use close_temporary_table()
767
 
*/
768
 
 
769
 
void close_temporary(Table *table, bool free_share, bool delete_table)
770
 
{
771
 
  StorageEngine *table_type= table->s->db_type();
772
 
 
773
 
  free_io_cache(table);
774
 
  table->closefrm(false);
775
 
 
776
 
  if (delete_table)
777
 
    rm_temporary_table(table_type, table->s->path.str);
778
 
 
779
 
  if (free_share)
780
 
  {
781
 
    table->s->free_table_share();
782
 
    /* This makes me sad, but we're allocating it via malloc */
783
 
    free(table);
784
 
  }
785
 
}
786
 
 
787
 
 
788
 
/*
789
 
  Used by ALTER Table when the table is a temporary one. It changes something
790
 
  only if the ALTER contained a RENAME clause (otherwise, table_name is the old
791
 
  name).
792
 
  Prepares a table cache key, which is the concatenation of db, table_name and
793
 
  session->slave_proxy_id, separated by '\0'.
794
 
*/
795
 
 
796
 
bool rename_temporary_table(Table *table, const char *db, const char *table_name)
797
 
{
798
 
  char *key;
799
 
  uint32_t key_length;
800
 
  TableShare *share= table->s;
801
 
 
802
 
  if (!(key=(char*) alloc_root(&share->mem_root, MAX_DBKEY_LENGTH)))
803
 
    return true;                                /* purecov: inspected */
804
 
 
805
 
  key_length= TableShare::createKey(key, db, table_name);
806
 
  share->set_table_cache_key(key, key_length);
807
 
 
808
 
  return false;
809
 
}
810
 
 
811
724
 
812
725
/* move table first in unused links */
813
726
 
1029
942
                        table->s->table_cache_key.str,
1030
943
                        table->s->table_cache_key.length))
1031
944
  {
1032
 
    intern_close_table(table);
 
945
    table->intern_close_table();
1033
946
    /*
1034
947
      If there was an error during opening of table (for example if it
1035
948
      does not exist) '*table' object can be wiped out. To be able
1214
1127
*/
1215
1128
 
1216
1129
 
1217
 
Table *Session::open_table(TableList *table_list, bool *refresh, uint32_t flags)
 
1130
Table *Session::openTable(TableList *table_list, bool *refresh, uint32_t flags)
1218
1131
{
1219
1132
  register Table *table;
1220
1133
  char key[MAX_DBKEY_LENGTH];
1701
1614
  situations like FLUSH TABLES or ALTER Table. In general
1702
1615
  case one should just repeat open_tables()/lock_tables()
1703
1616
  combination when one needs tables to be reopened (for
1704
 
  example see open_and_lock_tables()).
 
1617
  example see openTablesLock()).
1705
1618
 
1706
1619
  @note One should have lock on LOCK_open when calling this.
1707
1620
 
2298
2211
      not opened yet. Try to open the table.
2299
2212
    */
2300
2213
    if (tables->table == NULL)
2301
 
      tables->table= open_table(tables, &refresh, flags);
 
2214
      tables->table= openTable(tables, &refresh, flags);
2302
2215
 
2303
2216
    if (tables->table == NULL)
2304
2217
    {
2376
2289
  table_list->table             table
2377
2290
*/
2378
2291
 
2379
 
Table *Session::open_ltable(TableList *table_list, thr_lock_type lock_type)
 
2292
Table *Session::openTableLock(TableList *table_list, thr_lock_type lock_type)
2380
2293
{
2381
2294
  Table *table;
2382
2295
  bool refresh;
2383
2296
 
2384
2297
  set_proc_info("Opening table");
2385
2298
  current_tablenr= 0;
2386
 
  while (!(table= open_table(table_list, &refresh, 0)) &&
 
2299
  while (!(table= openTable(table_list, &refresh)) &&
2387
2300
         refresh)
2388
2301
    ;
2389
2302
 
2431
2344
  -1    Error
2432
2345
*/
2433
2346
 
2434
 
int lock_tables(Session *session, TableList *tables, uint32_t count, bool *need_reopen)
 
2347
int Session::lock_tables(TableList *tables, uint32_t count, bool *need_reopen)
2435
2348
{
2436
2349
  TableList *table;
 
2350
  Session *session= this;
2437
2351
 
2438
2352
  /*
2439
2353
    We can't meet statement requiring prelocking if we already
2486
2400
#  Table object
2487
2401
*/
2488
2402
 
2489
 
Table *open_temporary_table(Session *session, const char *path, const char *db,
2490
 
                            const char *table_name, bool link_in_list,
2491
 
                            open_table_mode open_mode)
 
2403
Table *Session::open_temporary_table(const char *path, const char *db_arg,
 
2404
                                     const char *table_name_arg, bool link_in_list,
 
2405
                                     open_table_mode open_mode)
2492
2406
{
2493
 
  Table *tmp_table;
 
2407
  Table *new_tmp_table;
2494
2408
  TableShare *share;
2495
2409
  char cache_key[MAX_DBKEY_LENGTH], *saved_cache_key, *tmp_path;
2496
2410
  uint32_t key_length, path_length;
2497
2411
  TableList table_list;
2498
2412
 
2499
 
  table_list.db=         (char*) db;
2500
 
  table_list.table_name= (char*) table_name;
 
2413
  table_list.db=         (char*) db_arg;
 
2414
  table_list.table_name= (char*) table_name_arg;
2501
2415
  /* Create the cache_key for temporary tables */
2502
2416
  key_length= table_list.create_table_def_key(cache_key);
2503
2417
  path_length= strlen(path);
2504
2418
 
2505
 
  if (!(tmp_table= (Table*) malloc(sizeof(*tmp_table) + sizeof(*share) +
 
2419
  if (!(new_tmp_table= (Table*) malloc(sizeof(*new_tmp_table) + sizeof(*share) +
2506
2420
                                   path_length + 1 + key_length)))
2507
2421
    return NULL;
2508
2422
 
2509
 
  share= (TableShare*) (tmp_table+1);
 
2423
  share= (TableShare*) (new_tmp_table+1);
2510
2424
  tmp_path= (char*) (share+1);
2511
2425
  saved_cache_key= strcpy(tmp_path, path)+path_length+1;
2512
2426
  memcpy(saved_cache_key, cache_key, key_length);
2516
2430
  /*
2517
2431
    First open the share, and then open the table from the share we just opened.
2518
2432
  */
2519
 
  if (open_table_def(session, share) ||
2520
 
      open_table_from_share(session, share, table_name,
 
2433
  if (open_table_def(this, share) ||
 
2434
      open_table_from_share(this, share, table_name_arg,
2521
2435
                            (open_mode == OTM_ALTER) ? 0 :
2522
2436
                            (uint32_t) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE |
2523
2437
                                        HA_GET_INDEX),
2525
2439
                            (EXTRA_RECORD | OPEN_FRM_FILE_ONLY)
2526
2440
                            : (EXTRA_RECORD),
2527
2441
                            ha_open_options,
2528
 
                            tmp_table, open_mode))
 
2442
                            new_tmp_table, open_mode))
2529
2443
  {
2530
2444
    /* No need to lock share->mutex as this is not needed for tmp tables */
2531
2445
    share->free_table_share();
2532
 
    free((char*) tmp_table);
 
2446
    free((char*) new_tmp_table);
2533
2447
    return 0;
2534
2448
  }
2535
2449
 
2536
 
  tmp_table->reginfo.lock_type= TL_WRITE;        // Simulate locked
 
2450
  new_tmp_table->reginfo.lock_type= TL_WRITE;    // Simulate locked
2537
2451
  if (open_mode == OTM_ALTER)
2538
2452
  {
2539
2453
    /*
2543
2457
    share->tmp_table= TMP_TABLE_FRM_FILE_ONLY;
2544
2458
  }
2545
2459
  else
2546
 
    share->tmp_table= (tmp_table->file->has_transactions() ?
 
2460
    share->tmp_table= (new_tmp_table->file->has_transactions() ?
2547
2461
                       TRANSACTIONAL_TMP_TABLE : NON_TRANSACTIONAL_TMP_TABLE);
2548
2462
 
2549
2463
  if (link_in_list)
2550
2464
  {
2551
2465
    /* growing temp list at the head */
2552
 
    tmp_table->next= session->temporary_tables;
2553
 
    if (tmp_table->next)
2554
 
      tmp_table->next->prev= tmp_table;
2555
 
    session->temporary_tables= tmp_table;
2556
 
    session->temporary_tables->prev= 0;
2557
 
  }
2558
 
  tmp_table->pos_in_table_list= 0;
2559
 
 
2560
 
  return tmp_table;
2561
 
}
2562
 
 
2563
 
 
2564
 
bool rm_temporary_table(StorageEngine *base, char *path)
2565
 
{
2566
 
  bool error=0;
2567
 
 
2568
 
  assert(base);
2569
 
 
2570
 
  if(delete_table_proto_file(path))
2571
 
    error=1; /* purecov: inspected */
2572
 
 
2573
 
  if (base->deleteTable(current_session, path))
2574
 
  {
2575
 
    error=1;
2576
 
    errmsg_printf(ERRMSG_LVL_WARN, _("Could not remove temporary table: '%s', error: %d"),
2577
 
                  path, my_errno);
2578
 
  }
2579
 
  return(error);
 
2466
    new_tmp_table->next= this->temporary_tables;
 
2467
    if (new_tmp_table->next)
 
2468
      new_tmp_table->next->prev= new_tmp_table;
 
2469
    this->temporary_tables= new_tmp_table;
 
2470
    this->temporary_tables->prev= 0;
 
2471
  }
 
2472
  new_tmp_table->pos_in_table_list= 0;
 
2473
 
 
2474
  return new_tmp_table;
2580
2475
}
2581
2476
 
2582
2477
 
4504
4399
  false if all is OK
4505
4400
*/
4506
4401
 
4507
 
int setup_conds(Session *session, TableList *leaves, COND **conds)
 
4402
int Session::setup_conds(TableList *leaves, COND **conds)
4508
4403
{
 
4404
  Session *session= this;
4509
4405
  Select_Lex *select_lex= session->lex->current_select;
4510
4406
  TableList *table= NULL;       // For HP compilers
4511
4407
  void *save_session_marker= session->session_marker;