~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/session.cc

  • Committer: LinuxJedi
  • Date: 2010-09-01 17:46:04 UTC
  • mto: (1750.1.1 build)
  • mto: This revision was merged to the branch mainline in revision 1751.
  • Revision ID: linuxjedi@linuxjedi-laptop-20100901174604-dvdwv3vey32ffbrk
Add a data_dictionary table for the MySQL protocol plugin

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;
227
212
  mysys_var= 0;
228
213
  scoreboard_index= -1;
229
214
  dbug_sentry=Session_SENTRY_MAGIC;
230
 
  cleanup_done= abort_on_warning= no_warnings_for_error= false;  
231
 
 
232
 
  /* query_cache init */
233
 
  query_cache_key= "";
234
 
  resultset= NULL;
 
215
  cleanup_done= abort_on_warning= no_warnings_for_error= false;
235
216
 
236
217
  /* Variables with default values */
237
218
  proc_info="login";
316
297
    return;
317
298
 
318
299
  setAbort(true);
319
 
  boost_unique_lock_t scopedLock(mysys_var->mutex);
 
300
  pthread_mutex_lock(&mysys_var->mutex);
320
301
  if (mysys_var->current_cond)
321
302
  {
322
 
    mysys_var->current_mutex->lock();
323
 
    mysys_var->current_cond->notify_all();
324
 
    mysys_var->current_mutex->unlock();
 
303
    pthread_mutex_lock(mysys_var->current_mutex);
 
304
    pthread_cond_broadcast(mysys_var->current_cond);
 
305
    pthread_mutex_unlock(mysys_var->current_mutex);
325
306
  }
 
307
  pthread_mutex_unlock(&mysys_var->mutex);
326
308
}
327
309
 
328
310
void Session::pop_internal_handler()
342
324
{
343
325
  assert(cleanup_done == false);
344
326
 
345
 
  setKilled(KILL_CONNECTION);
 
327
  killed= KILL_CONNECTION;
346
328
#ifdef ENABLE_WHEN_BINLOG_WILL_BE_ABLE_TO_PREPARE
347
329
  if (transaction.xid_state.xa_state == XA_PREPARED)
348
330
  {
368
350
  close_temporary_tables();
369
351
 
370
352
  if (global_read_lock)
371
 
  {
372
 
    unlockGlobalReadLock();
373
 
  }
 
353
    unlock_global_read_lock(this);
374
354
 
375
355
  cleanup_done= true;
376
356
}
381
361
 
382
362
  if (client->isConnected())
383
363
  {
384
 
    assert(security_ctx);
385
364
    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
 
 
 
365
        errmsg_printf(ERRMSG_LVL_WARN, ER(ER_FORCING_CLOSE),internal::my_progname,
 
366
                      thread_id,
 
367
                      (getSecurityContext().getUser().c_str() ?
 
368
                       getSecurityContext().getUser().c_str() : ""));
393
369
    disconnect(0, false);
394
370
  }
395
371
 
408
384
  dbug_sentry= Session_SENTRY_GONE;
409
385
 
410
386
  main_mem_root.free_root(MYF(0));
411
 
  currentMemRoot().release();
412
 
  currentSession().release();
 
387
  pthread_setspecific(THR_Session,  0);
413
388
 
414
389
  plugin::Logging::postEndDo(this);
415
390
  plugin::EventObserver::deregisterSessionEvents(*this); 
416
391
 
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
 
 
 
392
  /* Ensure that no one is using Session */
 
393
  LOCK_delete.unlock();
 
394
}
 
395
 
 
396
void Session::awake(Session::killed_state state_to_set)
 
397
{
435
398
  this->checkSentry();
436
 
 
437
 
  setKilled(state_to_set);
438
 
  scheduler->killSession(this);
439
 
 
 
399
  safe_mutex_assert_owner(&LOCK_delete);
 
400
 
 
401
  killed= state_to_set;
440
402
  if (state_to_set != Session::KILL_QUERY)
441
403
  {
 
404
    scheduler->killSession(this);
442
405
    DRIZZLE_CONNECTION_DONE(thread_id);
443
406
  }
444
 
 
445
407
  if (mysys_var)
446
408
  {
447
 
    boost_unique_lock_t scopedLock(mysys_var->mutex);
 
409
    pthread_mutex_lock(&mysys_var->mutex);
448
410
    /*
449
 
      "
450
411
      This broadcast could be up in the air if the victim thread
451
412
      exits the cond in the time between read and broadcast, but that is
452
413
      ok since all we want to do is to make the victim thread get out
467
428
    */
468
429
    if (mysys_var->current_cond && mysys_var->current_mutex)
469
430
    {
470
 
      mysys_var->current_mutex->lock();
471
 
      mysys_var->current_cond->notify_all();
472
 
      mysys_var->current_mutex->unlock();
 
431
      pthread_mutex_lock(mysys_var->current_mutex);
 
432
      pthread_cond_broadcast(mysys_var->current_cond);
 
433
      pthread_mutex_unlock(mysys_var->current_mutex);
473
434
    }
 
435
    pthread_mutex_unlock(&mysys_var->mutex);
474
436
  }
475
437
}
476
438
 
