~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/session.cc

  • Committer: patrick crews
  • Date: 2011-02-23 17:17:25 UTC
  • mto: (2195.1.1 build)
  • mto: This revision was merged to the branch mainline in revision 2196.
  • Revision ID: gleebix@gmail.com-20110223171725-4tgewemxhsw1m7q8
Integrated randgen with dbqp.  We now have mode=randgen and a set of randgen test suites (very basic now).  Output = same as dtr : )  We also have mode=cleanup to kill any servers we have started.  Docs updates too.  Gendata utility allows us to populate test servers 

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
3
 *
4
 
 *  Copyright (C) 2008 Sun Microsystems
 
4
 *  Copyright (C) 2008 Sun Microsystems, Inc.
5
5
 *
6
6
 *  This program is free software; you can redistribute it and/or modify
7
7
 *  it under the terms of the GNU General Public License as published by
21
21
 * @file Implementation of the Session class and API
22
22
 */
23
23
 
24
 
#include "config.h"
25
 
#include "drizzled/session.h"
26
 
#include "drizzled/session/cache.h"
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"
40
 
#include "drizzled/plugin/scheduler.h"
41
 
#include "drizzled/plugin/authentication.h"
42
 
#include "drizzled/plugin/logging.h"
43
 
#include "drizzled/plugin/transactional_storage_engine.h"
44
 
#include "drizzled/plugin/query_rewrite.h"
45
 
#include "drizzled/probes.h"
46
 
#include "drizzled/table_proto.h"
47
 
#include "drizzled/db.h"
48
 
#include "drizzled/pthread_globals.h"
49
 
#include "drizzled/transaction_services.h"
50
 
#include "drizzled/drizzled.h"
51
 
 
52
 
#include "drizzled/table/instance.h"
53
 
 
54
 
#include "plugin/myisam/myisam.h"
55
 
#include "drizzled/internal/iocache.h"
56
 
#include "drizzled/internal/thread_var.h"
57
 
#include "drizzled/plugin/event_observer.h"
58
 
 
59
 
#include "drizzled/util/functors.h"
60
 
 
61
 
#include "drizzled/display.h"
62
 
 
63
 
#include <fcntl.h>
 
24
#include <config.h>
 
25
 
 
26
#include <drizzled/copy_field.h>
 
27
#include <drizzled/data_home.h>
 
28
#include <drizzled/display.h>
 
29
#include <drizzled/drizzled.h>
 
30
#include <drizzled/error.h>
 
31
#include <drizzled/gettext.h>
 
32
#include <drizzled/identifier.h>
 
33
#include <drizzled/internal/iocache.h>
 
34
#include <drizzled/internal/thread_var.h>
 
35
#include <drizzled/internal_error_handler.h>
 
36
#include <drizzled/item/cache.h>
 
37
#include <drizzled/item/empty_string.h>
 
38
#include <drizzled/item/float.h>
 
39
#include <drizzled/item/return_int.h>
 
40
#include <drizzled/lock.h>
 
41
#include <drizzled/plugin/authentication.h>
 
42
#include <drizzled/plugin/client.h>
 
43
#include <drizzled/plugin/event_observer.h>
 
44
#include <drizzled/plugin/logging.h>
 
45
#include <drizzled/plugin/query_rewrite.h>
 
46
#include <drizzled/plugin/scheduler.h>
 
47
#include <drizzled/plugin/transactional_storage_engine.h>
 
48
#include <drizzled/probes.h>
 
49
#include <drizzled/pthread_globals.h>
 
50
#include <drizzled/query_id.h>
 
51
#include <drizzled/refresh_version.h>
 
52
#include <drizzled/select_dump.h>
 
53
#include <drizzled/select_exists_subselect.h>
 
54
#include <drizzled/select_export.h>
 
55
#include <drizzled/select_max_min_finder_subselect.h>
 
56
#include <drizzled/select_singlerow_subselect.h>
 
57
#include <drizzled/select_subselect.h>
 
58
#include <drizzled/select_to_file.h>
 
59
#include <drizzled/session.h>
 
60
#include <drizzled/session/cache.h>
 
61
#include <drizzled/show.h>
 
62
#include <drizzled/sql_base.h>
 
63
#include <drizzled/table/singular.h>
 
64
#include <drizzled/table_proto.h>
 
65
#include <drizzled/tmp_table_param.h>
 
66
#include <drizzled/transaction_services.h>
 
67
#include <drizzled/user_var_entry.h>
 
68
#include <drizzled/util/functors.h>
 
69
#include <plugin/myisam/myisam.h>
 
70
 
64
71
#include <algorithm>
65
72
#include <climits>
 
73
#include <fcntl.h>
 
74
#include <sys/stat.h>
 
75
 
66
76
#include <boost/filesystem.hpp>
67
 
 
68
 
#include "drizzled/util/backtrace.h"
 
77
#include <boost/checked_delete.hpp>
 
78
 
 
79
#include <drizzled/util/backtrace.h>
 
80
 
 
81
#include <drizzled/schema.h>
69
82
 
70
83
using namespace std;
71
84
 
