~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/session.cc

  • Committer: Stewart Smith
  • Date: 2010-09-20 05:32:43 UTC
  • mto: (1786.1.1 build)
  • mto: This revision was merged to the branch mainline in revision 1787.
  • Revision ID: stewart@flamingspork.com-20100920053243-u844cs5xc1sby4xw
add argument check to EXP()

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/identifier.h"
53
 
 
54
 
#include "drizzled/table/instance.h"
 
51
#include "drizzled/table_share_instance.h"
55
52
 
56
53
#include "plugin/myisam/myisam.h"
57
54
#include "drizzled/internal/iocache.h"
58
55
#include "drizzled/internal/thread_var.h"
59
56
#include "drizzled/plugin/event_observer.h"
60
57
 
61
 
#include "drizzled/util/functors.h"
62
 
 
63
 
#include "drizzled/display.h"
64
 
 
65
58
#include <fcntl.h>
66
59
#include <algorithm>
67
60
#include <climits>
68
 
#include <boost/filesystem.hpp>
69
 
 
70
 
#include "drizzled/util/backtrace.h"
71
61
 
72
62
using namespace std;
73
 
 
74
 
namespace fs=boost::filesystem;
75
63
namespace drizzled
76
64
{
77
65
 
83
71
char empty_c_string[1]= {0};    /* used for not defined db */
84
72
 
85
73
const char * const Session::DEFAULT_WHERE= "field list";
 
74
extern pthread_key_t THR_Session;
 
75
extern pthread_key_t THR_Mem_root;
86
76
 
87
77
bool Key_part_spec::operator==(const Key_part_spec& other) const
88
78
{
89
79
  return length == other.length &&
90
80
         field_name.length == other.field_name.length &&
91
 
    !my_strcasecmp(system_charset_info, field_name.str, other.field_name.str);
 
81
         !strcmp(field_name.str, other.field_name.str);
92
82
}
93
83
 
94
84
Open_tables_state::Open_tables_state(uint64_t version_arg) :
164
154
Session::Session(plugin::Client *client_arg) :
165
155
  Open_tables_state(refresh_version),
166
156
  mem_root(&main_mem_root),
167
 
  xa_id(0),
168
157
  lex(&main_lex),
169
 
  query(new std::string),
170
 
  _schema(new std::string("")),
171
 
  catalog("LOCAL"),
 
158
  query(),
172
159
  client(client_arg),
173
160
  scheduler(NULL),
174
161
  scheduler_arg(NULL),
175
162
  lock_id(&main_lock_id),
176
 
  thread_stack(NULL),
177
 
  security_ctx(identifier::User::make_shared()),
178
163
  user_time(0),
179
164
  ha_data(plugin::num_trx_monitored_objects),
180
 
  concurrent_execute_allowed(true),
181
165
  arg_of_last_insert_id_function(false),
182
166
  first_successful_insert_id_in_prev_stmt(0),
183
167
  first_successful_insert_id_in_cur_stmt(0),
184
168
  limit_found_rows(0),
185
 
  _global_read_lock(NONE),
186
 
  _killed(NOT_KILLED),
 
169
  global_read_lock(0),
187
170
  some_tables_deleted(false),
188
171
  no_errors(false),
189
172
  password(false),
196
179
  cached_table(0),
197
180
  transaction_message(NULL),
198
181
  statement_message(NULL),
199
 
  session_event_observers(NULL),
200
 
  use_usage(false)
 
182
  session_event_observers(NULL)
201
183
{
 
184
  memset(process_list_info, 0, PROCESS_LIST_WIDTH);
202
185
  client->setSession(this);
203
186
 
204
187
  /*
207
190
    will be re-initialized in init_for_queries().
208
191
  */
209
192
  memory::init_sql_alloc(&main_mem_root, memory::ROOT_MIN_BLOCK_SIZE, 0);
 
193
  thread_stack= NULL;
210
194
  count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;
 
195
  killed= NOT_KILLED;
211
196
  col_access= 0;
212
197
  tmp_table= 0;
213
198
  used_tables= 0;
316
301
    return;
317
302
 
318
303
  setAbort(true);
319
 
  boost_unique_lock_t scopedLock(mysys_var->mutex);
 
304
  pthread_mutex_lock(&mysys_var->mutex);
320
305
  if (mysys_var->current_cond)
321
306
  {
322
 
    mysys_var->current_mutex->lock();
323
 
    mysys_var->current_cond->notify_all();
324
 
    mysys_var->current_mutex->unlock();
 
307
    pthread_mutex_lock(mysys_var->current_mutex);
 
308
    pthread_cond_broadcast(mysys_var->current_cond);
 
309
    pthread_mutex_unlock(mysys_var->current_mutex);
325
310
  }
 
311
  pthread_mutex_unlock(&mysys_var->mutex);
326
312
}
327
313
 
328
314
void Session::pop_internal_handler()
342
328
{
343
329
  assert(cleanup_done == false);
344
330
 
345
 
  setKilled(KILL_CONNECTION);
 
331
  killed= KILL_CONNECTION;
346
332
#ifdef ENABLE_WHEN_BINLOG_WILL_BE_ABLE_TO_PREPARE
347
333
  if (transaction.xid_state.xa_state == XA_PREPARED)
348
334
  {
368
354
  close_temporary_tables();
369
355
 
370
356
  if (global_read_lock)
371
 
  {
372
 
    unlockGlobalReadLock();
373
 
  }
 
357
    unlock_global_read_lock(this);
374
358
 
375
359
  cleanup_done= true;
376
360
}
381
365
 
382
366
  if (client->isConnected())
383
367
  {
384
 
    assert(security_ctx);
385
368
    if (global_system_variables.log_warnings)
386
 
    {
387
 
      errmsg_printf(ERRMSG_LVL_WARN, ER(ER_FORCING_CLOSE),
388
 
                    internal::my_progname,
389
 
                    thread_id,
390
 
                    security_ctx->username().c_str());
391
 
    }
392
 
 
 
369
        errmsg_printf(ERRMSG_LVL_WARN, ER(ER_FORCING_CLOSE),internal::my_progname,
 
370
                      thread_id,
 
371
                      (getSecurityContext().getUser().c_str() ?
 
372
                       getSecurityContext().getUser().c_str() : ""));
393
373
    disconnect(0, false);
394
374
  }
395
375
 
408
388
  dbug_sentry= Session_SENTRY_GONE;
409
389
 
410
390
  main_mem_root.free_root(MYF(0));
411
 
  currentMemRoot().release();
412
 
  currentSession().release();
 
391
  pthread_setspecific(THR_Session,  0);
413
392
 
414
393
  plugin::Logging::postEndDo(this);
415
394
  plugin::EventObserver::deregisterSessionEvents(*this); 
416
395
 
417
 
  for (PropertyMap::iterator iter= life_properties.begin(); iter != life_properties.end(); iter++)
418
 
  {
419
 
    delete (*iter).second;
420
 
  }
421
 
  life_properties.clear();
422
 
}
423
 
 
424
 
void Session::setClient(plugin::Client *client_arg)
425
 
{
426
 
  client= client_arg;
427
 
  client->setSession(this);
428
 
}
429
 
 
430
 
void Session::awake(Session::killed_state_t state_to_set)
431
 
{
432
 
  if ((state_to_set == Session::KILL_QUERY) and (command == COM_SLEEP))
433
 
    return;
434
 
 
 
396
  /* Ensure that no one is using Session */
 
397
  LOCK_delete.unlock();
 
398
}
 
399
 
 
400
void Session::awake(Session::killed_state state_to_set)
 
401
{
435
402
  this->checkSentry();
436
 
 
437
 
  setKilled(state_to_set);
438
 
  scheduler->killSession(this);
439
 
 
 
403
  safe_mutex_assert_owner(&LOCK_delete);
 
404
 
 
405
  killed= state_to_set;
440
406
  if (state_to_set != Session::KILL_QUERY)
441
407
  {
 
408
    scheduler->killSession(this);
442
409
    DRIZZLE_CONNECTION_DONE(thread_id);
443
410
  }
444
 
 
445
411
  if (mysys_var)
446
412
  {
447
 
    boost_unique_lock_t scopedLock(mysys_var->mutex);
 
413
    pthread_mutex_lock(&mysys_var->mutex);
448
414
    /*
449
 
      "
450
415
      This broadcast could be up in the air if the victim thread
451
416
      exits the cond in the time between read and broadcast, but that is
452
417
      ok since all we want to do is to make the victim thread get out
467
432
    */
468
433
    if (mysys_var->current_cond && mysys_var->current_mutex)
469
434
    {
470
 
      mysys_var->current_mutex->lock();
471
 
      mysys_var->current_cond->notify_all();
472
 
      mysys_var->current_mutex->unlock();
 
435
      pthread_mutex_lock(mysys_var->current_mutex);
 
436
      pthread_cond_broadcast(mysys_var->current_cond);
 
437
      pthread_mutex_unlock(mysys_var->current_mutex);
473
438
    }
 
439
    pthread_mutex_unlock(&mysys_var->mutex);
474
440
  }
475
441
}
476
442
 
486
452
  */
487
453
  assert(thread_stack);
488
454
 
489
 
  currentSession().release();
490
 
  currentSession().reset(this);
491
 
 
492
 
  currentMemRoot().release();
493
 
  currentMemRoot().reset(&mem_root);
 
455
  if (pthread_setspecific(THR_Session,  this) ||
 
456
      pthread_setspecific(THR_Mem_root, &mem_root))
 
457
    return true;
494
458
 
495
459
  mysys_var=my_thread_var;
496
460
 
499
463
    This allows us to move Session to different threads if needed.
500
464
  */
501
465
  mysys_var->id= thread_id;
 
466
  real_id= pthread_self();                      // For debugging
502
467
 
503
468
  /*
504
469
    We have to call thr_lock_info_init() again here as Session may have been
529
494
                                variables.query_prealloc_size);
530
495
  transaction.xid_state.xid.null();
531
496
  transaction.xid_state.in_session=1;
532
 
  if (use_usage)
533
 
    resetUsage();
534
497
}
535
498
 
536
499
bool Session::initGlobals()
554
517
 
555
518
  prepareForQueries();
556
519
 
557
 
  while (not client->haveError() && getKilled() != KILL_CONNECTION)
 
520
  while (! client->haveError() && killed != KILL_CONNECTION)
558
521
  {
559
 
    if (not executeStatement())
 
522
    if (! executeStatement())
560
523
      break;
561
524
  }
562
525
 
563
526
  disconnect(0, true);
564
527
}
565
528
 
566
 
bool Session::schedule(Session::shared_ptr &arg)
 
529
bool Session::schedule()
567
530
{
568
 
  arg->scheduler= plugin::Scheduler::getScheduler();
569
 
  assert(arg->scheduler);
 
531
  scheduler= plugin::Scheduler::getScheduler();
 
532
  assert(scheduler);
570
533
 
571
534
  connection_count.increment();
572
535
 
576
539
  }
577
540
 
578
541
  current_global_counters.connections++;
579
 
  arg->thread_id= arg->variables.pseudo_thread_id= global_thread_id++;
580
 
 
581
 
  session::Cache::singleton().insert(arg);
582
 
 
583
 
  if (unlikely(plugin::EventObserver::connectSession(*arg)))
584
 
  {
585
 
    // We should do something about an error...
586
 
  }
587
 
 
588
 
  if (plugin::Scheduler::getScheduler()->addSession(arg))
589
 
  {
590
 
    DRIZZLE_CONNECTION_START(arg->getSessionId());
 
542
  thread_id= variables.pseudo_thread_id= global_thread_id++;
 
543
 
 
544
  LOCK_thread_count.lock();
 
545
  getSessionList().push_back(this);
 
546
  LOCK_thread_count.unlock();
 
547
 
 
548
  if (scheduler->addSession(this))
 
549
  {
 
550
    DRIZZLE_CONNECTION_START(thread_id);
591
551
    char error_message_buff[DRIZZLE_ERRMSG_SIZE];
592
552
 
593
 
    arg->setKilled(Session::KILL_CONNECTION);
 
553
    killed= Session::KILL_CONNECTION;
594
554
 
595
 
    arg->status_var.aborted_connects++;
 
555
    status_var.aborted_connects++;
596
556
 
597
557
    /* Can't use my_error() since store_globals has not been called. */
598
558
    /* TODO replace will better error message */
599
559
    snprintf(error_message_buff, sizeof(error_message_buff),
600
560
             ER(ER_CANT_CREATE_THREAD), 1);
601
 
    arg->client->sendError(ER_CANT_CREATE_THREAD, error_message_buff);
602
 
 
 
561
    client->sendError(ER_CANT_CREATE_THREAD, error_message_buff);
603
562
    return true;
604
563
  }