486
448
  */
487
449
  assert(thread_stack);
488
450
 
489
 
  currentSession().release();
490
 
  currentSession().reset(this);
491
 
 
492
 
  currentMemRoot().release();
493
 
  currentMemRoot().reset(&mem_root);
 
451
  if (pthread_setspecific(THR_Session,  this) ||
 
452
      pthread_setspecific(THR_Mem_root, &mem_root))
 
453
    return true;
494
454
 
495
455
  mysys_var=my_thread_var;
496
456
 
499
459
    This allows us to move Session to different threads if needed.
500
460
  */
501
461
  mysys_var->id= thread_id;
 
462
  real_id= pthread_self();                      // For debugging
502
463
 
503
464
  /*
504
465
    We have to call thr_lock_info_init() again here as Session may have been
529
490
                                variables.query_prealloc_size);
530
491
  transaction.xid_state.xid.null();
531
492
  transaction.xid_state.in_session=1;
532
 
  if (use_usage)
533
 
    resetUsage();
534
493
}
535
494
 
536
495
bool Session::initGlobals()
554
513
 
555
514
  prepareForQueries();
556
515
 
557
 
  while (not client->haveError() && getKilled() != KILL_CONNECTION)
 
516
  while (! client->haveError() && killed != KILL_CONNECTION)
558
517
  {
559
 
    if (not executeStatement())
 
518
    if (! executeStatement())
560
519
      break;
561
520
  }
562
521
 
563
522
  disconnect(0, true);
564
523
}
565
524
 
566
 
bool Session::schedule(Session::shared_ptr &arg)
 
525
bool Session::schedule()
567
526
{
568
 
  arg->scheduler= plugin::Scheduler::getScheduler();
569
 
  assert(arg->scheduler);
 
527
  scheduler= plugin::Scheduler::getScheduler();
 
528
  assert(scheduler);
570
529
 
571
530
  connection_count.increment();
572
531
 
576
535
  }
577
536
 
578
537
  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());
 
538
  thread_id= variables.pseudo_thread_id= global_thread_id++;
 
539
 
 
540
  LOCK_thread_count.lock();
 
541
  getSessionList().push_back(this);
 
542
  LOCK_thread_count.unlock();
 
543
 
 
544
  if (scheduler->addSession(this))
 
545
  {
 
546
    DRIZZLE_CONNECTION_START(thread_id);
591
547
    char error_message_buff[DRIZZLE_ERRMSG_SIZE];
592
548
 
593
 
    arg->setKilled(Session::KILL_CONNECTION);
 
549
    killed= Session::KILL_CONNECTION;
594
550
 
595
 
    arg->status_var.aborted_connects++;
 
551
    status_var.aborted_connects++;
596
552
 
597
553
    /* Can't use my_error() since store_globals has not been called. */
598
554
    /* TODO replace will better error message */
599
555
    snprintf(error_message_buff, sizeof(error_message_buff),
600
556
             ER(ER_CANT_CREATE_THREAD), 1);
601
 
    arg->client->sendError(ER_CANT_CREATE_THREAD, error_message_buff);
602
 
 
 
557
    client->sendError(ER_CANT_CREATE_THREAD, error_message_buff);
603
558
    return true;
604
559
  }
605
560
 
607
562
}
608
563
 
609
564
 
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)
 
565
const char* Session::enter_cond(boost::condition_variable &cond, boost::mutex &mutex, const char* msg)
622
566
{
623
567
  const char* old_msg = get_proc_info();
624
568
  safe_mutex_assert_owner(mutex);
625
 
  mysys_var->current_mutex = &mutex;
626
 
  mysys_var->current_cond = &cond;
 
569
  mysys_var->current_mutex = mutex.native_handle();
 
570
  mysys_var->current_cond = cond.native_handle();
627
571
  this->set_proc_info(msg);
628
572
  return old_msg;
629
573
}
636
580
    locked (if that would not be the case, you'll get a deadlock if someone
637
581
    does a Session::awake() on you).
638
582
  */
639
 
  mysys_var->current_mutex->unlock();
640
 
  boost_unique_lock_t scopedLock(mysys_var->mutex);
 
583
  pthread_mutex_unlock(mysys_var->current_mutex);
 
584
  pthread_mutex_lock(&mysys_var->mutex);
641
585
  mysys_var->current_mutex = 0;
642
586
  mysys_var->current_cond = 0;
643
587
  this->set_proc_info(old_msg);
 
588
  pthread_mutex_unlock(&mysys_var->mutex);
644
589
}
645
590
 
646
591
bool Session::authenticate()
647
592
{
648
 
  lex->start(this);
 
593
  lex_start(this);
649
594
  if (client->authenticate())
650
595
    return false;
651
596
 
654
599
  return true;
655
600
}
656
601
 
657
 
bool Session::checkUser(const std::string &passwd_str,
658
 
                        const std::string &in_db)
 