99
112
/*
100
113
  The following functions form part of the C plugin API
101
114
*/
102
 
int mysql_tmpfile(const char *prefix)
 
115
int tmpfile(const char *prefix)
103
116
{
104
117
  char filename[FN_REFLEN];
105
118
  int fd = internal::create_temp_file(filename, drizzle_tmpdir.c_str(), prefix, MYF(MY_WME));
110
123
  return fd;
111
124
}
112
125
 
113
 
int session_tablespace_op(const Session *session)
114
 
{
115
 
  return test(session->tablespace_op);
116
 
}
117
 
 
118
 
/**
119
 
   Set the process info field of the Session structure.
120
 
 
121
 
   This function is used by plug-ins. Internally, the
122
 
   Session::set_proc_info() function should be used.
123
 
 
124
 
   @see Session::set_proc_info
125
 
 */
126
 
void set_session_proc_info(Session *session, const char *info)
127
 
{
128
 
  session->set_proc_info(info);
129
 
}
130
 
 
131
 
const char *get_session_proc_info(Session *session)
132
 
{
133
 
  return session->get_proc_info();
134
 
}
135
 
 
136
126
void **Session::getEngineData(const plugin::MonitoredInTransaction *monitored)
137
127
{
138
128
  return static_cast<void **>(&ha_data[monitored->getId()].ha_ptr);
149
139
  return session->options & test_options;
150
140
}
151
141
 
152
 
int session_sql_command(const Session *session)
153
 
{
154
 
  return (int) session->lex->sql_command;
155
 
}
156
 
 
157
 
enum_tx_isolation session_tx_isolation(const Session *session)
158
 
{
159
 
  return (enum_tx_isolation)session->variables.tx_isolation;
160
 
}
161
 
 
162
 
Session::Session(plugin::Client *client_arg) :
 
142
Session::Session(plugin::Client *client_arg, catalog::Instance::shared_ptr catalog_arg) :
163
143
  Open_tables_state(refresh_version),
164
144
  mem_root(&main_mem_root),
165
145
  xa_id(0),
166
146
  lex(&main_lex),
167
147
  query(new std::string),
168
148
  _schema(new std::string("")),
169
 
  catalog("LOCAL"),
170
149
  client(client_arg),
171
150
  scheduler(NULL),
172
151
  scheduler_arg(NULL),
173
152
  lock_id(&main_lock_id),
174
 
  user_time(0),
 
153
  thread_stack(NULL),
 
154
  security_ctx(identifier::User::make_shared()),
 
155
  _where(Session::DEFAULT_WHERE),
 
156
  dbug_sentry(Session_SENTRY_MAGIC),
 
157
  mysys_var(0),
 
158
  command(COM_CONNECT),
 
159
  file_id(0),
 
160
  _epoch(boost::gregorian::date(1970,1,1)),
 
161
  _connect_time(boost::posix_time::microsec_clock::universal_time()),
 
162
  utime_after_lock(0),
175
163
  ha_data(plugin::num_trx_monitored_objects),
 
164
  query_id(0),
 
165
  warn_query_id(0),
176
166
  concurrent_execute_allowed(true),
177
167
  arg_of_last_insert_id_function(false),
178
168
  first_successful_insert_id_in_prev_stmt(0),
179
169
  first_successful_insert_id_in_cur_stmt(0),
180
170
  limit_found_rows(0),
 
171
  options(session_startup_options),
 
172
  row_count_func(-1),
 
173
  sent_row_count(0),
 
174
  examined_row_count(0),
 
175
  used_tables(0),
 
176
  total_warn_count(0),
 
177
  col_access(0),
 
178
  statement_id_counter(0),
 
179
  row_count(0),
 
180
  thread_id(0),
 
181
  tmp_table(0),
181
182
  _global_read_lock(NONE),
 
183
  count_cuted_fields(CHECK_FIELD_ERROR_FOR_NULL),
182
184
  _killed(NOT_KILLED),
183
185
  some_tables_deleted(false),
184
186
  no_errors(false),
186
188
  is_fatal_error(false),
187
189
  transaction_rollback_request(false),
188
190
  is_fatal_sub_stmt_error(0),
 
191
  tablespace_op(false),
189
192
  derived_tables_processing(false),
190
 
  tablespace_op(false),
191
193
  m_lip(NULL),
192
194
  cached_table(0),
193
195
  transaction_message(NULL),
194
196
  statement_message(NULL),
195
197
  session_event_observers(NULL),
 
198
  _catalog(catalog_arg),
196
199
  use_usage(false)
