~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_base.cc

Extracted the LOAD command into its own class and implementation files.
Removed the corresponding case label from the switch statement.

Show diffs side-by-side

added added

removed removed

Lines of Context:
41
41
#include <drizzled/sql_base.h>
42
42
#include <drizzled/show.h>
43
43
#include <drizzled/item/cmpfunc.h>
44
 
#include <drizzled/replication_services.h>
 
44
#include <drizzled/transaction_services.h>
45
45
#include <drizzled/check_stack_overrun.h>
46
46
#include <drizzled/lock.h>
47
47
#include <drizzled/listen.h>
49
49
 
50
50
using namespace std;
51
51
 
52
 
extern drizzled::ReplicationServices replication_services;
 
52
extern drizzled::TransactionServices transaction_services;
53
53
 
54
54
/**
55
55
  @defgroup Data_Dictionary Data Dictionary
93
93
 
94
94
void table_cache_free(void)
95
95
{
96
 
  refresh_version++;                            // Force close of open tables
97
 
 
98
 
  while (unused_tables)
99
 
    hash_delete(&open_cache,(unsigned char*) unused_tables);
100
 
 
 
96
  close_cached_tables(NULL, NULL, false, false);
101
97
  if (!open_cache.records)                      // Safety first
102
98
    hash_free(&open_cache);
103
99
}
238
234
 ****************************************************************************/
239
235
 
240
236
 
241
 
void Table::intern_close_table()
 
237
void intern_close_table(Table *table)
242
238
{                                               // Free all structures
243
 
  free_io_cache();
244
 
  if (file)                              // Not true if name lock
245
 
    closefrm(true);                     // close file
 
239
  free_io_cache(table);
 
240
  if (table->file)                              // Not true if name lock
 
241
    table->closefrm(true);                      // close file
246
242
}
247
243
 
248
244
/*
259
255
void free_cache_entry(void *entry)
260
256
{
261
257
  Table *table= static_cast<Table *>(entry);
262
 
  table->intern_close_table();
 
258
  intern_close_table(table);
263
259
  if (!table->in_use)
264
260
  {
265
261
    table->next->prev=table->prev;              /* remove from used chain */
271
267
        unused_tables= NULL;
272
268
    }
273
269
  }
 
270
 
274
271
  free(table);
275
272
}
276
273
 
277
274
/* Free resources allocated by filesort() and read_record() */
278
275
 
279
 
void Table::free_io_cache()
 
276
void free_io_cache(Table *table)
280
277
{
281
 
  if (sort.io_cache)
 
278
  if (table->sort.io_cache)
282
279
  {
283
 
    close_cached_file(sort.io_cache);
284
 
    delete sort.io_cache;
285
 
    sort.io_cache= 0;
 
280
    close_cached_file(table->sort.io_cache);
 
281
    delete table->sort.io_cache;
 
282
    table->sort.io_cache= 0;
286
283
  }
287
284
}
288
285
 
302
299
  and tables must be NULL.
303
300
*/
304
301
 
305
 
bool Session::close_cached_tables(TableList *tables, bool wait_for_refresh, bool wait_for_placeholders)
 
302
bool close_cached_tables(Session *session, TableList *tables,
 
303
                         bool wait_for_refresh, bool wait_for_placeholders)