602
bool Session::checkUser(const char *passwd, uint32_t passwd_len, const char *in_db)
659
603
{
 
604
  const string passwd_str(passwd, passwd_len);
660
605
  bool is_authenticated=
661
 
    plugin::Authentication::isAuthenticated(user(), passwd_str);
 
606
    plugin::Authentication::isAuthenticated(getSecurityContext(),
 
607
                                            passwd_str);
662
608
 
663
609
  if (is_authenticated != true)
664
610
  {
668
614
  }
669
615
 
670
616
  /* Change database if necessary */
671
 
  if (not in_db.empty())
 
617
  if (in_db && in_db[0])
672
618
  {
673
619
    SchemaIdentifier identifier(in_db);
674
620
    if (mysql_change_db(this, identifier))
678
624
    }
679
625
  }
680
626
  my_ok();
681
 
  password= not passwd_str.empty();
 
627
  password= test(passwd_len);          // remember for error messages
682
628
 
683
629
  /* Ready to handle queries */
684
630
  return true;
700
646
  main_da.reset_diagnostics_area();
701
647
 
702
648
  if (client->readCommand(&l_packet, &packet_length) == false)
703
 
  {
704
 
    return false;
705
 
  }
706
 
 
707
 
  if (getKilled() == KILL_CONNECTION)
708
649
    return false;
709
650
 
710
651
  if (packet_length == 0)
711
652
    return true;
712
653
 
713
 
  l_command= static_cast<enum_server_command>(l_packet[0]);
 
654
  l_command= (enum enum_server_command) (unsigned char) l_packet[0];
714
655
 
715
656
  if (command >= COM_END)
716
657
    command= COM_END;                           // Wrong command
717
658
 
718
659
  assert(packet_length);
719
 
  return not dispatch_command(l_command, this, l_packet+1, (uint32_t) (packet_length-1));
 
660
  return ! dispatch_command(l_command, this, l_packet+1, (uint32_t) (packet_length-1));
720
661
}
721
662
 
722
663
bool Session::readAndStoreQuery(const char *in_packet, uint32_t in_packet_length)
728
669
    in_packet_length--;
729
670
  }
730
671
  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])))
 
672
  while (in_packet_length > 0 &&
 
673
         (pos[-1] == ';' || my_isspace(charset() ,pos[-1])))
732
674
  {
733
675
    pos--;
734
676
    in_packet_length--;
735
677
  }
736
678
 
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));
 
679
  query.assign(in_packet, in_packet + in_packet_length);
745
680
 
746
681
  return true;
747
682
}
796
731
  }
797
732
 
798
733
  if (result == false)
799
 
  {
800
734
    my_error(killed_errno(), MYF(0));
801
 
  }
802
735
  else if ((result == true) && do_release)
803
 
  {
804
 
    setKilled(Session::KILL_CONNECTION);
805
 
  }
 
736
    killed= Session::KILL_CONNECTION;
806
737
 
807
738
  return result;
808
739
}
873
804
  where= Session::DEFAULT_WHERE;
874
805
 
875
806
  /* Reset the temporary shares we built */
876
 
  for_each(temporary_shares.begin(),
877
 
           temporary_shares.end(),
878
 
           DeletePtr());
 
807
  for (std::vector<TableShareInstance *>::iterator iter= temporary_shares.begin();
 
808
       iter != temporary_shares.end(); iter++)
 
809
  {
 
810
    delete *iter;
 
811
  }
879
812
  temporary_shares.clear();
880
813
}
881
814
 
961
894
  my_message(errcode, err, MYF(0));
962
895
  if (file > 0)
963
896
  {
964
 
    (void) cache->end_io_cache();
 
897
    (void) end_io_cache(cache);
965
898
    (void) internal::my_close(file, MYF(0));
966
 
    (void) internal::my_delete(path.file_string().c_str(), MYF(0));             // Delete file on error
 
899
    (void) internal::my_delete(path, MYF(0));           // Delete file on error
967
900
    file= -1;
968
901
  }
969
902
}
971
904
 
972
905
bool select_to_file::send_eof()
973
906
{
974
 
  int error= test(cache->end_io_cache());
 
907
  int error= test(end_io_cache(cache));
975
908
  if (internal::my_close(file, MYF(MY_WME)))
976
909
    error= 1;
977
910
  if (!error)
993
926
  /* In case of error send_eof() may be not called: close the file here. */
994
927
  if (file >= 0)
995
928
  {
996
 
    (void) cache->end_io_cache();
 
929
    (void) end_io_cache(cache);
997
930
    (void) internal::my_close(file, MYF(0));
998
931
    file= -1;
999
932
  }
1000
 
  path= "";
 
933
  path[0]= '\0';
1001
934
  row_count= 0;
1002
935
}
1003
936
 
1007
940
    cache(static_cast<internal::IO_CACHE *>(memory::sql_calloc(sizeof(internal::IO_CACHE)))),
1008
941
    row_count(0L)
1009
942
{
1010
 
  path= "";
 
943
  path[0]=0;
1011
944
}
1012
945
 