197
200
{
198
201
  client->setSession(this);
203
206
    will be re-initialized in init_for_queries().
204
207
  */
205
208
  memory::init_sql_alloc(&main_mem_root, memory::ROOT_MIN_BLOCK_SIZE, 0);
206
 
  thread_stack= NULL;
207
 
  count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;
208
 
  col_access= 0;
209
 
  tmp_table= 0;
210
 
  used_tables= 0;
211
209
  cuted_fields= sent_row_count= row_count= 0L;
212
 
  row_count_func= -1;
213
 
  statement_id_counter= 0UL;
214
210
  // Must be reset to handle error with Session's created for init of mysqld
215
211
  lex->current_select= 0;
216
 
  start_time=(time_t) 0;
217
 
  start_utime= 0L;
218
 
  utime_after_lock= 0L;
219
212
  memset(&variables, 0, sizeof(variables));
220
 
  thread_id= 0;
221
 
  file_id = 0;
222
 
  query_id= 0;
223
 
  warn_query_id= 0;
224
 
  mysys_var= 0;
225
213
  scoreboard_index= -1;
226
 
  dbug_sentry=Session_SENTRY_MAGIC;
227
214
  cleanup_done= abort_on_warning= no_warnings_for_error= false;  
228
215
 
229
216
  /* query_cache init */
232
219
 
233
220
  /* Variables with default values */
234
221
  proc_info="login";
235
 
  where= Session::DEFAULT_WHERE;
236
 
  command= COM_CONNECT;
237
222
 
238
223
  plugin_sessionvar_init(this);
239
224
  /*
243
228
  */
244
229
  variables.pseudo_thread_id= thread_id;
245
230
  server_status= SERVER_STATUS_AUTOCOMMIT;
246
 
  options= session_startup_options;
247
231
 
248
232
  if (variables.max_join_size == HA_POS_ERROR)
249
233
    options |= OPTION_BIG_SELECTS;
253
237
  open_options=ha_open_options;
254
238
  update_lock_default= TL_WRITE;
255
239
  session_tx_isolation= (enum_tx_isolation) variables.tx_isolation;
256
 
  warn_list.empty();
 
240
  warn_list.clear();
257
241
  memset(warn_count, 0, sizeof(warn_count));
258
 
  total_warn_count= 0;
259
242
  memset(&status_var, 0, sizeof(status_var));
260
243
 
261
244
  /* Initialize sub structures */
291
274
  m_internal_handler= handler;
292
275
}
293
276
 
294
 
bool Session::handle_error(uint32_t sql_errno, const char *message,
295
 
                       DRIZZLE_ERROR::enum_warning_level level)
 
277
bool Session::handle_error(drizzled::error_t sql_errno, const char *message,
 
278
                           DRIZZLE_ERROR::enum_warning_level level)
296
279
{
297
280
  if (m_internal_handler)
298
281
  {
328
311
  m_internal_handler= NULL;
329
312
}
330
313
 
331
 
void Session::get_xid(DRIZZLE_XID *xid)
 
314
void Session::get_xid(DrizzleXid *xid)
332
315
{
333
 
  *xid = *(DRIZZLE_XID *) &transaction.xid_state.xid;
 
316
  *xid = *(DrizzleXid *) &transaction.xid_state.xid;
334
317
}
335
318
 
336
319
/* Do operations that may take a long time */
348
331
#endif
349
332
  {
350
333
    TransactionServices &transaction_services= TransactionServices::singleton();
351
 
    transaction_services.rollbackTransaction(this, true);
 
334
    transaction_services.rollbackTransaction(*this, true);
352
335
    xid_cache_delete(&transaction.xid_state);
353
336
  }
354
337
 
357
340
       iter++)
358
341
  {
359
342
    user_var_entry *entry= (*iter).second;
360
 
    delete entry;
 
343
    boost::checked_delete(entry);
361
344
  }
362
345
  user_vars.clear();
363
346
 
376
359
{
377
360
  this->checkSentry();
378
361
 
379
 
  if (client->isConnected())
 
362
  if (client and client->isConnected())
380
363
  {
 
364
    assert(security_ctx);
381
365
    if (global_system_variables.log_warnings)
382
 
        errmsg_printf(ERRMSG_LVL_WARN, ER(ER_FORCING_CLOSE),internal::my_progname,
383
 
                      thread_id,
384
 
                      (getSecurityContext().getUser().c_str() ?
385
 
                       getSecurityContext().getUser().c_str() : ""));
386
 
    disconnect(0, false);
 
366
    {
 
367
      errmsg_printf(error::WARN, ER(ER_FORCING_CLOSE),
 
368
                    internal::my_progname,
 
369
                    thread_id,
 
370
                    security_ctx->username().c_str());
 
371
    }
 
372
 
 
373
    disconnect();
387
374
  }
388
375
 
389
376
  /* Close connection */
390
 
  client->close();
391
 
  delete client;
 
377
  if (client)
 
378
  {
 
379
    client->close();
 
380
    boost::checked_delete(client);
 
381
    client= NULL;
 
382
  }
392
383
 
393
384
  if (cleanup_done == false)
394
385
    cleanup();
406
397
 
407
398
  plugin::Logging::postEndDo(this);
408
399
  plugin::EventObserver::deregisterSessionEvents(*this); 
409
 
 
410
 
  for (PropertyMap::iterator iter= life_properties.begin(); iter != life_properties.end(); iter++)
411
 
  {
412
 
    delete (*iter).second;
413
 
  }
414
 
  life_properties.clear();
415
400
}
416
401
 
