~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/session.cc

  • Committer: Andrew Hutchings
  • Date: 2010-10-27 06:36:38 UTC
  • mto: (1883.1.2 build)
  • mto: This revision was merged to the branch mainline in revision 1884.
  • Revision ID: andrew@linuxjedi.co.uk-20101027063638-08d33sknkd691zz2
Fix min() usage for 32bit
Fix Solaris doesn't follow POSIX standard for send()

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
51
#include "drizzled/table/instance.h"
55
52
 
56
53
#include "plugin/myisam/myisam.h"
60
57
 
61
58
#include "drizzled/util/functors.h"
62
59
 
63
 
#include "drizzled/display.h"
64
 
 
65
60
#include <fcntl.h>
66
61
#include <algorithm>
67
62
#include <climits>
68
 
#include <boost/filesystem.hpp>
69
 
 
70
 
#include "drizzled/util/backtrace.h"
 
63
#include "boost/filesystem.hpp" 
71
64
 
72
65
using namespace std;
73
66
 
88
81
{
89
82
  return length == other.length &&
90
83
         field_name.length == other.field_name.length &&
91
 
    !my_strcasecmp(system_charset_info, field_name.str, other.field_name.str);
 
84
         !strcmp(field_name.str, other.field_name.str);
92
85
}
93
86
 
94
87
Open_tables_state::Open_tables_state(uint64_t version_arg) :
164
157
Session::Session(plugin::Client *client_arg) :
165
158
  Open_tables_state(refresh_version),
166
159
  mem_root(&main_mem_root),
167
 
  xa_id(0),
168
160
  lex(&main_lex),
169
 
  query(new std::string),
170
 
  _schema(new std::string("")),
171
161
  catalog("LOCAL"),
172
162
  client(client_arg),
173
163
  scheduler(NULL),
174
164
  scheduler_arg(NULL),
175
165
  lock_id(&main_lock_id),
176
 
  thread_stack(NULL),
177
 
  security_ctx(identifier::User::make_shared()),
178
166
  user_time(0),
179
167
  ha_data(plugin::num_trx_monitored_objects),
180
 
  concurrent_execute_allowed(true),
181
168
  arg_of_last_insert_id_function(false),
182
169
  first_successful_insert_id_in_prev_stmt(0),
183
170
  first_successful_insert_id_in_cur_stmt(0),
184
171
  limit_found_rows(0),
185
 
  _global_read_lock(NONE),
186
 
  _killed(NOT_KILLED),
 
172
  global_read_lock(0),
187
173
  some_tables_deleted(false),
188
174
  no_errors(false),
189
175
  password(false),
199
185
  session_event_observers(NULL),
200
186
  use_usage(false)
201
187
{
 
188
  memset(process_list_info, 0, PROCESS_LIST_WIDTH);
202
189
  client->setSession(this);
203
190
 
204
191
  /*
207
194
    will be re-initialized in init_for_queries().
208
195
  */
209
196
  memory::init_sql_alloc(&main_mem_root, memory::ROOT_MIN_BLOCK_SIZE, 0);
 
197
  thread_stack= NULL;
210
198
  count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;
 
199
  killed= NOT_KILLED;
211
200
  col_access= 0;
212
201
  tmp_table= 0;
213
202
  used_tables= 0;
342
331
{
343
332
  assert(cleanup_done == false);
344
333
 
345
 
  setKilled(KILL_CONNECTION);
 
334
  killed= KILL_CONNECTION;
346
335
#ifdef ENABLE_WHEN_BINLOG_WILL_BE_ABLE_TO_PREPARE
347
336
  if (transaction.xid_state.xa_state == XA_PREPARED)
348
337
  {
368
357
  close_temporary_tables();
369
358
 
370
359
  if (global_read_lock)
371
 
  {
372
 
    unlockGlobalReadLock();
373
 
  }
 
360
    unlock_global_read_lock(this);
374
361
 
375
362
  cleanup_done= true;
376
363
}
381
368
 
382
369
  if (client->isConnected())
383
370
  {
384
 
    assert(security_ctx);
385
371
    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
 
 
 
372
        errmsg_printf(ERRMSG_LVL_WARN, ER(ER_FORCING_CLOSE),internal::my_progname,
 
373
                      thread_id,
 
374
                      (getSecurityContext().getUser().c_str() ?
 
375
                       getSecurityContext().getUser().c_str() : ""));
393
376
    disconnect(0, false);
394
377
  }
395
378
 
419
402
    delete (*iter).second;
420
403
  }
421
404
  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
 
 
 
405
 
 
406
  /* Ensure that no one is using Session */
 
407
  LOCK_delete.unlock();
 
408
}
 