1013
946
select_to_file::~select_to_file()
1041
974
*/
1042
975
 
1043
976
 
1044
 
static int create_file(Session *session,
1045
 
                       fs::path &target_path,
1046
 
                       file_exchange *exchange,
1047
 
                       internal::IO_CACHE *cache)
 
977
static int create_file(Session *session, char *path, file_exchange *exchange, internal::IO_CACHE *cache)
1048
978
{
1049
 
  fs::path to_file(exchange->file_name);
1050
979
  int file;
1051
 
 
1052
 
  if (not to_file.has_root_directory())
 
980
  uint32_t option= MY_UNPACK_FILENAME | MY_RELATIVE_PATH;
 
981
 
 
982
#ifdef DONT_ALLOW_FULL_LOAD_DATA_PATHS
 
983
  option|= MY_REPLACE_DIR;                      // Force use of db directory
 
984
#endif
 
985
 
 
986
  if (!internal::dirname_length(exchange->file_name))
1053
987
  {
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;
 
988
    strcpy(path, data_home_real);
 
989
    if (! session->db.empty())
 
990
      strncat(path, session->db.c_str(), FN_REFLEN-strlen(data_home_real)-1);
 
991
    (void) internal::fn_format(path, exchange->file_name, path, "", option);
1070
992
  }
1071
993
  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))
 
994
    (void) internal::fn_format(path, exchange->file_name, data_home_real, "", option);
 
995
 
 
996
  if (opt_secure_file_priv &&
 
997
      strncmp(opt_secure_file_priv, path, strlen(opt_secure_file_priv)))
 
998
  {
 
999
    /* Write only allowed to dir or subdir specified by secure_file_priv */
 
1000
    my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--secure-file-priv");
 
1001
    return -1;
 
1002
  }
 
1003
 
 
1004
  if (!access(path, F_OK))
1087
1005
  {
1088
1006
    my_error(ER_FILE_EXISTS_ERROR, MYF(0), exchange->file_name);
1089
1007
    return -1;
1090
1008
  }
1091
1009
  /* 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)
 
1010
  if ((file= internal::my_create(path, 0666, O_WRONLY|O_EXCL, MYF(MY_WME))) < 0)
1093
1011
    return file;
1094
1012
  (void) fchmod(file, 0666);                    // Because of umask()
1095
 
  if (cache->init_io_cache(file, 0L, internal::WRITE_CACHE, 0L, 1, MYF(MY_WME)))
 
1013
  if (init_io_cache(cache, file, 0L, internal::WRITE_CACHE, 0L, 1, MYF(MY_WME)))
1096
1014
  {
1097
1015
    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
 
1016
    internal::my_delete(path, MYF(0));  // Delete file on error, it was just created
1099
1017
    return -1;
1100
1018
  }
1101
1019
  return file;
1109
1027
  bool string_results= false, non_string_results= false;
1110
1028
  unit= u;
1111
1029
  if ((uint32_t) strlen(exchange->file_name) + NAME_LEN >= FN_REFLEN)
1112
 
  {
1113
 
    path= exchange->file_name;
1114
 
  }
 
1030
    strncpy(path,exchange->file_name,FN_REFLEN-1);
1115
1031
 
1116
1032
  /* Check if there is any blobs in data */
1117
1033
  {
1121
1037
    {
1122
1038
      if (item->max_length >= MAX_BLOB_WIDTH)
1123
1039
      {
1124
 
        blob_flag=1;
1125
 
        break;
 
1040
        blob_flag=1;
 
1041
        break;
1126
1042
      }
1127
 
 
1128
1043
      if (item->result_type() == STRING_RESULT)
1129
1044
        string_results= true;
1130
1045
      else
1175
1090
  if (unit->offset_limit_cnt)
1176
1091
  {                                             // using limit offset,count
1177
1092
    unit->offset_limit_cnt--;
1178
 
    return false;
 
1093
    return(0);
1179
1094
  }
1180
1095
  row_count++;
1181
1096
  Item *item;
1184
1099
 
1185
1100
  if (my_b_write(cache,(unsigned char*) exchange->line_start->ptr(),
1186
1101
                 exchange->line_start->length()))
1187
 
    return true;
1188
 
 
 
1102
    goto err;
1189
1103
  while ((item=li++))
1190
1104
  {
1191
1105
    Item_result result_type=item->result_type();
1196
1110
    {
1197
1111
      if (my_b_write(cache,(unsigned char*) exchange->enclosed->ptr(),
1198
1112
                     exchange->enclosed->length()))
1199
 
        return true;
 
1113
        goto err;
1200
1114
    }
1201
1115
    if (!res)
1202
1116
    {                                           // NULL
1207
1121
          null_buff[0]=escape_char;
1208
1122
          null_buff[1]='N';
1209
1123
          if (my_b_write(cache,(unsigned char*) null_buff,2))
1210
 
            return true;
 
1124
            goto err;
1211
1125
        }
1212
1126
        else if (my_b_write(cache,(unsigned char*) "NULL",4))
1213
 
          return true;
 
1127
          goto err;
1214
1128
      }
1215
1129
      else
1216
1130
      {
1220
1134
    else
1221
1135
    {
1222
1136
      if (fixed_row_size)
1223
 
        used_length= min(res->length(), static_cast<size_t>(item->max_length));
 
1137
        used_length= min(res->length(),item->max_length);
1224
1138
      else
1225
1139
        used_length= res->length();
1226
1140
 
1301
1215
            tmp_buff[1]= *pos ? *pos : '0';
1302
1216
            if (my_b_write(cache,(unsigned char*) start,(uint32_t) (pos-start)) ||
1303
1217
                my_b_write(cache,(unsigned char*) tmp_buff,2))
1304
 
              return true;
 
1218
              goto err;
1305
1219
            start=pos+1;
1306
1220
          }
1307
1221
        }
1308
1222
        if (my_b_write(cache,(unsigned char*) start,(uint32_t) (pos-start)))
1309
 
          return true;
 
1223
          goto err;
1310
1224
      }
1311
1225
      else if (my_b_write(cache,(unsigned char*) res->ptr(),used_length))
1312
 
        return true;
 
1226
        goto err;
1313
1227
    }
