~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/session.cc

  • Committer: Brian Aker
  • Date: 2010-08-10 01:34:18 UTC
  • mto: This revision was merged to the branch mainline in revision 1703.
  • Revision ID: brian@gaz-20100810013418-lcyhyrx5elzuvjmn
Encapsulate the internal share for HEAP.

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
 */
23
23
 
24
24
#include "config.h"
25
 
#include "drizzled/session.h"
26
 
#include "drizzled/session/cache.h"
 
25
#include <drizzled/session.h>
 
26
#include "drizzled/session_list.h"
27
27
#include <sys/stat.h>
28
 
#include "drizzled/error.h"
29
 
#include "drizzled/gettext.h"
30
 
#include "drizzled/query_id.h"
31
 
#include "drizzled/data_home.h"
32
 
#include "drizzled/sql_base.h"
33
 
#include "drizzled/lock.h"
34
 
#include "drizzled/item/cache.h"
35
 
#include "drizzled/item/float.h"
36
 
#include "drizzled/item/return_int.h"
37
 
#include "drizzled/item/empty_string.h"
38
 
#include "drizzled/show.h"
39
 
#include "drizzled/plugin/client.h"
 
28
#include <drizzled/error.h>
 
29
#include <drizzled/gettext.h>
 
30
#include <drizzled/query_id.h>
 
31
#include <drizzled/data_home.h>
 
32
#include <drizzled/sql_base.h>
 
33
#include <drizzled/lock.h>
 
34
#include <drizzled/item/cache.h>
 
35
#include <drizzled/item/float.h>
 
36
#include <drizzled/item/return_int.h>
 
37
#include <drizzled/item/empty_string.h>
 
38
#include <drizzled/show.h>
 
39
#include <drizzled/plugin/client.h>
40
40
#include "drizzled/plugin/scheduler.h"
41
41
#include "drizzled/plugin/authentication.h"
42
42
#include "drizzled/plugin/logging.h"
43
43
#include "drizzled/plugin/transactional_storage_engine.h"
44
 
#include "drizzled/plugin/query_rewrite.h"
45
44
#include "drizzled/probes.h"
46
45
#include "drizzled/table_proto.h"
47
46
#include "drizzled/db.h"
49
48
#include "drizzled/transaction_services.h"
50
49
#include "drizzled/drizzled.h"
51
50
 
52
 
#include "drizzled/table/instance.h"
 
51
#include "drizzled/table_share_instance.h"
53
52
 
54
53
#include "plugin/myisam/myisam.h"
55
54
#include "drizzled/internal/iocache.h"
56
55
#include "drizzled/internal/thread_var.h"
57
56
#include "drizzled/plugin/event_observer.h"
58
57
 
59
 
#include "drizzled/util/functors.h"
60
 
 
61
 
#include "drizzled/display.h"
62
 
 
63
58
#include <fcntl.h>
64
59
#include <algorithm>
65
60
#include <climits>
66
 
#include <boost/filesystem.hpp>
67
 
 
68
 
#include "drizzled/util/backtrace.h"
69
61
 
70
62
using namespace std;
71
 
 
72
 