605
564
 
607
566
}
608
567
 
609
568
 
610
 
/*
611
 
  Is this session viewable by the current user?
612
 
*/
613
 
bool Session::isViewable() const
614
 
{
615
 
  return plugin::Authorization::isAuthorized(current_session->user(),
616
 
                                             this,
617
 
                                             false);
618
 
}
619
 
 
620
 
 
621
 
const char* Session::enter_cond(boost::condition_variable_any &cond, boost::mutex &mutex, const char* msg)
 
569
const char* Session::enter_cond(boost::condition_variable &cond, boost::mutex &mutex, const char* msg)
622
570
{
623
571
  const char* old_msg = get_proc_info();
624
572
  safe_mutex_assert_owner(mutex);
625
 
  mysys_var->current_mutex = &mutex;
626
 
  mysys_var->current_cond = &cond;
 
573
  mysys_var->current_mutex = mutex.native_handle();
 
574
  mysys_var->current_cond = cond.native_handle();
627
575
  this->set_proc_info(msg);
628
576
  return old_msg;
629
577
}
636
584
    locked (if that would not be the case, you'll get a deadlock if someone
637
585
    does a Session::awake() on you).
638
586
  */
639
 
  mysys_var->current_mutex->unlock();
640
 
  boost_unique_lock_t scopedLock(mysys_var->mutex);
 
