~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/session.cc

  • Committer: Brian Aker
  • Date: 2010-08-18 16:12:58 UTC
  • mto: This revision was merged to the branch mainline in revision 1720.
  • Revision ID: brian@tangent.org-20100818161258-1vm71da888dfvwsx
Remove the code surrounding stack trace.

Show diffs side-by-side

added added

removed removed

Lines of Context:
46
46
#include "drizzled/db.h"
47
47
#include "drizzled/pthread_globals.h"
48
48
#include "drizzled/transaction_services.h"
 
49
#include "drizzled/drizzled.h"
 
50
 
 
51
#include "drizzled/table_share_instance.h"
49
52
 
50
53
#include "plugin/myisam/myisam.h"
51
54
#include "drizzled/internal/iocache.h"
 
55
#include "drizzled/internal/thread_var.h"
 
56
#include "drizzled/plugin/event_observer.h"
52
57
 
53
58
#include <fcntl.h>
54
59
#include <algorithm>
58
63
namespace drizzled
59
64
{
60
65
 
61
 
extern "C"
62
 
{
63
 
  unsigned char *get_var_key(user_var_entry *entry, size_t *length, bool );
64
 
  void free_user_var(user_var_entry *entry);
65
 
}
66
 
 
67
66
/*
68
67
  The following is used to initialise Table_ident with a internal
69
68
  table name
74
73
const char * const Session::DEFAULT_WHERE= "field list";
75
74
extern pthread_key_t THR_Session;
76
75
extern pthread_key_t THR_Mem_root;
77
 
extern uint32_t max_used_connections;
78
 
extern atomic<uint32_t> connection_count;
79
 
 
80
 
 
81
 
/****************************************************************************
82
 
** User variables
83
 
****************************************************************************/
84
 
unsigned char *get_var_key(user_var_entry *entry, size_t *length, bool )
85
 
{
86
 
  *length= entry->name.length;
87
 
  return (unsigned char*) entry->name.str;
88
 
}
89
 
 
90
 
void free_user_var(user_var_entry *entry)
91
 
{
92
 
  delete entry;
93
 
}
94
76
 
95
77
bool Key_part_spec::operator==(const Key_part_spec& other) const
96
78
{
99
81
         !strcmp(field_name.str, other.field_name.str);
100
82
}
101
83
 
102
 
Open_tables_state::Open_tables_state(uint64_t version_arg)
103
 
  :version(version_arg), backups_available(false)
 
84
Open_tables_state::Open_tables_state(uint64_t version_arg) :
 
85
  version(version_arg)
104
86
{
105
 
  reset_open_tables_state();
 
87
  open_tables= temporary_tables= derived_tables= NULL;
 
88
  extra_lock= lock= NULL;
106
89
}
107
90
 
108
91
/*
109
92
  The following functions form part of the C plugin API
110
93
*/
111
 
extern "C" int mysql_tmpfile(const char *prefix)
 
94
int mysql_tmpfile(const char *prefix)
112
95
{
113
96
  char filename[FN_REFLEN];
114
 
  int fd = internal::create_temp_file(filename, drizzle_tmpdir, prefix, MYF(MY_WME));
 
97
  int fd = internal::create_temp_file(filename, drizzle_tmpdir.c_str(), prefix, MYF(MY_WME));
115
98
  if (fd >= 0) {
116
99
    unlink(filename);
117
100
  }
119
102
  return fd;
120
103
}
121
104
 
122
 
extern "C"
123
105
int session_tablespace_op(const Session *session)
124
106
{
125
107
  return test(session->tablespace_op);
133
115
 
134
116
   @see Session::set_proc_info
135
117
 */
136
 
extern "C" void
137
 
set_session_proc_info(Session *session, const char *info)
 
118
void set_session_proc_info(Session *session, const char *info)
138
119
{
139
120
  session->set_proc_info(info);
140
121
}
141
122
 
142
 
extern "C"
143
123
const char *get_session_proc_info(Session *session)
144
124
{
145
125
  return session->get_proc_info();
156
136
  return &ha_data[monitored->getId()].resource_context[index];
157
137
}
158
138
 
159
 
extern "C"
160
139
int64_t session_test_options(const Session *session, int64_t test_options)
161
140
{
162
141
  return session->options & test_options;
163
142
}
164
143
 
165
 
extern "C"
166
144
int session_sql_command(const Session *session)
167
145
{
168
146
  return (int) session->lex->sql_command;
169
147
}
170
148
 
171
 
extern "C"
172
 
int session_tx_isolation(const Session *session)
 
149
enum_tx_isolation session_tx_isolation(const Session *session)
173
150
{
174
 
  return (int) session->variables.tx_isolation;
 
151
  return (enum_tx_isolation)session->variables.tx_isolation;
175
152
}
176
153
 
177
 
Session::Session(plugin::Client *client_arg)
178
 
  :
 
154
Session::Session(plugin::Client *client_arg) :
179
155
  Open_tables_state(refresh_version),
180
156
  mem_root(&main_mem_root),
181
157
  lex(&main_lex),
202
178
  m_lip(NULL),
203
179
  cached_table(0),
204
180
  transaction_message(NULL),
205
 
  statement_message(NULL)
 
181
  statement_message(NULL),
 
182
  session_event_observers(NULL)
206
183
{
207
184
  memset(process_list_info, 0, PROCESS_LIST_WIDTH);
208
185
  client->setSession(this);
214
191
  */
215
192
  memory::init_sql_alloc(&main_mem_root, memory::ROOT_MIN_BLOCK_SIZE, 0);
216
193
  thread_stack= NULL;
217
 
  count_cuted_fields= CHECK_FIELD_IGNORE;
 
194
  count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;
218
195
  killed= NOT_KILLED;
219
196
  col_access= 0;
220
197
  tmp_table= 0;
233
210
  query_id= 0;
234
211
  warn_query_id= 0;
235
212
  mysys_var= 0;
 
213
  scoreboard_index= -1;
236
214
  dbug_sentry=Session_SENTRY_MAGIC;
237
215
  cleanup_done= abort_on_warning= no_warnings_for_error= false;
238
 
  pthread_mutex_init(&LOCK_delete, MY_MUTEX_INIT_FAST);
239
216
 
240
217
  /* Variables with default values */
241
218
  proc_info="login";
267
244
 
268
245
  /* Initialize sub structures */
269
246
  memory::init_sql_alloc(&warn_root, WARN_ALLOC_BLOCK_SIZE, WARN_ALLOC_PREALLOC_SIZE);
270
 
  hash_init(&user_vars, system_charset_info, USER_VARS_HASH_SIZE, 0, 0,
271
 
            (hash_get_key) get_var_key,
272
 
            (hash_free_key) free_user_var, 0);
273
247
 
274
248
  substitute_null_with_insert_id = false;
275
 
  thr_lock_info_init(&lock_info); /* safety: will be reset after start */
 
249
  lock_info.init(); /* safety: will be reset after start */
276
250
  thr_lock_owner_init(&main_lock_id, &lock_info);
277
251
 
278
252
  m_internal_handler= NULL;
 
253
  
 
254
  plugin::EventObserver::registerSessionEvents(*this); 
279
255
}
280
256
 
281
257
void Session::free_items()
310
286
  return false;                                 // 'false', as per coding style
311
287
}
312
288
 
 
289
void Session::setAbort(bool arg)
 
290
{
 
291
  mysys_var->abort= arg;
 
292
}
 
293
 
 
294
void Session::lockOnSys()
 
295
{
 
296
  if (not mysys_var)
 
297
    return;
 
298
 
 
299
  setAbort(true);
 
300
  pthread_mutex_lock(&mysys_var->mutex);
 
301
  if (mysys_var->current_cond)
 
302
  {
 
303
    pthread_mutex_lock(mysys_var->current_mutex);
 
304
    pthread_cond_broadcast(mysys_var->current_cond);
 
305
    pthread_mutex_unlock(mysys_var->current_mutex);
 
306
  }
 
307
  pthread_mutex_unlock(&mysys_var->mutex);
 
308
}
 
309
 
313
310
void Session::pop_internal_handler()
314
311
{
315
312
  assert(m_internal_handler != NULL);
316
313
  m_internal_handler= NULL;
317
314
}
318
315
 
319
 
#if defined(__cplusplus)
320
 
extern "C" {
321
 
#endif
322
 
 
323
 
void *session_alloc(Session *session, unsigned int size)
324
 
{
325
 
  return session->alloc(size);
326
 
}
327
 
 
328
 
void *session_calloc(Session *session, unsigned int size)
329
 
{
330
 
  return session->calloc(size);
331
 
}
332
 
 
333
 
char *session_strdup(Session *session, const char *str)
334
 
{
335
 
  return session->strdup(str);
336
 
}
337
 
 
338
 
char *session_strmake(Session *session, const char *str, unsigned int size)
339
 
{
340
 
  return session->strmake(str, size);
341
 
}
342
 
 
343
 
void *session_memdup(Session *session, const void* str, unsigned int size)
344
 
{
345
 
  return session->memdup(str, size);
346
 
}
347
 
 
348
 
void session_get_xid(const Session *session, DRIZZLE_XID *xid)
349
 
{
350
 
  *xid = *(DRIZZLE_XID *) &session->transaction.xid_state.xid;
351
 
}
352
 
 
353
 
#if defined(__cplusplus)
354
 
}
355
 
#endif
 
316
void Session::get_xid(DRIZZLE_XID *xid)
 
317
{
 
318
  *xid = *(DRIZZLE_XID *) &transaction.xid_state.xid;
 
319
}
356
320
 
357
321
/* Do operations that may take a long time */
358
322
 
369
333
#endif
370
334
  {
371
335
    TransactionServices &transaction_services= TransactionServices::singleton();
372
 
    transaction_services.ha_rollback_trans(this, true);
 
336
    transaction_services.rollbackTransaction(this, true);
373
337
    xid_cache_delete(&transaction.xid_state);
374
338
  }
375
 
  hash_free(&user_vars);
 
339
 
 
340
  for (UserVars::iterator iter= user_vars.begin();
 
341
       iter != user_vars.end();
 
342
       iter++)
 
343
  {
 
344
    user_var_entry *entry= (*iter).second;
 
345
    delete entry;
 
346
  }
 
347
  user_vars.clear();
 
348
 
 
349
 
376
350
  close_temporary_tables();
377
351
 
378
352
  if (global_read_lock)
384
358
Session::~Session()
385
359
{
386
360
  this->checkSentry();
387
 
  add_to_status(&global_status_var, &status_var);
388
361
 
389
362
  if (client->isConnected())
390
363
  {
406
379
  plugin::StorageEngine::closeConnection(this);
407
380
  plugin_sessionvar_cleanup(this);
408
381
 
409
 
  free_root(&warn_root,MYF(0));
 
382
  warn_root.free_root(MYF(0));
410
383
  mysys_var=0;                                  // Safety (shouldn't be needed)
411
384
  dbug_sentry= Session_SENTRY_GONE;
412
385
 
413
 
  free_root(&main_mem_root, MYF(0));
 
386
  main_mem_root.free_root(MYF(0));
414
387
  pthread_setspecific(THR_Session,  0);
415
388
 
416
389
  plugin::Logging::postEndDo(this);
 
390
  plugin::EventObserver::deregisterSessionEvents(*this); 
417
391
 
418
392
  /* Ensure that no one is using Session */
419
 
  pthread_mutex_unlock(&LOCK_delete);
420
 
  pthread_mutex_destroy(&LOCK_delete);
421
 
}
422
 
 
423
 
/*
424
 
  Add all status variables to another status variable array
425
 
 
426
 
  SYNOPSIS
427
 
   add_to_status()
428
 
   to_var       add to this array
429
 
   from_var     from this array
430
 
 
431
 
  NOTES
432
 
    This function assumes that all variables are long/ulong.
433
 
    If this assumption will change, then we have to explictely add
434
 
    the other variables after the while loop
435
 
*/
436
 
void add_to_status(system_status_var *to_var, system_status_var *from_var)
437
 
{
438
 
  ulong *end= (ulong*) ((unsigned char*) to_var +
439
 
                        offsetof(system_status_var, last_system_status_var) +
440
 
                        sizeof(ulong));
441
 
  ulong *to= (ulong*) to_var, *from= (ulong*) from_var;
442
 
 
443
 
  while (to != end)
444
 
    *(to++)+= *(from++);
445
 
}
446
 
 
447
 
/*
448
 
  Add the difference between two status variable arrays to another one.
449
 
 
450
 
  SYNOPSIS
451
 
    add_diff_to_status
452
 
    to_var       add to this array
453
 
    from_var     from this array
454
 
    dec_var      minus this array
455
 
 
456
 
  NOTE
457
 
    This function assumes that all variables are long/ulong.
458
 
*/
459
 
void add_diff_to_status(system_status_var *to_var, system_status_var *from_var,
460
 
                        system_status_var *dec_var)
461
 
{
462
 
  ulong *end= (ulong*) ((unsigned char*) to_var + offsetof(system_status_var,
463
 
                                                  last_system_status_var) +
464
 
                        sizeof(ulong));
465
 
  ulong *to= (ulong*) to_var, *from= (ulong*) from_var, *dec= (ulong*) dec_var;
466
 
 
467
 
  while (to != end)
468
 
    *(to++)+= *(from++) - *(dec++);
 
393
  LOCK_delete.unlock();
469
394
}
470
395
 
471
396
void Session::awake(Session::killed_state state_to_set)
540
465
    We have to call thr_lock_info_init() again here as Session may have been
541
466
    created in another thread
542
467
  */
543
 
  thr_lock_info_init(&lock_info);
 
468
  lock_info.init();
 
469
 
544
470
  return false;
545
471
}
546
472
 
560
486
  command= COM_SLEEP;
561
487
  set_time();
562
488
 
563
 
  reset_root_defaults(mem_root, variables.query_alloc_block_size,
564
 
                      variables.query_prealloc_size);
 
489
  mem_root->reset_root_defaults(variables.query_alloc_block_size,
 
490
                                variables.query_prealloc_size);
565
491
  transaction.xid_state.xid.null();
566
492
  transaction.xid_state.in_session=1;
567
493
}
571
497
  if (storeGlobals())