namespace fs=boost::filesystem;
73
63
namespace drizzled
74
64
{
75
65
 
81
71
char empty_c_string[1]= {0};    /* used for not defined db */
82
72
 
83
73
const char * const Session::DEFAULT_WHERE= "field list";
 
74
extern pthread_key_t THR_Session;
 
75
extern pthread_key_t THR_Mem_root;
84
76
 
85
77
bool Key_part_spec::operator==(const Key_part_spec& other) const
86
78
{
87
79
  return length == other.length &&
88
80
         field_name.length == other.field_name.length &&
89
 
    !my_strcasecmp(system_charset_info, field_name.str, other.field_name.str);
 
81
         !strcmp(field_name.str, other.field_name.str);
90
82
}
91
83
 
92
84
Open_tables_state::Open_tables_state(uint64_t version_arg) :
162
154
Session::Session(plugin::Client *client_arg) :
163
155
  Open_tables_state(refresh_version),
164
156
  mem_root(&main_mem_root),
165
 
  xa_id(0),
166
157
  lex(&main_lex),
167
 
  query(new std::string),
168
 
  _schema(new std::string("")),
169
 
  catalog("LOCAL"),
 
158
  query(),
170
159
  client(client_arg),
171
160
  scheduler(NULL),
172
161
  scheduler_arg(NULL),
173
162
  lock_id(&main_lock_id),
174
163
  user_time(0),
175
164
  ha_data(plugin::num_trx_monitored_objects),
176
 
  concurrent_execute_allowed(true),
177
165
  arg_of_last_insert_id_function(false),
178
166
  first_successful_insert_id_in_prev_stmt(0),
179
167
  first_successful_insert_id_in_cur_stmt(0),
180
168
  limit_found_rows(0),
181
 
  _global_read_lock(NONE),
182
 
  _killed(NOT_KILLED),
 
169
  global_read_lock(0),
183
170
  some_tables_deleted(false),
184
171
  no_errors(false),
185
172
  password(false),
192
179
  cached_table(0),
193
180
  transaction_message(NULL),
194
181
  statement_message(NULL),
195
 
  session_event_observers(NULL),
196
 
  use_usage(false)
 
182
  session_event_observers(NULL)
197
183
{
 
184
  memset(process_list_info, 0, PROCESS_LIST_WIDTH);
198
185
  client->setSession(this);
199
186
 
200
187
  /*
205
192
  memory::init_sql_alloc(&main_mem_root, memory::ROOT_MIN_BLOCK_SIZE, 0);
206
193
  thread_stack= NULL;
207
194
  count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;
 
195
  killed= NOT_KILLED;
208
196
  col_access= 0;
209
197
  tmp_table= 0;
210
198
  used_tables= 0;
224
212
  mysys_var= 0;
225
213
  scoreboard_index= -1;
226
214
  dbug_sentry=Session_SENTRY_MAGIC;
227
 
  cleanup_done= abort_on_warning= no_warnings_for_error= false;  
228
 
 
229
 
  /* query_cache init */
230
 
  query_cache_key= "";
231
 
  resultset= NULL;
 
215
  cleanup_done= abort_on_warning= no_warnings_for_error= false;
232
216
 
233
217
  /* Variables with default values */
234
218
  proc_info="login";
302
286
  return false;                                 // 'false', as per coding style
303
287
}
304
288
 
305
 
void Session::setAbort(bool arg)
306
 
{
307
 
  mysys_var->abort= arg;
308
 
}
309
 
 
310
 
void Session::lockOnSys()
311
 
{
312
 
  if (not mysys_var)
313
 
    return;
314
 
 
315
 
  setAbort(true);
316
 
  boost_unique_lock_t scopedLock(mysys_var->mutex);
317
 
  if (mysys_var->current_cond)
318
 
  {
319
 
    mysys_var->current_mutex->lock();
320
 
    mysys_var->current_cond->notify_all();
321
 
    mysys_var->current_mutex->unlock();
322
 
  }
323
 
}
324
 
 
325
289
void Session::pop_internal_handler()
326
290
{
327
291
  assert(m_internal_handler != NULL);
339
303
{
340
304
  assert(cleanup_done == false);
341
305
 
342
 
  setKilled(KILL_CONNECTION);
 
306
  killed= KILL_CONNECTION;
343
307
#ifdef ENABLE_WHEN_BINLOG_WILL_BE_ABLE_TO_PREPARE
344
308
  if (transaction.xid_state.xa_state == XA_PREPARED)
345
309
  {
365
329
  close_temporary_tables();
366
330
 
367
331
  if (global_read_lock)
368
 
  {
369
 
    unlockGlobalReadLock();
370
 
  }
 
332
    unlock_global_read_lock(this);
371
333
 
372
334
  cleanup_done= true;
373
335
}
401
363
  dbug_sentry= Session_SENTRY_GONE;
402
364
 
403
365
  main_mem_root.free_root(MYF(0));
404
 
  currentMemRoot().release();
405
 
  currentSession().release();
 
366
  pthread_setspecific(THR_Session,  0);
406
367
 
407
368
  plugin::Logging::postEndDo(this);
408
369
  plugin::EventObserver::deregisterSessionEvents(*this); 
409
370
 
410
 
  for (PropertyMap::iterator iter= life_properties.begin(); iter != life_properties.end(); iter++)
411
 
  {
412
 
    delete (*iter).second;
413
 
  }
414
 
  life_properties.clear();
415
 
}
416
 
 
417
 
void Session::setClient(plugin::Client *client_arg)
418
 
{
419
 
  client= client_arg;
420
 
  client->setSession(this);
421
 
}
422
 
 
423
 
void Session::awake(Session::killed_state_t state_to_set)
424
 
{
425
 
  if ((state_to_set == Session::KILL_QUERY) and (command == COM_SLEEP))
426
 
    return;
427
 
 
 
371
  /* Ensure that no one is using Session */
 
372
  LOCK_delete.unlock();
 
373
}
 
374
 
 
375
void Session::awake(Session::killed_state state_to_set)
 
376
{
428
377
  this->checkSentry();
429
 
 
430
 
  setKilled(state_to_set);
431
 
  scheduler->killSession(this);
432
 
 
 
378
  safe_mutex_assert_owner(&LOCK_delete);
 
379
 
 
380
  killed= state_to_set;
433
381
  if (state_to_set != Session::KILL_QUERY)
434
382
  {
 
383
    scheduler->killSession(this);
435
384
    DRIZZLE_CONNECTION_DONE(thread_id);
436
385
  }
437
 
 
438
386
  if (mysys_var)
439
387
  {
440
 
    boost_unique_lock_t scopedLock(mysys_var->mutex);
 
388
    pthread_mutex_lock(&mysys_var->mutex);
441
389
    /*
442
 
      "
443
390
      This broadcast could be up in the air if the victim thread
444
391
      exits the cond in the time between read and broadcast, but that is
445
392
      ok since all we want to do is to make the victim thread get out
460
407
    */
461
408
    if (mysys_var->current_cond && mysys_var->current_mutex)
462
409
    {
463
 
      mysys_var->current_mutex->lock();
464
 
      mysys_var->current_cond->notify_all();
465
 
      mysys_var->current_mutex->unlock();
 
410
      pthread_mutex_lock(mysys_var->current_mutex);
 
411
      pthread_cond_broadcast(mysys_var->current_cond);
 
412
      pthread_mutex_unlock(mysys_var->current_mutex);
466
413
    }
 
414
    pthread_mutex_unlock(&mysys_var->mutex);
467
415
  }
468
416
}
469
417
 
479
427
  */
480
428
  assert(thread_stack);
481
429
 
482
 
  currentSession().release();
483
 
  currentSession().reset(this);
484
 
 
485
 
  currentMemRoot().release();
486
 
  currentMemRoot().reset(&mem_root);
 
430
  if (pthread_setspecific(THR_Session,  this) ||
 
431
      pthread_setspecific(THR_Mem_root, &mem_root))
 
432
    return true;
487
433
 
488
434
  mysys_var=my_thread_var;
489
435
 
492
438
    This allows us to move Session to different threads if needed.
493
439
  */
494
440
  mysys_var->id= thread_id;
 
441
  real_id= pthread_self();                      // For debugging
495
442
 
496
443
  /*
497
444
    We have to call thr_lock_info_init() again here as Session may have been
522
469
                                variables.query_prealloc_size);
523
470
  transaction.xid_state.xid.null();
524
471
  transaction.xid_state.in_session=1;
525
 
  if (use_usage)
526
 
    resetUsage();
527
472
}
528
473
 
529
474
bool Session::initGlobals()
531
476
  if (storeGlobals())
532
477
  {
533
478
    disconnect(ER_OUT_OF_RESOURCES, true);
534
 
    status_var.aborted_connects++;
 
479
    status_var_increment(status_var.aborted_connects); 
535
480
    return true;
536
481
  }
537
482
  return false;
547
492
 
548
493
  prepareForQueries();
549
494
 
550
 
  while (not client->haveError() && getKilled() != KILL_CONNECTION)
 
495
  while (! client->haveError() && killed != KILL_CONNECTION)
551
496
  {
552
 
    if (not executeStatement())
 
497
    if (! executeStatement())
553
498
      break;
554
499
  }
555
500
 
556
501
  disconnect(0, true);
557
502
}
558
503
 
559
 
bool Session::schedule(Session::shared_ptr &arg)
 
504
bool Session::schedule()
560
505
{
561
 
  arg->scheduler= plugin::Scheduler::getScheduler();
562
 
  assert(arg->scheduler);
 
506
  scheduler= plugin::Scheduler::getScheduler();
 
507
  assert(scheduler);
563
508
 
564
509
  connection_count.increment();
565
510
 
568
513
    current_global_counters.max_used_connections= connection_count;
569
514
  }
570
515
 
571
 
  current_global_counters.connections++;
572
 
  arg->thread_id= arg->variables.pseudo_thread_id= global_thread_id++;
573
 
 
574
 
  session::Cache::singleton().insert(arg);
575
 
 
576
 
  if (unlikely(plugin::EventObserver::connectSession(*arg)))
577
 
  {
578
 
    // We should do something about an error...
579
 
  }
580
 
 
581
 
  if (plugin::Scheduler::getScheduler()->addSession(arg))
582
 
  {
583
 
    DRIZZLE_CONNECTION_START(arg->getSessionId());
 
516
  thread_id= variables.pseudo_thread_id= global_thread_id++;
 
517
 
 
518
  LOCK_thread_count.lock();
 
519
  getSessionList().push_back(this);
 
520
  LOCK_thread_count.unlock();
 
521
 
 
522
  if (scheduler->addSession(this))
 
523
  {
 
524
    DRIZZLE_CONNECTION_START(thread_id);
584
525
    char error_message_buff[DRIZZLE_ERRMSG_SIZE];
585
526
 
586
 
    arg->setKilled(Session::KILL_CONNECTION);
 
527
    killed= Session::KILL_CONNECTION;
587
528
 
588
 
    arg->status_var.aborted_connects++;
 
529
    status_var_increment(status_var.aborted_connects);
589
530
 
590
531
    /* Can't use my_error() since store_globals has not been called. */
591
532
    /* TODO replace will better error message */
592
533
    snprintf(error_message_buff, sizeof(error_message_buff),
593
534
             ER(ER_CANT_CREATE_THREAD), 1);
594
 
    arg->client->sendError(ER_CANT_CREATE_THREAD, error_message_buff);
595
 
 
 
535
    client->sendError(ER_CANT_CREATE_THREAD, error_message_buff);
596
536
    return true;
597
537
  }
598
538
 
600
540
}
601
541
 