1314
1228
    if (fixed_row_size)
1315
1229
    {                                           // Fill with space
1325
1239
        for (; length > sizeof(space) ; length-=sizeof(space))
1326
1240
        {
1327
1241
          if (my_b_write(cache,(unsigned char*) space,sizeof(space)))
1328
 
            return true;
 
1242
            goto err;
1329
1243
        }
1330
1244
        if (my_b_write(cache,(unsigned char*) space,length))
1331
 
          return true;
 
1245
          goto err;
1332
1246
      }
1333
1247
    }
1334
1248
    if (res && enclosed)
1335
1249
    {
1336
1250
      if (my_b_write(cache, (unsigned char*) exchange->enclosed->ptr(),
1337
1251
                     exchange->enclosed->length()))
1338
 
        return true;
 
1252
        goto err;
1339
1253
    }
1340
1254
    if (--items_left)
1341
1255
    {
1342
1256
      if (my_b_write(cache, (unsigned char*) exchange->field_term->ptr(),
1343
1257
                     field_term_length))
1344
 
        return true;
 
1258
        goto err;
1345
1259
    }
1346
1260
  }
1347
1261
  if (my_b_write(cache,(unsigned char*) exchange->line_term->ptr(),
1348
1262
                 exchange->line_term->length()))
1349
 
  {
1350
 
    return true;
1351
 
  }
1352
 
 
1353
 
  return false;
 
1263
    goto err;
 
1264
  return(0);
 
1265
err:
 
1266
  return(1);
1354
1267
}
1355
1268
 
1356
1269
 
1383
1296
  if (row_count++ > 1)
1384
1297
  {
1385
1298
    my_message(ER_TOO_MANY_ROWS, ER(ER_TOO_MANY_ROWS), MYF(0));
1386
 
    return 1;
 
1299
    goto err;
1387
1300
  }
1388
1301
  while ((item=li++))
1389
1302
  {
1391
1304
    if (!res)                                   // If NULL
1392
1305
    {
1393
1306
      if (my_b_write(cache,(unsigned char*) "",1))
1394
 
        return 1;
 
1307
        goto err;
1395
1308
    }
1396
1309
    else if (my_b_write(cache,(unsigned char*) res->ptr(),res->length()))
1397
1310
    {
1398
 
      my_error(ER_ERROR_ON_WRITE, MYF(0), path.file_string().c_str(), errno);
1399
 
      return 1;
 
1311
      my_error(ER_ERROR_ON_WRITE, MYF(0), path, errno);
 
1312
      goto err;
1400
1313
    }
1401
1314
  }
1402
1315
  return(0);
 
1316
err:
 
1317
  return(1);
1403
1318
}
1404
1319
 
1405
1320
 
1457
1372
      switch (val_item->result_type())
1458
1373
      {
1459
1374
      case REAL_RESULT:
1460
 
        op= &select_max_min_finder_subselect::cmp_real;
1461
 
        break;
 
1375
        op= &select_max_min_finder_subselect::cmp_real;
 
1376
        break;
1462
1377
      case INT_RESULT:
1463
 
        op= &select_max_min_finder_subselect::cmp_int;
1464
 
        break;
 
1378
        op= &select_max_min_finder_subselect::cmp_int;
 
1379
        break;
1465
1380
      case STRING_RESULT:
1466
 
        op= &select_max_min_finder_subselect::cmp_str;
1467
 
        break;
 
1381
        op= &select_max_min_finder_subselect::cmp_str;
 
1382
        break;
1468
1383
      case DECIMAL_RESULT:
1469
1384
        op= &select_max_min_finder_subselect::cmp_decimal;
1470
1385
        break;
1471
1386
      case ROW_RESULT:
1472
1387
        // This case should never be choosen
1473
 
        assert(0);
1474
 
        op= 0;
 
1388
        assert(0);
 
1389
        op= 0;
1475
1390
      }