572
498
  {
573
499
    disconnect(ER_OUT_OF_RESOURCES, true);
574
 
    statistic_increment(aborted_connects, &LOCK_status);
 
500
    status_var.aborted_connects++;
575
501
    return true;
576
502
  }
577
503
  return false;
603
529
 
604
530
  connection_count.increment();
605
531
 
606
 
  if (connection_count > max_used_connections)
607
 
    max_used_connections= connection_count;
 
532
  if (connection_count > current_global_counters.max_used_connections)
 
533
  {
 
534
    current_global_counters.max_used_connections= connection_count;
 
535
  }
608
536
 
609
537
  thread_id= variables.pseudo_thread_id= global_thread_id++;
610
538
 
611
 
  pthread_mutex_lock(&LOCK_thread_count);
 
539
  LOCK_thread_count.lock();
612
540
  getSessionList().push_back(this);
613
 
  pthread_mutex_unlock(&LOCK_thread_count);
 
541
  LOCK_thread_count.unlock();
614
542
 
615
543
  if (scheduler->addSession(this))
616
544
  {
619
547
 
620
548
    killed= Session::KILL_CONNECTION;
621
549
 
622
 
    statistic_increment(aborted_connects, &LOCK_status);
 
550
    status_var.aborted_connects++;
623
551
 
624
552
    /* Can't use my_error() since store_globals has not been called. */
625
553
    /* TODO replace will better error message */
633
561
}
634
562
 