602
542
 
603
 
/*
604
 
  Is this session viewable by the current user?
605
 
*/
606
 
bool Session::isViewable() const
607
 
{
608
 
  return plugin::Authorization::isAuthorized(current_session->getSecurityContext(),
609
 
                                             this,
610
 
                                             false);
611
 
}
612
 
 
613
 
 
614
 
const char* Session::enter_cond(boost::condition_variable_any &cond, boost::mutex &mutex, const char* msg)
 
543
const char* Session::enter_cond(pthread_cond_t *cond,
 
544
                                pthread_mutex_t* mutex,
 
545
                                const char* msg)
615
546
{
616
547
  const char* old_msg = get_proc_info();
617
548
  safe_mutex_assert_owner(mutex);
618
 
  mysys_var->current_mutex = &mutex;
619
 
  mysys_var->current_cond = &cond;
 
549
  mysys_var->current_mutex = mutex;
 
550
  mysys_var->current_cond = cond;
620
551
  this->set_proc_info(msg);
621
552
  return old_msg;
622
553
}
629
560
    locked (if that would not be the case, you'll get a deadlock if someone
630
561
    does a Session::awake() on you).
631
562
  */
632
 
  mysys_var->current_mutex->unlock();
633
 
  boost_unique_lock_t scopedLock(mysys_var->mutex);
 
563
  pthread_mutex_unlock(mysys_var->current_mutex);
 
564
  pthread_mutex_lock(&mysys_var->mutex);
634
565
  mysys_var->current_mutex = 0;
635
566
  mysys_var->current_cond = 0;
636
567
  this->set_proc_info(old_msg);
 
568
  pthread_mutex_unlock(&mysys_var->mutex);
637
569
}
638
570
 
639
571
bool Session::authenticate()
640
572
{
641
 
  lex->start(this);
 
573
  lex_start(this);
642
574
  if (client->authenticate())
643
575
    return false;
644
576
 
645
 
  status_var.aborted_connects++;
 
577
  status_var_increment(status_var.aborted_connects); 
646
578
 
647
579
  return true;
648
580
}
649
581
 
650
 
bool Session::checkUser(const std::string &passwd_str,
651
 
                        const std::string &in_db)
 
582
bool Session::checkUser(const char *passwd, uint32_t passwd_len, const char *in_db)
652
583
{
 
584
  const string passwd_str(passwd, passwd_len);
653
585
  bool is_authenticated=
654
586
    plugin::Authentication::isAuthenticated(getSecurityContext(),
655
587
                                            passwd_str);
656
588
 
657
589
  if (is_authenticated != true)
658
590
  {
659
 
    status_var.access_denied++;
 
591
    status_var_increment(status_var.access_denied);
660
592
    /* isAuthenticated has pushed the error message */
661
593
    return false;
662
594
  }
663
595
 
664
596
  /* Change database if necessary */
665
 
  if (not in_db.empty())
 
597
  if (in_db && in_db[0])
666
598
  {
667
599
    SchemaIdentifier identifier(in_db);
668
600
    if (mysql_change_db(this, identifier))
672
604
    }
673
605
  }
674
606
  my_ok();
675
 
  password= not passwd_str.empty();
 
607
  password= test(passwd_len);          // remember for error messages
676
608
 
677
609
  /* Ready to handle queries */
678
610
  return true;
694
626
  main_da.reset_diagnostics_area();
695
627
 
696
628
  if (client->readCommand(&l_packet, &packet_length) == false)
697
 
  {
698
 
    return false;
699
 
  }
700
 
 
701
 
  if (getKilled() == KILL_CONNECTION)
702
629
    return false;
703
630
 
704
631
  if (packet_length == 0)
705
632
    return true;
706
633
 
707
 
  l_command= static_cast<enum_server_command>(l_packet[0]);
 
634
  l_command= (enum enum_server_command) (unsigned char) l_packet[0];
708
635
 
709
636
  if (command >= COM_END)
710
637
    command= COM_END;                           // Wrong command
711
638
 
712
639
  assert(packet_length);
713
 
  return not dispatch_command(l_command, this, l_packet+1, (uint32_t) (packet_length-1));
 
640
  return ! dispatch_command(l_command, this, l_packet+1, (uint32_t) (packet_length-1));
714
641
}
715
642
 
716
643
bool Session::readAndStoreQuery(const char *in_packet, uint32_t in_packet_length)
722
649
    in_packet_length--;
723
650
  }
724
651
  const char *pos= in_packet + in_packet_length; /* Point at end null */
725
 
  while (in_packet_length > 0 && (pos[-1] == ';' || my_isspace(charset() ,pos[-1])))
 
652
  while (in_packet_length > 0 &&
 
653
         (pos[-1] == ';' || my_isspace(charset() ,pos[-1])))
726
654
  {
727
655
    pos--;
728
656
    in_packet_length--;
729
657
  }
730
658
 
731
 
  std::string *new_query= new std::string(in_packet, in_packet + in_packet_length);
732
 
  // We can not be entirely sure _schema has a value
733
 
  if (_schema)
734
 
  {
735
 
    plugin::QueryRewriter::rewriteQuery(*_schema, *new_query);
736
 
  }
737
 
  query.reset(new_query);
738
 
  _state.reset(new State(in_packet, in_packet_length));
 
659
  query.assign(in_packet, in_packet + in_packet_length);
739
660
 
740
661
  return true;
741
662
}
790
711
  }
791
712
 
792
713
  if (result == false)
793
 
  {
794
714
    my_error(killed_errno(), MYF(0));
795
 
  }
796
715
  else if ((result == true) && do_release)
797
 
  {
798
 
    setKilled(Session::KILL_CONNECTION);
799
 
  }
 
