~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/session.cc

  • Committer: Tim Penhey
  • Date: 2010-01-20 02:39:01 UTC
  • mto: This revision was merged to the branch mainline in revision 1275.
  • Revision ID: tim.penhey@canonical.com-20100120023901-8teeunid6gwlthzx
Add in a rot 13 function.

Show diffs side-by-side

added added

removed removed

Lines of Context:
25
25
#include <drizzled/session.h>
26
26
#include "drizzled/session_list.h"
27
27
#include <sys/stat.h>
 
28
#include "drizzled/my_error.h"
28
29
#include <drizzled/error.h>
29
30
#include <drizzled/gettext.h>
30
31
#include <drizzled/query_id.h>
39
40
#include <drizzled/plugin/client.h>
40
41
#include "drizzled/plugin/scheduler.h"
41
42
#include "drizzled/plugin/authentication.h"
42
 
#include "drizzled/plugin/logging.h"
43
 
#include "drizzled/plugin/transactional_storage_engine.h"
44
43
#include "drizzled/probes.h"
45
44
#include "drizzled/table_proto.h"
46
45
#include "drizzled/db.h"
47
46
#include "drizzled/pthread_globals.h"
48
 
#include "drizzled/transaction_services.h"
49
47
 
50
48
#include "plugin/myisam/myisam.h"
51
49
#include "drizzled/internal/iocache.h"
55
53
#include <climits>
56
54
 
57
55
using namespace std;
58
 
namespace drizzled
59
 