1476
1391
    }
1477
1392
    cache->store(val_item);
1560
1475
void Session::end_statement()
1561
1476
{
1562
1477
  /* Cleanup SQL processing state to reuse this statement in next query. */
1563
 
  lex->end();
1564
 
  query_cache_key= ""; // reset the cache key
1565
 
  resetResultsetMessage();
 
1478
  lex_end(lex);
1566
1479
}
1567
1480
 
1568
1481
bool Session::copy_db_to(char **p_db, size_t *p_db_length)
1569
1482
{
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
 
 
 
1483
  if (db.empty())
 
1484
  {
 
1485
    my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
 
1486
    return true;
 
1487
  }
 
1488
  *p_db= strmake(db.c_str(), db.length());
 
1489
  *p_db_length= db.length();
1586
1490
  return false;
1587
1491
}
1588
1492
 
1622
1526
}
1623
1527
 
1624
1528
 
1625
 
void Session::set_db(const std::string &new_db)
 
1529
bool Session::set_db(const std::string &new_db)
1626
1530
{
1627
1531
  /* Do not reallocate memory if current chunk is big enough. */
1628
1532
  if (new_db.length())
1629
 
  {
1630
 
    _schema.reset(new std::string(new_db));
1631
 
  }
 
1533
    db= new_db;
1632
1534
  else
1633
 
  {
1634
 
    _schema.reset(new std::string(""));
1635
 
  }
1636
 
}
1637
 
 
 
1535
    db.clear();
 
1536
 
 
1537
  return false;
 
1538
}
 
1539
 
 
1540
 
 
1541
 
 
1542
 
 
1543
/**
 
1544
  Check the killed state of a user thread
 
1545
  @param session  user thread
 
1546
  @retval 0 the user thread is active
 
1547
  @retval 1 the user thread has been killed
 
1548
*/
 
1549
int session_killed(const Session *session)
 
1550
{
 
1551
  return(session->killed);
 
1552
}
 
1553
 
 
1554
 
 
1555
const struct charset_info_st *session_charset(Session *session)
 
1556
{
 
1557
  return(session->charset());
 
1558
}
1638
1559
 
1639
1560
/**
1640
1561
  Mark transaction to rollback and mark error as fatal to a sub-statement.
1657
1578
  plugin_sessionvar_cleanup(this);
1658
1579
 
1659
1580
  /* If necessary, log any aborted or unauthorized connections */
1660
 
  if (getKilled() || client->wasAborted())
 
1581
  if (killed || client->wasAborted())
1661
1582
  {
1662
1583
    status_var.aborted_threads++;
1663
1584
  }
1664
1585
 
1665
1586
  if (client->wasAborted())
1666
1587
  {
1667
 
    if (not getKilled() && variables.log_warnings > 1)
 
1588
    if (! killed && variables.log_warnings > 1)
1668
1589
    {
 
1590
      SecurityContext *sctx= &security_ctx;
 
1591
 
1669
1592
      errmsg_printf(ERRMSG_LVL_WARN, ER(ER_NEW_ABORTING_CONNECTION)
1670
1593
                  , 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()
 
1594
                  , (db.empty() ? "unconnected" : db.c_str())
 
1595
                  , sctx->getUser().empty() == false ? sctx->getUser().c_str() : "unauthenticated"
 
1596
                  , sctx->getIp().c_str()
1674
1597
                  , (main_da.is_error() ? main_da.message() : ER(ER_UNKNOWN_ERROR)));
1675
1598
    }
1676
1599
  }
1677
1600
 
1678
1601
  /* Close out our connection to the client */
1679
1602
  if (should_lock)
1680
 
    session::Cache::singleton().mutex().lock();
1681
 
 
1682
 
  setKilled(Session::KILL_CONNECTION);
1683
 
 
 
1603
    LOCK_thread_count.lock();
 
1604
  killed= Session::KILL_CONNECTION;
1684
1605
  if (client->isConnected())
1685
1606
  {
1686
1607
    if (errcode)
1690
1611
    }
1691
1612
    client->close();
1692
1613
  }
1693
 
 
1694
1614
  if (should_lock)
1695
 
  {
1696
 
    session::Cache::singleton().mutex().unlock();
1697
 
  }
 
1615
    (void) LOCK_thread_count.unlock();
1698
1616
}
1699
1617
 
1700
1618
void Session::reset_for_next_command()
1722
1640
  Close all temporary tables created by 'CREATE TEMPORARY TABLE' for thread
1723
1641
*/
1724
1642
 
1725
 
void Open_tables_state::close_temporary_tables()
 