716
    killed= Session::KILL_CONNECTION;
800
717
 
801
718
  return result;
802
719
}
867
784
  where= Session::DEFAULT_WHERE;
868
785
 
869
786
  /* Reset the temporary shares we built */
870
 
  for_each(temporary_shares.begin(),
871
 
           temporary_shares.end(),
872
 
           DeletePtr());
 
787
  for (std::vector<TableShareInstance *>::iterator iter= temporary_shares.begin();
 
788
       iter != temporary_shares.end(); iter++)
 
789
  {
 
790
    delete *iter;
 
791
  }
873
792
  temporary_shares.clear();
874
793
}
875
794
 
955
874
  my_message(errcode, err, MYF(0));
956
875
  if (file > 0)
957
876
  {
958
 
    (void) cache->end_io_cache();
 
877
    (void) end_io_cache(cache);
959
878
    (void) internal::my_close(file, MYF(0));
960
 
    (void) internal::my_delete(path.file_string().c_str(), MYF(0));             // Delete file on error
 
879
    (void) internal::my_delete(path, MYF(0));           // Delete file on error
961
880
    file= -1;
962
881
  }
963
882
}
965
884
 
966
885
bool select_to_file::send_eof()
967
886
{
968
 
  int error= test(cache->end_io_cache());
 
887
  int error= test(end_io_cache(cache));
969
888
  if (internal::my_close(file, MYF(MY_WME)))
970
889
    error= 1;
971
890
  if (!error)
987
906
  /* In case of error send_eof() may be not called: close the file here. */
988
907
  if (file >= 0)
989
908
  {
990
 
    (void) cache->end_io_cache();
 
909
    (void) end_io_cache(cache);
991
910
    (void) internal::my_close(file, MYF(0));
992
911
    file= -1;
993
912
  }
994
 
  path= "";
 
913
  path[0]= '\0';
995
914
  row_count= 0;
996
915
}
997
916
 
1001
920
    cache(static_cast<internal::IO_CACHE *>(memory::sql_calloc(sizeof(internal::IO_CACHE)))),
1002
921
    row_count(0L)
1003
922
{
1004
 
  path= "";
 
923
  path[0]=0;
1005
924
}
1006
925
 
1007
926
select_to_file::~select_to_file()
1035
954
*/
1036
955
 
1037
956
 
1038
 
static int create_file(Session *session,
1039
 
                       fs::path &target_path,
1040
 
                       file_exchange *exchange,
1041
 
                       internal::IO_CACHE *cache)
 
957
static int create_file(Session *session, char *path, file_exchange *exchange, internal::IO_CACHE *cache)
1042
958
{
1043
 
  fs::path to_file(exchange->file_name);
1044
959
  int file;
1045
 
 
1046
 
  if (not to_file.has_root_directory())
 
960
  uint32_t option= MY_UNPACK_FILENAME | MY_RELATIVE_PATH;
 
961
 
 
962
#ifdef DONT_ALLOW_FULL_LOAD_DATA_PATHS
 
963
  option|= MY_REPLACE_DIR;                      // Force use of db directory
 
964
#endif
 
965
 
 
966
  if (!internal::dirname_length(exchange->file_name))
1047
967
  {
1048
 
    target_path= fs::system_complete(getDataHomeCatalog());
1049
 
    util::string::const_shared_ptr schema(session->schema());
1050
 
    if (schema and not schema->empty())
1051
 
    {
1052
 
      int count_elements= 0;
1053
 
      for (fs::path::iterator iter= to_file.begin();
1054
 
           iter != to_file.end();
1055
 
           ++iter, ++count_elements)
1056
 
      { }
1057
 
 
1058
 
      if (count_elements == 1)
1059
 
      {
1060
 
        target_path /= *schema;
1061
 
      }
1062
 
    }
1063
 
    target_path /= to_file;
 
968
    strcpy(path, data_home_real);
 
969
    if (! session->db.empty())
 
970
      strncat(path, session->db.c_str(), FN_REFLEN-strlen(data_home_real)-1);
 
971
    (void) internal::fn_format(path, exchange->file_name, path, "", option);
1064
972
  }
1065
973
  else
1066
 
  {
1067
 
    target_path = exchange->file_name;
1068
 
  }
1069
 
 
1070
 
  if (not secure_file_priv.string().empty())
1071
 
  {
1072
 
    if (target_path.file_string().substr(0, secure_file_priv.file_string().size()) != secure_file_priv.file_string())
1073
 
    {
1074
 
      /* Write only allowed to dir or subdir specified by secure_file_priv */
1075
 
      my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--secure-file-priv");
1076
 
      return -1;
1077
 
    }
1078
 
  }
1079
 
 
1080
 
  if (!access(target_path.file_string().c_str(), F_OK))
 
974
    (void) internal::fn_format(path, exchange->file_name, data_home_real, "", option);
 
975
 
 
976
  if (opt_secure_file_priv &&
 
977
      strncmp(opt_secure_file_priv, path, strlen(opt_secure_file_priv)))
 
978
  {
 
979
    /* Write only allowed to dir or subdir specified by secure_file_priv */
 
980
    my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--secure-file-priv");
 
981
    return -1;
 
982
  }
 
983
 
 
984
  if (!access(path, F_OK))
1081
985
  {
1082
986
    my_error(ER_FILE_EXISTS_ERROR, MYF(0), exchange->file_name);
1083
987
    return -1;
1084
988
  }
1085
989
  /* Create the file world readable */
1086
 
  if ((file= internal::my_create(target_path.file_string().c_str(), 0666, O_WRONLY|O_EXCL, MYF(MY_WME))) < 0)
 
990
  if ((file= internal::my_create(path, 0666, O_WRONLY|O_EXCL, MYF(MY_WME))) < 0)
1087
991
    return file;
1088
992
  (void) fchmod(file, 0666);                    // Because of umask()
1089
 
  if (cache->init_io_cache(file, 0L, internal::WRITE_CACHE, 0L, 1, MYF(MY_WME)))
 
993
  if (init_io_cache(cache, file, 0L, internal::WRITE_CACHE, 0L, 1, MYF(MY_WME)))
1090
994
  {
1091
995
    internal::my_close(file, MYF(0));
1092
 
    internal::my_delete(target_path.file_string().c_str(), MYF(0));  // Delete file on error, it was just created
 
996
    internal::my_delete(path, MYF(0));  // Delete file on error, it was just created
1093
997
    return -1;
1094
998
  }
1095
999
  return file;
1103
1007
  bool string_results= false, non_string_results= false;
1104
1008
  unit= u;
1105
1009
  if ((uint32_t) strlen(exchange->file_name) + NAME_LEN >= FN_REFLEN)
1106
 
  {
1107
 
    path= exchange->file_name;
1108
 
  }
 
1010
    strncpy(path,exchange->file_name,FN_REFLEN-1);
1109
1011
 
1110
1012
  /* Check if there is any blobs in data */
1111
1013
  {
1115
1017
    {
1116
1018
      if (item->max_length >= MAX_BLOB_WIDTH)
1117
1019
      {
1118
 
        blob_flag=1;
1119
 
        break;
 
1020
        blob_flag=1;
 
1021
        break;
1120
1022
      }
1121
 
 
1122
1023
      if (item->result_type() == STRING_RESULT)
1123
1024
        string_results= true;
1124
1025
      else
1169
1070
  if (unit->offset_limit_cnt)
1170
1071
  {                                             // using limit offset,count
1171
1072
    unit->offset_limit_cnt--;
1172
 
    return false;
 
1073
    return(0);
1173
1074
  }
1174
1075
  row_count++;
1175
1076
  Item *item;
1178
1079
 
1179
1080
  if (my_b_write(cache,(unsigned char*) exchange->line_start->ptr(),
1180
1081
                 exchange->line_start->length()))
1181
 
    return true;
1182
 
 
 
1082
    goto err;
1183
1083
  while ((item=li++))
1184
1084
  {
1185
1085
    Item_result result_type=item->result_type();
1190
1090
    {
1191
1091
      if (my_b_write(cache,(unsigned char*) exchange->enclosed->ptr(),
1192
1092
                     exchange->enclosed->length()))
1193
 
        return true;
 
1093
        goto err;
1194
1094
    }
1195
1095
    if (!res)
1196
1096
    {                                           // NULL
1201
1101
          null_buff[0]=escape_char;
1202
1102
          null_buff[1]='N';
1203
1103
          if (my_b_write(cache,(unsigned char*) null_buff,2))
1204
 
            return true;
 
1104
            goto err;
1205
1105
        }
1206
1106
        else if (my_b_write(cache,(unsigned char*) "NULL",4))
1207
 
          return true;
 
1107
          goto err;
1208
1108
      }
1209
1109
      else
1210
1110
      {
1214
1114
    else
1215
1115
    {
1216
1116
      if (fixed_row_size)
1217
 
        used_length= min(res->length(), static_cast<size_t>(item->max_length));
 
1117
        used_length= min(res->length(),item->max_length);
1218
1118
      else
1219
1119
        used_length= res->length();
1220
1120
 
1295
1195
            tmp_buff[1]= *pos ? *pos : '0';
1296
1196
            if (my_b_write(cache,(unsigned char*) start,(uint32_t) (pos-start)) ||
1297
1197
                my_b_write(cache,(unsigned char*) tmp_buff,2))
1298
 
              return true;
 
1198
              goto err;
1299
1199
            start=pos+1;
1300
1200
          }
1301
1201
        }
1302
1202
        if (my_b_write(cache,(unsigned char*) start,(uint32_t) (pos-start)))
1303
 
          return true;
 
1203
          goto err;
1304
1204
      }
1305
1205
      else if (my_b_write(cache,(unsigned char*) res->ptr(),used_length))
1306
 
        return true;
 
1206
        goto err;
1307
1207
    }
1308
1208
    if (fixed_row_size)
1309
1209
    {                                           // Fill with space
1319
1219
        for (; length > sizeof(space) ; length-=sizeof(space))
1320
1220
        {
1321
1221
          if (my_b_write(cache,(unsigned char*) space,sizeof(space)))
1322
 
            return true;
 
1222
            goto err;
1323
1223
        }
1324
1224
        if (my_b_write(cache,(unsigned char*) space,length))
1325
 
          return true;
 
1225
          goto err;
1326
1226
      }
1327
1227
    }
