~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/session.cc

  • Committer: Padraig O'Sullivan
  • Date: 2010-02-11 16:22:34 UTC
  • mto: (1300.3.1 query-as-string)
  • mto: This revision was merged to the branch mainline in revision 1307.
  • Revision ID: osullivan.padraig@gmail.com-20100211162234-tkk64v4vdqkb9syv
Removed the found_semicolon member from the parsing stage

Show diffs side-by-side

added added

removed removed

Lines of Context:
44
44
#include "drizzled/table_proto.h"
45
45
#include "drizzled/db.h"
46
46
#include "drizzled/pthread_globals.h"
 
47
#include "drizzled/transaction_services.h"
47
48
 
48
49
#include "plugin/myisam/myisam.h"
49
50
#include "drizzled/internal/iocache.h"
53
54
#include <climits>
54
55
 
55
56
using namespace std;
56
 
using namespace drizzled;
 
57
namespace drizzled
 
58
{
57
59
 
58
60
extern "C"
59
61
{
72
74
extern pthread_key_t THR_Session;
73
75
extern pthread_key_t THR_Mem_root;
74
76
extern uint32_t max_used_connections;
75
 
extern drizzled::atomic<uint32_t> connection_count;
 
77
extern atomic<uint32_t> connection_count;
76
78
 
77
 
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
78
 
/* Used templates */
79
 
template class List<Key>;
80
 
template class List_iterator<Key>;
81
 
template class List<Key_part_spec>;
82
 
template class List_iterator<Key_part_spec>;
83
 
template class List<AlterDrop>;
84
 
template class List_iterator<AlterDrop>;
85
 
template class List<AlterColumn>;
86
 
template class List_iterator<AlterColumn>;
87
 
#endif
88
79
 
89
80
/****************************************************************************
90
81
** User variables
119
110
extern "C" int mysql_tmpfile(const char *prefix)
120
111
{
121
112
  char filename[FN_REFLEN];
122
 
  int fd = create_temp_file(filename, drizzle_tmpdir, prefix, MYF(MY_WME));
 
113
  int fd = internal::create_temp_file(filename, drizzle_tmpdir, prefix, MYF(MY_WME));
123
114
  if (fd >= 0) {
124
115
    unlink(filename);
125
116
  }
218
209
    the destructor works OK in case of an error. The main_mem_root
219
210
    will be re-initialized in init_for_queries().
220
211
  */
221
 
  init_sql_alloc(&main_mem_root, ALLOC_ROOT_MIN_BLOCK_SIZE, 0);
 
212
  memory::init_sql_alloc(&main_mem_root, memory::ROOT_MIN_BLOCK_SIZE, 0);
222
213
  thread_stack= NULL;
223
214
  count_cuted_fields= CHECK_FIELD_IGNORE;
224
215
  killed= NOT_KILLED;
237
228
  thread_id= 0;
238
229
  file_id = 0;
239
230
  query_id= 0;
240
 
  query= NULL;
241
 
  query_length= 0;
242
 
  warn_id= 0;
 
231
  query.clear();
 
232
  warn_query_id= 0;
243
233
  memset(ha_data, 0, sizeof(ha_data));
244
 
  replication_data= 0;
245
234
  mysys_var= 0;
246
235
  dbug_sentry=Session_SENTRY_MAGIC;
247
236
  cleanup_done= abort_on_warning= no_warnings_for_error= false;
248
 
  transaction.on= 1;
249
237
  pthread_mutex_init(&LOCK_delete, MY_MUTEX_INIT_FAST);
250
238
 
251
239
  /* Variables with default values */
278
266
  memset(&status_var, 0, sizeof(status_var));
279
267
 
280
268
  /* Initialize sub structures */
281
 
  init_sql_alloc(&warn_root, WARN_ALLOC_BLOCK_SIZE, WARN_ALLOC_PREALLOC_SIZE);
 
269
  memory::init_sql_alloc(&warn_root, WARN_ALLOC_BLOCK_SIZE, WARN_ALLOC_PREALLOC_SIZE);
282
270
  hash_init(&user_vars, system_charset_info, USER_VARS_HASH_SIZE, 0, 0,
283
271
            (hash_get_key) get_var_key,
284
272
            (hash_free_key) free_user_var, 0);
293
281
void Session::free_items()
294
282
{
295
283
  Item *next;
296
 
  /* This works because items are allocated with sql_alloc() */
 
284
  /* This works because items are allocated with memory::sql_alloc() */
297
285
  for (; free_list; free_list= next)
298
286
  {
299
287
    next= free_list->next;
380
368
  }
381
369
#endif
382
370
  {
383
 
    ha_rollback(this);
 
371
    TransactionServices &transaction_services= TransactionServices::singleton();
 
372
    transaction_services.ha_rollback_trans(this, true);
384
373
    xid_cache_delete(&transaction.xid_state);
385
374
  }
386
375
  hash_free(&user_vars);
400
389
  if (client->isConnected())
401
390
  {
402
391
    if (global_system_variables.log_warnings)
403
 
        errmsg_printf(ERRMSG_LVL_WARN, ER(ER_FORCING_CLOSE),my_progname,
 
392
        errmsg_printf(ERRMSG_LVL_WARN, ER(ER_FORCING_CLOSE),internal::my_progname,
404
393
                      thread_id,
405
394
                      (security_ctx.user.c_str() ?
406
395
                       security_ctx.user.c_str() : ""));
418
407
  plugin_sessionvar_cleanup(this);
419
408
 
420
409
  free_root(&warn_root,MYF(0));
421
 
  free_root(&transaction.mem_root,MYF(0));
422
410
  mysys_var=0;                                  // Safety (shouldn't be needed)
423
411
  dbug_sentry= Session_SENTRY_GONE;
424
412
 
524
512
 
525
513
/*
526
514
  Remember the location of thread info, the structure needed for
527
 
  sql_alloc() and the structure for the net buffer
 
515
  memory::sql_alloc() and the structure for the net buffer
528
516
*/
529
517
bool Session::storeGlobals()
530
518
{
570
558
  set_proc_info(NULL);
571
559
  command= COM_SLEEP;
572
560
  set_time();
573
 
  ha_enable_transaction(this,true);
574
561
 
575
562
  reset_root_defaults(mem_root, variables.query_alloc_block_size,
576
563
                      variables.query_prealloc_size);
577
 
  reset_root_defaults(&transaction.mem_root,
578
 
                      variables.trans_alloc_block_size,
579
 
                      variables.trans_prealloc_size);
580
564
  transaction.xid_state.xid.null();
581
565
  transaction.xid_state.in_session=1;
582
566
}
616
600
  scheduler= plugin::Scheduler::getScheduler();
617
601
  assert(scheduler);
618
602
 
619
 
  ++connection_count;
 
603
  connection_count.increment();
620
604
 
621
605
  if (connection_count > max_used_connections)
622
606
    max_used_connections= connection_count;
688
672
 
689
673
bool Session::checkUser(const char *passwd, uint32_t passwd_len, const char *in_db)
690
674
{
 
675
  LEX_STRING db_str= { (char *) in_db, in_db ? strlen(in_db) : 0 };
691
676
  bool is_authenticated;
692
677
 
693
678
  if (passwd_len != 0 && passwd_len != SCRAMBLE_LENGTH)
713
698
  /* Change database if necessary */
714
699
  if (in_db && in_db[0])
715
700
  {
716
 
    const string database_name_string(in_db);
717
 
    NonNormalisedDatabaseName database_name(database_name_string);
718
 
    NormalisedDatabaseName normalised_database_name(database_name);
719
 
 
720
 
    if (mysql_change_db(this, normalised_database_name, false))
 
701
    if (mysql_change_db(this, &db_str, false))
721
702
    {
722
703
      /* mysql_change_db() has pushed the error message. */
723
704
      return false;
776
757
    in_packet_length--;
777
758
  }
778
759
 
779
 
  /* We must allocate some extra memory for the cached query string */
780
 
  query_length= 0; /* Extra safety: Avoid races */
781
 
  query= (char*) memdup_w_gap((unsigned char*) in_packet, in_packet_length, db.length() + 1);
782
 
  if (! query)
 
760
  query.assign(in_packet, in_packet + in_packet_length);
 
761
  if (query.empty())
783
762
    return false;
784
763
 
785
 
  query[in_packet_length]=0;
786
 
  query_length= in_packet_length;
787
 
 
788
764
  return true;
789
765
}
790
766
 
792
768
{
793
769
  bool do_release= 0;
794
770
  bool result= true;
 
771
  TransactionServices &transaction_services= TransactionServices::singleton();
795
772
 
796
773
  if (transaction.xid_state.xa_state != XA_NOTR)
797
774
  {
807
784
       * (Which of course should never happen...)
808
785
       */
809
786
      server_status&= ~SERVER_STATUS_IN_TRANS;
810
 
      if (ha_commit(this))
 
787
      if (transaction_services.ha_commit_trans(this, true))
811
788
        result= false;
812
789
      options&= ~(OPTION_BEGIN);
813
790
      transaction.all.modified_non_trans_table= false;
825
802
    case ROLLBACK_AND_CHAIN:
826
803
    {
827
804
      server_status&= ~SERVER_STATUS_IN_TRANS;
828
 
      if (ha_rollback(this))
 
805
      if (transaction_services.ha_rollback_trans(this, true))
829
806
        result= false;
830
807
      options&= ~(OPTION_BEGIN);
831
808
      transaction.all.modified_non_trans_table= false;
849
826
bool Session::endActiveTransaction()
850
827
{
851
828
  bool result= true;
 
829
  TransactionServices &transaction_services= TransactionServices::singleton();
852
830
 
853
831
  if (transaction.xid_state.xa_state != XA_NOTR)
854
832
  {
858
836
  if (options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
859
837
  {
860
838
    server_status&= ~SERVER_STATUS_IN_TRANS;
861
 
    if (ha_commit(this))
 
839
    if (transaction_services.ha_commit_trans(this, true))
862
840
      result= false;
863
841
  }
864
842
  options&= ~(OPTION_BEGIN);
940
918
  return lex_str;
941
919
}
942
920
 
943
 
/* routings to adding tables to list of changed in transaction tables */
944
 
inline static void list_include(CHANGED_TableList** prev,
945
 
                                CHANGED_TableList* curr,
946
 
                                CHANGED_TableList* new_table)
947
 
{
948
 
  if (new_table)
949
 
  {
950
 
    *prev = new_table;
951
 
    (*prev)->next = curr;
952
 
  }
953
 
}
954
 
 
955
 
/* add table to list of changed in transaction tables */
956
 
 
957
 
void Session::add_changed_table(Table *table)
958
 
{
959
 
  assert((options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) &&
960
 
              table->cursor->has_transactions());
961
 
  add_changed_table(table->s->table_cache_key.str,
962
 
                    (long) table->s->table_cache_key.length);
963
 
}
964
 
 
965
 
 
966
 
void Session::add_changed_table(const char *key, long key_length)
967
 
{
968
 
  CHANGED_TableList **prev_changed = &transaction.changed_tables;
969
 
  CHANGED_TableList *curr = transaction.changed_tables;
970
 
 
971
 
  for (; curr; prev_changed = &(curr->next), curr = curr->next)
972
 
  {
973
 
    int cmp =  (long)curr->key_length - (long)key_length;
974
 
    if (cmp < 0)
975
 
    {
976
 
      list_include(prev_changed, curr, changed_table_dup(key, key_length));
977
 
      return;
978
 
    }
979
 
    else if (cmp == 0)
980
 
    {
981
 
      cmp = memcmp(curr->key, key, curr->key_length);
982
 
      if (cmp < 0)
983
 
      {
984
 
        list_include(prev_changed, curr, changed_table_dup(key, key_length));
985
 
        return;
986
 
      }
987
 
      else if (cmp == 0)
988
 
      {
989
 
        return;
990
 
      }
991
 
    }
992
 
  }
993
 
  *prev_changed = changed_table_dup(key, key_length);
994
 
}
995
 
 
996
 
 
997
 
CHANGED_TableList* Session::changed_table_dup(const char *key, long key_length)
998
 
{
999
 
  CHANGED_TableList* new_table =
1000
 
    (CHANGED_TableList*) trans_alloc(ALIGN_SIZE(sizeof(CHANGED_TableList))+
1001
 
                                      key_length + 1);
1002
 
  if (!new_table)
1003
 
  {
1004
 
    my_error(EE_OUTOFMEMORY, MYF(ME_BELL),
1005
 
             ALIGN_SIZE(sizeof(TableList)) + key_length + 1);
1006
 
    killed= KILL_CONNECTION;
1007
 
    return 0;
1008
 
  }
1009
 
 
1010
 
  new_table->key= ((char*)new_table)+ ALIGN_SIZE(sizeof(CHANGED_TableList));
1011
 
  new_table->next = 0;
1012
 
  new_table->key_length = key_length;
1013
 
  ::memcpy(new_table->key, key, key_length);
1014
 
  return new_table;
1015
 
}
1016
 
 
1017
 
 
1018
921
int Session::send_explain_fields(select_result *result)
1019
922
{
1020
923
  List<Item> field_list;
1068
971
  if (file > 0)
1069
972
  {
1070
973
    (void) end_io_cache(cache);
1071
 
    (void) my_close(file, MYF(0));
1072
 
    (void) my_delete(path, MYF(0));             // Delete file on error
 
974
    (void) internal::my_close(file, MYF(0));
 
975
    (void) internal::my_delete(path, MYF(0));           // Delete file on error
1073
976
    file= -1;
1074
977
  }
1075
978
}
1078
981
bool select_to_file::send_eof()
1079
982
{
1080
983
  int error= test(end_io_cache(cache));
1081
 
  if (my_close(file, MYF(MY_WME)))
 
984
  if (internal::my_close(file, MYF(MY_WME)))
1082
985
    error= 1;
1083
986
  if (!error)
1084
987
  {
1100
1003
  if (file >= 0)
1101
1004
  {
1102
1005
    (void) end_io_cache(cache);
1103
 
    (void) my_close(file, MYF(0));
 
1006
    (void) internal::my_close(file, MYF(0));
1104
1007
    file= -1;
1105
1008
  }
1106
1009
  path[0]= '\0';
1110
1013
select_to_file::select_to_file(file_exchange *ex)
1111
1014
  : exchange(ex),
1112
1015
    file(-1),
1113
 
    cache(static_cast<IO_CACHE *>(sql_calloc(sizeof(IO_CACHE)))),
 
1016
    cache(static_cast<internal::IO_CACHE *>(memory::sql_calloc(sizeof(internal::IO_CACHE)))),
1114
1017
    row_count(0L)
1115
1018
{
1116
1019
  path[0]=0;
1147
1050
*/
1148
1051
 
1149
1052
 
1150
 
static int create_file(Session *session, char *path, file_exchange *exchange, IO_CACHE *cache)
 
1053
static int create_file(Session *session, char *path, file_exchange *exchange, internal::IO_CACHE *cache)
1151
1054
{
1152
1055
  int file;
1153
1056
  uint32_t option= MY_UNPACK_FILENAME | MY_RELATIVE_PATH;
1156
1059
  option|= MY_REPLACE_DIR;                      // Force use of db directory
1157
1060
#endif
1158
1061
 
1159
 
  if (!dirname_length(exchange->file_name))
 
1062
  if (!internal::dirname_length(exchange->file_name))
1160
1063
  {
1161
1064
    strcpy(path, drizzle_real_data_home);
1162
1065
    if (! session->db.empty())
1163
1066
      strncat(path, session->db.c_str(), FN_REFLEN-strlen(drizzle_real_data_home)-1);
1164
 
    (void) fn_format(path, exchange->file_name, path, "", option);
 
1067
    (void) internal::fn_format(path, exchange->file_name, path, "", option);
1165
1068
  }
1166
1069
  else
1167
 
    (void) fn_format(path, exchange->file_name, drizzle_real_data_home, "", option);
 
1070
    (void) internal::fn_format(path, exchange->file_name, drizzle_real_data_home, "", option);
1168
1071
 
1169
1072
  if (opt_secure_file_priv &&
1170
1073
      strncmp(opt_secure_file_priv, path, strlen(opt_secure_file_priv)))
1180
1083
    return -1;
1181
1084
  }
1182
1085
  /* Create the file world readable */
1183
 
  if ((file= my_create(path, 0666, O_WRONLY|O_EXCL, MYF(MY_WME))) < 0)
 
1086
  if ((file= internal::my_create(path, 0666, O_WRONLY|O_EXCL, MYF(MY_WME))) < 0)
1184
1087
    return file;
1185
1088
  (void) fchmod(file, 0666);                    // Because of umask()
1186
 
  if (init_io_cache(cache, file, 0L, WRITE_CACHE, 0L, 1, MYF(MY_WME)))
 
1089
  if (init_io_cache(cache, file, 0L, internal::WRITE_CACHE, 0L, 1, MYF(MY_WME)))
1187
1090
  {
1188
 
    my_close(file, MYF(0));
1189
 
    my_delete(path, MYF(0));  // Delete file on error, it was just created
 
1091
    internal::my_close(file, MYF(0));
 
1092
    internal::my_delete(path, MYF(0));  // Delete file on error, it was just created
1190
1093
    return -1;
1191
1094
  }
1192
1095
  return file;
1681
1584
  quick_group= 1;
1682
1585
  table_charset= 0;
1683
1586
  precomputed_group_by= 0;
1684
 
  bit_fields_as_long= 0;
1685
1587
}
1686
1588
 
1687
1589
void Tmp_Table_Param::cleanup(void)
1740
1642
  set_open_tables_state(backup);
1741
1643
}
1742
1644
 
1743
 
 
1744
 
bool Session::set_db(const NormalisedDatabaseName &new_db)
 
1645
bool Session::set_db(const char *new_db, size_t length)
1745
1646
{
1746
 
  db= new_db.to_string();
 
1647
  /* Do not reallocate memory if current chunk is big enough. */
 
1648
  if (length)
 
1649
    db= new_db;
 
1650
  else
 
1651
    db.clear();
1747
1652
 
1748
1653
  return false;
1749
1654
}
1750
1655
 
1751
 
void Session::clear_db()
1752
 
{
1753
 
  db.clear();
1754
 
}
 
1656
 
1755
1657
 
1756
1658
 
1757
1659
/**
1781
1683
  return(session->charset());
1782
1684
}
1783
1685
 
1784
 
char **session_query(Session *session)
1785
 
{
1786
 
  return(&session->query);
1787
 
}
1788
 
 
1789
1686
int session_non_transactional_update(const Session *session)
1790
1687
{
1791
1688
  return(session->transaction.all.modified_non_trans_table);
2081
1978
   */
2082
1979
  if (backups_available == false)
2083
1980
  {
 
1981
    TransactionServices &transaction_services= TransactionServices::singleton();
2084
1982
    main_da.can_overwrite_status= true;
2085
 
    ha_autocommit_or_rollback(this, is_error());
 
1983
    transaction_services.ha_autocommit_or_rollback(this, is_error());
2086
1984
    main_da.can_overwrite_status= false;
2087
1985
    transaction.stmt.reset();
2088
1986
  }
2196
2094
  }
2197
2095
  return error;
2198
2096
}
 
2097
 
 
2098
} /* namespace drizzled */