1643
void Session::close_temporary_tables()
1726
1644
{
1727
1645
  Table *table;
1728
1646
  Table *tmp_next;
1742
1660
  unlink from session->temporary tables and close temporary table
1743
1661
*/
1744
1662
 
1745
 
void Open_tables_state::close_temporary_table(Table *table)
 
1663
void Session::close_temporary_table(Table *table)
1746
1664
{
1747
1665
  if (table->getPrev())
1748
1666
  {
1778
1696
  If this is needed, use close_temporary_table()
1779
1697
*/
1780
1698
 
1781
 
void Open_tables_state::nukeTable(Table *table)
 
1699
void Session::nukeTable(Table *table)
1782
1700
{
1783
1701
  plugin::StorageEngine *table_type= table->getShare()->db_type();
1784
1702
 
1809
1727
 
1810
1728
user_var_entry *Session::getVariable(LEX_STRING &name, bool create_if_not_exists)
1811
1729
{
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);
 
1730
  user_var_entry *entry= NULL;
 
1731
  UserVarsRange ppp= user_vars.equal_range(std::string(name.str, name.length));
1818
1732
 
1819
1733
  for (UserVars::iterator iter= ppp.first;
1820
 
       iter != ppp.second; ++iter)
 
1734
         iter != ppp.second; ++iter)
1821
1735
  {
1822
 
    return (*iter).second;
 
1736
    entry= (*iter).second;
1823
1737
  }
1824
1738
 
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)
 
1739
  if ((entry == NULL) && create_if_not_exists)
1837
1740
  {
1838
 
    delete entry;
 
1741
    entry= new (nothrow) user_var_entry(name.str, query_id);
 
1742
 
 
1743
    if (entry == NULL)
 
1744
      return NULL;
 
1745
 
 
1746
    std::pair<UserVars::iterator, bool> returnable= user_vars.insert(make_pair(std::string(name.str, name.length), entry));
 
1747
 
 
1748
    if (not returnable.second)
 
1749
    {
 
1750
      delete entry;
 
1751
      return NULL;
 
1752
    }
1839
1753
  }
1840
1754
 
1841
1755
  return entry;
1842
1756
}
1843
1757
 
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()
 
1758
void Session::mark_temp_tables_as_free_for_reuse()
1856
1759
{
1857
1760
  for (Table *table= temporary_tables ; table ; table= table->getNext())
1858
1761
  {
1859
 
    if (table->query_id == getQueryId())
 
1762
    if (table->query_id == query_id)
1860
1763
    {
1861
1764
      table->query_id= 0;
1862
1765
      table->cursor->ha_reset();
1868
1771
{
1869
1772
  for (; table ; table= table->getNext())
1870
1773
  {
1871
 
    if (table->query_id == getQueryId())
 
1774
    if (table->query_id == query_id)
1872
1775
    {
1873
1776
      table->query_id= 0;
1874
1777
      table->cursor->ha_reset();
1887
1790
*/
1888
1791
void Session::close_thread_tables()
1889
1792
{
1890
 
  clearDerivedTables();
 
1793
  if (derived_tables)
 
1794
    derived_tables= NULL; // They should all be invalid by this point
1891
1795
 
1892
1796
  /*
1893
1797
    Mark all temporary tables used by this statement as free for reuse.
1920
1824
      handled either before writing a query log event (inside
1921
1825
      binlog_query()) or when preparing a pending event.
1922
1826
     */
1923
 
    unlockTables(lock);
 
1827
    mysql_unlock_tables(this, lock);
1924
1828
    lock= 0;
1925
1829
  }
1926
1830
  /*
1927
 
    Note that we need to hold table::Cache::singleton().mutex() while changing the
 
1831
    Note that we need to hold LOCK_open while changing the
1928
1832
    open_tables list. Another thread may work on it.
1929
 
    (See: table::Cache::singleton().removeTable(), mysql_wait_completed_table())
 
1833
    (See: remove_table_from_cache(), mysql_wait_completed_table())
1930
1834
    Closing a MERGE child before the parent would be fatal if the
1931
1835
    other thread tries to abort the MERGE lock in between.
1932
1836
  */
1965
1869
    close_tables_for_reopen(&tables);
1966
1870
  }
1967
1871
  if ((mysql_handle_derived(lex, &mysql_derived_prepare) ||
1968
 
       (
 
1872
       (fill_derived_tables() &&
1969
1873
        mysql_handle_derived(lex, &mysql_derived_filling))))
1970
1874
    return true;
1971
1875
 
1972
1876
  return false;
1973
1877
}
1974
1878
 
 
1879
bool Session::openTables(TableList *tables, uint32_t flags)
 
1880
{
 
1881
  uint32_t counter;
 
1882
  bool ret= fill_derived_tables();
 
1883
  assert(ret == false);
 
1884
  if (open_tables_from_list(&tables, &counter, flags) ||
 
1885
      mysql_handle_derived(lex, &mysql_derived_prepare))
 
1886
  {
 
1887
    return true;
 
1888
  }
 
1889
  return false;
 
1890
}
 
1891
 
1975
1892
/*
1976
1893
  @note "best_effort" is used in cases were if a failure occurred on this
1977
1894
  operation it would not be surprising because we are only removing because there
1978
1895
  might be an issue (lame engines).
1979
1896
*/
1980
1897
 
1981
 
bool Open_tables_state::rm_temporary_table(const TableIdentifier &identifier, bool best_effort)
 
1898
bool Session::rm_temporary_table(TableIdentifier &identifier, bool best_effort)
1982
1899
{
1983
 
  if (plugin::StorageEngine::dropTable(*static_cast<Session *>(this), identifier))
 
1900
  if (plugin::StorageEngine::dropTable(*this, identifier))
1984
1901
  {
1985
1902
    if (not best_effort)
1986
1903
    {
1987
 
      std::string path;
1988
 
      identifier.getSQLPath(path);
1989
1904
      errmsg_printf(ERRMSG_LVL_WARN, _("Could not remove temporary table: '%s', error: %d"),
1990
 
                    path.c_str(), errno);
 
1905
                    identifier.getSQLPath().c_str(), errno);
1991
1906
    }
1992
1907
 
1993
1908
    return true;
1996
1911
  return false;
1997
1912
}
1998
1913
 
1999
 
bool Open_tables_state::rm_temporary_table(plugin::StorageEngine *base, const TableIdentifier &identifier)
 
1914
bool Session::rm_temporary_table(plugin::StorageEngine *base, TableIdentifier &identifier)
2000
1915
{
2001
1916
  assert(base);
2002
1917
 
2003
 
  if (plugin::StorageEngine::dropTable(*static_cast<Session *>(this), *base, identifier))
 
1918
  if (plugin::StorageEngine::dropTable(*this, *base, identifier))
2004
1919
  {
2005
 
    std::string path;
2006
 
    identifier.getSQLPath(path);
2007
1920
    errmsg_printf(ERRMSG_LVL_WARN, _("Could not remove temporary table: '%s', error: %d"),
2008
 
                  path.c_str(), errno);
 
1921
                  identifier.getSQLPath().c_str(), errno);
2009
1922
 
2010
1923
    return true;
2011
1924
  }
2017
1930
  @note this will be removed, I am looking through Hudson to see if it is finding
2018
1931
  any tables that are missed during cleanup.
2019
1932
*/
2020
 
void Open_tables_state::dumpTemporaryTableNames(const char *foo)
 
1933
void Session::dumpTemporaryTableNames(const char *foo)
2021
1934
{
2022
1935
  Table *table;
2023
1936
 
2041
1954
      cerr << "\t\t Proto " << proto->schema() << " " << proto->name() << "\n";
2042
1955
    }
2043
1956
    else
2044
 
    {
2045
1957
      cerr << "\tTabl;e Name " << table->getShare()->getSchemaName() << "." << table->getShare()->getTableName() << " : " << answer << "\n";
2046
 
    }
2047
1958
  }
2048
1959
}
2049
1960
 
2050
 
bool Session::TableMessages::storeTableMessage(const TableIdentifier &identifier, message::Table &table_message)
 
1961
bool Session::storeTableMessage(const TableIdentifier &identifier, message::Table &table_message)
2051
1962
{
2052
1963
  table_message_cache.insert(make_pair(identifier.getPath(), table_message));
2053
1964
 
2054
1965
  return true;
2055
1966
}
2056
1967
 
2057
 
bool Session::TableMessages::removeTableMessage(const TableIdentifier &identifier)
 
1968
bool Session::removeTableMessage(const TableIdentifier &identifier)
2058
1969
{
2059
1970
  TableMessageCache::iterator iter;
2060
1971
 
2068
1979
  return true;
2069
1980
}
2070
1981
 
2071
 
bool Session::TableMessages::getTableMessage(const TableIdentifier &identifier, message::Table &table_message)
 
1982
bool Session::getTableMessage(const TableIdentifier &identifier, message::Table &table_message)
2072
1983
{
2073
1984
  TableMessageCache::iterator iter;
2074
1985
 
2082
1993
  return true;
2083
1994
}
2084
1995
 
2085
 
bool Session::TableMessages::doesTableMessageExist(const TableIdentifier &identifier)
 
1996
bool Session::doesTableMessageExist(const TableIdentifier &identifier)
2086
1997
{
2087
1998
  TableMessageCache::iterator iter;
2088
1999
 
2096
2007
  return true;
2097
2008
}
2098
2009
 
2099
 
bool Session::TableMessages::renameTableMessage(const TableIdentifier &from, const TableIdentifier &to)
 
2010
bool Session::renameTableMessage(const TableIdentifier &from, const TableIdentifier &to)
2100
2011
{
2101
2012
  TableMessageCache::iterator iter;
2102
2013
 
2115
2026
  return true;
2116
2027
}
2117
2028
 
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 */
 
2029
TableShareInstance *Session::getTemporaryShare(TableIdentifier::Type type_arg)
 
2030
{
 
2031
  temporary_shares.push_back(new TableShareInstance(type_arg)); // This will not go into the tableshare cache, so no key is used.
 
2032
 
 
2033
  TableShareInstance *tmp_share= temporary_shares.back();
 
2034
 
 
2035
  assert(tmp_share);
 
2036
 
 
2037
  return tmp_share;
 
2038
}
2184
2039
 
2185
2040
} /* namespace drizzled */