1328
1228
    if (res && enclosed)
1329
1229
    {
1330
1230
      if (my_b_write(cache, (unsigned char*) exchange->enclosed->ptr(),
1331
1231
                     exchange->enclosed->length()))
1332
 
        return true;
 
1232
        goto err;
1333
1233
    }
1334
1234
    if (--items_left)
1335
1235
    {
1336
1236
      if (my_b_write(cache, (unsigned char*) exchange->field_term->ptr(),
1337
1237
                     field_term_length))
1338
 
        return true;
 
1238
        goto err;
1339
1239
    }
1340
1240
  }
1341
1241
  if (my_b_write(cache,(unsigned char*) exchange->line_term->ptr(),
1342
1242
                 exchange->line_term->length()))
1343
 
  {
1344
 
    return true;
1345
 
  }
1346
 
 
1347
 
  return false;
 
1243
    goto err;
 
1244
  return(0);
 
1245
err:
 
1246
  return(1);
1348
1247
}
1349
1248
 
1350
1249
 
1377
1276
  if (row_count++ > 1)
1378
1277
  {
1379
1278
    my_message(ER_TOO_MANY_ROWS, ER(ER_TOO_MANY_ROWS), MYF(0));
1380
 
    return 1;
 
1279
    goto err;
1381
1280
  }
1382
1281
  while ((item=li++))
1383
1282
  {
1385
1284
    if (!res)                                   // If NULL
1386
1285
    {
1387
1286
      if (my_b_write(cache,(unsigned char*) "",1))
1388
 
        return 1;
 
1287
        goto err;
1389
1288
    }
1390
1289
    else if (my_b_write(cache,(unsigned char*) res->ptr(),res->length()))
1391
1290
    {
1392
 
      my_error(ER_ERROR_ON_WRITE, MYF(0), path.file_string().c_str(), errno);
1393
 
      return 1;
 
1291
      my_error(ER_ERROR_ON_WRITE, MYF(0), path, errno);
 
1292
      goto err;
1394
1293
    }
1395
1294
  }
1396
1295
  return(0);
 
1296
err:
 
1297
  return(1);
1397
1298
}
1398
1299
 
1399
1300
 
1451
1352
      switch (val_item->result_type())
1452
1353
      {
1453
1354
      case REAL_RESULT:
1454
 
        op= &select_max_min_finder_subselect::cmp_real;
1455
 
        break;
 
1355
        op= &select_max_min_finder_subselect::cmp_real;
 
1356
        break;
1456
1357
      case INT_RESULT:
1457
 
        op= &select_max_min_finder_subselect::cmp_int;
1458
 
        break;
 
1358
        op= &select_max_min_finder_subselect::cmp_int;
 
1359
        break;
1459
1360
      case STRING_RESULT:
1460
 
        op= &select_max_min_finder_subselect::cmp_str;
1461
 
        break;
 
1361
        op= &select_max_min_finder_subselect::cmp_str;
 
1362
        break;
1462
1363
      case DECIMAL_RESULT:
1463
1364
        op= &select_max_min_finder_subselect::cmp_decimal;
1464
1365
        break;
1465
1366
      case ROW_RESULT:
1466
1367
        // This case should never be choosen
1467
 
        assert(0);
1468
 
        op= 0;
 
1368
        assert(0);
 
1369
        op= 0;
1469
1370
      }