587
  pthread_mutex_unlock(mysys_var->current_mutex);
 
588
  pthread_mutex_lock(&mysys_var->mutex);
641
589
  mysys_var->current_mutex = 0;
642
590
  mysys_var->current_cond = 0;
643
591
  this->set_proc_info(old_msg);
 
592
  pthread_mutex_unlock(&mysys_var->mutex);
644
593
}
645
594
 
646
595
bool Session::authenticate()
647
596
{
648
 
  lex->start(this);
 
597
  lex_start(this);
649
598
  if (client->authenticate())
650
599
    return false;
651
600
 
654
603
  return true;
655
604
}
656
605
 
657
 
bool Session::checkUser(const std::string &passwd_str,
658
 
                        const std::string &in_db)
 
606
bool Session::checkUser(const char *passwd, uint32_t passwd_len, const char *in_db)
659
607
{
 
608
  const string passwd_str(passwd, passwd_len);
660
609
  bool is_authenticated=
661
 
    plugin::Authentication::isAuthenticated(user(), passwd_str);
 
610
    plugin::Authentication::isAuthenticated(getSecurityContext(),
 
611
                                            passwd_str);
662
612
 
663
613
  if (is_authenticated != true)
664
614
  {
668
618
  }
669
619
 
670
620
  /* Change database if necessary */
671
 
  if (not in_db.empty())
 
621
  if (in_db && in_db[0])
672
622
  {
673
623
    SchemaIdentifier identifier(in_db);
674
624
    if (mysql_change_db(this, identifier))
678
628
    }
679
629
  }
680
630
  my_ok();
681
 
  password= not passwd_str.empty();
 
631
  password= test(passwd_len);          // remember for error messages
682
632
 
683
633
  /* Ready to handle queries */
684
634
  return true;
700
650
  main_da.reset_diagnostics_area();
701
651
 
702
652
  if (client->readCommand(&l_packet, &packet_length) == false)
703
 
  {
704
653
    return false;
705
 
  }
706
654
 
707
 
  if (getKilled() == KILL_CONNECTION)
 
655
  if (killed == KILL_CONNECTION)
708
656
    return false;
709
657
 
710
658
  if (packet_length == 0)
711
659
    return true;
712
660
 
713
 
  l_command= static_cast<enum_server_command>(l_packet[0]);
 
661
  l_command= (enum enum_server_command) (unsigned char) l_packet[0];
714
662
 
715
663
  if (command >= COM_END)
716
664
    command= COM_END;                           // Wrong command
717
665
 
718
666
  assert(packet_length);
719
 
  return not dispatch_command(l_command, this, l_packet+1, (uint32_t) (packet_length-1));
 
667
  return ! dispatch_command(l_command, this, l_packet+1, (uint32_t) (packet_length-1));
720
668
}
721
669
 
722
670
bool Session::readAndStoreQuery(const char *in_packet, uint32_t in_packet_length)
728
676
    in_packet_length--;
729
677
  }
730
678
  const char *pos= in_packet + in_packet_length; /* Point at end null */
731
 
  while (in_packet_length > 0 && (pos[-1] == ';' || my_isspace(charset() ,pos[-1])))
 
679
  while (in_packet_length > 0 &&
 
680
         (pos[-1] == ';' || my_isspace(charset() ,pos[-1])))
732
681
  {
733
682
    pos--;
734
683
    in_packet_length--;
735
684
  }
736
685
 
737
 
  std::string *new_query= new std::string(in_packet, in_packet + in_packet_length);
738
 
  // We can not be entirely sure _schema has a value
739
 
  if (_schema)
740
 
  {
741
 
    plugin::QueryRewriter::rewriteQuery(*_schema, *new_query);
742
 
  }
743
 
  query.reset(new_query);
744
 
  _state.reset(new State(in_packet, in_packet_length));
 
686
  query.assign(in_packet, in_packet + in_packet_length);
745
687
 
746
688
  return true;
747
689
}
796
738
  }
797
739
 
798
740
  if (result == false)
799
 
  {
800
741
    my_error(killed_errno(), MYF(0));
801
 
  }
802
742
  else if ((result == true) && do_release)
803
 
  {
804
 
    setKilled(Session::KILL_CONNECTION);
805
 
  }
 
743
    killed= Session::KILL_CONNECTION;
806
744
 
807
745
  return result;
808
746
}
873
811
  where= Session::DEFAULT_WHERE;
874
812
 
875
813
  /* Reset the temporary shares we built */
876
 
  for_each(temporary_shares.begin(),
877
 
           temporary_shares.end(),
878
 
           DeletePtr());
 
814
  for (std::vector<TableShareInstance *>::iterator iter= temporary_shares.begin();
 
815
       iter != temporary_shares.end(); iter++)
 
816
  {
 
817
    delete *iter;
 
818
  }
879
819
  temporary_shares.clear();
880
820
}
881
821
 
961
901
  my_message(errcode, err, MYF(0));
962
902
  if (file > 0)
963
903
  {
964
 
    (void) cache->end_io_cache();
 
904
    (void) end_io_cache(cache);
965
905
    (void) internal::my_close(file, MYF(0));
966
 
    (void) internal::my_delete(path.file_string().c_str(), MYF(0));             // Delete file on error
 
906
    (void) internal::my_delete(path, MYF(0));           // Delete file on error
967
907
    file= -1;
968
908
  }