417
402
void Session::setClient(plugin::Client *client_arg)
530
515
{
531
516
  if (storeGlobals())
532
517
  {
533
 
    disconnect(ER_OUT_OF_RESOURCES, true);
 
518
    disconnect(ER_OUT_OF_RESOURCES);
534
519
    status_var.aborted_connects++;
535
520
    return true;
536
521
  }
541
526
{
542
527
  if (initGlobals() || authenticate())
543
528
  {
544
 
    disconnect(0, true);
 
529
    disconnect();
545
530
    return;
546
531
  }
547
532
 
553
538
      break;
554
539
  }
555
540
 
556
 
  disconnect(0, true);
 
541
  disconnect();
557
542
}
558
543
 
559
544
bool Session::schedule(Session::shared_ptr &arg)
561
546
  arg->scheduler= plugin::Scheduler::getScheduler();
562
547
  assert(arg->scheduler);
563
548
 
564
 
  connection_count.increment();
565
 
 
566
 
  if (connection_count > current_global_counters.max_used_connections)
 
549
  ++connection_count;
 
550
 
 
551
  long current_connections= connection_count;
 
552
 
 
553
  if (current_connections > 0 and static_cast<uint64_t>(current_connections) > current_global_counters.max_used_connections)
567
554
  {
568
 
    current_global_counters.max_used_connections= connection_count;
 
555
    current_global_counters.max_used_connections= static_cast<uint64_t>(connection_count);
569
556
  }
570
557
 
571
558
  current_global_counters.connections++;
603
590
/*
604
591
  Is this session viewable by the current user?
605
592
*/
606
 
bool Session::isViewable() const
 
593
bool Session::isViewable(identifier::User::const_reference user_arg) const
607
594
{
608
 
  return plugin::Authorization::isAuthorized(current_session->getSecurityContext(),
609
 
                                             this,
610
 
                                             false);
 
595
  return plugin::Authorization::isAuthorized(user_arg, *this, false);
611
596
}
612
597
 
613
598
 
638
623
 
639
624
bool Session::authenticate()
640
625
{
641
 
  lex->start(this);
642
626
  if (client->authenticate())
643
627
    return false;
644
628
 
651
635
                        const std::string &in_db)
652
636
{
653
637
  bool is_authenticated=
654
 
    plugin::Authentication::isAuthenticated(getSecurityContext(),
655
 
                                            passwd_str);
 
638
    plugin::Authentication::isAuthenticated(*user(), passwd_str);
656
639
 
657
640
  if (is_authenticated != true)
658
641
  {
664
647
  /* Change database if necessary */
665
648
  if (not in_db.empty())
666
649
  {
667
 
    SchemaIdentifier identifier(in_db);
668
 
    if (mysql_change_db(this, identifier))
 
650
    identifier::Schema identifier(in_db);
 
651
    if (schema::change(*this, identifier))
669
652
    {
670
 
      /* mysql_change_db() has pushed the error message. */
 
653
      /* change_db() has pushed the error message. */
671
654
      return false;
672
655
    }
673
656
  }
735
718
    plugin::QueryRewriter::rewriteQuery(*_schema, *new_query);
736
719
  }
737
720
  query.reset(new_query);
738
 
  _state.reset(new State(in_packet, in_packet_length));
 
721
  _state.reset(new session::State(in_packet, in_packet_length));
739
722
 
740
723
  return true;
741
724
}
760
743
       * (Which of course should never happen...)
761
744
       */
762
745
      server_status&= ~SERVER_STATUS_IN_TRANS;
763
 
      if (transaction_services.commitTransaction(this, true))
 
746
      if (transaction_services.commitTransaction(*this, true))
764
747
        result= false;
765
748
      options&= ~(OPTION_BEGIN);
766
749
      break;
777
760
    case ROLLBACK_AND_CHAIN:
778
761
    {
779
762
      server_status&= ~SERVER_STATUS_IN_TRANS;
780
 
      if (transaction_services.rollbackTransaction(this, true))
 
763
      if (transaction_services.rollbackTransaction(*this, true))
781
764
        result= false;
782
765
      options&= ~(OPTION_BEGIN);
783
766
      if (result == true && (completion == ROLLBACK_AND_CHAIN))
791
774
 
792
775
  if (result == false)
793
776
  {
794
 
    my_error(killed_errno(), MYF(0));
 
777
    my_error(static_cast<drizzled::error_t>(killed_errno()), MYF(0));
795
778
  }
796
779
  else if ((result == true) && do_release)
797
780
  {
814
797
  if (options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
815
798
  {
816
799
    server_status&= ~SERVER_STATUS_IN_TRANS;
817
 
    if (transaction_services.commitTransaction(this, true))
 
800
    if (transaction_services.commitTransaction(*this, true))
818
801
      result= false;
819
802
  }
820
803
  options&= ~(OPTION_BEGIN);
825
808
{
826
809
  bool result= true;
827
810
 
828
 
  if (! endActiveTransaction())
 
811
  assert(! inTransaction());
 
812
 
 
813
  options|= OPTION_BEGIN;
 
814
  server_status|= SERVER_STATUS_IN_TRANS;
 
815
 
 
816
  if (plugin::TransactionalStorageEngine::notifyStartTransaction(this, opt))
829
817
  {
830
818
    result= false;
831
819
  }
832
 
  else
833
 
  {
834
 
    options|= OPTION_BEGIN;
835
 
    server_status|= SERVER_STATUS_IN_TRANS;
836
 
 
837
 
    if (plugin::TransactionalStorageEngine::notifyStartTransaction(this, opt))
838
 
    {
839
 
      result= false;
840
 
    }
841
 
  }
842
820
 
843
821
  return result;
844
822
}
860
838
    first_successful_insert_id_in_cur_stmt= 0;
861
839
    substitute_null_with_insert_id= true;
862
840
  }
 
841
 
863
842
  arg_of_last_insert_id_function= false;
 
843
 
864
844
  /* Free Items that were created during this execution */
865
845
  free_items();
866
 
  /* Reset where. */
867
 
  where= Session::DEFAULT_WHERE;
 
846
 
 
847
  /* Reset _where. */
 
848
  _where= Session::DEFAULT_WHERE;
868
849
 
869
850
  /* Reset the temporary shares we built */
870
851
  for_each(temporary_shares.begin(),
895
876
                                     bool allocate_lex_string)
896
877
{
897
878
  if (allocate_lex_string)
898
 
    if (!(lex_str= (LEX_STRING *)alloc(sizeof(LEX_STRING))))
 
879
    if (!(lex_str= (LEX_STRING *)getMemRoot()->allocate(sizeof(LEX_STRING))))
899
880
      return 0;
900
881
  if (!(lex_str->str= mem_root->strmake_root(str, length)))
901
882
    return 0;
941
922
  return (result->send_fields(field_list));
942
923
}
943
924
 
944
 
void select_result::send_error(uint32_t errcode, const char *err)
 
925
void select_result::send_error(drizzled::error_t errcode, const char *err)
945
926
{
946
927
  my_message(errcode, err, MYF(0));
947
928
}
950
931
  Handling writing to file
951
932
************************************************************************/
952
933
 
953
 
void select_to_file::send_error(uint32_t errcode,const char *err)
 
934
void select_to_file::send_error(drizzled::error_t errcode,const char *err)
954
935
{
955
936
  my_message(errcode, err, MYF(0));
956
937
  if (file > 0)
1109
1090
 
1110
1091
  /* Check if there is any blobs in data */
1111
1092
  {
1112
 
    List_iterator_fast<Item> li(list);
 
1093
    List<Item>::iterator li(list.begin());
1113
1094
    Item *item;
1114
1095
    while ((item=li++))
1115
1096
    {
1174
1155
  row_count++;
1175
1156
  Item *item;
1176
1157
  uint32_t used_length=0,items_left=items.elements;
1177
 
  List_iterator_fast<Item> li(items);
 
1158
  List<Item>::iterator li(items.begin());
1178
1159
 
1179
1160
  if (my_b_write(cache,(unsigned char*) exchange->line_start->ptr(),
1180
1161
                 exchange->line_start->length()))
1363
1344
 
1364
1345
bool select_dump::send_data(List<Item> &items)
1365
1346
{
1366
 
  List_iterator_fast<Item> li(items);
 
1347
  List<Item>::iterator li(items.begin());
1367
1348
  char buff[MAX_FIELD_WIDTH];
1368
1349
  String tmp(buff,sizeof(buff),&my_charset_bin),*res;
1369
1350
  tmp.length(0);
1416
1397
    unit->offset_limit_cnt--;
1417
1398
    return(0);
1418
1399
  }
1419
 
  List_iterator_fast<Item> li(items);
 
1400
  List<Item>::iterator li(items.begin());
1420
1401
  Item *val_item;
1421
1402
  for (uint32_t i= 0; (val_item= li++); i++)
1422
1403
    it->store(i, val_item);
1434
1415
bool select_max_min_finder_subselect::send_data(List<Item> &items)
1435
1416
{
1436
1417
  Item_maxmin_subselect *it= (Item_maxmin_subselect *)item;
1437
 
  List_iterator_fast<Item> li(items);
 
1418
  List<Item>::iterator li(items.begin());
1438
1419
  Item *val_item= li++;
1439
1420
  it->register_value();
1440
1421
  if (it->assigned())
1504
1485
bool select_max_min_finder_subselect::cmp_decimal()
1505
1486
{
1506
1487
  Item *maxmin= ((Item_singlerow_subselect *)item)->element_index(0);
1507
 
  my_decimal cval, *cvalue= cache->val_decimal(&cval);
1508
 
  my_decimal mval, *mvalue= maxmin->val_decimal(&mval);
 
1488
  type::Decimal cval, *cvalue= cache->val_decimal(&cval);
 
1489
  type::Decimal mval, *mvalue= maxmin->val_decimal(&mval);
1509
1490
  if (fmax)
1510
1491
    return (cache->null_value && !maxmin->null_value) ||
1511
1492
      (!cache->null_value && !maxmin->null_value &&
1512
 
       my_decimal_cmp(cvalue, mvalue) > 0) ;
 
1493
       class_decimal_cmp(cvalue, mvalue) > 0) ;
1513
1494
  return (maxmin->null_value && !cache->null_value) ||
1514
1495
    (!cache->null_value && !maxmin->null_value &&
1515
 
     my_decimal_cmp(cvalue,mvalue) < 0);
 
1496
     class_decimal_cmp(cvalue,mvalue) < 0);
1516
1497
}
1517
1498
 
1518
1499
bool select_max_min_finder_subselect::cmp_str()
1598
1579
  /* Fix for Intel compiler */
1599
1580
  if (copy_field)
1600
1581
  {
1601
 
    delete [] copy_field;
1602
 
    save_copy_field= copy_field= 0;
 
1582
    boost::checked_array_delete(copy_field);
 
1583
    save_copy_field= save_copy_field_end= copy_field= copy_field_end= 0;
1603
1584
  }
1604
1585
}
1605
1586
 
1606
1587
void Session::send_kill_message() const
1607
1588
{
1608
 
  int err= killed_errno();
1609
 
  if (err)
 
1589
  drizzled::error_t err= static_cast<drizzled::error_t>(killed_errno());
 
1590
  if (err != EE_OK)
1610
1591
    my_message(err, ER(err), MYF(0));
1611
1592
}
1612
1593
 
1636
1617
  @param  session   Thread handle
1637
1618
  @param  all   true <=> rollback main transaction.
1638
1619
*/
1639
 
void mark_transaction_to_rollback(Session *session, bool all)
 
1620
void Session::markTransactionForRollback(bool all)
1640
1621
{
1641
 
  if (session)
1642
 
  {
1643
 
    session->is_fatal_sub_stmt_error= true;
1644
 
    session->transaction_rollback_request= all;
1645
 
  }
 
1622
  is_fatal_sub_stmt_error= true;
 
1623
  transaction_rollback_request= all;
1646
1624
}
1647
1625
 
1648
 
void Session::disconnect(uint32_t errcode, bool should_lock)
 
1626
void Session::disconnect(enum error_t errcode)
1649
1627
{
1650
1628
  /* Allow any plugins to cleanup their session variables */
1651
1629
  plugin_sessionvar_cleanup(this);
1660
1638
  {
1661
1639
    if (not getKilled() && variables.log_warnings > 1)
1662
1640
    {
1663
 
      SecurityContext *sctx= &security_ctx;
1664
 
 
1665
 
      errmsg_printf(ERRMSG_LVL_WARN, ER(ER_NEW_ABORTING_CONNECTION)
 
1641
      errmsg_printf(error::WARN, ER(ER_NEW_ABORTING_CONNECTION)
1666
1642
                  , thread_id
1667
1643
                  , (_schema->empty() ? "unconnected" : _schema->c_str())
1668
 
                  , sctx->getUser().empty() == false ? sctx->getUser().c_str() : "unauthenticated"
1669
 
                  , sctx->getIp().c_str()
 
1644
                  , security_ctx->username().empty() == false ? security_ctx->username().c_str() : "unauthenticated"
 
1645
                  , security_ctx->address().c_str()
1670
1646
                  , (main_da.is_error() ? main_da.message() : ER(ER_UNKNOWN_ERROR)));
1671
1647
    }
1672
1648
  }
1673
1649
 
1674
 
  /* Close out our connection to the client */
1675
 
  if (should_lock)
1676
 
    session::Cache::singleton().mutex().lock();
1677
 
 
1678
1650
  setKilled(Session::KILL_CONNECTION);
1679
1651
 
1680
1652
  if (client->isConnected())
1681
1653
  {
1682
 
    if (errcode)
 
1654
    if (errcode != EE_OK)
1683
1655
    {
1684
1656
      /*my_error(errcode, ER(errcode));*/
1685
1657
      client->sendError(errcode, ER(errcode));
1686
1658
    }
1687
1659
    client->close();
1688
1660
  }
1689
 
 
1690
 
  if (should_lock)
1691
 
  {
1692
 
    session::Cache::singleton().mutex().unlock();
1693
 
  }
1694
1661
}
1695
1662
 
1696
1663
void Session::reset_for_next_command()
1781
1748
  table->free_io_cache();
1782
1749
  table->delete_table();
1783
1750
 
1784
 
  TableIdentifier identifier(table->getShare()->getSchemaName(), table->getShare()->getTableName(), table->getShare()->getPath());
 
1751
  identifier::Table identifier(table->getShare()->getSchemaName(), table->getShare()->getTableName(), table->getShare()->getPath());
1785
1752
  rm_temporary_table(table_type, identifier);
1786
1753
 
1787
 
  delete table->getMutableShare();
 
1754
  boost::checked_delete(table->getMutableShare());
1788
1755
 
1789
 
  /* This makes me sad, but we're allocating it via malloc */
1790
 
  delete table;
 
1756
  boost::checked_delete(table);
1791
1757
}
1792
1758
 
1793
1759
/** Clear most status variables. */
1810
1776
 
1811
1777
user_var_entry *Session::getVariable(const std::string  &name, bool create_if_not_exists)
1812
1778
{
1813
 
  UserVarsRange ppp= user_vars.equal_range(name);
 
1779
  if (cleanup_done)
 
1780
    return NULL;
1814
1781
 
1815
 
  for (UserVars::iterator iter= ppp.first;
1816
 
       iter != ppp.second; ++iter)
1817
 
  {
 
1782
  UserVars::iterator iter= user_vars.find(name);
 
1783
  if (iter != user_vars.end())
1818
1784
    return (*iter).second;
1819
 
  }
1820
1785
 
1821
1786
  if (not create_if_not_exists)
1822
1787
    return NULL;
1831
1796
 
1832
1797
  if (not returnable.second)
1833
1798
  {
1834
 
    delete entry;
 
1799
    boost::checked_delete(entry);
1835
1800
  }
1836
1801
 
1837
1802
  return entry;
1840
1805
void Session::setVariable(const std::string &name, const std::string &value)
1841
1806
{
1842
1807
  user_var_entry *updateable_var= getVariable(name.c_str(), true);
1843
 
 
1844
 
  updateable_var->update_hash(false,
1845
 
                              (void*)value.c_str(),
1846
 
                              static_cast<uint32_t>(value.length()), STRING_RESULT,
1847
 
                              &my_charset_bin,
1848
 
                              DERIVATION_IMPLICIT, false);
 
1808
  if (updateable_var)
 
1809
  {
 
1810
    updateable_var->update_hash(false,
 
1811
                                (void*)value.c_str(),
 
1812
                                static_cast<uint32_t>(value.length()), STRING_RESULT,
 
1813
                                &my_charset_bin,
 
1814
                                DERIVATION_IMPLICIT, false);
 
1815
  }
1849
1816
}
1850
1817
 
1851
1818
void Open_tables_state::mark_temp_tables_as_free_for_reuse()
1900
1867
  {
1901
1868
    TransactionServices &transaction_services= TransactionServices::singleton();
1902
1869
    main_da.can_overwrite_status= true;
1903
 
    transaction_services.autocommitOrRollback(this, is_error());
 
1870
    transaction_services.autocommitOrRollback(*this, is_error());
1904
1871
    main_da.can_overwrite_status= false;
1905
1872
    transaction.stmt.reset();
1906
1873
  }
1922
1889
  /*
1923
1890
    Note that we need to hold table::Cache::singleton().mutex() while changing the
1924
1891
    open_tables list. Another thread may work on it.
1925
 
    (See: table::Cache::singleton().removeTable(), mysql_wait_completed_table())
 
1892
    (See: table::Cache::singleton().removeTable(), wait_completed_table())
1926
1893
    Closing a MERGE child before the parent would be fatal if the
1927
1894
    other thread tries to abort the MERGE lock in between.
1928
1895
  */
1956
1923
 
1957
1924
    if (not lock_tables(tables, counter, &need_reopen))
1958
1925
      break;
 
1926
 
1959
1927
    if (not need_reopen)
1960
1928
      return true;
 
1929
 
1961
1930
    close_tables_for_reopen(&tables);
1962
1931
  }
1963
 
  if ((mysql_handle_derived(lex, &mysql_derived_prepare) ||
1964
 
       (
1965
 
        mysql_handle_derived(lex, &mysql_derived_filling))))
 
1932
 
 
1933
  if ((handle_derived(lex, &derived_prepare) || (handle_derived(lex, &derived_filling))))
1966
1934
    return true;
1967
1935
 
1968
1936
  return false;
1974
1942
  might be an issue (lame engines).
1975
1943
*/
1976
1944
 
1977
 
bool Open_tables_state::rm_temporary_table(const TableIdentifier &identifier, bool best_effort)
 
1945
bool Open_tables_state::rm_temporary_table(const identifier::Table &identifier, bool best_effort)
1978
1946
{
1979
 
  if (plugin::StorageEngine::dropTable(*static_cast<Session *>(this), identifier))
 
1947
  if (not plugin::StorageEngine::dropTable(*static_cast<Session *>(this), identifier))
1980
1948
  {
1981
1949
    if (not best_effort)
1982
1950
    {
1983
1951
      std::string path;
1984
1952
      identifier.getSQLPath(path);
1985
 
      errmsg_printf(ERRMSG_LVL_WARN, _("Could not remove temporary table: '%s', error: %d"),
 
1953
      errmsg_printf(error::WARN, _("Could not remove temporary table: '%s', error: %d"),
1986
1954
                    path.c_str(), errno);
1987
1955
    }
1988
1956
 
1992
1960
  return false;
1993
1961
}
1994
1962
 
1995
 
bool Open_tables_state::rm_temporary_table(plugin::StorageEngine *base, const TableIdentifier &identifier)
 
1963
bool Open_tables_state::rm_temporary_table(plugin::StorageEngine *base, const identifier::Table &identifier)
1996
1964
{
 
1965
  drizzled::error_t error;
1997
1966
  assert(base);
1998
1967
 
1999
 
  if (plugin::StorageEngine::dropTable(*static_cast<Session *>(this), *base, identifier))
 
1968
  if (not plugin::StorageEngine::dropTable(*static_cast<Session *>(this), *base, identifier, error))
2000
1969
  {
2001
1970
    std::string path;
2002
1971
    identifier.getSQLPath(path);
2003
 
    errmsg_printf(ERRMSG_LVL_WARN, _("Could not remove temporary table: '%s', error: %d"),
2004
 
                  path.c_str(), errno);
 
1972
    errmsg_printf(error::WARN, _("Could not remove temporary table: '%s', error: %d"),
 
1973
                  path.c_str(), error);
2005
1974
 
2006
1975
    return true;
2007
1976
  }
2025
1994
  {
2026
1995
    bool have_proto= false;
2027
1996
 
2028
 
    message::Table *proto= table->getShare()->getTableProto();
2029
 
    if (table->getShare()->getTableProto())
 
1997
    message::Table *proto= table->getShare()->getTableMessage();
 
1998
    if (table->getShare()->getTableMessage())
2030
1999
      have_proto= true;
2031
2000
 
2032
2001
    const char *answer= have_proto ? "true" : "false";
2043
2012
  }
2044
2013
}
2045
2014
 
2046
 
bool Session::TableMessages::storeTableMessage(const TableIdentifier &identifier, message::Table &table_message)
2047
 
{
2048
 
  table_message_cache.insert(make_pair(identifier.getPath(), table_message));
2049
 
 
2050
 
  return true;
2051
 
}
2052
 
 
2053
 
bool Session::TableMessages::removeTableMessage(const TableIdentifier &identifier)
2054
 
{
2055
 
  TableMessageCache::iterator iter;
2056
 
 
2057
 
  iter= table_message_cache.find(identifier.getPath());
2058
 
 
2059
 
  if (iter == table_message_cache.end())
2060
 
    return false;
2061
 
 
2062
 
  table_message_cache.erase(iter);
2063
 
 
2064
 
  return true;
2065
 
}
2066
 
 
2067
 
bool Session::TableMessages::getTableMessage(const TableIdentifier &identifier, message::Table &table_message)
2068
 
{
2069
 
  TableMessageCache::iterator iter;
2070
 
 
2071
 
  iter= table_message_cache.find(identifier.getPath());
2072
 
 
2073
 
  if (iter == table_message_cache.end())
2074
 
    return false;
2075
 
 
2076
 
  table_message.CopyFrom(((*iter).second));
2077
 
 
2078
 
  return true;
2079
 
}
2080
 
 
2081
 
bool Session::TableMessages::doesTableMessageExist(const TableIdentifier &identifier)
2082
 
{
2083
 
  TableMessageCache::iterator iter;
2084
 
 
2085
 
  iter= table_message_cache.find(identifier.getPath());
2086
 
 
2087
 
  if (iter == table_message_cache.end())
2088
 
  {
2089
 
    return false;
2090
 
  }
2091
 
 
2092
 
  return true;
2093
 
}
2094
 
 
2095
 
bool Session::TableMessages::renameTableMessage(const TableIdentifier &from, const TableIdentifier &to)
2096
 
{
2097
 
  TableMessageCache::iterator iter;
2098
 
 
2099
 
  table_message_cache[to.getPath()]= table_message_cache[from.getPath()];
2100
 
 
2101
 
  iter= table_message_cache.find(to.getPath());
2102
 
 
2103
 
  if (iter == table_message_cache.end())
2104
 
  {
2105
 
    return false;
2106
 
  }
2107
 
 
2108
 
  (*iter).second.set_schema(to.getSchemaName());
2109
 
  (*iter).second.set_name(to.getTableName());
2110
 
 
2111
 
  return true;
2112
 
}
2113
 
 
2114
 
table::Instance *Session::getInstanceTable()
2115
 
{
2116
 
  temporary_shares.push_back(new table::Instance()); // This will not go into the tableshare cache, so no key is used.
2117
 
 
2118
 
  table::Instance *tmp_share= temporary_shares.back();
 
2015
table::Singular *Session::getInstanceTable()
 
2016
{
 
2017
  temporary_shares.push_back(new table::Singular()); // This will not go into the tableshare cache, so no key is used.
 
2018
 
 
2019
  table::Singular *tmp_share= temporary_shares.back();
2119
2020
 
2120
2021
  assert(tmp_share);
2121
2022
 
2141
2042
  @return
2142
2043
    0 if out of memory, Table object in case of success
2143
2044
*/
2144
 
table::Instance *Session::getInstanceTable(List<CreateField> &field_list)
 
2045
table::Singular *Session::getInstanceTable(List<CreateField> &field_list)
2145
2046
{
2146
 
  temporary_shares.push_back(new table::Instance(this, field_list)); // This will not go into the tableshare cache, so no key is used.
 
2047
  temporary_shares.push_back(new table::Singular(this, field_list)); // This will not go into the tableshare cache, so no key is used.
2147
2048
 
2148
 
  table::Instance *tmp_share= temporary_shares.back();
 
2049
  table::Singular *tmp_share= temporary_shares.back();
2149
2050
 
2150
2051
  assert(tmp_share);
2151
2052