635
563
 
636
 
const char* Session::enter_cond(pthread_cond_t *cond,
637
 
                                pthread_mutex_t* mutex,
638
 
                                const char* msg)
 
564
const char* Session::enter_cond(boost::condition_variable &cond, boost::mutex &mutex, const char* msg)
639
565
{
640
566
  const char* old_msg = get_proc_info();
641
567
  safe_mutex_assert_owner(mutex);
642
 
  mysys_var->current_mutex = mutex;
643
 
  mysys_var->current_cond = cond;
 
568
  mysys_var->current_mutex = mutex.native_handle();
 
569
  mysys_var->current_cond = cond.native_handle();
644
570
  this->set_proc_info(msg);
645
571
  return old_msg;
646
572
}
667
593
  if (client->authenticate())
668
594
    return false;
669
595
 
670
 
  statistic_increment(aborted_connects, &LOCK_status);
 
596
  status_var.aborted_connects++;
 
597
 
671
598
  return true;
672
599
}
673
600
 
680
607
 
681
608
  if (is_authenticated != true)
682
609
  {
 
610
    status_var.access_denied++;
683
611
    /* isAuthenticated has pushed the error message */
684
612
    return false;
685
613
  }
772
700
       * (Which of course should never happen...)
773
701
       */
774
702
      server_status&= ~SERVER_STATUS_IN_TRANS;