969
909
}
971
911
 
972
912
bool select_to_file::send_eof()
973
913
{
974
 
  int error= test(cache->end_io_cache());
 
914
  int error= test(end_io_cache(cache));
975
915
  if (internal::my_close(file, MYF(MY_WME)))
976
916
    error= 1;
977
917
  if (!error)
993
933
  /* In case of error send_eof() may be not called: close the file here. */
994
934
  if (file >= 0)
995
935
  {
996
 
    (void) cache->end_io_cache();
 
936
    (void) end_io_cache(cache);
997
937
    (void) internal::my_close(file, MYF(0));
998
938
    file= -1;
999
939
  }
1000
 
  path= "";
 
940
  path[0]= '\0';
1001
941
  row_count= 0;
1002
942
}
1003
943
 
1007
947
    cache(static_cast<internal::IO_CACHE *>(memory::sql_calloc(sizeof(internal::IO_CACHE)))),
1008
948
    row_count(0L)
1009
949
{
1010
 
  path= "";
 
950
  path[0]=0;
1011
951
}
1012
952
 
1013
953
select_to_file::~select_to_file()
1041
981
*/
1042
982
 
1043
983
 
1044
 
static int create_file(Session *session,
1045
 
                       fs::path &target_path,
1046
 
                       file_exchange *exchange,
1047
 
                       internal::IO_CACHE *cache)
 
984
static int create_file(Session *session, char *path, file_exchange *exchange, internal::IO_CACHE *cache)
1048
985
{
1049
 
  fs::path to_file(exchange->file_name);
1050
986
  int file;
1051
 
 
1052
 
  if (not to_file.has_root_directory())
 
987
  uint32_t option= MY_UNPACK_FILENAME | MY_RELATIVE_PATH;
 
988
 
 
989
#ifdef DONT_ALLOW_FULL_LOAD_DATA_PATHS
 
990
  option|= MY_REPLACE_DIR;                      // Force use of db directory
 
991
#endif
 
992
 
 
993
  if (!internal::dirname_length(exchange->file_name))
1053
994
  {
1054
 
    target_path= fs::system_complete(getDataHomeCatalog());
1055
 
    util::string::const_shared_ptr schema(session->schema());
1056
 
    if (schema and not schema->empty())
1057
 
    {
1058
 
      int count_elements= 0;
1059
 
      for (fs::path::iterator iter= to_file.begin();
1060
 
           iter != to_file.end();
1061
 
           ++iter, ++count_elements)
1062
 
      { }
1063
 
 
1064
 
      if (count_elements == 1)
1065
 
      {
1066
 
        target_path /= *schema;
1067
 
      }
1068
 
    }
1069
 
    target_path /= to_file;
 
995
    strcpy(path, data_home_real);
 
996
    if (! session->db.empty())
 
997
      strncat(path, session->db.c_str(), FN_REFLEN-strlen(data_home_real)-1);
 
998
    (void) internal::fn_format(path, exchange->file_name, path, "", option);
1070
999
  }
1071
1000
  else
1072
 
  {
1073
 
    target_path = exchange->file_name;
1074
 
  }
1075
 
 
1076
 
  if (not secure_file_priv.string().empty())
1077
 
  {
1078
 
    if (target_path.file_string().substr(0, secure_file_priv.file_string().size()) != secure_file_priv.file_string())
1079
 
    {
1080
 
      /* Write only allowed to dir or subdir specified by secure_file_priv */
1081
 
      my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--secure-file-priv");
1082
 
      return -1;
1083
 
    }
1084
 
  }
1085
 
 
1086
 
  if (!access(target_path.file_string().c_str(), F_OK))
 
1001
    (void) internal::fn_format(path, exchange->file_name, data_home_real, "", option);
 
1002
 
 
1003
  if (opt_secure_file_priv &&
 
1004
      strncmp(opt_secure_file_priv, path, strlen(opt_secure_file_priv)))
 
1005
  {
 
1006
    /* Write only allowed to dir or subdir specified by secure_file_priv */
 
1007
    my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--secure-file-priv");
 
1008
    return -1;
 
1009
  }
 
1010
 
 
1011
  if (!access(path, F_OK))
1087
1012
  {
1088
1013
    my_error(ER_FILE_EXISTS_ERROR, MYF(0), exchange->file_name);
1089
1014
    return -1;
1090
1015
  }
1091
1016
  /* Create the file world readable */
1092
 
  if ((file= internal::my_create(target_path.file_string().c_str(), 0666, O_WRONLY|O_EXCL, MYF(MY_WME))) < 0)
 
1017
  if ((file= internal::my_create(path, 0666, O_WRONLY|O_EXCL, MYF(MY_WME))) < 0)
1093
1018
    return file;
1094
1019
  (void) fchmod(file, 0666);                    // Because of umask()
1095
 
  if (cache->init_io_cache(file, 0L, internal::WRITE_CACHE, 0L, 1, MYF(MY_WME)))
 
1020
  if (init_io_cache(cache, file, 0L, internal::WRITE_CACHE, 0L, 1, MYF(MY_WME)))
1096
1021
  {
1097
1022
    internal::my_close(file, MYF(0));
1098
 
    internal::my_delete(target_path.file_string().c_str(), MYF(0));  // Delete file on error, it was just created
 
1023
    internal::my_delete(path, MYF(0));  // Delete file on error, it was just created
1099
1024
    return -1;
1100
1025
  }
1101
1026
  return file;
1109
1034
  bool string_results= false, non_string_results= false;
1110
1035
  unit= u;
1111
1036
  if ((uint32_t) strlen(exchange->file_name) + NAME_LEN >= FN_REFLEN)
1112
 
  {
1113
 
    path= exchange->file_name;
1114
 
  }
 
1037
    strncpy(path,exchange->file_name,FN_REFLEN-1);
1115
1038
 
1116
1039
  /* Check if there is any blobs in data */
1117
1040
  {
1121
1044
    {
1122
1045
      if (item->max_length >= MAX_BLOB_WIDTH)
1123
1046
      {
1124
 
        blob_flag=1;
1125
 
        break;
 
1047
        blob_flag=1;
 
1048
        break;
1126
1049
      }
1127
 
 
1128
1050
      if (item->result_type() == STRING_RESULT)
1129
1051
        string_results= true;
1130
1052
      else
1175
1097
  if (unit->offset_limit_cnt)
1176
1098
  {                                             // using limit offset,count
1177
1099
    unit->offset_limit_cnt--;
1178
 
    return false;
 
1100
    return(0);
1179
1101
  }
1180
1102
  row_count++;
1181
1103
  Item *item;
1184
1106
 
1185
1107
  if (my_b_write(cache,(unsigned char*) exchange->line_start->ptr(),
1186
1108
                 exchange->line_start->length()))
1187
 
    return true;
1188
 
 
 
1109
    goto err;
1189
1110
  while ((item=li++))
1190
1111
  {
1191
1112
    Item_result result_type=item->result_type();
1196
1117
    {
1197
1118
      if (my_b_write(cache,(unsigned char*) exchange->enclosed->ptr(),
1198
1119
                     exchange->enclosed->length()))
1199
 
        return true;
 
1120
        goto err;
1200
1121
    }
1201
1122
    if (!res)
1202
1123
    {                                           // NULL
1207
1128
          null_buff[0]=escape_char;
1208
1129
          null_buff[1]='N';
1209
1130
          if (my_b_write(cache,(unsigned char*) null_buff,2))
1210
 
            return true;
 
1131
            goto err;
1211
1132
        }
1212
1133
        else if (my_b_write(cache,(unsigned char*) "NULL",4))
1213
 
          return true;
 
1134
          goto err;
1214
1135
      }
1215
1136
      else
1216
1137
      {
1220
1141
    else
1221
1142
    {
1222
1143
      if (fixed_row_size)
1223
 
        used_length= min(res->length(), static_cast<size_t>(item->max_length));
 
1144
        used_length= min(res->length(),item->max_length);
1224
1145
      else
1225
1146
        used_length= res->length();
1226
1147
 
1301
1222
            tmp_buff[1]= *pos ? *pos : '0';
1302
1223
            if (my_b_write(cache,(unsigned char*) start,(uint32_t) (pos-start)) ||
1303
1224
                my_b_write(cache,(unsigned char*) tmp_buff,2))
1304
 
              return true;
 
1225
              goto err;
1305
1226
            start=pos+1;
1306
1227
          }
1307
1228
        }
1308
1229
        if (my_b_write(cache,(unsigned char*) start,(uint32_t) (pos-start)))
1309
 
          return true;
 
1230
          goto err;
1310
1231
      }
1311
1232
      else if (my_b_write(cache,(unsigned char*) res->ptr(),used_length))
1312
 
        return true;
 
1233
        goto err;
1313
1234
    }
1314
1235
    if (fixed_row_size)
1315
1236
    {                                           // Fill with space
1325
1246
        for (; length > sizeof(space) ; length-=sizeof(space))
1326
1247
        {
1327
1248
          if (my_b_write(cache,(unsigned char*) space,sizeof(space)))
1328
 
            return true;
 
1249
            goto err;
1329
1250
        }
1330
1251
        if (my_b_write(cache,(unsigned char*) space,length))
1331
 
          return true;
 
1252
          goto err;
1332
1253
      }
1333
1254
    }