1470
1371
    }
1471
1372
    cache->store(val_item);
1554
1455
void Session::end_statement()
1555
1456
{
1556
1457
  /* Cleanup SQL processing state to reuse this statement in next query. */
1557
 
  lex->end();
1558
 
  query_cache_key= ""; // reset the cache key
1559
 
  resetResultsetMessage();
 
1458
  lex_end(lex);
1560
1459
}
1561
1460
 
1562
1461
bool Session::copy_db_to(char **p_db, size_t *p_db_length)
1563
1462
{
1564
 
  assert(_schema);
1565
 
  if (_schema and _schema->empty())
1566
 
  {
1567
 
    my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
1568
 
    return true;
1569
 
  }
1570
 
  else if (not _schema)
1571
 
  {
1572
 
    my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
1573
 
    return true;
1574
 
  }
1575
 
  assert(_schema);
1576
 
 
1577
 
  *p_db= strmake(_schema->c_str(), _schema->size());
1578
 
  *p_db_length= _schema->size();
1579
 
 
 
1463
  if (db.empty())
 
1464
  {
 
1465
    my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
 
1466
    return true;
 
1467
  }
 
1468
  *p_db= strmake(db.c_str(), db.length());
 
1469
  *p_db_length= db.length();
1580
1470
  return false;
1581
1471
}
1582
1472
 
1616
1506
}
1617
1507
 
1618
1508
 
1619
 
void Session::set_db(const std::string &new_db)
 
1509
bool Session::set_db(const std::string &new_db)
1620
1510
{
1621
1511
  /* Do not reallocate memory if current chunk is big enough. */
1622
1512
  if (new_db.length())
1623
 
  {
1624
 
    _schema.reset(new std::string(new_db));
1625
 
  }
 
1513
    db= new_db;
1626
1514
  else
1627
 
  {
1628
 
    _schema.reset(new std::string(""));
1629
 
  }
1630
 
}
1631
 
 
 
1515
    db.clear();
 
1516
 
 
1517
  return false;
 
1518
}
 
1519
 
 
1520
 
 
1521
 
 
1522
 
 
1523
/**
 
1524
  Check the killed state of a user thread
 
1525
  @param session  user thread
 
1526
  @retval 0 the user thread is active
 
1527
  @retval 1 the user thread has been killed
 
1528
*/
 
1529
int session_killed(const Session *session)
 
1530
{
 
1531
  return(session->killed);
 
1532
}
 
1533
 
 
1534
 
 
1535
const struct charset_info_st *session_charset(Session *session)
 
1536
{
 
1537
  return(session->charset());
 
1538
}
1632
1539
 
1633
1540
/**
1634
1541
  Mark transaction to rollback and mark error as fatal to a sub-statement.
1651
1558
  plugin_sessionvar_cleanup(this);
1652
1559
 
1653
1560
  /* If necessary, log any aborted or unauthorized connections */
1654
 
  if (getKilled() || client->wasAborted())
 
1561
  if (killed || client->wasAborted())
1655
1562
  {
1656
 
    status_var.aborted_threads++;
 
1563
    status_var_increment(status_var.aborted_threads);
1657
1564
  }
1658
1565
 
1659
1566
  if (client->wasAborted())
1660
1567
  {
1661
 
    if (not getKilled() && variables.log_warnings > 1)
 
1568
    if (! killed && variables.log_warnings > 1)
1662
1569
    {
1663
1570
      SecurityContext *sctx= &security_ctx;
1664
1571
 
1665
1572
      errmsg_printf(ERRMSG_LVL_WARN, ER(ER_NEW_ABORTING_CONNECTION)
1666
1573
                  , thread_id
1667
 
                  , (_schema->empty() ? "unconnected" : _schema->c_str())
 
1574
                  , (db.empty() ? "unconnected" : db.c_str())
1668
1575
                  , sctx->getUser().empty() == false ? sctx->getUser().c_str() : "unauthenticated"
1669
1576
                  , sctx->getIp().c_str()
1670
1577
                  , (main_da.is_error() ? main_da.message() : ER(ER_UNKNOWN_ERROR)));
1673
1580
 
1674
1581
  /* Close out our connection to the client */
1675
1582
  if (should_lock)
1676
 
    session::Cache::singleton().mutex().lock();
1677
 
 
1678
 
  setKilled(Session::KILL_CONNECTION);
1679
 
 
 
1583
    LOCK_thread_count.lock();
 
1584
  killed= Session::KILL_CONNECTION;
1680
1585
  if (client->isConnected())
1681
1586
  {
1682
1587
    if (errcode)
1686
1591
    }
1687
1592
    client->close();
1688
1593
  }
1689
 
 
1690
1594
  if (should_lock)
1691
 
  {
1692
 
    session::Cache::singleton().mutex().unlock();
1693
 
  }
 
1595
    (void) LOCK_thread_count.unlock();
1694
1596
}
1695
1597
 
1696
1598
void Session::reset_for_next_command()
1718
1620
  Close all temporary tables created by 'CREATE TEMPORARY TABLE' for thread
1719
1621
*/
1720
1622
 
1721
 
void Open_tables_state::close_temporary_tables()
 