409
 
 
410
void Session::awake(Session::killed_state state_to_set)
 
411
{
435
412
  this->checkSentry();
436
 
 
437
 
  setKilled(state_to_set);
438
 
  scheduler->killSession(this);
439
 
 
 
413
  safe_mutex_assert_owner(&LOCK_delete);
 
414
 
 
415
  killed= state_to_set;
440
416
  if (state_to_set != Session::KILL_QUERY)
441
417
  {
 
418
    scheduler->killSession(this);
442
419
    DRIZZLE_CONNECTION_DONE(thread_id);
443
420
  }
444
 
 
445
421
  if (mysys_var)
446
422
  {
447
423
    boost_unique_lock_t scopedLock(mysys_var->mutex);
554
530
 
555
531
  prepareForQueries();
556
532
 
557
 
  while (not client->haveError() && getKilled() != KILL_CONNECTION)
 
533
  while (! client->haveError() && killed != KILL_CONNECTION)
558
534
  {
559
 
    if (not executeStatement())
 
535
    if (! executeStatement())
560
536
      break;
561
537
  }
562
538
 
563
539
  disconnect(0, true);
564
540
}
565
541
 
566
 
bool Session::schedule(Session::shared_ptr &arg)
 
542
bool Session::schedule()
567
543
{
568
 
  arg->scheduler= plugin::Scheduler::getScheduler();
569
 
  assert(arg->scheduler);
 
544
  scheduler= plugin::Scheduler::getScheduler();
 
545
  assert(scheduler);
570
546
 
571
547
  connection_count.increment();
572
548
 
576
552
  }
577
553
 
578
554
  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());
 
555
  thread_id= variables.pseudo_thread_id= global_thread_id++;
 
556
 
 
557
  {
 
558
    boost::mutex::scoped_lock scoped(LOCK_thread_count);
 
559
    getSessionList().push_back(this);
 
560
  }
 
561
 
 
562
  if (unlikely(plugin::EventObserver::connectSession(*this)))
 
563
  {
 
564
    // We should do something about an error...
 
565
  }
 
566
 
 
567
  if (unlikely(plugin::EventObserver::connectSession(*this)))
 
568
  {
 
569
    // We should do something about an error...
 
570
  }
 
571
 
 
572
  if (scheduler->addSession(this))
 
573
  {
 
574
    DRIZZLE_CONNECTION_START(thread_id);
591
575
    char error_message_buff[DRIZZLE_ERRMSG_SIZE];
592
576
 
593
 
    arg->setKilled(Session::KILL_CONNECTION);
 
577
    killed= Session::KILL_CONNECTION;
594
578
 
595
 
    arg->status_var.aborted_connects++;
 
579
    status_var.aborted_connects++;
596
580
 
597
581
    /* Can't use my_error() since store_globals has not been called. */
598
582
    /* TODO replace will better error message */
599
583
    snprintf(error_message_buff, sizeof(error_message_buff),
600
584
             ER(ER_CANT_CREATE_THREAD), 1);
601
 
    arg->client->sendError(ER_CANT_CREATE_THREAD, error_message_buff);
602
 
 
 
585
    client->sendError(ER_CANT_CREATE_THREAD, error_message_buff);
603
586
    return true;
604
587
  }
605
588
 
607
590
}
608
591
 