1334
1255
    if (res && enclosed)
1335
1256
    {
1336
1257
      if (my_b_write(cache, (unsigned char*) exchange->enclosed->ptr(),
1337
1258
                     exchange->enclosed->length()))
1338
 
        return true;
 
1259
        goto err;
1339
1260
    }
1340
1261
    if (--items_left)
1341
1262
    {
1342
1263
      if (my_b_write(cache, (unsigned char*) exchange->field_term->ptr(),
1343
1264
                     field_term_length))
1344
 
        return true;
 
1265
        goto err;
1345
1266
    }
1346
1267
  }
1347
1268
  if (my_b_write(cache,(unsigned char*) exchange->line_term->ptr(),
1348
1269
                 exchange->line_term->length()))
1349
 
  {
1350
 
    return true;
1351
 
  }
1352
 
 
1353
 
  return false;
 
1270
    goto err;
 
1271
  return(0);
 
1272
err:
 
1273
  return(1);
1354
1274
}
1355
1275
 
1356
1276
 
1383
1303
  if (row_count++ > 1)
1384
1304
  {
1385
1305
    my_message(ER_TOO_MANY_ROWS, ER(ER_TOO_MANY_ROWS), MYF(0));
1386
 
    return 1;
 
1306
    goto err;
1387
1307
  }
1388
1308
  while ((item=li++))
1389
1309
  {
1391
1311
    if (!res)                                   // If NULL
1392
1312
    {
1393
1313
      if (my_b_write(cache,(unsigned char*) "",1))
1394
 
        return 1;
 
1314
        goto err;
1395
1315
    }
1396
1316
    else if (my_b_write(cache,(unsigned char*) res->ptr(),res->length()))
1397
1317
    {
1398
 
      my_error(ER_ERROR_ON_WRITE, MYF(0), path.file_string().c_str(), errno);
1399
 
      return 1;
 
1318
      my_error(ER_ERROR_ON_WRITE, MYF(0), path, errno);
 
1319
      goto err;
1400
1320
    }
1401
1321
  }
1402
1322
  return(0);
 
1323
err:
 
1324
  return(1);
1403
1325
}
1404
1326
 
1405
1327
 
1457
1379
      switch (val_item->result_type())
1458
1380
      {
1459
1381
      case REAL_RESULT:
1460
 
        op= &select_max_min_finder_subselect::cmp_real;
1461
 
        break;
 
1382
        op= &select_max_min_finder_subselect::cmp_real;
 
1383
        break;
1462
1384
      case INT_RESULT:
1463
 
        op= &select_max_min_finder_subselect::cmp_int;
1464
 
        break;
 
1385
        op= &select_max_min_finder_subselect::cmp_int;
 
1386
        break;
1465
1387
      case STRING_RESULT:
1466
 
        op= &select_max_min_finder_subselect::cmp_str;
1467
 
        break;
 
1388
        op= &select_max_min_finder_subselect::cmp_str;
 
1389
        break;
1468
1390
      case DECIMAL_RESULT:
1469
1391
        op= &select_max_min_finder_subselect::cmp_decimal;
1470
1392
        break;
1471
1393
      case ROW_RESULT:
1472
1394
        // This case should never be choosen
1473
 
        assert(0);
1474
 
        op= 0;
 
1395
        assert(0);
 
1396
        op= 0;
1475
1397
      }
1476
1398
    }
1477
1399
    cache->store(val_item);
1560
1482
void Session::end_statement()
1561
1483
{
1562
1484
  /* Cleanup SQL processing state to reuse this statement in next query. */
1563
 
  lex->end();
 
1485
  lex_end(lex);
1564
1486
  query_cache_key= ""; // reset the cache key
1565
1487
  resetResultsetMessage();
1566
1488
}
1567
1489
 