1623
void Session::close_temporary_tables()
1722
1624
{
1723
1625
  Table *table;
1724
1626
  Table *tmp_next;
1738
1640
  unlink from session->temporary tables and close temporary table
1739
1641
*/
1740
1642
 
1741
 
void Open_tables_state::close_temporary_table(Table *table)
 
1643
void Session::close_temporary_table(Table *table)
1742
1644
{
1743
1645
  if (table->getPrev())
1744
1646
  {
1774
1676
  If this is needed, use close_temporary_table()
1775
1677
*/
1776
1678
 
1777
 
void Open_tables_state::nukeTable(Table *table)
 
1679
void Session::nukeTable(Table *table)
1778
1680
{
1779
1681
  plugin::StorageEngine *table_type= table->getShare()->db_type();
1780
1682
 
1795
1697
 
1796
1698
void Session::refresh_status()
1797
1699
{
 
1700
  LOCK_status.lock();
 
1701
 
1798
1702
  /* Reset thread's status variables */
1799
1703
  memset(&status_var, 0, sizeof(status_var));
1800
1704
 
 
1705
  /* Reset the counters of all key caches (default and named). */
 
1706
  reset_key_cache_counters();
1801
1707
  flush_status_time= time((time_t*) 0);
1802
1708
  current_global_counters.max_used_connections= 1; /* We set it to one, because we know we exist */
1803
 
  current_global_counters.connections= 0;
 
1709
  LOCK_status.unlock();
1804
1710
}
1805
1711
 
1806
1712
user_var_entry *Session::getVariable(LEX_STRING &name, bool create_if_not_exists)
1807
1713
{
1808
 
  return getVariable(std::string(name.str, name.length), create_if_not_exists);
1809
 
}
1810
 
 
1811
 
user_var_entry *Session::getVariable(const std::string  &name, bool create_if_not_exists)
1812
 
{
1813
 
  UserVarsRange ppp= user_vars.equal_range(name);
 
1714
  user_var_entry *entry= NULL;
 
1715
  UserVarsRange ppp= user_vars.equal_range(std::string(name.str, name.length));
1814
1716
 
1815
1717
  for (UserVars::iterator iter= ppp.first;
1816
 
       iter != ppp.second; ++iter)
 
1718
         iter != ppp.second; ++iter)
1817
1719
  {
1818
 
    return (*iter).second;
 
1720
    entry= (*iter).second;
1819
1721
  }
1820
1722
 
1821
 
  if (not create_if_not_exists)
1822
 
    return NULL;
1823
 
 
1824
 
  user_var_entry *entry= NULL;
1825
 
  entry= new (nothrow) user_var_entry(name.c_str(), query_id);
1826
 
 
1827
 
  if (entry == NULL)
1828
 
    return NULL;
1829
 
 
1830
 
  std::pair<UserVars::iterator, bool> returnable= user_vars.insert(make_pair(name, entry));
1831
 
 
1832
 
  if (not returnable.second)
 
1723
  if ((entry == NULL) && create_if_not_exists)
1833
1724
  {
1834
 
    delete entry;
 
1725
    entry= new (nothrow) user_var_entry(name.str, query_id);
 
1726
 
 
1727
    if (entry == NULL)
 
1728
      return NULL;
 
1729
 
 
1730
    std::pair<UserVars::iterator, bool> returnable= user_vars.insert(make_pair(std::string(name.str, name.length), entry));
 
1731
 
 
1732
    if (not returnable.second)
 
1733
    {
 
1734
      delete entry;
 
1735
      return NULL;
 
1736
    }
1835
1737
  }
1836
1738
 
1837
1739
  return entry;
1838
1740
}
1839
1741
 
1840
 
void Session::setVariable(const std::string &name, const std::string &value)
1841
 
{
1842
 
  user_var_entry *updateable_var= getVariable(name.c_str(), true);
1843
 
 
1844
 
  updateable_var->update_hash(false,
1845
 
                              (void*)value.c_str(),
1846
 
                              static_cast<uint32_t>(value.length()), STRING_RESULT,
1847
 
                              &my_charset_bin,
1848
 
                              DERIVATION_IMPLICIT, false);
1849
 
}
1850
 
 
1851
 
void Open_tables_state::mark_temp_tables_as_free_for_reuse()
 
1742
void Session::mark_temp_tables_as_free_for_reuse()
1852
1743
{
1853
1744
  for (Table *table= temporary_tables ; table ; table= table->getNext())
1854
1745
  {
1855
 
    if (table->query_id == getQueryId())
 
1746
    if (table->query_id == query_id)
1856
1747
    {
1857
1748
      table->query_id= 0;
1858
1749
      table->cursor->ha_reset();
1864
1755
{
1865
1756
  for (; table ; table= table->getNext())
1866
1757
  {
1867
 
    if (table->query_id == getQueryId())
 
1758
    if (table->query_id == query_id)
1868
1759
    {
1869
1760
      table->query_id= 0;
1870
1761
      table->cursor->ha_reset();
1883
1774
*/
1884
1775
void Session::close_thread_tables()
1885
1776
{
1886
 
  clearDerivedTables();
 
1777
  if (derived_tables)
 
1778
    derived_tables= NULL; // They should all be invalid by this point
1887
1779
 
1888
1780
  /*
1889
1781
    Mark all temporary tables used by this statement as free for reuse.
1916
1808
      handled either before writing a query log event (inside
1917
1809
      binlog_query()) or when preparing a pending event.
1918
1810
     */
1919
 
    unlockTables(lock);
 
1811
    mysql_unlock_tables(this, lock);
1920
1812
    lock= 0;
1921
1813
  }
1922
1814
  /*
1923
 
    Note that we need to hold table::Cache::singleton().mutex() while changing the
 
1815
    Note that we need to hold LOCK_open while changing the
1924
1816
    open_tables list. Another thread may work on it.
1925
 
    (See: table::Cache::singleton().removeTable(), mysql_wait_completed_table())
 
1817
    (See: remove_table_from_cache(), mysql_wait_completed_table())
1926
1818
    Closing a MERGE child before the parent would be fatal if the
1927
1819
    other thread tries to abort the MERGE lock in between.
1928
1820
  */
1961
1853
    close_tables_for_reopen(&tables);
1962
1854
  }
1963
1855
  if ((mysql_handle_derived(lex, &mysql_derived_prepare) ||
1964
 
       (
 
1856
       (fill_derived_tables() &&
1965
1857
        mysql_handle_derived(lex, &mysql_derived_filling))))
1966
1858
    return true;
1967
1859
 
1968
1860
  return false;
1969
1861
}
1970
1862
 
 
1863
bool Session::openTables(TableList *tables, uint32_t flags)
 
1864
{
 
1865
  uint32_t counter;
 
1866
  bool ret= fill_derived_tables();
 
1867
  assert(ret == false);
 
1868
  if (open_tables_from_list(&tables, &counter, flags) ||
 
1869
      mysql_handle_derived(lex, &mysql_derived_prepare))
 
1870
  {
 
1871
    return true;
 
1872
  }
 
1873
  return false;
 
1874
}
 
1875
 
1971
1876
/*
1972
1877
  @note "best_effort" is used in cases were if a failure occurred on this
1973
1878
  operation it would not be surprising because we are only removing because there
1974
1879
  might be an issue (lame engines).
1975
1880
*/
1976
1881
 
1977
 
bool Open_tables_state::rm_temporary_table(const TableIdentifier &identifier, bool best_effort)
 
1882
bool Session::rm_temporary_table(TableIdentifier &identifier, bool best_effort)
1978
1883
{
1979
 
  if (plugin::StorageEngine::dropTable(*static_cast<Session *>(this), identifier))
 
1884
  if (plugin::StorageEngine::dropTable(*this, identifier))
1980
1885
  {
1981
1886
    if (not best_effort)
1982
1887
    {
1983
 
      std::string path;
1984
 
      identifier.getSQLPath(path);
1985
1888
      errmsg_printf(ERRMSG_LVL_WARN, _("Could not remove temporary table: '%s', error: %d"),
1986
 
                    path.c_str(), errno);
 
1889
                    identifier.getSQLPath().c_str(), errno);
1987
1890
    }
1988
1891
 
1989
1892
    return true;
1992
1895
  return false;
1993
1896
}
1994
1897
 
1995
 
bool Open_tables_state::rm_temporary_table(plugin::StorageEngine *base, const TableIdentifier &identifier)
 
1898
bool Session::rm_temporary_table(plugin::StorageEngine *base, TableIdentifier &identifier)
1996
1899
{
1997
1900
  assert(base);
1998
1901
 
1999
 
  if (plugin::StorageEngine::dropTable(*static_cast<Session *>(this), *base, identifier))
 
1902
  if (plugin::StorageEngine::dropTable(*this, *base, identifier))
2000
1903
  {
2001
 
    std::string path;
2002
 
    identifier.getSQLPath(path);
2003
1904
    errmsg_printf(ERRMSG_LVL_WARN, _("Could not remove temporary table: '%s', error: %d"),
2004
 
                  path.c_str(), errno);
 
1905
                  identifier.getSQLPath().c_str(), errno);
2005
1906
 
2006
1907
    return true;
2007
1908
  }
2013
1914
  @note this will be removed, I am looking through Hudson to see if it is finding
2014
1915
  any tables that are missed during cleanup.
2015
1916
*/
2016
 
void Open_tables_state::dumpTemporaryTableNames(const char *foo)
 
1917
void Session::dumpTemporaryTableNames(const char *foo)
2017
1918
{
2018
1919
  Table *table;
2019
1920
 
2037
1938
      cerr << "\t\t Proto " << proto->schema() << " " << proto->name() << "\n";
2038
1939
    }
2039
1940
    else
2040
 
    {
2041
1941
      cerr << "\tTabl;e Name " << table->getShare()->getSchemaName() << "." << table->getShare()->getTableName() << " : " << answer << "\n";
2042
 
    }
2043
1942
  }
2044
1943
}
2045
1944
 
2046
 
bool Session::TableMessages::storeTableMessage(const TableIdentifier &identifier, message::Table &table_message)
 
1945
bool Session::storeTableMessage(const TableIdentifier &identifier, message::Table &table_message)
2047
1946
{
2048
1947
  table_message_cache.insert(make_pair(identifier.getPath(), table_message));
2049
1948
 
2050
1949
  return true;
2051
1950
}
2052
1951
 
2053
 
bool Session::TableMessages::removeTableMessage(const TableIdentifier &identifier)
 
1952
bool Session::removeTableMessage(const TableIdentifier &identifier)
2054
1953
{
2055
1954
  TableMessageCache::iterator iter;
2056
1955
 
2064
1963
  return true;
2065
1964
}
2066
1965
 
2067
 
bool Session::TableMessages::getTableMessage(const TableIdentifier &identifier, message::Table &table_message)
 
1966
bool Session::getTableMessage(const TableIdentifier &identifier, message::Table &table_message)
2068
1967
{
2069
1968
  TableMessageCache::iterator iter;
2070
1969
 
2078
1977
  return true;
2079
1978
}
2080
1979
 
2081
 
bool Session::TableMessages::doesTableMessageExist(const TableIdentifier &identifier)
 
1980
bool Session::doesTableMessageExist(const TableIdentifier &identifier)
2082
1981
{
2083
1982
  TableMessageCache::iterator iter;
2084
1983
 
2092
1991
  return true;
2093
1992
}
2094
1993
 
2095
 
bool Session::TableMessages::renameTableMessage(const TableIdentifier &from, const TableIdentifier &to)
 
1994
bool Session::renameTableMessage(const TableIdentifier &from, const TableIdentifier &to)
2096
1995
{
2097
1996
  TableMessageCache::iterator iter;
2098
1997
 
2111
2010
  return true;
2112
2011
}
2113
2012
 
2114
 
table::Instance *Session::getInstanceTable()
2115
 
{
2116
 
  temporary_shares.push_back(new table::Instance()); // This will not go into the tableshare cache, so no key is used.
2117
 
 
2118
 
  table::Instance *tmp_share= temporary_shares.back();
2119
 
 
2120
 
  assert(tmp_share);
2121
 
 
2122
 
  return tmp_share;
2123
 
}
2124
 
 
2125
 
 
2126
 
/**
2127
 
  Create a reduced Table object with properly set up Field list from a
2128
 
  list of field definitions.
2129
 
 
2130
 
    The created table doesn't have a table Cursor associated with
2131
 
    it, has no keys, no group/distinct, no copy_funcs array.
2132
 
    The sole purpose of this Table object is to use the power of Field
2133
 
    class to read/write data to/from table->getInsertRecord(). Then one can store
2134
 
    the record in any container (RB tree, hash, etc).
2135
 
    The table is created in Session mem_root, so are the table's fields.
2136
 
    Consequently, if you don't BLOB fields, you don't need to free it.
2137
 
 
2138
 
  @param session         connection handle
2139
 
  @param field_list  list of column definitions
2140
 
 
2141
 
  @return
2142
 
    0 if out of memory, Table object in case of success
2143
 
*/
2144
 
table::Instance *Session::getInstanceTable(List<CreateField> &field_list)
2145
 
{
2146
 
  temporary_shares.push_back(new table::Instance(this, field_list)); // This will not go into the tableshare cache, so no key is used.
2147
 
 
2148
 
  table::Instance *tmp_share= temporary_shares.back();
2149
 
 
2150
 
  assert(tmp_share);
2151
 
 
2152
 
  return tmp_share;
2153
 
}
2154
 
 
2155
 
namespace display  {
2156
 
 
2157
 
static const std::string NONE= "NONE";
2158
 
static const std::string GOT_GLOBAL_READ_LOCK= "HAS GLOBAL READ LOCK";
2159
 
static const std::string MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT= "HAS GLOBAL READ LOCK WITH BLOCKING COMMIT";
2160
 
 
2161
 
const std::string &type(drizzled::Session::global_read_lock_t type)
2162
 
{
2163
 
  switch (type) {
2164
 
    default:
2165
 
    case Session::NONE:
2166
 
      return NONE;
2167
 
    case Session::GOT_GLOBAL_READ_LOCK:
2168
 
      return GOT_GLOBAL_READ_LOCK;
2169
 
    case Session::MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT:
2170
 
      return MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT;
2171
 
  }
2172
 
}
2173
 
 
2174
 
size_t max_string_length(drizzled::Session::global_read_lock_t)
2175
 
{
2176
 
  return MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT.size();
2177
 
}
2178
 
 
2179
 
} /* namespace display */
 
2013
TableShareInstance *Session::getTemporaryShare(TableIdentifier::Type type_arg)
 
2014
{
 
2015
  temporary_shares.push_back(new TableShareInstance(type_arg)); // This will not go into the tableshare cache, so no key is used.
 
2016
 
 
2017
  TableShareInstance *tmp_share= temporary_shares.back();
 
2018
 
 
2019
  assert(tmp_share);
 
2020
 
 
2021
  return tmp_share;
 
2022
}
2180
2023
 
2181
2024
} /* namespace drizzled */