609
592
 
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
593
const char* Session::enter_cond(boost::condition_variable_any &cond, boost::mutex &mutex, const char* msg)
622
594
{
623
595
  const char* old_msg = get_proc_info();
645
617
 
646
618
bool Session::authenticate()
647
619
{
648
 
  lex->start(this);
 
620
  lex_start(this);
649
621
  if (client->authenticate())
650
622
    return false;
651
623
 
658
630
                        const std::string &in_db)
659
631
{
660
632
  bool is_authenticated=
661
 
    plugin::Authentication::isAuthenticated(user(), passwd_str);
 
633
    plugin::Authentication::isAuthenticated(getSecurityContext(),
 
634
                                            passwd_str);
662
635
 
663
636
  if (is_authenticated != true)
664
637
  {
700
673
  main_da.reset_diagnostics_area();
701
674
 
702
675
  if (client->readCommand(&l_packet, &packet_length) == false)
703
 
  {
704
676
    return false;
705
 
  }
706
677
 
707
 
  if (getKilled() == KILL_CONNECTION)
 
678
  if (killed == KILL_CONNECTION)
708
679
    return false;
709
680
 
710
681
  if (packet_length == 0)
711
682
    return true;
712
683
 
713
 
  l_command= static_cast<enum_server_command>(l_packet[0]);
 
684
  l_command= (enum enum_server_command) (unsigned char) l_packet[0];
714
685
 
715
686
  if (command >= COM_END)
716
687
    command= COM_END;                           // Wrong command
717
688
 
718
689
  assert(packet_length);
719
 
  return not dispatch_command(l_command, this, l_packet+1, (uint32_t) (packet_length-1));
 
690
  return ! dispatch_command(l_command, this, l_packet+1, (uint32_t) (packet_length-1));
720
691
}
721
692
 
722
693
bool Session::readAndStoreQuery(const char *in_packet, uint32_t in_packet_length)
728
699
    in_packet_length--;
729
700
  }
730
701
  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])))
 
702
  while (in_packet_length > 0 &&
 
703
         (pos[-1] == ';' || my_isspace(charset() ,pos[-1])))
732
704
  {
733
705
    pos--;
734
706
    in_packet_length--;
735
707
  }
736
708
 
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));
 
709
  query.assign(in_packet, in_packet + in_packet_length);
745
710
 
746
711
  return true;
747
712
}
796
761
  }
797
762
 
798
763
  if (result == false)
799
 
  {
800
764
    my_error(killed_errno(), MYF(0));
801
 
  }
802
765
  else if ((result == true) && do_release)
803
 
  {
804
 
    setKilled(Session::KILL_CONNECTION);
805
 
  }
 
766
    killed= Session::KILL_CONNECTION;
806
767
 
807
768
  return result;
808
769
}
961
922
  my_message(errcode, err, MYF(0));
962
923
  if (file > 0)