1568
1490
bool Session::copy_db_to(char **p_db, size_t *p_db_length)
1569
1491
{
1570
 
  assert(_schema);
1571
 
  if (_schema and _schema->empty())
1572
 
  {
1573
 
    my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
1574
 
    return true;
1575
 
  }
1576
 
  else if (not _schema)
1577
 
  {
1578
 
    my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
1579
 
    return true;
1580
 
  }
1581
 
  assert(_schema);
1582
 
 
1583
 
  *p_db= strmake(_schema->c_str(), _schema->size());
1584
 
  *p_db_length= _schema->size();
1585
 
 
 
1492
  if (db.empty())
 
1493
  {
 
1494
    my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
 
1495
    return true;
 
1496
  }
 
1497
  *p_db= strmake(db.c_str(), db.length());
 
1498
  *p_db_length= db.length();
1586
1499
  return false;
1587
1500
}
1588
1501
 
1622
1535
}
1623
1536
 
1624
1537
 
1625
 
void Session::set_db(const std::string &new_db)
 
1538
bool Session::set_db(const std::string &new_db)
1626
1539
{
1627
1540
  /* Do not reallocate memory if current chunk is big enough. */
1628
1541
  if (new_db.length())
1629
 
  {
1630
 
    _schema.reset(new std::string(new_db));
1631
 
  }
 
1542
    db= new_db;
1632
1543
  else
1633
 
  {
1634
 
    _schema.reset(new std::string(""));
1635
 
  }
1636
 
}
1637
 
 
 
1544
    db.clear();
 
1545
 
 
1546
  return false;
 
1547
}
 
1548
 
 
1549
 
 
1550
 
 
1551
 
 
1552
/**
 
1553
  Check the killed state of a user thread
 
1554
  @param session  user thread
 
1555
  @retval 0 the user thread is active
 
1556
  @retval 1 the user thread has been killed
 
1557
*/
 
1558
int session_killed(const Session *session)
 
1559
{
 
1560
  return(session->killed);
 
1561
}
 
1562
 
 
1563
 
 
1564
const struct charset_info_st *session_charset(Session *session)
 
1565
{
 
1566
  return(session->charset());
 
1567
}
1638
1568
 
1639
1569
/**
1640
1570
  Mark transaction to rollback and mark error as fatal to a sub-statement.
1657
1587
  plugin_sessionvar_cleanup(this);
1658
1588
 
1659
1589
  /* If necessary, log any aborted or unauthorized connections */
1660
 
  if (getKilled() || client->wasAborted())
 
1590
  if (killed || client->wasAborted())
1661
1591
  {
1662
1592
    status_var.aborted_threads++;
1663
1593
  }
1664
1594
 
1665
1595
  if (client->wasAborted())
1666
1596
  {
1667
 
    if (not getKilled() && variables.log_warnings > 1)
 
1597
    if (! killed && variables.log_warnings > 1)
1668
1598
    {
 
1599
      SecurityContext *sctx= &security_ctx;
 
1600
 
1669
1601
      errmsg_printf(ERRMSG_LVL_WARN, ER(ER_NEW_ABORTING_CONNECTION)
1670
1602
                  , thread_id
1671
 
                  , (_schema->empty() ? "unconnected" : _schema->c_str())
1672
 
                  , security_ctx->username().empty() == false ? security_ctx->username().c_str() : "unauthenticated"
1673
 
                  , security_ctx->address().c_str()
 
1603
                  , (db.empty() ? "unconnected" : db.c_str())
 
1604
                  , sctx->getUser().empty() == false ? sctx->getUser().c_str() : "unauthenticated"
 
1605
                  , sctx->getIp().c_str()
1674
1606
                  , (main_da.is_error() ? main_da.message() : ER(ER_UNKNOWN_ERROR)));
1675
1607
    }
1676
1608
  }
1677
1609
 
1678
1610
  /* Close out our connection to the client */
1679
1611
  if (should_lock)
1680
 
    session::Cache::singleton().mutex().lock();
1681
 
 
1682
 
  setKilled(Session::KILL_CONNECTION);
1683
 
 
 
1612
    LOCK_thread_count.lock();
 
1613
  killed= Session::KILL_CONNECTION;
1684
1614
  if (client->isConnected())
1685
1615
  {
1686
1616
    if (errcode)
1690
1620
    }
1691
1621
    client->close();
1692
1622
  }
1693
 
 
1694
1623
  if (should_lock)
1695
 
  {
1696
 
    session::Cache::singleton().mutex().unlock();
1697
 
  }
 
1624
    (void) LOCK_thread_count.unlock();
1698
1625
}
1699
1626
 
1700
1627
void Session::reset_for_next_command()
1722
1649
  Close all temporary tables created by 'CREATE TEMPORARY TABLE' for thread
1723
1650
*/
1724
1651
 
1725
 
void Open_tables_state::close_temporary_tables()
 