306
304
{
307
305
  bool result= false;
308
 
  Session *session= this;
 
306
  assert(session || (!wait_for_refresh && !tables));
309
307
 
310
308
  pthread_mutex_lock(&LOCK_open); /* Optionally lock for remove tables from open_cahe if not in use */
311
309
 
313
311
  {
314
312
    refresh_version++;                          // Force close of open tables
315
313
    while (unused_tables)
 
314
    {
 
315
#ifdef EXTRA_DEBUG
 
316
      if (hash_delete(&open_cache,(unsigned char*) unused_tables))
 
317
        printf("Warning: Couldn't delete open table from hash\n");
 
318
#else
316
319
      hash_delete(&open_cache,(unsigned char*) unused_tables);
317
 
 
 
320
#endif
 
321
    }
318
322
    if (wait_for_refresh)
319
323
    {
320
324
      /*
325
329
        request is aborted. They loop in open_and_lock_tables() and
326
330
        enter open_table(). Here they notice the table is refreshed and
327
331
        wait for COND_refresh. Then they loop again in
328
 
        openTablesLock() and this time open_table() succeeds. At
 
332
        open_and_lock_tables() and this time open_table() succeeds. At
329
333
        this moment, if we (the FLUSH TABLES thread) are scheduled and
330
334
        on another FLUSH TABLES enter close_cached_tables(), they could
331
335
        awake while we sleep below, waiting for others threads (us) to
340
344
        The fix for this problem is to set some_tables_deleted for all
341
345
        threads with open tables. These threads can still get their
342
346
        locks, but will immediately release them again after checking
343
 
        this variable. They will then loop in openTablesLock()
 
347
        this variable. They will then loop in open_and_lock_tables()
344
348
        again. There they will wait until we update all tables version
345
349
        below.
346
350
 
377
381
 
378
382
  if (wait_for_refresh)
379
383
  {
 
384
    assert(session);
380
385
    /*
381
386
      If there is any table that has a lower refresh_version, wait until
382
387
      this is closed (or this thread is killed) before returning
429
434
    result= session->reopen_tables(true, true);
430
435
 
431
436
    /* Set version for table */
432
 
    for (Table *table= session->open_tables; table ; table= table->next)
 
437
    for (Table *table=session->open_tables; table ; table= table->next)
433
438
    {
434
439
      /*
435
440
        Preserve the version (0) of write locked tables so that a impending
444
449
 
445
450
  if (wait_for_refresh)
446
451
  {
 
452
    assert(session);
 
453
 
447
454
    pthread_mutex_lock(&session->mysys_var->mutex);
448
455
    session->mysys_var->current_mutex= 0;
449
456
    session->mysys_var->current_cond= 0;
543
550
  table_name            Table name
544
551
 
545
552
NOTES:
546
 
This is called by find_table_in_global_list().
 
553
This is called by find_table_in_local_list() and
 
554
find_table_in_global_list().
547
555
 
548
556
RETURN VALUES
549
557
NULL    Table not found
721
729
  return 0;
722
730
}
723
731
 
 
732
/*
 
733
  unlink from session->temporary tables and close temporary table
 
734
*/
 
735
 
 
736
void Session::close_temporary_table(Table *table,
 
737
                                    bool free_share, bool delete_table)
 
738
{
 
739
  if (table->prev)
 
740
  {
 
741
    table->prev->next= table->next;
 
742
    if (table->prev->next)
 
743
      table->next->prev= table->prev;
 
744
  }
 
745
  else
 
746
  {
 
747
    /* removing the item from the list */
 
748
    assert(table == temporary_tables);
 
749
    /*
 
750
      slave must reset its temporary list pointer to zero to exclude
 
751
      passing non-zero value to end_slave via rli->save_temporary_tables
 
752
      when no temp tables opened, see an invariant below.
 
753
    */
 
754
    temporary_tables= table->next;
 
755
    if (temporary_tables)
 
756
      table->next->prev= NULL;
 
757
  }
 
758
  close_temporary(table, free_share, delete_table);
 
759
}
 
760
 
 
761
 
 
762
/*
 
763
  Close and delete a temporary table
 
764
 
 
765
  NOTE
 
766
  This dosn't unlink table from session->temporary
 
767
  If this is needed, use close_temporary_table()
 
768
*/
 
769
 
 
770
void close_temporary(Table *table, bool free_share, bool delete_table)
 
771
{
 
772
  StorageEngine *table_type= table->s->db_type();
 
773
 
 
774
  free_io_cache(table);
 
775
  table->closefrm(false);
 
776
 
 
777
  if (delete_table)
 
778
    rm_temporary_table(table_type, table->s->path.str);
 
779
 
 
780
  if (free_share)
 
781
  {
 
782
    table->s->free_table_share();
 
783
    delete 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
 
724
811
 
725
812
/* move table first in unused links */
726
813
 
942
1029
                        table->s->table_cache_key.str,
943
1030
                        table->s->table_cache_key.length))
944
1031
  {
945
 
    table->intern_close_table();
 
1032
    intern_close_table(table);
946
1033
    /*
947
1034
      If there was an error during opening of table (for example if it
948
1035
      does not exist) '*table' object can be wiped out. To be able
1127
1214
*/
1128
1215
 
1129
1216
 
1130
 
Table *Session::openTable(TableList *table_list, bool *refresh, uint32_t flags)
 
1217
Table *Session::open_table(TableList *table_list, bool *refresh, uint32_t flags)
1131
1218
{
1132
1219
  register Table *table;
1133
1220
  char key[MAX_DBKEY_LENGTH];
1348
1435
 
1349
1436
    if (table_list->create)
1350
1437
    {
1351
 
      char path[FN_REFLEN];
1352
 
      size_t length;
1353
 
 
1354
 
      length= build_table_filename(path, sizeof(path),
1355
 
                                   table_list->db, table_list->table_name,
1356
 
                                   false);
1357
 
 
1358
 
      if (StorageEngine::getTableProto(path, NULL) != EEXIST)
 
1438
      if (ha_table_exists_in_engine(this, table_list->db,
 
1439
                                    table_list->table_name)
 
1440
          != HA_ERR_TABLE_EXIST)
1359
1441
      {
1360
1442
        /*
1361
1443
          Table to be created, so we need to create placeholder in table-cache.
1381
1463
    }
1382
1464
 
1383
1465
    /* make a new table */
1384
 
    table= (Table *)malloc(sizeof(Table));
 
1466
    table= new Table;
1385
1467
    if (table == NULL)
1386
1468
    {
1387
1469
      pthread_mutex_unlock(&LOCK_open);
1614
1696
  situations like FLUSH TABLES or ALTER Table. In general
1615
1697
  case one should just repeat open_tables()/lock_tables()
1616
1698
  combination when one needs tables to be reopened (for
1617
 
  example see openTablesLock()).
 
1699
  example see open_and_lock_tables()).
1618
1700
 
1619
1701
  @note One should have lock on LOCK_open when calling this.
1620
1702
 
2110
2192
        end= query;
2111
2193
        end+= sprintf(query, "DELETE FROM `%s`.`%s`", share->db.str,
2112
2194
                      share->table_name.str);
2113
 
        replication_services.rawStatement(session, query, (size_t)(end - query)); 
 
2195
        transaction_services.rawStatement(session, query, (size_t)(end - query)); 
2114
2196
        free(query);
2115
2197
      }
2116
2198
      else
2211
2293
      not opened yet. Try to open the table.
2212
2294
    */
2213
2295
    if (tables->table == NULL)
2214
 
      tables->table= openTable(tables, &refresh, flags);
 
2296
      tables->table= open_table(tables, &refresh, flags);
2215
2297
 
2216
2298
    if (tables->table == NULL)
2217
2299
    {
2289
2371
  table_list->table             table
2290
2372
*/
2291
2373
 
2292
 
Table *Session::openTableLock(TableList *table_list, thr_lock_type lock_type)
 
2374
Table *Session::open_ltable(TableList *table_list, thr_lock_type lock_type)
2293
2375
{
2294
2376
  Table *table;
2295
2377
  bool refresh;
2296
2378
 
2297
2379
  set_proc_info("Opening table");
2298
2380
  current_tablenr= 0;
2299
 
  while (!(table= openTable(table_list, &refresh)) &&
 
2381
  while (!(table= open_table(table_list, &refresh, 0)) &&
2300
2382
         refresh)
2301
2383
    ;
2302
2384
 
2344
2426
  -1    Error
2345
2427
*/
2346
2428
 
2347
 
int Session::lock_tables(TableList *tables, uint32_t count, bool *need_reopen)
 
2429
int lock_tables(Session *session, TableList *tables, uint32_t count, bool *need_reopen)
2348
2430
{
2349
2431
  TableList *table;
2350
 
  Session *session= this;
2351
2432
 
2352
2433
  /*
2353
2434
    We can't meet statement requiring prelocking if we already
2400
2481
#  Table object
2401
2482
*/
2402
2483
 
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)
 
2484
Table *open_temporary_table(Session *session, const char *path, const char *db,
 
2485
                            const char *table_name, bool link_in_list,
 
2486
                            open_table_mode open_mode)
2406
2487
{
2407
 
  Table *new_tmp_table;
 
2488
  Table *tmp_table;
2408
2489
  TableShare *share;
2409
2490
  char cache_key[MAX_DBKEY_LENGTH], *saved_cache_key, *tmp_path;
2410
2491
  uint32_t key_length, path_length;
2411
2492
  TableList table_list;
2412
2493
 
2413
 
  table_list.db=         (char*) db_arg;
2414
 
  table_list.table_name= (char*) table_name_arg;
 
2494
  table_list.db=         (char*) db;
 
2495
  table_list.table_name= (char*) table_name;
2415
2496
  /* Create the cache_key for temporary tables */
2416
2497
  key_length= table_list.create_table_def_key(cache_key);
2417
2498
  path_length= strlen(path);
2418
2499
 
2419
 
  if (!(new_tmp_table= (Table*) malloc(sizeof(*new_tmp_table) + sizeof(*share) +
 
2500
  if (!(tmp_table= (Table*) malloc(sizeof(*tmp_table) + sizeof(*share) +
2420
2501
                                   path_length + 1 + key_length)))
2421
2502
    return NULL;
2422
2503
 
2423
 
  share= (TableShare*) (new_tmp_table+1);
 
2504
  share= (TableShare*) (tmp_table+1);
2424
2505
  tmp_path= (char*) (share+1);
2425
2506
  saved_cache_key= strcpy(tmp_path, path)+path_length+1;
2426
2507
  memcpy(saved_cache_key, cache_key, key_length);
2430
2511
  /*
2431
2512
    First open the share, and then open the table from the share we just opened.
2432
2513
  */
2433
 
  if (open_table_def(this, share) ||
2434
 
      open_table_from_share(this, share, table_name_arg,
 
2514
  if (open_table_def(session, share) ||
 
2515
      open_table_from_share(session, share, table_name,
2435
2516
                            (open_mode == OTM_ALTER) ? 0 :
2436
2517
                            (uint32_t) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE |
2437
2518
                                        HA_GET_INDEX),
2439
2520
                            (EXTRA_RECORD | OPEN_FRM_FILE_ONLY)
2440
2521
                            : (EXTRA_RECORD),
2441
2522
                            ha_open_options,
2442
 
                            new_tmp_table, open_mode))
 
2523
                            tmp_table, open_mode))
2443
2524
  {
2444
2525
    /* No need to lock share->mutex as this is not needed for tmp tables */
2445
2526
    share->free_table_share();
2446
 
    free((char*) new_tmp_table);
 
2527
    free((char*) tmp_table);
2447
2528
    return 0;
2448
2529
  }
2449
2530
 
2450
 
  new_tmp_table->reginfo.lock_type= TL_WRITE;    // Simulate locked
 
2531
  tmp_table->reginfo.lock_type= TL_WRITE;        // Simulate locked
2451
2532
  if (open_mode == OTM_ALTER)
2452
2533
  {
2453
2534
    /*
2457
2538
    share->tmp_table= TMP_TABLE_FRM_FILE_ONLY;
2458
2539
  }
2459
2540
  else
2460
 
    share->tmp_table= (new_tmp_table->file->has_transactions() ?
 
2541
    share->tmp_table= (tmp_table->file->has_transactions() ?
2461
2542
                       TRANSACTIONAL_TMP_TABLE : NON_TRANSACTIONAL_TMP_TABLE);
2462
2543
 
2463
2544
  if (link_in_list)
2464
2545
  {
2465
2546
    /* growing temp list at the head */
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;
 
2547
    tmp_table->next= session->temporary_tables;
 
2548
    if (tmp_table->next)
 
2549
      tmp_table->next->prev= tmp_table;
 
2550
    session->temporary_tables= tmp_table;
 
2551
    session->temporary_tables->prev= 0;
 
2552
  }
 
2553
  tmp_table->pos_in_table_list= 0;
 
2554
 
 
2555
  return tmp_table;
 
2556
}
 
2557
 
 
2558
 
 
2559
bool rm_temporary_table(StorageEngine *base, char *path)
 
2560
{
 
2561
  bool error=0;
 
2562
 
 
2563
  assert(base);
 
2564
 
 
2565
  if(delete_table_proto_file(path))
 
2566
    error=1; /* purecov: inspected */
 
2567
 
 
2568
  if (base->deleteTable(current_session, path))
 
2569
  {
 
2570
    error=1;
 
2571
    errmsg_printf(ERRMSG_LVL_WARN, _("Could not remove temporary table: '%s', error: %d"),
 
2572
                  path, my_errno);
 
2573
  }
 
2574
  return(error);
2475
2575
}
2476
2576
 
2477
2577
 
4399
4499
  false if all is OK
4400
4500
*/
4401
4501
 
4402
 
int Session::setup_conds(TableList *leaves, COND **conds)
 
4502
int setup_conds(Session *session, TableList *leaves, COND **conds)
4403
4503
{
4404
 
  Session *session= this;
4405
4504
  Select_Lex *select_lex= session->lex->current_select;
4406
4505
  TableList *table= NULL;       // For HP compilers
4407
4506
  void *save_session_marker= session->session_marker;