{
 
56
using namespace drizzled;
60
57
 
61
58
extern "C"
62
59
{
75
72
extern pthread_key_t THR_Session;
76
73
extern pthread_key_t THR_Mem_root;
77
74
extern uint32_t max_used_connections;
78
 
extern atomic<uint32_t> connection_count;
 
75
extern drizzled::atomic<uint32_t> connection_count;
79
76
 
80
77
 
81
78
/****************************************************************************
111
108
extern "C" int mysql_tmpfile(const char *prefix)
112
109
{
113
110
  char filename[FN_REFLEN];
114
 
  int fd = internal::create_temp_file(filename, drizzle_tmpdir, prefix, MYF(MY_WME));
 
111
  int fd = create_temp_file(filename, drizzle_tmpdir, prefix, MYF(MY_WME));
115
112
  if (fd >= 0) {
116
113
    unlink(filename);
117
114
  }
145
142
  return session->get_proc_info();
146
143
}
147
144
 
148
 
void **Session::getEngineData(const plugin::MonitoredInTransaction *monitored)
 
145
void **Session::getEngineData(const plugin::StorageEngine *engine)
149
146
{
150
 
  return static_cast<void **>(&ha_data[monitored->getId()].ha_ptr);
 
147
  return static_cast<void **>(&ha_data[engine->slot].ha_ptr);
151
148
}
152
149
 
153
 
ResourceContext *Session::getResourceContext(const plugin::MonitoredInTransaction *monitored,
154
 
                                             size_t index)
 
150
Ha_trx_info *Session::getEngineInfo(const plugin::StorageEngine *engine,
 
151
                                    size_t index)
155
152
{
156
 
  return &ha_data[monitored->getId()].resource_context[index];
 
153
  return &ha_data[engine->getSlot()].ha_info[index];
157
154
}
158
155
 
159
156
extern "C"
179
176
  Open_tables_state(refresh_version),
180
177
  mem_root(&main_mem_root),
181
178
  lex(&main_lex),
182
 
  query(),
183
179
  client(client_arg),
184
180
  scheduler(NULL),
185
181
  scheduler_arg(NULL),
186
182
  lock_id(&main_lock_id),
187
183
  user_time(0),
188
 
  ha_data(plugin::num_trx_monitored_objects),
189
184
  arg_of_last_insert_id_function(false),
190
185
  first_successful_insert_id_in_prev_stmt(0),
191
186
  first_successful_insert_id_in_cur_stmt(0),
231
226
  thread_id= 0;
232
227
  file_id = 0;
233
228
  query_id= 0;
234
 
  warn_query_id= 0;
 
229
  query= NULL;
 
230
  query_length= 0;
 
231
  warn_id= 0;
 
232
  memset(ha_data, 0, sizeof(ha_data));
 
233
  replication_data= 0;
235
234
  mysys_var= 0;
236
235
  dbug_sentry=Session_SENTRY_MAGIC;
237
236
  cleanup_done= abort_on_warning= no_warnings_for_error= false;
 
237
  transaction.on= 1;
238
238
  pthread_mutex_init(&LOCK_delete, MY_MUTEX_INIT_FAST);
239
239
 
240
240
  /* Variables with default values */
257
257
  else
258
258
    options &= ~OPTION_BIG_SELECTS;
259
259
 
 
260
  transaction.all.modified_non_trans_table= transaction.stmt.modified_non_trans_table= false;
260
261
  open_options=ha_open_options;
261
262
  update_lock_default= TL_WRITE;
262
263
  session_tx_isolation= (enum_tx_isolation) variables.tx_isolation;
368
369
  }
369
370
#endif
370
371
  {
371
 
    TransactionServices &transaction_services= TransactionServices::singleton();
372
 
    transaction_services.ha_rollback_trans(this, true);
 
372
    ha_rollback(this);
373
373
    xid_cache_delete(&transaction.xid_state);
374
374
  }
375
375
  hash_free(&user_vars);
383
383
 
384
384
Session::~Session()
385
385
{
386
 
  this->checkSentry();
 
386
  Session_CHECK_SENTRY(this);
387
387
  add_to_status(&global_status_var, &status_var);
388
388
 
389
389
  if (client->isConnected())
390
390
  {
391
391
    if (global_system_variables.log_warnings)
392
 
        errmsg_printf(ERRMSG_LVL_WARN, ER(ER_FORCING_CLOSE),internal::my_progname,
 
392
        errmsg_printf(ERRMSG_LVL_WARN, ER(ER_FORCING_CLOSE),my_progname,
393
393
                      thread_id,
394
 
                      (getSecurityContext().getUser().c_str() ?
395
 
                       getSecurityContext().getUser().c_str() : ""));
 
394
                      (security_ctx.user.c_str() ?
 
395
                       security_ctx.user.c_str() : ""));
396
396
    disconnect(0, false);
397
397
  }
398
398
 
407
407
  plugin_sessionvar_cleanup(this);
408
408
 
409
409
  free_root(&warn_root,MYF(0));
 
410
  free_root(&transaction.mem_root,MYF(0));
410
411
  mysys_var=0;                                  // Safety (shouldn't be needed)
411
412
  dbug_sentry= Session_SENTRY_GONE;
412
413
 
413
414
  free_root(&main_mem_root, MYF(0));
414
415
  pthread_setspecific(THR_Session,  0);
415
416
 
416
 
  plugin::Logging::postEndDo(this);
417
417
 
418
418
  /* Ensure that no one is using Session */
419
419
  pthread_mutex_unlock(&LOCK_delete);
433
433
    If this assumption will change, then we have to explictely add
434
434
    the other variables after the while loop
435
435
*/
436
 
void add_to_status(system_status_var *to_var, system_status_var *from_var)
 
436
void add_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var)
437
437
{
438
438
  ulong *end= (ulong*) ((unsigned char*) to_var +
439
 
                        offsetof(system_status_var, last_system_status_var) +
 
439
                        offsetof(STATUS_VAR, last_system_status_var) +
440
440
                        sizeof(ulong));
441
441
  ulong *to= (ulong*) to_var, *from= (ulong*) from_var;
442
442
 
456
456
  NOTE
457
457
    This function assumes that all variables are long/ulong.
458
458
*/
459
 
void add_diff_to_status(system_status_var *to_var, system_status_var *from_var,
460
 
                        system_status_var *dec_var)
 
459
void add_diff_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var,
 
460
                        STATUS_VAR *dec_var)
461
461
{
462
 
  ulong *end= (ulong*) ((unsigned char*) to_var + offsetof(system_status_var,
 
462
  ulong *end= (ulong*) ((unsigned char*) to_var + offsetof(STATUS_VAR,
463
463
                                                  last_system_status_var) +
464
464
                        sizeof(ulong));
465
465
  ulong *to= (ulong*) to_var, *from= (ulong*) from_var, *dec= (ulong*) dec_var;
470
470
 
471
471
void Session::awake(Session::killed_state state_to_set)
472
472
{
473
 
  this->checkSentry();
 
473
  Session_CHECK_SENTRY(this);
474
474
  safe_mutex_assert_owner(&LOCK_delete);
475
475
 
476
476
  killed= state_to_set;
559
559
  set_proc_info(NULL);
560
560
  command= COM_SLEEP;
561
561
  set_time();
 
562
  ha_enable_transaction(this,true);
562
563
 
563
564
  reset_root_defaults(mem_root, variables.query_alloc_block_size,
564
565
                      variables.query_prealloc_size);
 
566
  reset_root_defaults(&transaction.mem_root,
 
567
                      variables.trans_alloc_block_size,
 
568
                      variables.trans_prealloc_size);
565
569
  transaction.xid_state.xid.null();
566
570
  transaction.xid_state.in_session=1;
567
571
}
673
677
 
674
678
bool Session::checkUser(const char *passwd, uint32_t passwd_len, const char *in_db)
675
679
{
676
 
  const string passwd_str(passwd, passwd_len);
677
 
  bool is_authenticated=
678
 
    plugin::Authentication::isAuthenticated(getSecurityContext(),
679
 
                                            passwd_str);
 
680
  bool is_authenticated;
 
681
 
 
682
  if (passwd_len != 0 && passwd_len != SCRAMBLE_LENGTH)
 
683
  {
 
684
    my_error(ER_HANDSHAKE_ERROR, MYF(0), security_ctx.ip.c_str());
 
685
    return false;
 
686
  }
 
687
 
 
688
  is_authenticated= plugin::Authentication::isAuthenticated(this, passwd);
680
689
 
681
690
  if (is_authenticated != true)
682
691
  {
683
 
    /* isAuthenticated has pushed the error message */
 
692
    my_error(ER_ACCESS_DENIED_ERROR, MYF(0),
 
693
             security_ctx.user.c_str(),
 
694
             security_ctx.ip.c_str(),
 
695
             passwd_len ? ER(ER_YES) : ER(ER_NO));
 
696
 
684
697
    return false;
685
698
  }
686
699
 
 
700
  security_ctx.skip_grants();
 
701
 
687
702
  /* Change database if necessary */
688
703
  if (in_db && in_db[0])
689
704
  {
690
 
    SchemaIdentifier identifier(in_db);
691
 
    if (mysql_change_db(this, identifier))
 
705
    const string database_name_string(in_db);
 
706
    NonNormalisedDatabaseName database_name(database_name_string);
 
707
    NormalisedDatabaseName normalised_database_name(database_name);
 
708
 
 
709
    if (mysql_change_db(this, normalised_database_name, false))
692
710
    {
693
711
      /* mysql_change_db() has pushed the error message. */
694
712
      return false;
747
765
    in_packet_length--;
748
766
  }
749
767
 
750
 
  query.assign(in_packet, in_packet + in_packet_length);
 
768
  /* We must allocate some extra memory for the cached query string */
 
769
  query_length= 0; /* Extra safety: Avoid races */
 
770
  query= (char*) memdup_w_gap((unsigned char*) in_packet, in_packet_length, db.length() + 1);
 
771
  if (! query)
 
772
    return false;
 
773
 
 
774
  query[in_packet_length]=0;
 
775
  query_length= in_packet_length;
751
776
 
752
777
  return true;
753
778
}
756
781
{
757
782
  bool do_release= 0;
758
783
  bool result= true;
759
 
  TransactionServices &transaction_services= TransactionServices::singleton();
760
784
 
761
785
  if (transaction.xid_state.xa_state != XA_NOTR)
762
786
  {
772
796
       * (Which of course should never happen...)
773
797
       */
774
798
      server_status&= ~SERVER_STATUS_IN_TRANS;
775
 
      if (transaction_services.ha_commit_trans(this, true))
 
799
      if (ha_commit(this))
776
800
        result= false;
777
801
      options&= ~(OPTION_BEGIN);
 
802
      transaction.all.modified_non_trans_table= false;
778
803
      break;
779
804
    case COMMIT_RELEASE:
780
805
      do_release= 1; /* fall through */
789
814
    case ROLLBACK_AND_CHAIN:
790
815
    {
791
816
      server_status&= ~SERVER_STATUS_IN_TRANS;
792
 
      if (transaction_services.ha_rollback_trans(this, true))
 
817
      if (ha_rollback(this))
793
818
        result= false;
794
819
      options&= ~(OPTION_BEGIN);
 
820
      transaction.all.modified_non_trans_table= false;
795
821
      if (result == true && (completion == ROLLBACK_AND_CHAIN))
796
822
        result= startTransaction();
797
823
      break;
812
838
bool Session::endActiveTransaction()
813
839
{
814
840
  bool result= true;
815
 
  TransactionServices &transaction_services= TransactionServices::singleton();
816
841
 
817
842
  if (transaction.xid_state.xa_state != XA_NOTR)
818
843
  {
822
847
  if (options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
823
848
  {
824
849
    server_status&= ~SERVER_STATUS_IN_TRANS;
825
 
    if (transaction_services.ha_commit_trans(this, true))
 
850
    if (ha_commit(this))
826
851
      result= false;
827
852
  }
828
853
  options&= ~(OPTION_BEGIN);
 
854
  transaction.all.modified_non_trans_table= false;
829
855
  return result;
830
856
}
831
857
 
842
868
    options|= OPTION_BEGIN;
843
869
    server_status|= SERVER_STATUS_IN_TRANS;
844
870
 
845
 
    if (plugin::TransactionalStorageEngine::notifyStartTransaction(this, opt))
 
871
    if (opt == START_TRANS_OPT_WITH_CONS_SNAPSHOT)
846
872
    {
847
 
      result= false;
 
873
      // TODO make this a loop for all engines, not just this one (Inno only
 
874
      // right now)
 
875
      if (plugin::StorageEngine::startConsistentSnapshot(this))
 
876
      {
 
877
        result= false;
 
878
      }
848
879
    }
849
880
  }
850
881
 
886
917
  @return  NULL on failure, or pointer to the LEX_STRING object
887
918
*/
888
919
LEX_STRING *Session::make_lex_string(LEX_STRING *lex_str,
889
 
                                     const std::string &str,
890
 
                                     bool allocate_lex_string)
891
 
{
892
 
  return make_lex_string(lex_str, str.c_str(), str.length(), allocate_lex_string);
893
 
}
894
 
 
895
 
LEX_STRING *Session::make_lex_string(LEX_STRING *lex_str,
896
 
                                     const char* str, uint32_t length,
897
 
                                     bool allocate_lex_string)
 
920
                                 const char* str, uint32_t length,
 
921
                                 bool allocate_lex_string)
898
922
{
899
923
  if (allocate_lex_string)
900
924
    if (!(lex_str= (LEX_STRING *)alloc(sizeof(LEX_STRING))))
905
929
  return lex_str;
906
930
}
907
931
 
 
932
/* routings to adding tables to list of changed in transaction tables */
 
933
inline static void list_include(CHANGED_TableList** prev,
 
934
                                CHANGED_TableList* curr,
 
935
                                CHANGED_TableList* new_table)
 
936
{
 
937
  if (new_table)
 
938
  {
 
939
    *prev = new_table;
 
940
    (*prev)->next = curr;
 
941
  }
 
942
}
 
943
 
 
944
/* add table to list of changed in transaction tables */
 
945
 
 
946
void Session::add_changed_table(Table *table)
 
947
{
 
948
  assert((options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) &&
 
949
              table->cursor->has_transactions());
 
950
  add_changed_table(table->s->table_cache_key.str,
 
951
                    (long) table->s->table_cache_key.length);
 
952
}
 
953
 
 
954
 
 
955
void Session::add_changed_table(const char *key, long key_length)
 
956
{
 
957
  CHANGED_TableList **prev_changed = &transaction.changed_tables;
 
958
  CHANGED_TableList *curr = transaction.changed_tables;
 
959
 
 
960
  for (; curr; prev_changed = &(curr->next), curr = curr->next)
 
961
  {
 
962
    int cmp =  (long)curr->key_length - (long)key_length;
 
963
    if (cmp < 0)
 
964
    {
 
965
      list_include(prev_changed, curr, changed_table_dup(key, key_length));
 
966
      return;
 
967
    }
 
968
    else if (cmp == 0)
 
969
    {
 
970
      cmp = memcmp(curr->key, key, curr->key_length);
 
971
      if (cmp < 0)
 
972
      {
 
973
        list_include(prev_changed, curr, changed_table_dup(key, key_length));
 
974
        return;
 
975
      }
 
976
      else if (cmp == 0)
 
977
      {
 
978
        return;
 
979
      }
 
980
    }
 
981
  }
 
982
  *prev_changed = changed_table_dup(key, key_length);
 
983
}
 
984
 
 
985
 
 
986
CHANGED_TableList* Session::changed_table_dup(const char *key, long key_length)
 
987
{
 
988
  CHANGED_TableList* new_table =
 
989
    (CHANGED_TableList*) trans_alloc(ALIGN_SIZE(sizeof(CHANGED_TableList))+
 
990
                                      key_length + 1);
 
991
  if (!new_table)
 
992
  {
 
993
    my_error(EE_OUTOFMEMORY, MYF(ME_BELL),
 
994
             ALIGN_SIZE(sizeof(TableList)) + key_length + 1);
 
995
    killed= KILL_CONNECTION;
 
996
    return 0;
 
997
  }
 
998
 
 
999
  new_table->key= ((char*)new_table)+ ALIGN_SIZE(sizeof(CHANGED_TableList));
 
1000
  new_table->next = 0;
 
1001
  new_table->key_length = key_length;
 
1002
  ::memcpy(new_table->key, key, key_length);
 
1003
  return new_table;
 
1004
}
 
1005
 
 
1006
 
908
1007
int Session::send_explain_fields(select_result *result)
909
1008
{
910
1009
  List<Item> field_list;
958
1057
  if (file > 0)
959
1058
  {
960
1059
    (void) end_io_cache(cache);
961
 
    (void) internal::my_close(file, MYF(0));
962
 
    (void) internal::my_delete(path, MYF(0));           // Delete file on error
 
1060
    (void) my_close(file, MYF(0));
 
1061
    (void) my_delete(path, MYF(0));             // Delete file on error
963
1062
    file= -1;
964
1063
  }
965
1064
}
968
1067
bool select_to_file::send_eof()
969
1068
{
970
1069
  int error= test(end_io_cache(cache));
971
 
  if (internal::my_close(file, MYF(MY_WME)))
 
1070
  if (my_close(file, MYF(MY_WME)))
972
1071
    error= 1;
973
1072
  if (!error)
974
1073
  {
990
1089
  if (file >= 0)
991
1090
  {
992
1091
    (void) end_io_cache(cache);
993
 
    (void) internal::my_close(file, MYF(0));
 
1092
    (void) my_close(file, MYF(0));
994
1093
    file= -1;
995
1094
  }
996
1095
  path[0]= '\0';
1000
1099
select_to_file::select_to_file(file_exchange *ex)
1001
1100
  : exchange(ex),
1002
1101
    file(-1),
1003
 
    cache(static_cast<internal::IO_CACHE *>(memory::sql_calloc(sizeof(internal::IO_CACHE)))),
 
1102
    cache(static_cast<IO_CACHE *>(memory::sql_calloc(sizeof(IO_CACHE)))),
1004
1103
    row_count(0L)
1005
1104
{
1006
1105
  path[0]=0;
1037
1136
*/
1038
1137
 
1039
1138
 
1040
 
static int create_file(Session *session, char *path, file_exchange *exchange, internal::IO_CACHE *cache)
 
1139
static int create_file(Session *session, char *path, file_exchange *exchange, IO_CACHE *cache)
1041
1140
{
1042
1141
  int file;
1043
1142
  uint32_t option= MY_UNPACK_FILENAME | MY_RELATIVE_PATH;
1046
1145
  option|= MY_REPLACE_DIR;                      // Force use of db directory
1047
1146
#endif
1048
1147
 
1049
 
  if (!internal::dirname_length(exchange->file_name))
 
1148
  if (!dirname_length(exchange->file_name))
1050
1149
  {
1051
1150
    strcpy(path, drizzle_real_data_home);
1052
1151
    if (! session->db.empty())
1053
1152
      strncat(path, session->db.c_str(), FN_REFLEN-strlen(drizzle_real_data_home)-1);
1054
 
    (void) internal::fn_format(path, exchange->file_name, path, "", option);
 
1153
    (void) fn_format(path, exchange->file_name, path, "", option);
1055
1154
  }
1056
1155
  else
1057
 
    (void) internal::fn_format(path, exchange->file_name, drizzle_real_data_home, "", option);
 
1156
    (void) fn_format(path, exchange->file_name, drizzle_real_data_home, "", option);
1058
1157
 
1059
1158
  if (opt_secure_file_priv &&
1060
1159
      strncmp(opt_secure_file_priv, path, strlen(opt_secure_file_priv)))
1070
1169
    return -1;
1071
1170
  }
1072
1171
  /* Create the file world readable */
1073
 
  if ((file= internal::my_create(path, 0666, O_WRONLY|O_EXCL, MYF(MY_WME))) < 0)
 
1172
  if ((file= my_create(path, 0666, O_WRONLY|O_EXCL, MYF(MY_WME))) < 0)
1074
1173
    return file;
1075
1174
  (void) fchmod(file, 0666);                    // Because of umask()
1076
 
  if (init_io_cache(cache, file, 0L, internal::WRITE_CACHE, 0L, 1, MYF(MY_WME)))
 
1175
  if (init_io_cache(cache, file, 0L, WRITE_CACHE, 0L, 1, MYF(MY_WME)))
1077
1176
  {
1078
 
    internal::my_close(file, MYF(0));
1079
 
    internal::my_delete(path, MYF(0));  // Delete file on error, it was just created
 
1177
    my_close(file, MYF(0));
 
1178
    my_delete(path, MYF(0));  // Delete file on error, it was just created
1080
1179
    return -1;
1081
1180
  }
1082
1181
  return file;
1143
1242
  return 0;
1144
1243
}
1145
1244
 
 
1245
 
 
1246
#define NEED_ESCAPING(x) ((int) (unsigned char) (x) == escape_char    || \
 
1247
                          (enclosed ? (int) (unsigned char) (x) == field_sep_char      \
 
1248
                                    : (int) (unsigned char) (x) == field_term_char) || \
 
1249
                          (int) (unsigned char) (x) == line_sep_char  || \
 
1250
                          !(x))
 
1251
 
1146
1252
bool select_export::send_data(List<Item> &items)
1147
1253
{
1148
1254
  char buff[MAX_FIELD_WIDTH],null_buff[2],space[MAX_FIELD_WIDTH];
1259
1365
            assert before the loop makes that sure.
1260
1366
          */
1261
1367
 
1262
 
          if ((needs_escaping(*pos, enclosed) ||
 
1368
          if ((NEED_ESCAPING(*pos) ||
1263
1369
               (check_second_byte &&
1264
1370
                my_mbcharlen(character_set_client, (unsigned char) *pos) == 2 &&
1265
1371
                pos + 1 < end &&
1266
 
                needs_escaping(pos[1], enclosed))) &&
 
1372
                NEED_ESCAPING(pos[1]))) &&
1267
1373
              /*
1268
1374
                Don't escape field_term_char by doubling - doubling is only
1269
1375
                valid for ENCLOSED BY characters:
1564
1670
  quick_group= 1;
1565
1671
  table_charset= 0;
1566
1672
  precomputed_group_by= 0;
 
1673
  bit_fields_as_long= 0;
1567
1674
}
1568
1675
 
1569
1676
void Tmp_Table_Param::cleanup(void)
1588
1695
  memset(&status_var, 0, sizeof(status_var));
1589
1696
}
1590
1697
 
 
1698
void Security_context::skip_grants()
 
1699
{
 
1700
  /* privileges for the user are unknown everything is allowed */
 
1701
}
 
1702
 
1591
1703
 
1592
1704
/****************************************************************************
1593
1705
  Handling of open and locked tables states.
1617
1729
  set_open_tables_state(backup);
1618
1730
}
1619
1731
 
1620
 
bool Session::set_db(const std::string &new_db)
 
1732
 
 
1733
bool Session::set_db(const NormalisedDatabaseName &new_db)
1621
1734
{
1622
 
  /* Do not reallocate memory if current chunk is big enough. */
1623
 
  if (new_db.length())
1624
 
    db= new_db;
1625
 
  else
1626
 
    db.clear();
 
1735
  db= new_db.to_string();
1627
1736
 
1628
1737
  return false;
1629
1738
}
1630
1739
 
1631
 
 
 
1740
void Session::clear_db()
 
1741
{
 
1742
  db.clear();
 
1743
}
1632
1744
 
1633
1745
 
1634
1746
/**
1658
1770
  return(session->charset());
1659
1771
}
1660
1772
 
 
1773
char **session_query(Session *session)
 
1774
{
 
1775
  return(&session->query);
 
1776
}
 
1777
 
1661
1778
int session_non_transactional_update(const Session *session)
1662
1779
{
1663
 
  return(session->transaction.all.hasModifiedNonTransData());
 
1780
  return(session->transaction.all.modified_non_trans_table);
1664
1781
}
1665
1782
 
1666
1783
void session_mark_transaction_to_rollback(Session *session, bool all)
1696
1813
  {
1697
1814
    if (! killed && variables.log_warnings > 1)
1698
1815
    {
1699
 
      SecurityContext *sctx= &security_ctx;
 
1816
      Security_context *sctx= &security_ctx;
1700
1817
 
1701
1818
      errmsg_printf(ERRMSG_LVL_WARN, ER(ER_NEW_ABORTING_CONNECTION)
1702
1819
                  , thread_id
1703
1820
                  , (db.empty() ? "unconnected" : db.c_str())
1704
 
                  , sctx->getUser().empty() == false ? sctx->getUser().c_str() : "unauthenticated"
1705
 
                  , sctx->getIp().c_str()
 
1821
                  , sctx->user.empty() == false ? sctx->user.c_str() : "unauthenticated"
 
1822
                  , sctx->ip.c_str()
1706
1823
                  , (main_da.is_error() ? main_da.message() : ER(ER_UNKNOWN_ERROR)));
1707
1824
    }
1708
1825
  }
1738
1855
  server_status&= ~ (SERVER_MORE_RESULTS_EXISTS |
1739
1856
                          SERVER_QUERY_NO_INDEX_USED |
1740
1857
                          SERVER_QUERY_NO_GOOD_INDEX_USED);
 
1858
  /*
 
1859
    If in autocommit mode and not in a transaction, reset
 
1860
    OPTION_STATUS_NO_TRANS_UPDATE to not get warnings
 
1861
    in ha_rollback_trans() about some tables couldn't be rolled back.
 
1862
  */
 
1863
  if (!(options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))
 
1864
  {
 
1865
    transaction.all.modified_non_trans_table= false;
 
1866
  }
1741
1867
 
1742
1868
  clear_error();
1743
1869
  main_da.reset_diagnostics_area();
1754
1880
  Table *table;
1755
1881
  Table *tmp_next;
1756
1882
 
1757
 
  if (not temporary_tables)
 
1883
  if (!temporary_tables)
1758
1884
    return;
1759
1885
 
1760
1886
  for (table= temporary_tables; table; table= tmp_next)
1761
1887
  {
1762
1888
    tmp_next= table->next;
1763
 
    nukeTable(table);
 
1889
    close_temporary(table);
1764
1890
  }
1765
1891
  temporary_tables= NULL;
1766
1892
}
1790
1916
    if (temporary_tables)
1791
1917
      table->next->prev= NULL;
1792
1918
  }
1793
 
  nukeTable(table);
 
1919
  close_temporary(table);
1794
1920
}
1795
1921
 
1796
1922
/*
1797
 
  Close and drop a temporary table
 
1923
  Close and delete a temporary table
1798
1924
 
1799
1925
  NOTE
1800
1926
  This dosn't unlink table from session->temporary
1801
1927
  If this is needed, use close_temporary_table()
1802
1928
*/
1803
1929
 
1804
 
void Session::nukeTable(Table *table)
 
1930
void Session::close_temporary(Table *table)
1805
1931
{
1806
1932
  plugin::StorageEngine *table_type= table->s->db_type();
1807
1933
 
1808
1934
  table->free_io_cache();
1809
1935
  table->closefrm(false);
1810
1936
 
1811
 
  TableIdentifier identifier(table->s->getSchemaName(), table->s->table_name.str, table->s->path.str);
1812
 
  rm_temporary_table(table_type, identifier);
 
1937
  rm_temporary_table(table_type, table->s->path.str);
1813
1938
 
1814
1939
  table->s->free_table_share();
1815
1940
 
1945
2070
   */
1946
2071
  if (backups_available == false)
1947
2072
  {
1948
 
    TransactionServices &transaction_services= TransactionServices::singleton();
1949
2073
    main_da.can_overwrite_status= true;
1950
 
    transaction_services.ha_autocommit_or_rollback(this, is_error());
 
2074
    ha_autocommit_or_rollback(this, is_error());
1951
2075
    main_da.can_overwrite_status= false;
1952
2076
    transaction.stmt.reset();
1953
2077
  }
2001
2125
    if (open_tables_from_list(&tables, &counter))
2002
2126
      return true;
2003
2127
 
2004
 
    if (not lock_tables(tables, counter, &need_reopen))
 
2128
    if (!lock_tables(tables, counter, &need_reopen))
2005
2129
      break;
2006
 
    if (not need_reopen)
 
2130
    if (!need_reopen)
2007
2131
      return true;
2008
2132
    close_tables_for_reopen(&tables);
2009
2133
  }
2026
2150
  return false;
2027
2151
}
2028
2152
 
2029
 
bool Session::rm_temporary_table(TableIdentifier &identifier)
2030
 
{
2031
 
  if (plugin::StorageEngine::dropTable(*this, identifier))
2032
 
  {
2033
 
    errmsg_printf(ERRMSG_LVL_WARN, _("Could not remove temporary table: '%s', error: %d"),
2034
 
                  identifier.getSQLPath().c_str(), errno);
2035
 
    dumpTemporaryTableNames("rm_temporary_table()");
2036
 
 
2037
 
    return true;
2038
 
  }
2039
 
 
2040
 
  return false;
2041
 
}
2042
 
 
2043
2153
bool Session::rm_temporary_table(plugin::StorageEngine *base, TableIdentifier &identifier)
2044
2154
{
2045
 
  assert(base);
2046
 
 
2047
 
  if (plugin::StorageEngine::dropTable(*this, *base, identifier))
2048
 
  {
2049
 
    errmsg_printf(ERRMSG_LVL_WARN, _("Could not remove temporary table: '%s', error: %d"),
2050
 
                  identifier.getSQLPath().c_str(), errno);
2051
 
    dumpTemporaryTableNames("rm_temporary_table()");
2052
 
 
2053
 
    return true;
2054
 
  }
2055
 
 
2056
 
  return false;
2057
 
}
2058
 
 
2059
 
/**
2060
 
  @note this will be removed, I am looking through Hudson to see if it is finding
2061
 
  any tables that are missed during cleanup.
2062
 
*/
2063
 
void Session::dumpTemporaryTableNames(const char *foo)
2064
 
{
2065
 
  Table *table;
2066
 
 
2067
 
  if (not temporary_tables)
2068
 
    return;
2069
 
 
2070
 
  cerr << "Begin Run: " << foo << "\n";
2071
 
  for (table= temporary_tables; table; table= table->next)
2072
 
  {
2073
 
    bool have_proto= false;
2074
 
 
2075
 
    message::Table *proto= table->s->getTableProto();
2076
 
    if (table->s->getTableProto())
2077
 
      have_proto= true;
2078
 
 
2079
 
    const char *answer= have_proto ? "true" : "false";
2080
 
 
2081
 
    if (have_proto)
2082
 
    {
2083
 
      cerr << "\tTable Name " << table->s->getSchemaName() << "." << table->s->table_name.str << " : " << answer << "\n";
2084
 
      cerr << "\t\t Proto " << proto->schema() << " " << proto->name() << "\n";
2085
 
    }
2086
 
    else
2087
 
      cerr << "\tTabl;e Name " << table->s->getSchemaName() << "." << table->s->table_name.str << " : " << answer << "\n";
2088
 
  }
2089
 
}
2090
 
 
2091
 
bool Session::storeTableMessage(TableIdentifier &identifier, message::Table &table_message)
2092
 
{
2093
 
  table_message_cache.insert(make_pair(identifier.getPath(), table_message));
2094
 
 
2095
 
  return true;
2096
 
}
2097
 
 
2098
 
bool Session::removeTableMessage(TableIdentifier &identifier)
2099
 
{
2100
 
  TableMessageCache::iterator iter;
2101
 
 
2102
 
  iter= table_message_cache.find(identifier.getPath());
2103
 
 
2104
 
  if (iter == table_message_cache.end())
2105
 
    return false;
2106
 
 
2107
 
  table_message_cache.erase(iter);
2108
 
 
2109
 
  return true;
2110
 
}
2111
 
 
2112
 
bool Session::getTableMessage(TableIdentifier &identifier, message::Table &table_message)
2113
 
{
2114
 
  TableMessageCache::iterator iter;
2115
 
 
2116
 
  iter= table_message_cache.find(identifier.getPath());
2117
 
 
2118
 
  if (iter == table_message_cache.end())
2119
 
    return false;
2120
 
 
2121
 
  table_message.CopyFrom(((*iter).second));
2122
 
 
2123
 
  return true;
2124
 
}
2125
 
 
2126
 
bool Session::doesTableMessageExist(TableIdentifier &identifier)
2127
 
{
2128
 
  TableMessageCache::iterator iter;
2129
 
 
2130
 
  iter= table_message_cache.find(identifier.getPath());
2131
 
 
2132
 
  if (iter == table_message_cache.end())
2133
 
  {
2134
 
    return false;
2135
 
  }
2136
 
 
2137
 
  return true;
2138
 
}
2139
 
 
2140
 
bool Session::renameTableMessage(TableIdentifier &from, TableIdentifier &to)
2141
 
{
2142
 
  TableMessageCache::iterator iter;
2143
 
 
2144
 
  table_message_cache[to.getPath()]= table_message_cache[from.getPath()];
2145
 
 
2146
 
  iter= table_message_cache.find(to.getPath());
2147
 
 
2148
 
  if (iter == table_message_cache.end())
2149
 
  {
2150
 
    return false;
2151
 
  }
2152
 
 
2153
 
  (*iter).second.set_schema(to.getSchemaName());
2154
 
  (*iter).second.set_name(to.getTableName());
2155
 
 
2156
 
  return true;
2157
 
}
2158
 
 
2159
 
} /* namespace drizzled */
 
2155
  bool error= false;
 
2156
 
 
2157
  assert(base);
 
2158
 
 
2159
  if (plugin::StorageEngine::deleteDefinitionFromPath(identifier))
 
2160
    error= true;
 
2161
 
 
2162
  if (base->doDropTable(*this, identifier.getPath()))
 
2163
  {
 
2164
    error= true;
 
2165
    errmsg_printf(ERRMSG_LVL_WARN, _("Could not remove temporary table: '%s', error: %d"),
 
2166
                  identifier.getPath(), errno);
 
2167
  }
 
2168
  return error;
 
2169
}
 
2170
 
 
2171
bool Session::rm_temporary_table(plugin::StorageEngine *base, const char *path)
 
2172
{
 
2173
  bool error= false;
 
2174
 
 
2175
  assert(base);
 
2176
 
 
2177
  if (delete_table_proto_file(path))
 
2178
    error= true;
 
2179
 
 
2180
  if (base->doDropTable(*this, path))
 
2181
  {
 
2182
    error= true;
 
2183
    errmsg_printf(ERRMSG_LVL_WARN, _("Could not remove temporary table: '%s', error: %d"),
 
2184
                  path, errno);
 
2185
  }
 
2186
  return error;
 
2187
}