1652
void Session::close_temporary_tables()
1726
1653
{
1727
1654
  Table *table;
1728
1655
  Table *tmp_next;
1742
1669
  unlink from session->temporary tables and close temporary table
1743
1670
*/
1744
1671
 
1745
 
void Open_tables_state::close_temporary_table(Table *table)
 
1672
void Session::close_temporary_table(Table *table)
1746
1673
{
1747
1674
  if (table->getPrev())
1748
1675
  {
1778
1705
  If this is needed, use close_temporary_table()
1779
1706
*/
1780
1707
 
1781
 
void Open_tables_state::nukeTable(Table *table)
 
1708
void Session::nukeTable(Table *table)
1782
1709
{
1783
1710
  plugin::StorageEngine *table_type= table->getShare()->db_type();
1784
1711
 
1809
1736
 
1810
1737
user_var_entry *Session::getVariable(LEX_STRING &name, bool create_if_not_exists)
1811
1738
{
1812
 
  return getVariable(std::string(name.str, name.length), create_if_not_exists);
1813
 
}
1814
 
 
1815
 
user_var_entry *Session::getVariable(const std::string  &name, bool create_if_not_exists)
1816
 
{
1817
 
  UserVarsRange ppp= user_vars.equal_range(name);
 
1739
  user_var_entry *entry= NULL;
 
1740
  UserVarsRange ppp= user_vars.equal_range(std::string(name.str, name.length));
1818
1741
 
1819
1742
  for (UserVars::iterator iter= ppp.first;
1820
 
       iter != ppp.second; ++iter)
 
1743
         iter != ppp.second; ++iter)
1821
1744
  {
1822
 
    return (*iter).second;
 
1745
    entry= (*iter).second;
1823
1746
  }
1824
1747
 
1825
 
  if (not create_if_not_exists)
1826
 
    return NULL;
1827
 
 
1828
 
  user_var_entry *entry= NULL;
1829
 
  entry= new (nothrow) user_var_entry(name.c_str(), query_id);
1830
 
 
1831
 
  if (entry == NULL)
1832
 
    return NULL;
1833
 
 
1834
 
  std::pair<UserVars::iterator, bool> returnable= user_vars.insert(make_pair(name, entry));
1835
 
 
1836
 
  if (not returnable.second)
 
1748
  if ((entry == NULL) && create_if_not_exists)
1837
1749
  {
1838
 
    delete entry;
 
1750
    entry= new (nothrow) user_var_entry(name.str, query_id);
 
1751
 
 
1752
    if (entry == NULL)
 
1753
      return NULL;
 
1754
 
 
1755
    std::pair<UserVars::iterator, bool> returnable= user_vars.insert(make_pair(std::string(name.str, name.length), entry));
 
1756
 
 
1757
    if (not returnable.second)
 
1758
    {
 
1759
      delete entry;
 
1760
      return NULL;
 
1761
    }
1839
1762
  }
1840
1763
 
1841
1764
  return entry;
1842
1765
}
1843
1766
 
1844
 
void Session::setVariable(const std::string &name, const std::string &value)
1845
 
{
1846
 
  user_var_entry *updateable_var= getVariable(name.c_str(), true);
1847
 
 
1848
 
  updateable_var->update_hash(false,
1849
 
                              (void*)value.c_str(),
1850
 
                              static_cast<uint32_t>(value.length()), STRING_RESULT,
1851
 
                              &my_charset_bin,
1852
 
                              DERIVATION_IMPLICIT, false);
1853
 
}
1854
 
 
1855
 
void Open_tables_state::mark_temp_tables_as_free_for_reuse()
 
1767
void Session::mark_temp_tables_as_free_for_reuse()
1856
1768
{
1857
1769
  for (Table *table= temporary_tables ; table ; table= table->getNext())
1858
1770
  {
1859
 
    if (table->query_id == getQueryId())
 
1771
    if (table->query_id == query_id)
1860
1772
    {
1861
1773
      table->query_id= 0;
1862
1774
      table->cursor->ha_reset();
1868
1780
{
1869
1781
  for (; table ; table= table->getNext())
1870
1782
  {
1871
 
    if (table->query_id == getQueryId())
 
1783
    if (table->query_id == query_id)
1872
1784
    {
1873
1785
      table->query_id= 0;
1874
1786
      table->cursor->ha_reset();
1887
1799
*/
1888
1800
void Session::close_thread_tables()
1889
1801
{
1890
 
  clearDerivedTables();
 
1802
  if (derived_tables)
 
1803
    derived_tables= NULL; // They should all be invalid by this point
1891
1804
 
1892
1805
  /*
1893
1806
    Mark all temporary tables used by this statement as free for reuse.
1920
1833
      handled either before writing a query log event (inside
1921
1834
      binlog_query()) or when preparing a pending event.
1922
1835
     */
1923
 
    unlockTables(lock);
 
1836
    mysql_unlock_tables(this, lock);
1924
1837
    lock= 0;
1925
1838
  }
1926
1839
  /*
1927
 
    Note that we need to hold table::Cache::singleton().mutex() while changing the
 
1840
    Note that we need to hold LOCK_open while changing the
1928
1841
    open_tables list. Another thread may work on it.
1929
 
    (See: table::Cache::singleton().removeTable(), mysql_wait_completed_table())
 
1842
    (See: remove_table_from_cache(), mysql_wait_completed_table())
1930
1843
    Closing a MERGE child before the parent would be fatal if the
1931
1844
    other thread tries to abort the MERGE lock in between.
1932
1845
  */
1965
1878
    close_tables_for_reopen(&tables);
1966
1879
  }
1967
1880
  if ((mysql_handle_derived(lex, &mysql_derived_prepare) ||
1968
 
       (
 
1881
       (fill_derived_tables() &&
1969
1882
        mysql_handle_derived(lex, &mysql_derived_filling))))
1970
1883
    return true;
1971
1884
 
1972
1885
  return false;
1973
1886
}
1974
1887
 
 
1888
bool Session::openTables(TableList *tables, uint32_t flags)
 
1889
{
 
1890
  uint32_t counter;
 
1891
  bool ret= fill_derived_tables();
 
1892
  assert(ret == false);
 
1893
  if (open_tables_from_list(&tables, &counter, flags) ||
 
1894
      mysql_handle_derived(lex, &mysql_derived_prepare))
 
1895
  {
 
1896
    return true;
 
1897
  }
 
1898
  return false;
 
1899
}
 
1900
 
1975
1901
/*
1976
1902
  @note "best_effort" is used in cases were if a failure occurred on this
1977
1903
  operation it would not be surprising because we are only removing because there
1978
1904
  might be an issue (lame engines).
1979
1905
*/
1980
1906
 
1981
 
bool Open_tables_state::rm_temporary_table(const TableIdentifier &identifier, bool best_effort)
 
1907
bool Session::rm_temporary_table(TableIdentifier &identifier, bool best_effort)
1982
1908
{
1983
 
  if (plugin::StorageEngine::dropTable(*static_cast<Session *>(this), identifier))
 
1909
  if (plugin::StorageEngine::dropTable(*this, identifier))
1984
1910
  {
1985
1911
    if (not best_effort)
1986
1912
    {
1987
 
      std::string path;
1988
 
      identifier.getSQLPath(path);
1989
1913
      errmsg_printf(ERRMSG_LVL_WARN, _("Could not remove temporary table: '%s', error: %d"),
1990
 
                    path.c_str(), errno);
 
1914
                    identifier.getSQLPath().c_str(), errno);
1991
1915
    }
1992
1916
 
1993
1917
    return true;
1996
1920
  return false;
1997
1921
}
1998
1922
 
1999
 
bool Open_tables_state::rm_temporary_table(plugin::StorageEngine *base, const TableIdentifier &identifier)
 
1923
bool Session::rm_temporary_table(plugin::StorageEngine *base, TableIdentifier &identifier)
2000
1924
{
2001
1925
  assert(base);
2002
1926
 
2003
 
  if (plugin::StorageEngine::dropTable(*static_cast<Session *>(this), *base, identifier))
 
1927
  if (plugin::StorageEngine::dropTable(*this, *base, identifier))
2004
1928
  {
2005
 
    std::string path;
2006
 
    identifier.getSQLPath(path);
2007
1929
    errmsg_printf(ERRMSG_LVL_WARN, _("Could not remove temporary table: '%s', error: %d"),
2008
 
                  path.c_str(), errno);
 
1930
                  identifier.getSQLPath().c_str(), errno);
2009
1931
 
2010
1932
    return true;
2011
1933
  }
2017
1939
  @note this will be removed, I am looking through Hudson to see if it is finding
2018
1940
  any tables that are missed during cleanup.
2019
1941
*/
2020
 
void Open_tables_state::dumpTemporaryTableNames(const char *foo)
 
1942
void Session::dumpTemporaryTableNames(const char *foo)
2021
1943
{
2022
1944
  Table *table;
2023
1945
 
2041
1963
      cerr << "\t\t Proto " << proto->schema() << " " << proto->name() << "\n";
2042
1964
    }
2043
1965
    else
2044
 
    {
2045
1966
      cerr << "\tTabl;e Name " << table->getShare()->getSchemaName() << "." << table->getShare()->getTableName() << " : " << answer << "\n";
2046
 
    }
2047
1967
  }
2048
1968
}
2049
1969
 
2050
 
bool Session::TableMessages::storeTableMessage(const TableIdentifier &identifier, message::Table &table_message)
 
1970
bool Session::storeTableMessage(const TableIdentifier &identifier, message::Table &table_message)
2051
1971
{
2052
1972
  table_message_cache.insert(make_pair(identifier.getPath(), table_message));
2053
1973
 
2054
1974
  return true;
2055
1975
}
2056
1976
 
2057
 
bool Session::TableMessages::removeTableMessage(const TableIdentifier &identifier)
 
1977
bool Session::removeTableMessage(const TableIdentifier &identifier)
2058
1978
{
2059
1979
  TableMessageCache::iterator iter;
2060
1980
 
2068
1988
  return true;
2069
1989
}
2070
1990
 
2071
 
bool Session::TableMessages::getTableMessage(const TableIdentifier &identifier, message::Table &table_message)
 
1991
bool Session::getTableMessage(const TableIdentifier &identifier, message::Table &table_message)
2072
1992
{
2073
1993
  TableMessageCache::iterator iter;
2074
1994
 
2082
2002
  return true;
2083
2003
}
2084
2004
 
2085
 
bool Session::TableMessages::doesTableMessageExist(const TableIdentifier &identifier)
 
2005
bool Session::doesTableMessageExist(const TableIdentifier &identifier)
2086
2006
{
2087
2007
  TableMessageCache::iterator iter;
2088
2008
 
2096
2016
  return true;
2097
2017
}
2098
2018
 
2099
 
bool Session::TableMessages::renameTableMessage(const TableIdentifier &from, const TableIdentifier &to)
 
2019
bool Session::renameTableMessage(const TableIdentifier &from, const TableIdentifier &to)
2100
2020
{
2101
2021
  TableMessageCache::iterator iter;
2102
2022
 
2115
2035
  return true;
2116
2036
}
2117
2037
 
2118
 
table::Instance *Session::getInstanceTable()
2119
 
{
2120
 
  temporary_shares.push_back(new table::Instance()); // This will not go into the tableshare cache, so no key is used.
2121
 
 
2122
 
  table::Instance *tmp_share= temporary_shares.back();
2123
 
 
2124
 
  assert(tmp_share);
2125
 
 
2126
 
  return tmp_share;
2127
 
}
2128
 
 
2129
 
 
2130
 
/**
2131
 
  Create a reduced Table object with properly set up Field list from a
2132
 
  list of field definitions.
2133
 
 
2134
 
    The created table doesn't have a table Cursor associated with
2135
 
    it, has no keys, no group/distinct, no copy_funcs array.
2136
 
    The sole purpose of this Table object is to use the power of Field
2137
 
    class to read/write data to/from table->getInsertRecord(). Then one can store
2138
 
    the record in any container (RB tree, hash, etc).
2139
 
    The table is created in Session mem_root, so are the table's fields.
2140
 
    Consequently, if you don't BLOB fields, you don't need to free it.
2141
 
 
2142
 
  @param session         connection handle
2143
 
  @param field_list  list of column definitions
2144
 
 
2145
 
  @return
2146
 
    0 if out of memory, Table object in case of success
2147
 
*/
2148
 
table::Instance *Session::getInstanceTable(List<CreateField> &field_list)
2149
 
{
2150
 
  temporary_shares.push_back(new table::Instance(this, field_list)); // This will not go into the tableshare cache, so no key is used.
2151
 
 
2152
 
  table::Instance *tmp_share= temporary_shares.back();
2153
 
 
2154
 
  assert(tmp_share);
2155
 
 
2156
 
  return tmp_share;
2157
 
}
2158
 
 
2159
 
namespace display  {
2160
 
 
2161
 
static const std::string NONE= "NONE";
2162
 
static const std::string GOT_GLOBAL_READ_LOCK= "HAS GLOBAL READ LOCK";
2163
 
static const std::string MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT= "HAS GLOBAL READ LOCK WITH BLOCKING COMMIT";
2164
 
 
2165
 
const std::string &type(drizzled::Session::global_read_lock_t type)
2166
 
{
2167
 
  switch (type) {
2168
 
    default:
2169
 
    case Session::NONE:
2170
 
      return NONE;
2171
 
    case Session::GOT_GLOBAL_READ_LOCK:
2172
 
      return GOT_GLOBAL_READ_LOCK;
2173
 
    case Session::MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT:
2174
 
      return MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT;
2175
 
  }
2176
 
}
2177
 
 
2178
 
size_t max_string_length(drizzled::Session::global_read_lock_t)
2179
 
{
2180
 
  return MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT.size();
2181
 
}
2182
 
 
2183
 
} /* namespace display */
 
2038
TableShareInstance *Session::getTemporaryShare(TableIdentifier::Type type_arg)
 
2039
{
 
2040
  temporary_shares.push_back(new TableShareInstance(type_arg)); // This will not go into the tableshare cache, so no key is used.
 
2041
 
 
2042
  TableShareInstance *tmp_share= temporary_shares.back();
 
2043
 
 
2044
  assert(tmp_share);
 
2045
 
 
2046
  return tmp_share;
 
2047
}
2184
2048
 
2185
2049
} /* namespace drizzled */