963
924
  {
964
 
    (void) cache->end_io_cache();
 
925
    (void) end_io_cache(cache);
965
926
    (void) internal::my_close(file, MYF(0));
966
927
    (void) internal::my_delete(path.file_string().c_str(), MYF(0));             // Delete file on error
967
928
    file= -1;
971
932
 
972
933
bool select_to_file::send_eof()
973
934
{
974
 
  int error= test(cache->end_io_cache());
 
935
  int error= test(end_io_cache(cache));
975
936
  if (internal::my_close(file, MYF(MY_WME)))
976
937
    error= 1;
977
938
  if (!error)
993
954
  /* In case of error send_eof() may be not called: close the file here. */
994
955
  if (file >= 0)
995
956
  {
996
 
    (void) cache->end_io_cache();
 
957
    (void) end_io_cache(cache);
997
958
    (void) internal::my_close(file, MYF(0));
998
959
    file= -1;
999
960
  }
1052
1013
  if (not to_file.has_root_directory())
1053
1014
  {
1054
1015
    target_path= fs::system_complete(getDataHomeCatalog());
1055
 
    util::string::const_shared_ptr schema(session->schema());
1056
 
    if (schema and not schema->empty())
 
1016
    if (not session->db.empty())
1057
1017
    {
1058
1018
      int count_elements= 0;
1059
1019
      for (fs::path::iterator iter= to_file.begin();
1063
1023
 
1064
1024
      if (count_elements == 1)
1065
1025
      {
1066
 
        target_path /= *schema;
 
1026
        target_path /= session->db;
1067
1027
      }
1068
1028
    }
1069
1029
    target_path /= to_file;
1092
1052
  if ((file= internal::my_create(target_path.file_string().c_str(), 0666, O_WRONLY|O_EXCL, MYF(MY_WME))) < 0)
1093
1053
    return file;
1094
1054
  (void) fchmod(file, 0666);                    // Because of umask()
1095
 
  if (cache->init_io_cache(file, 0L, internal::WRITE_CACHE, 0L, 1, MYF(MY_WME)))
 
1055
  if (init_io_cache(cache, file, 0L, internal::WRITE_CACHE, 0L, 1, MYF(MY_WME)))
1096
1056
  {
1097
1057
    internal::my_close(file, MYF(0));
1098
1058
    internal::my_delete(target_path.file_string().c_str(), MYF(0));  // Delete file on error, it was just created
1121
1081
    {
1122
1082
      if (item->max_length >= MAX_BLOB_WIDTH)
1123
1083
      {
1124
 
        blob_flag=1;
1125
 
        break;
 
1084
        blob_flag=1;
 
1085
        break;
1126
1086
      }
1127
 
 
1128
1087
      if (item->result_type() == STRING_RESULT)
1129
1088
        string_results= true;
1130
1089
      else
1560
1519
void Session::end_statement()
1561
1520
{
1562
1521
  /* Cleanup SQL processing state to reuse this statement in next query. */
1563
 
  lex->end();
 
1522
  lex_end(lex);
1564
1523
  query_cache_key= ""; // reset the cache key
1565
1524
  resetResultsetMessage();
1566
1525
}
1567
1526
 
1568
1527
bool Session::copy_db_to(char **p_db, size_t *p_db_length)
1569
1528
{
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
 
 
 
1529
  if (db.empty())
 
1530
  {
 
1531
    my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
 
1532
    return true;
 
1533
  }
 
1534
  *p_db= strmake(db.c_str(), db.length());
 
1535
  *p_db_length= db.length();
1586
1536
  return false;
1587
1537
}
1588
1538
 
1622
1572
}
1623
1573
 
1624
1574
 
1625
 
void Session::set_db(const std::string &new_db)
 
1575
bool Session::set_db(const std::string &new_db)
1626
1576
{
1627
1577
  /* Do not reallocate memory if current chunk is big enough. */
1628
1578
  if (new_db.length())
1629
 
  {
1630
 
    _schema.reset(new std::string(new_db));
1631
 
  }
 
1579
    db= new_db;
1632
1580
  else
1633
 
  {
1634
 
    _schema.reset(new std::string(""));
1635
 
  }
1636
 
}
1637
 
 
 
1581
    db.clear();
 
1582
 
 
1583
  return false;
 
1584
}
 
1585
 
 
1586
 
 
1587
 
 
1588
 
 
1589
/**
 
1590
  Check the killed state of a user thread
 
1591
  @param session  user thread
 
1592
  @retval 0 the user thread is active
 
1593
  @retval 1 the user thread has been killed
 
1594
*/
 
1595
int session_killed(const Session *session)
 
1596
{
 
1597
  return(session->killed);
 
1598
}
 
1599
 
 
1600
 
 
1601
const struct charset_info_st *session_charset(Session *session)
 
1602
{
 
1603
  return(session->charset());
 
1604
}
1638
1605
 
1639
1606
/**
1640
1607
  Mark transaction to rollback and mark error as fatal to a sub-statement.
1657
1624
  plugin_sessionvar_cleanup(this);
1658
1625
 
1659
1626
  /* If necessary, log any aborted or unauthorized connections */
1660
 
  if (getKilled() || client->wasAborted())
 
1627
  if (killed || client->wasAborted())
1661
1628
  {
1662
1629
    status_var.aborted_threads++;
1663
1630
  }
1664
1631
 
1665
1632
  if (client->wasAborted())
1666
1633
  {
1667
 
    if (not getKilled() && variables.log_warnings > 1)
 
1634
    if (! killed && variables.log_warnings > 1)
1668
1635
    {
 
1636
      SecurityContext *sctx= &security_ctx;
 
1637
 
1669
1638
      errmsg_printf(ERRMSG_LVL_WARN, ER(ER_NEW_ABORTING_CONNECTION)
1670
1639
                  , 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()
 
1640
                  , (db.empty() ? "unconnected" : db.c_str())
 
1641
                  , sctx->getUser().empty() == false ? sctx->getUser().c_str() : "unauthenticated"
 
1642
                  , sctx->getIp().c_str()
1674
1643
                  , (main_da.is_error() ? main_da.message() : ER(ER_UNKNOWN_ERROR)));
1675
1644
    }
1676
1645
  }
1677
1646
 
1678
1647
  /* Close out our connection to the client */
1679
1648
  if (should_lock)
1680
 
    session::Cache::singleton().mutex().lock();
1681
 
 
1682
 
  setKilled(Session::KILL_CONNECTION);
1683
 
 
 
1649
    LOCK_thread_count.lock();
 
1650
  killed= Session::KILL_CONNECTION;
1684
1651
  if (client->isConnected())
1685
1652
  {
1686
1653
    if (errcode)
1690
1657
    }
1691
1658
    client->close();
1692
1659
  }
1693
 
 
1694
1660
  if (should_lock)
1695
 
  {
1696
 
    session::Cache::singleton().mutex().unlock();
1697
 
  }
 
1661
    (void) LOCK_thread_count.unlock();
1698
1662
}
1699
1663
 
1700
1664
void Session::reset_for_next_command()
1722
1686
  Close all temporary tables created by 'CREATE TEMPORARY TABLE' for thread
1723
1687
*/
1724
1688
 
1725
 
void Open_tables_state::close_temporary_tables()
 
1689
void Session::close_temporary_tables()
1726
1690
{
1727
1691
  Table *table;
1728
1692
  Table *tmp_next;
1742
1706
  unlink from session->temporary tables and close temporary table
1743
1707
*/
1744
1708
 
1745
 
void Open_tables_state::close_temporary_table(Table *table)
 
1709
void Session::close_temporary_table(Table *table)
1746
1710
{
1747
1711
  if (table->getPrev())
1748
1712
  {
1778
1742
  If this is needed, use close_temporary_table()
1779
1743
*/
1780
1744
 
1781
 
void Open_tables_state::nukeTable(Table *table)
 
1745
void Session::nukeTable(Table *table)
1782
1746
{
1783
1747
  plugin::StorageEngine *table_type= table->getShare()->db_type();
1784
1748
 
1852
1816
                              DERIVATION_IMPLICIT, false);
1853
1817
}
1854
1818
 
1855
 
void Open_tables_state::mark_temp_tables_as_free_for_reuse()
 
1819
void Session::mark_temp_tables_as_free_for_reuse()
1856
1820
{
1857
1821
  for (Table *table= temporary_tables ; table ; table= table->getNext())
1858
1822
  {
1859
 
    if (table->query_id == getQueryId())
 
1823
    if (table->query_id == query_id)
1860
1824
    {
1861
1825
      table->query_id= 0;
1862
1826
      table->cursor->ha_reset();
1868
1832
{
1869
1833
  for (; table ; table= table->getNext())
1870
1834
  {
1871
 
    if (table->query_id == getQueryId())
 
1835
    if (table->query_id == query_id)
1872
1836
    {
1873
1837
      table->query_id= 0;
1874
1838
      table->cursor->ha_reset();
1887
1851
*/
1888
1852
void Session::close_thread_tables()
1889
1853
{
1890
 
  clearDerivedTables();
 
1854
  if (derived_tables)
 
1855
    derived_tables= NULL; // They should all be invalid by this point
1891
1856
 
1892
1857
  /*
1893
1858
    Mark all temporary tables used by this statement as free for reuse.
1920
1885
      handled either before writing a query log event (inside
1921
1886
      binlog_query()) or when preparing a pending event.
1922
1887
     */
1923
 
    unlockTables(lock);
 
1888
    mysql_unlock_tables(this, lock);
1924
1889
    lock= 0;
1925
1890
  }
1926
1891
  /*
1927
 
    Note that we need to hold table::Cache::singleton().mutex() while changing the
 
1892
    Note that we need to hold LOCK_open while changing the
1928
1893
    open_tables list. Another thread may work on it.
1929
 
    (See: table::Cache::singleton().removeTable(), mysql_wait_completed_table())
 
1894
    (See: remove_table_from_cache(), mysql_wait_completed_table())
1930
1895
    Closing a MERGE child before the parent would be fatal if the
1931
1896
    other thread tries to abort the MERGE lock in between.
1932
1897
  */
1978
1943
  might be an issue (lame engines).
1979
1944
*/
1980
1945
 
1981
 
bool Open_tables_state::rm_temporary_table(const TableIdentifier &identifier, bool best_effort)
 
1946
bool Session::rm_temporary_table(TableIdentifier &identifier, bool best_effort)
1982
1947
{
1983
 
  if (plugin::StorageEngine::dropTable(*static_cast<Session *>(this), identifier))
 
1948
  if (plugin::StorageEngine::dropTable(*this, identifier))
1984
1949
  {
1985
1950
    if (not best_effort)
1986
1951
    {
1987
 
      std::string path;
1988
 
      identifier.getSQLPath(path);
1989
1952
      errmsg_printf(ERRMSG_LVL_WARN, _("Could not remove temporary table: '%s', error: %d"),
1990
 
                    path.c_str(), errno);
 
1953
                    identifier.getSQLPath().c_str(), errno);
1991
1954
    }
1992
1955
 
1993
1956
    return true;
1996
1959
  return false;
1997
1960
}
1998
1961
 
1999
 
bool Open_tables_state::rm_temporary_table(plugin::StorageEngine *base, const TableIdentifier &identifier)
 
1962
bool Session::rm_temporary_table(plugin::StorageEngine *base, TableIdentifier &identifier)
2000
1963
{
2001
1964
  assert(base);
2002
1965
 
2003
 
  if (plugin::StorageEngine::dropTable(*static_cast<Session *>(this), *base, identifier))
 
1966
  if (plugin::StorageEngine::dropTable(*this, *base, identifier))
2004
1967
  {
2005
 
    std::string path;
2006
 
    identifier.getSQLPath(path);
2007
1968
    errmsg_printf(ERRMSG_LVL_WARN, _("Could not remove temporary table: '%s', error: %d"),
2008
 
                  path.c_str(), errno);
 
1969
                  identifier.getSQLPath().c_str(), errno);
2009
1970
 
2010
1971
    return true;
2011
1972
  }
2017
1978
  @note this will be removed, I am looking through Hudson to see if it is finding
2018
1979
  any tables that are missed during cleanup.
2019
1980
*/
2020
 
void Open_tables_state::dumpTemporaryTableNames(const char *foo)
 
1981
void Session::dumpTemporaryTableNames(const char *foo)
2021
1982
{
2022
1983
  Table *table;
2023
1984
 
2041
2002
      cerr << "\t\t Proto " << proto->schema() << " " << proto->name() << "\n";
2042
2003
    }
2043
2004
    else
2044
 
    {
2045
2005
      cerr << "\tTabl;e Name " << table->getShare()->getSchemaName() << "." << table->getShare()->getTableName() << " : " << answer << "\n";
2046
 
    }
2047
2006
  }
2048
2007
}
2049
2008
 
2050
 
bool Session::TableMessages::storeTableMessage(const TableIdentifier &identifier, message::Table &table_message)
 
2009
bool Session::storeTableMessage(const TableIdentifier &identifier, message::Table &table_message)
2051
2010
{
2052
2011
  table_message_cache.insert(make_pair(identifier.getPath(), table_message));
2053
2012
 
2054
2013
  return true;
2055
2014
}
2056
2015
 
2057
 
bool Session::TableMessages::removeTableMessage(const TableIdentifier &identifier)
 
2016
bool Session::removeTableMessage(const TableIdentifier &identifier)
2058
2017
{
2059
2018
  TableMessageCache::iterator iter;
2060
2019
 
2068
2027
  return true;
2069
2028
}
2070
2029
 
2071
 
bool Session::TableMessages::getTableMessage(const TableIdentifier &identifier, message::Table &table_message)
 
2030
bool Session::getTableMessage(const TableIdentifier &identifier, message::Table &table_message)
2072
2031
{
2073
2032
  TableMessageCache::iterator iter;
2074
2033
 
2082
2041
  return true;
2083
2042
}
2084
2043
 
2085
 
bool Session::TableMessages::doesTableMessageExist(const TableIdentifier &identifier)
 
2044
bool Session::doesTableMessageExist(const TableIdentifier &identifier)
2086
2045
{
2087
2046
  TableMessageCache::iterator iter;
2088
2047
 
2096
2055
  return true;
2097
2056
}
2098
2057
 
2099
 
bool Session::TableMessages::renameTableMessage(const TableIdentifier &from, const TableIdentifier &to)
 
2058
bool Session::renameTableMessage(const TableIdentifier &from, const TableIdentifier &to)
2100
2059
{
2101
2060
  TableMessageCache::iterator iter;
2102
2061
 
2126
2085
  return tmp_share;
2127
2086
}
2128
2087
 
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 */
2184
 
 
2185
2088
} /* namespace drizzled */