775
 
      if (transaction_services.ha_commit_trans(this, true))
 
703
      if (transaction_services.commitTransaction(this, true))
776
704
        result= false;
777
705
      options&= ~(OPTION_BEGIN);
778
706
      break;
789
717
    case ROLLBACK_AND_CHAIN:
790
718
    {
791
719
      server_status&= ~SERVER_STATUS_IN_TRANS;
792
 
      if (transaction_services.ha_rollback_trans(this, true))
 
720
      if (transaction_services.rollbackTransaction(this, true))
793
721
        result= false;
794
722
      options&= ~(OPTION_BEGIN);
795
723
      if (result == true && (completion == ROLLBACK_AND_CHAIN))
822
750
  if (options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
823
751
  {
824
752
    server_status&= ~SERVER_STATUS_IN_TRANS;
825
 
    if (transaction_services.ha_commit_trans(this, true))
 
753
    if (transaction_services.commitTransaction(this, true))
826
754
      result= false;
827
755
  }
828
756
  options&= ~(OPTION_BEGIN);
873
801
  free_items();
874
802
  /* Reset where. */
875
803
  where= Session::DEFAULT_WHERE;
 
804
 
 
805
  /* Reset the temporary shares we built */
 
806
  for (std::vector<TableShareInstance *>::iterator iter= temporary_shares.begin();
 
807
       iter != temporary_shares.end(); iter++)
 
808
  {
 
809
    delete *iter;
 
810
  }
 
811
  temporary_shares.clear();
876
812
}
877
813
 
878
814
/**
899
835
  if (allocate_lex_string)
900
836
    if (!(lex_str= (LEX_STRING *)alloc(sizeof(LEX_STRING))))
901
837
      return 0;
902
 
  if (!(lex_str->str= strmake_root(mem_root, str, length)))
 
838
  if (!(lex_str->str= mem_root->strmake_root(str, length)))
903
839
    return 0;
904
840
  lex_str->length= length;
905
841
  return lex_str;
1048
984
 
1049
985
  if (!internal::dirname_length(exchange->file_name))
1050
986
  {
1051
 
    strcpy(path, drizzle_real_data_home);
 
987
    strcpy(path, data_home_real);
1052
988
    if (! session->db.empty())
1053
 
      strncat(path, session->db.c_str(), FN_REFLEN-strlen(drizzle_real_data_home)-1);
 
989
      strncat(path, session->db.c_str(), FN_REFLEN-strlen(data_home_real)-1);
1054
990
    (void) internal::fn_format(path, exchange->file_name, path, "", option);
1055
991
  }
1056
992
  else
1057
 
    (void) internal::fn_format(path, exchange->file_name, drizzle_real_data_home, "", option);
 
993
    (void) internal::fn_format(path, exchange->file_name, data_home_real, "", option);
1058
994
 
1059
995
  if (opt_secure_file_priv &&
1060
996
      strncmp(opt_secure_file_priv, path, strlen(opt_secure_file_priv)))
1589
1525
}
1590
1526
 
1591
1527
 
1592
 
/****************************************************************************
1593
 
  Handling of open and locked tables states.
1594
 
 
1595
 
  This is used when we want to open/lock (and then close) some tables when
1596
 
  we already have a set of tables open and locked. We use these methods for
1597
 
  access to mysql.proc table to find definitions of stored routines.
1598
 
****************************************************************************/
1599
 
 
1600
 
void Session::reset_n_backup_open_tables_state(Open_tables_state *backup)
1601
 
{
1602
 
  backup->set_open_tables_state(this);
1603
 
  reset_open_tables_state();
1604
 
  backups_available= false;
1605
 
}
1606
 
 
1607
 
 
1608
 
void Session::restore_backup_open_tables_state(Open_tables_state *backup)
1609
 
{
1610
 
  /*
1611
 
    Before we will throw away current open tables state we want
1612
 
    to be sure that it was properly cleaned up.
1613
 
  */
1614
 
  assert(open_tables == 0 && temporary_tables == 0 &&
1615
 
              derived_tables == 0 &&
1616
 
              lock == 0);
1617
 
  set_open_tables_state(backup);
1618
 
}
1619
 
 
1620
1528
bool Session::set_db(const std::string &new_db)
1621
1529
{
1622
1530
  /* Do not reallocate memory if current chunk is big enough. */
1637
1545
  @retval 0 the user thread is active
1638
1546
  @retval 1 the user thread has been killed
1639
1547
*/
1640
 
extern "C" int session_killed(const Session *session)
 
1548
int session_killed(const Session *session)
1641
1549
{
1642
1550
  return(session->killed);
1643
1551
}
1644
1552
 
1645
 
/**
1646
 
  Return the session id of a user session
1647
 
  @param pointer to Session object
1648
 
  @return session's id
1649
 
*/
1650
 
extern "C" unsigned long session_get_thread_id(const Session *session)
1651
 
{
1652
 
  return (unsigned long) session->getSessionId();
1653
 
}
1654
 
 
1655
1553
 
1656
1554
const struct charset_info_st *session_charset(Session *session)
1657
1555
{
1658
1556
  return(session->charset());
1659
1557
}
1660
1558
 
1661
 
int session_non_transactional_update(const Session *session)
1662
 
{
1663
 
  return(session->transaction.all.hasModifiedNonTransData());
1664
 
}
1665
 
 
1666
 
void session_mark_transaction_to_rollback(Session *session, bool all)
1667
 
{
1668
 
  mark_transaction_to_rollback(session, all);
1669
 
}
1670
 
 
1671
1559
/**
1672
1560
  Mark transaction to rollback and mark error as fatal to a sub-statement.
1673
1561
 
1690
1578
 
1691
1579
  /* If necessary, log any aborted or unauthorized connections */
1692
1580
  if (killed || client->wasAborted())
1693
 
    statistic_increment(aborted_threads, &LOCK_status);
 
1581
  {
 
1582
    status_var.aborted_threads++;
 
1583
  }
1694
1584
 
1695
1585
  if (client->wasAborted())
1696
1586
  {
1709
1599
 
1710
1600
  /* Close out our connection to the client */
1711
1601
  if (should_lock)
1712
 
    (void) pthread_mutex_lock(&LOCK_thread_count);
 
1602
    LOCK_thread_count.lock();
1713
1603
  killed= Session::KILL_CONNECTION;
1714
1604
  if (client->isConnected())
1715
1605
  {
1721
1611
    client->close();
1722
1612
  }
1723
1613
  if (should_lock)
1724
 
    (void) pthread_mutex_unlock(&LOCK_thread_count);
 
1614
    (void) LOCK_thread_count.unlock();
1725
1615
}
1726
1616
 
1727
1617
void Session::reset_for_next_command()
1759
1649
 
1760
1650
  for (table= temporary_tables; table; table= tmp_next)
1761
1651
  {
1762
 
    tmp_next= table->next;
 
1652
    tmp_next= table->getNext();
1763
1653
    nukeTable(table);
1764
1654
  }
1765
1655
  temporary_tables= NULL;
1771
1661
 
1772
1662
void Session::close_temporary_table(Table *table)
1773
1663
{
1774
 
  if (table->prev)
 
1664
  if (table->getPrev())
1775
1665
  {
1776
 
    table->prev->next= table->next;
1777
 
    if (table->prev->next)
1778
 
      table->next->prev= table->prev;
 
1666
    table->getPrev()->setNext(table->getNext());
 
1667
    if (table->getPrev()->getNext())
 
1668
    {
 
1669
      table->getNext()->setPrev(table->getPrev());
 
1670
    }
1779
1671
  }
1780
1672
  else
1781
1673
  {
1786
1678
      passing non-zero value to end_slave via rli->save_temporary_tables
1787
1679
      when no temp tables opened, see an invariant below.
1788
1680
    */
1789
 
    temporary_tables= table->next;
 
1681
    temporary_tables= table->getNext();
1790
1682
    if (temporary_tables)
1791
 
      table->next->prev= NULL;
 
1683
    {
 
1684
      table->getNext()->setPrev(NULL);
 
1685
    }
1792
1686
  }
1793
1687
  nukeTable(table);
1794
1688
}
1803
1697
 
1804
1698
void Session::nukeTable(Table *table)
1805
1699
{
1806
 
  plugin::StorageEngine *table_type= table->s->db_type();
 
1700
  plugin::StorageEngine *table_type= table->getShare()->db_type();
1807
1701
 
1808
1702
  table->free_io_cache();
1809
 
  table->closefrm(false);
 
1703
  table->delete_table();
1810
1704
 
1811
 
  TableIdentifier identifier(table->s->getSchemaName(), table->s->table_name.str, table->s->path.str);
 
1705
  TableIdentifier identifier(table->getShare()->getSchemaName(), table->getShare()->getTableName(), table->getShare()->getPath());
1812
1706
  rm_temporary_table(table_type, identifier);
1813
1707
 
1814
 
  table->s->free_table_share();
 
1708
  delete table->getMutableShare();
1815
1709
 
1816
1710
  /* This makes me sad, but we're allocating it via malloc */
1817
 
  free(table);
 
1711
  delete table;
1818
1712
}
1819
1713
 
1820
1714
/** Clear most status variables. */
1821
1715
extern time_t flush_status_time;
1822
 
extern uint32_t max_used_connections;
1823
1716
 
1824
1717
void Session::refresh_status()
1825
1718
{
1826
 
  pthread_mutex_lock(&LOCK_status);
1827
 
 
1828
 
  /* Add thread's status variabes to global status */
1829
 
  add_to_status(&global_status_var, &status_var);
1830
 
 
1831
1719
  /* Reset thread's status variables */
1832
1720
  memset(&status_var, 0, sizeof(status_var));
1833
1721
 
1834
 
  /* Reset some global variables */
1835
 
  reset_status_vars();
1836
 
 
1837
 
  /* Reset the counters of all key caches (default and named). */
1838
 
  reset_key_cache_counters();
1839
1722
  flush_status_time= time((time_t*) 0);
1840
 
  max_used_connections= 1; /* We set it to one, because we know we exist */
1841
 
  pthread_mutex_unlock(&LOCK_status);
 
1723
  current_global_counters.max_used_connections= 1; /* We set it to one, because we know we exist */
1842
1724
}
1843
1725
 
1844
1726
user_var_entry *Session::getVariable(LEX_STRING &name, bool create_if_not_exists)
1845
1727
{
1846
1728
  user_var_entry *entry= NULL;
 
1729
  UserVarsRange ppp= user_vars.equal_range(std::string(name.str, name.length));
1847
1730
 
1848
 
  entry= (user_var_entry*) hash_search(&user_vars, (unsigned char*) name.str, name.length);
 
1731
  for (UserVars::iterator iter= ppp.first;
 
1732
         iter != ppp.second; ++iter)
 
1733
  {
 
1734
    entry= (*iter).second;
 
1735
  }
1849
1736
 
1850
1737
  if ((entry == NULL) && create_if_not_exists)
1851
1738
  {
1852
 
    if (!hash_inited(&user_vars))
1853
 
      return NULL;
1854
1739
    entry= new (nothrow) user_var_entry(name.str, query_id);
1855
1740
 
1856
1741
    if (entry == NULL)
1857
1742
      return NULL;
1858
1743
 
1859
 
    if (my_hash_insert(&user_vars, (unsigned char*) entry))
 
1744
    std::pair<UserVars::iterator, bool> returnable= user_vars.insert(make_pair(std::string(name.str, name.length), entry));
 
1745
 
 
1746
    if (not returnable.second)
1860
1747
    {
1861
 
      assert(1);
1862
 
      free((char*) entry);
1863
 
      return 0;
 
1748
      delete entry;
 
1749
      return NULL;
1864
1750
    }
1865
 
 
1866
1751
  }
1867
1752
 
1868
1753
  return entry;
1870
1755
 
1871
1756
void Session::mark_temp_tables_as_free_for_reuse()
1872
1757
{
1873
 
  for (Table *table= temporary_tables ; table ; table= table->next)
 
1758
  for (Table *table= temporary_tables ; table ; table= table->getNext())
1874
1759
  {
1875
1760
    if (table->query_id == query_id)
1876
1761
    {
1882
1767
 
1883
1768
void Session::mark_used_tables_as_free_for_reuse(Table *table)
1884
1769
{
1885
 
  for (; table ; table= table->next)
 
1770
  for (; table ; table= table->getNext())
1886
1771
  {
1887
1772
    if (table->query_id == query_id)
1888
1773
    {
1903
1788
*/
1904
1789
void Session::close_thread_tables()
1905
1790
{
1906
 
  Table *table;
1907
 
 
1908
 
  /*
1909
 
    We are assuming here that session->derived_tables contains ONLY derived
1910
 
    tables for this substatement. i.e. instead of approach which uses
1911
 
    query_id matching for determining which of the derived tables belong
1912
 
    to this substatement we rely on the ability of substatements to
1913
 
    save/restore session->derived_tables during their execution.
1914
 
 
1915
 
    TODO: Probably even better approach is to simply associate list of
1916
 
          derived tables with (sub-)statement instead of thread and destroy
1917
 
          them at the end of its execution.
1918
 
  */
1919
1791
  if (derived_tables)
1920
 
  {
1921
 
    Table *next;
1922
 
    /*
1923
 
      Close all derived tables generated in queries like
1924
 
      SELECT * FROM (SELECT * FROM t1)
1925
 
    */
1926
 
    for (table= derived_tables ; table ; table= next)
1927
 
    {
1928
 
      next= table->next;
1929
 
      table->free_tmp_table(this);
1930
 
    }
1931
 
    derived_tables= 0;
1932
 
  }
 
1792
    derived_tables= NULL; // They should all be invalid by this point
1933
1793
 
1934
1794
  /*
1935
1795
    Mark all temporary tables used by this statement as free for reuse.
1943
1803
    does not belong to statement for which we do close_thread_tables()).
1944
1804
    TODO: This should be fixed in later releases.
1945
1805
   */
1946
 
  if (backups_available == false)
1947
1806
  {
1948
1807
    TransactionServices &transaction_services= TransactionServices::singleton();
1949
1808
    main_da.can_overwrite_status= true;
1950
 
    transaction_services.ha_autocommit_or_rollback(this, is_error());
 
1809
    transaction_services.autocommitOrRollback(this, is_error());
1951
1810
    main_da.can_overwrite_status= false;
1952
1811
    transaction.stmt.reset();
1953
1812
  }
2022
1881
  assert(ret == false);
2023
1882
  if (open_tables_from_list(&tables, &counter, flags) ||
2024
1883
      mysql_handle_derived(lex, &mysql_derived_prepare))
 
1884
  {
2025
1885
    return true;
 
1886
  }
2026
1887
  return false;
2027
1888
}
2028
1889
 
2029
 
bool Session::rm_temporary_table(TableIdentifier &identifier)
 
1890
/*
 
1891
  @note "best_effort" is used in cases were if a failure occurred on this
 
1892
  operation it would not be surprising because we are only removing because there
 
1893
  might be an issue (lame engines).
 
1894
*/
 
1895
 
 
1896
bool Session::rm_temporary_table(TableIdentifier &identifier, bool best_effort)
2030
1897
{
2031
1898
  if (plugin::StorageEngine::dropTable(*this, identifier))
2032
1899
  {
2033
 
    errmsg_printf(ERRMSG_LVL_WARN, _("Could not remove temporary table: '%s', error: %d"),
2034
 
                  identifier.getSQLPath().c_str(), errno);
2035
 
    dumpTemporaryTableNames("rm_temporary_table()");
 
1900
    if (not best_effort)
 
1901
    {
 
1902
      errmsg_printf(ERRMSG_LVL_WARN, _("Could not remove temporary table: '%s', error: %d"),
 
1903
                    identifier.getSQLPath().c_str(), errno);
 
1904
    }
2036
1905
 
2037
1906
    return true;
2038
1907
  }
2048
1917
  {
2049
1918
    errmsg_printf(ERRMSG_LVL_WARN, _("Could not remove temporary table: '%s', error: %d"),
2050
1919
                  identifier.getSQLPath().c_str(), errno);
2051
 
    dumpTemporaryTableNames("rm_temporary_table()");
2052
1920
 
2053
1921
    return true;
2054
1922
  }
2068
1936
    return;
2069
1937
 
2070
1938
  cerr << "Begin Run: " << foo << "\n";
2071
 
  for (table= temporary_tables; table; table= table->next)
 
1939
  for (table= temporary_tables; table; table= table->getNext())
2072
1940
  {
2073
1941
    bool have_proto= false;
2074
1942
 
2075
 
    message::Table *proto= table->s->getTableProto();
2076
 
    if (table->s->getTableProto())
 
1943
    message::Table *proto= table->getShare()->getTableProto();
 
1944
    if (table->getShare()->getTableProto())
2077
1945
      have_proto= true;
2078
1946
 
2079
1947
    const char *answer= have_proto ? "true" : "false";
2080
1948
 
2081
1949
    if (have_proto)
2082
1950
    {
2083
 
      cerr << "\tTable Name " << table->s->getSchemaName() << "." << table->s->table_name.str << " : " << answer << "\n";
 
1951
      cerr << "\tTable Name " << table->getShare()->getSchemaName() << "." << table->getShare()->getTableName() << " : " << answer << "\n";
2084
1952
      cerr << "\t\t Proto " << proto->schema() << " " << proto->name() << "\n";
2085
1953
    }
2086
1954
    else
2087
 
      cerr << "\tTabl;e Name " << table->s->getSchemaName() << "." << table->s->table_name.str << " : " << answer << "\n";
 
1955
      cerr << "\tTabl;e Name " << table->getShare()->getSchemaName() << "." << table->getShare()->getTableName() << " : " << answer << "\n";
2088
1956
  }
2089
1957
}
2090
1958
 
2091
 
bool Session::storeTableMessage(TableIdentifier &identifier, message::Table &table_message)
 
1959
bool Session::storeTableMessage(const TableIdentifier &identifier, message::Table &table_message)
2092
1960
{
2093
1961
  table_message_cache.insert(make_pair(identifier.getPath(), table_message));
2094
1962
 
2095
1963
  return true;
2096
1964
}
2097
1965
 
2098
 
bool Session::removeTableMessage(TableIdentifier &identifier)
 
1966
bool Session::removeTableMessage(const TableIdentifier &identifier)
2099
1967
{
2100
1968
  TableMessageCache::iterator iter;
2101
1969
 
2109
1977
  return true;
2110
1978
}
2111
1979
 
2112
 
bool Session::getTableMessage(TableIdentifier &identifier, message::Table &table_message)
 
1980
bool Session::getTableMessage(const TableIdentifier &identifier, message::Table &table_message)
2113
1981
{
2114
1982
  TableMessageCache::iterator iter;
2115
1983
 
2123
1991
  return true;
2124
1992
}
2125
1993
 
2126
 
bool Session::doesTableMessageExist(TableIdentifier &identifier)
 
1994
bool Session::doesTableMessageExist(const TableIdentifier &identifier)
2127
1995
{
2128
1996
  TableMessageCache::iterator iter;
2129
1997
 
2137
2005
  return true;
2138
2006
}
2139
2007
 
2140
 
bool Session::renameTableMessage(TableIdentifier &from, TableIdentifier &to)
 
2008
bool Session::renameTableMessage(const TableIdentifier &from, const TableIdentifier &to)
2141
2009
{
2142
2010
  TableMessageCache::iterator iter;
2143
2011
 
2156
2024
  return true;
2157
2025
}
2158
2026
 
 
2027
TableShareInstance *Session::getTemporaryShare(TableIdentifier::Type type_arg)
 
2028
{
 
2029
  temporary_shares.push_back(new TableShareInstance(type_arg)); // This will not go into the tableshare cache, so no key is used.
 
2030
 
 
2031
  TableShareInstance *tmp_share= temporary_shares.back();
 
2032
 
 
2033
  assert(tmp_share);
 
2034
 
 
2035
  return tmp_share;
 
2036
}
 
2037
 
2159
2038
} /* namespace drizzled */