~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/session.cc

  • Committer: Brian Aker
  • Date: 2010-12-04 03:02:43 UTC
  • mto: This revision was merged to the branch mainline in revision 1973.
  • Revision ID: brian@tangent.org-20101204030243-febgthqec5rxus47
Did a grep for _if(

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, Inc.
 
4
 *  Copyright (C) 2008 Sun Microsystems
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
 
 
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
 
 
 
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/probes.h"
 
45
#include "drizzled/table_proto.h"
 
46
#include "drizzled/db.h"
 
47
#include "drizzled/pthread_globals.h"
 
48
#include "drizzled/transaction_services.h"
 
49
#include "drizzled/drizzled.h"
 
50
 
 
51
#include "drizzled/table/instance.h"
 
52
 
 
53
#include "plugin/myisam/myisam.h"
 
54
#include "drizzled/internal/iocache.h"
 
55
#include "drizzled/internal/thread_var.h"
 
56
#include "drizzled/plugin/event_observer.h"
 
57
 
 
58
#include "drizzled/util/functors.h"
 
59
 
 
60
#include "drizzled/display.h"
 
61
 
 
62
#include <fcntl.h>
71
63
#include <algorithm>
72
64
#include <climits>
73
 
#include <fcntl.h>
74
 
#include <sys/stat.h>
75
 
 
76
65
#include <boost/filesystem.hpp>
77
 
#include <boost/checked_delete.hpp>
78
 
 
79
 
#include <drizzled/util/backtrace.h>
80
 
 
81
 
#include <drizzled/schema.h>
 
66
 
 
67
#include "drizzled/util/backtrace.h"
82
68
 
83
69
using namespace std;
84
70
 
99
85
{
100
86
  return length == other.length &&
101
87
         field_name.length == other.field_name.length &&
102
 
    !my_strcasecmp(system_charset_info, field_name.str, other.field_name.str);
 
88
         !strcmp(field_name.str, other.field_name.str);
103
89
}
104
90
 
105
91
Open_tables_state::Open_tables_state(uint64_t version_arg) :
112
98
/*
113
99
  The following functions form part of the C plugin API
114
100
*/
115
 
int tmpfile(const char *prefix)
 
101
int mysql_tmpfile(const char *prefix)
116
102
{
117
103
  char filename[FN_REFLEN];
118
104
  int fd = internal::create_temp_file(filename, drizzle_tmpdir.c_str(), prefix, MYF(MY_WME));
123
109
  return fd;
124
110
}
125
111
 
 
112
int session_tablespace_op(const Session *session)
 
113
{
 
114
  return test(session->tablespace_op);
 
115
}
 
116
 
 
117
/**
 
118
   Set the process info field of the Session structure.
 
119
 
 
120
   This function is used by plug-ins. Internally, the
 
121
   Session::set_proc_info() function should be used.
 
122
 
 
123
   @see Session::set_proc_info
 
124
 */
 
125
void set_session_proc_info(Session *session, const char *info)
 
126
{
 
127
  session->set_proc_info(info);
 
128
}
 
129
 
 
130
const char *get_session_proc_info(Session *session)
 
131
{
 
132
  return session->get_proc_info();
 
133
}
 
134
 
126
135
void **Session::getEngineData(const plugin::MonitoredInTransaction *monitored)
127
136
{
128
137
  return static_cast<void **>(&ha_data[monitored->getId()].ha_ptr);
139
148
  return session->options & test_options;
140
149
}
141
150
 
142
 
Session::Session(plugin::Client *client_arg, catalog::Instance::shared_ptr catalog_arg) :
 
151
int session_sql_command(const Session *session)
 
152
{
 
153
  return (int) session->lex->sql_command;
 
154
}
 
155
 
 
156
enum_tx_isolation session_tx_isolation(const Session *session)
 
157
{
 
158
  return (enum_tx_isolation)session->variables.tx_isolation;
 
159
}
 
160
 
 
161
Session::Session(plugin::Client *client_arg) :
143
162
  Open_tables_state(refresh_version),
144
163
  mem_root(&main_mem_root),
145
164
  xa_id(0),
146
165
  lex(&main_lex),
147
166
  query(new std::string),
148
 
  _schema(new std::string("")),
 
167
  catalog("LOCAL"),
149
168
  client(client_arg),
150
169
  scheduler(NULL),
151
170
  scheduler_arg(NULL),
152
171
  lock_id(&main_lock_id),
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),
 
172
  user_time(0),
163
173
  ha_data(plugin::num_trx_monitored_objects),
164
 
  query_id(0),
165
 
  warn_query_id(0),
166
174
  concurrent_execute_allowed(true),
167
175
  arg_of_last_insert_id_function(false),
168
176
  first_successful_insert_id_in_prev_stmt(0),
169
177
  first_successful_insert_id_in_cur_stmt(0),
170
178
  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),
182
179
  _global_read_lock(NONE),
183
 
  count_cuted_fields(CHECK_FIELD_ERROR_FOR_NULL),
184
180
  _killed(NOT_KILLED),
185
181
  some_tables_deleted(false),
186
182
  no_errors(false),
188
184
  is_fatal_error(false),
189
185
  transaction_rollback_request(false),
190
186
  is_fatal_sub_stmt_error(0),
 
187
  derived_tables_processing(false),
191
188
  tablespace_op(false),
192
 
  derived_tables_processing(false),
193
189
  m_lip(NULL),
194
190
  cached_table(0),
195
191
  transaction_message(NULL),
196
192
  statement_message(NULL),
197
193
  session_event_observers(NULL),
198
 
  _catalog(catalog_arg),
199
194
  use_usage(false)
200
195
{
201
196
  client->setSession(this);
206
201
    will be re-initialized in init_for_queries().
207
202
  */
208
203
  memory::init_sql_alloc(&main_mem_root, memory::ROOT_MIN_BLOCK_SIZE, 0);
 
204
  thread_stack= NULL;
 
205
  count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;
 
206
  col_access= 0;
 
207
  tmp_table= 0;
 
208
  used_tables= 0;
209
209
  cuted_fields= sent_row_count= row_count= 0L;
 
210
  row_count_func= -1;
 
211
  statement_id_counter= 0UL;
210
212
  // Must be reset to handle error with Session's created for init of mysqld
211
213
  lex->current_select= 0;
 
214
  start_time=(time_t) 0;
 
215
  start_utime= 0L;
 
216
  utime_after_lock= 0L;
212
217
  memset(&variables, 0, sizeof(variables));
 
218
  thread_id= 0;
 
219
  file_id = 0;
 
220
  query_id= 0;
 
221
  warn_query_id= 0;
 
222
  mysys_var= 0;
213
223
  scoreboard_index= -1;
 
224
  dbug_sentry=Session_SENTRY_MAGIC;
214
225
  cleanup_done= abort_on_warning= no_warnings_for_error= false;  
215
226
 
216
227
  /* query_cache init */
219
230
 
220
231
  /* Variables with default values */
221
232
  proc_info="login";
 
233
  where= Session::DEFAULT_WHERE;
 
234
  command= COM_CONNECT;
222
235
 
223
236
  plugin_sessionvar_init(this);
224
237
  /*
228
241
  */
229
242
  variables.pseudo_thread_id= thread_id;
230
243
  server_status= SERVER_STATUS_AUTOCOMMIT;
 
244
  options= session_startup_options;
231
245
 
232
246
  if (variables.max_join_size == HA_POS_ERROR)
233
247
    options |= OPTION_BIG_SELECTS;
237
251
  open_options=ha_open_options;
238
252
  update_lock_default= TL_WRITE;
239
253
  session_tx_isolation= (enum_tx_isolation) variables.tx_isolation;
240
 
  warn_list.clear();
 
254
  warn_list.empty();
241
255
  memset(warn_count, 0, sizeof(warn_count));
 
256
  total_warn_count= 0;
242
257
  memset(&status_var, 0, sizeof(status_var));
243
258
 
244
259
  /* Initialize sub structures */
274
289
  m_internal_handler= handler;
275
290
}
276
291
 
277
 
bool Session::handle_error(drizzled::error_t sql_errno, const char *message,
278
 
                           DRIZZLE_ERROR::enum_warning_level level)
 
292
bool Session::handle_error(uint32_t sql_errno, const char *message,
 
293
                       DRIZZLE_ERROR::enum_warning_level level)
279
294
{
280
295
  if (m_internal_handler)
281
296
  {
311
326
  m_internal_handler= NULL;
312
327
}
313
328
 
314
 
void Session::get_xid(DrizzleXid *xid)
 
329
void Session::get_xid(DRIZZLE_XID *xid)
315
330
{
316
 
  *xid = *(DrizzleXid *) &transaction.xid_state.xid;
 
331
  *xid = *(DRIZZLE_XID *) &transaction.xid_state.xid;
317
332
}
318
333
 
319
334
/* Do operations that may take a long time */
331
346
#endif
332
347
  {
333
348
    TransactionServices &transaction_services= TransactionServices::singleton();
334
 
    transaction_services.rollbackTransaction(*this, true);
 
349
    transaction_services.rollbackTransaction(this, true);
335
350
    xid_cache_delete(&transaction.xid_state);
336
351
  }
337
352
 
340
355
       iter++)
341
356
  {
342
357
    user_var_entry *entry= (*iter).second;
343
 
    boost::checked_delete(entry);
 
358
    delete entry;
344
359
  }
345
360
  user_vars.clear();
346
361
 
359
374
{
360
375
  this->checkSentry();
361
376
 
362
 
  if (client and client->isConnected())
 
377
  if (client->isConnected())
363
378
  {
364
 
    assert(security_ctx);
365
379
    if (global_system_variables.log_warnings)
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();
 
380
        errmsg_printf(ERRMSG_LVL_WARN, ER(ER_FORCING_CLOSE),internal::my_progname,
 
381
                      thread_id,
 
382
                      (getSecurityContext().getUser().c_str() ?
 
383
                       getSecurityContext().getUser().c_str() : ""));
 
384
    disconnect(0, false);
374
385
  }
375
386
 
376
387
  /* Close connection */
377
 
  if (client)
378
 
  {
379
 
    client->close();
380
 
    boost::checked_delete(client);
381
 
    client= NULL;
382
 
  }
 
388
  client->close();
 
389
  delete client;
383
390
 
384
391
  if (cleanup_done == false)
385
392
    cleanup();
397
404
 
398
405
  plugin::Logging::postEndDo(this);
399
406
  plugin::EventObserver::deregisterSessionEvents(*this); 
 
407
 
 
408
  for (PropertyMap::iterator iter= life_properties.begin(); iter != life_properties.end(); iter++)
 
409
  {
 
410
    delete (*iter).second;
 
411
  }
 
412
  life_properties.clear();
400
413
}
401
414
 
402
415
void Session::setClient(plugin::Client *client_arg)
407
420
 
408
421
void Session::awake(Session::killed_state_t state_to_set)
409
422
{
410
 
  if ((state_to_set == Session::KILL_QUERY) and (command == COM_SLEEP))
411
 
    return;
412
 
 
413
423
  this->checkSentry();
414
424
 
415
425
  setKilled(state_to_set);
515
525
{
516
526
  if (storeGlobals())
517
527
  {
518
 
    disconnect(ER_OUT_OF_RESOURCES);
 
528
    disconnect(ER_OUT_OF_RESOURCES, true);
519
529
    status_var.aborted_connects++;
520
530
    return true;
521
531
  }
526
536
{
527
537
  if (initGlobals() || authenticate())
528
538
  {
529
 
    disconnect();
 
539
    disconnect(0, true);
530
540
    return;
531
541
  }
532
542
 
538
548
      break;
539
549
  }
540
550
 
541
 
  disconnect();
 
551
  disconnect(0, true);
542
552
}
543
553
 
544
554
bool Session::schedule(Session::shared_ptr &arg)
546
556
  arg->scheduler= plugin::Scheduler::getScheduler();
547
557
  assert(arg->scheduler);
548
558
 
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)
 
559
  connection_count.increment();
 
560
 
 
561
  if (connection_count > current_global_counters.max_used_connections)
554
562
  {
555
 
    current_global_counters.max_used_connections= static_cast<uint64_t>(connection_count);
 
563
    current_global_counters.max_used_connections= connection_count;
556
564
  }
557
565
 
558
566
  current_global_counters.connections++;
590
598
/*
591
599
  Is this session viewable by the current user?
592
600
*/
593
 
bool Session::isViewable(identifier::User::const_reference user_arg) const
 
601
bool Session::isViewable() const
594
602
{
595
 
  return plugin::Authorization::isAuthorized(user_arg, *this, false);
 
603
  return plugin::Authorization::isAuthorized(current_session->getSecurityContext(),
 
604
                                             this,
 
605
                                             false);
596
606
}
597
607
 
598
608
 
623
633
 
624
634
bool Session::authenticate()
625
635
{
 
636
  lex->start(this);
626
637
  if (client->authenticate())
627
638
    return false;
628
639
 
635
646
                        const std::string &in_db)
636
647
{
637
648
  bool is_authenticated=
638
 
    plugin::Authentication::isAuthenticated(*user(), passwd_str);
 
649
    plugin::Authentication::isAuthenticated(getSecurityContext(),
 
650
                                            passwd_str);
639
651
 
640
652
  if (is_authenticated != true)
641
653
  {
647
659
  /* Change database if necessary */
648
660
  if (not in_db.empty())
649
661
  {
650
 
    identifier::Schema identifier(in_db);
651
 
    if (schema::change(*this, identifier))
 
662
    SchemaIdentifier identifier(in_db);
 
663
    if (mysql_change_db(this, identifier))
652
664
    {
653
 
      /* change_db() has pushed the error message. */
 
665
      /* mysql_change_db() has pushed the error message. */
654
666
      return false;
655
667
    }
656
668
  }
711
723
    in_packet_length--;
712
724
  }
713
725
 
714
 
  std::string *new_query= new std::string(in_packet, in_packet + in_packet_length);
715
 
  // We can not be entirely sure _schema has a value
716
 
  if (_schema)
717
 
  {
718
 
    plugin::QueryRewriter::rewriteQuery(*_schema, *new_query);
719
 
  }
720
 
  query.reset(new_query);
721
 
  _state.reset(new session::State(in_packet, in_packet_length));
 
726
  query.reset(new std::string(in_packet, in_packet + in_packet_length));
722
727
 
723
728
  return true;
724
729
}
743
748
       * (Which of course should never happen...)
744
749
       */
745
750
      server_status&= ~SERVER_STATUS_IN_TRANS;
746
 
      if (transaction_services.commitTransaction(*this, true))
 
751
      if (transaction_services.commitTransaction(this, true))
747
752
        result= false;
748
753
      options&= ~(OPTION_BEGIN);
749
754
      break;
760
765
    case ROLLBACK_AND_CHAIN:
761
766
    {
762
767
      server_status&= ~SERVER_STATUS_IN_TRANS;
763
 
      if (transaction_services.rollbackTransaction(*this, true))
 
768
      if (transaction_services.rollbackTransaction(this, true))
764
769
        result= false;
765
770
      options&= ~(OPTION_BEGIN);
766
771
      if (result == true && (completion == ROLLBACK_AND_CHAIN))
774
779
 
775
780
  if (result == false)
776
781
  {
777
 
    my_error(static_cast<drizzled::error_t>(killed_errno()), MYF(0));
 
782
    my_error(killed_errno(), MYF(0));
778
783
  }
779
784
  else if ((result == true) && do_release)
780
785
  {
797
802
  if (options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
798
803
  {
799
804
    server_status&= ~SERVER_STATUS_IN_TRANS;
800
 
    if (transaction_services.commitTransaction(*this, true))
 
805
    if (transaction_services.commitTransaction(this, true))
801
806
      result= false;
802
807
  }
803
808
  options&= ~(OPTION_BEGIN);
808
813
{
809
814
  bool result= true;
810
815
 
811
 
  assert(! inTransaction());
812
 
 
813
 
  options|= OPTION_BEGIN;
814
 
  server_status|= SERVER_STATUS_IN_TRANS;
815
 
 
816
 
  if (plugin::TransactionalStorageEngine::notifyStartTransaction(this, opt))
 
816
  if (! endActiveTransaction())
817
817
  {
818
818
    result= false;
819
819
  }
 
820
  else
 
821
  {
 
822
    options|= OPTION_BEGIN;
 
823
    server_status|= SERVER_STATUS_IN_TRANS;
 
824
 
 
825
    if (plugin::TransactionalStorageEngine::notifyStartTransaction(this, opt))
 
826
    {
 
827
      result= false;
 
828
    }
 
829
  }
820
830
 
821
831
  return result;
822
832
}
838
848
    first_successful_insert_id_in_cur_stmt= 0;
839
849
    substitute_null_with_insert_id= true;
840
850
  }
841
 
 
842
851
  arg_of_last_insert_id_function= false;
843
 
 
844
852
  /* Free Items that were created during this execution */
845
853
  free_items();
846
 
 
847
 
  /* Reset _where. */
848
 
  _where= Session::DEFAULT_WHERE;
 
854
  /* Reset where. */
 
855
  where= Session::DEFAULT_WHERE;
849
856
 
850
857
  /* Reset the temporary shares we built */
851
858
  for_each(temporary_shares.begin(),
876
883
                                     bool allocate_lex_string)
877
884
{
878
885
  if (allocate_lex_string)
879
 
    if (!(lex_str= (LEX_STRING *)getMemRoot()->allocate(sizeof(LEX_STRING))))
 
886
    if (!(lex_str= (LEX_STRING *)alloc(sizeof(LEX_STRING))))
880
887
      return 0;
881
888
  if (!(lex_str->str= mem_root->strmake_root(str, length)))
882
889
    return 0;
922
929
  return (result->send_fields(field_list));
923
930
}
924
931
 
925
 
void select_result::send_error(drizzled::error_t errcode, const char *err)
 
932
void select_result::send_error(uint32_t errcode, const char *err)
926
933
{
927
934
  my_message(errcode, err, MYF(0));
928
935
}
931
938
  Handling writing to file
932
939
************************************************************************/
933
940
 
934
 
void select_to_file::send_error(drizzled::error_t errcode,const char *err)
 
941
void select_to_file::send_error(uint32_t errcode,const char *err)
935
942
{
936
943
  my_message(errcode, err, MYF(0));
937
944
  if (file > 0)
1027
1034
  if (not to_file.has_root_directory())
1028
1035
  {
1029
1036
    target_path= fs::system_complete(getDataHomeCatalog());
1030
 
    util::string::const_shared_ptr schema(session->schema());
1031
 
    if (schema and not schema->empty())
 
1037
    if (not session->db.empty())
1032
1038
    {
1033
1039
      int count_elements= 0;
1034
1040
      for (fs::path::iterator iter= to_file.begin();
1038
1044
 
1039
1045
      if (count_elements == 1)
1040
1046
      {
1041
 
        target_path /= *schema;
 
1047
        target_path /= session->db;
1042
1048
      }
1043
1049
    }
1044
1050
    target_path /= to_file;
1090
1096
 
1091
1097
  /* Check if there is any blobs in data */
1092
1098
  {
1093
 
    List<Item>::iterator li(list.begin());
 
1099
    List_iterator_fast<Item> li(list);
1094
1100
    Item *item;
1095
1101
    while ((item=li++))
1096
1102
    {
1097
1103
      if (item->max_length >= MAX_BLOB_WIDTH)
1098
1104
      {
1099
 
        blob_flag=1;
1100
 
        break;
 
1105
        blob_flag=1;
 
1106
        break;
1101
1107
      }
1102
 
 
1103
1108
      if (item->result_type() == STRING_RESULT)
1104
1109
        string_results= true;
1105
1110
      else
1155
1160
  row_count++;
1156
1161
  Item *item;
1157
1162
  uint32_t used_length=0,items_left=items.elements;
1158
 
  List<Item>::iterator li(items.begin());
 
1163
  List_iterator_fast<Item> li(items);
1159
1164
 
1160
1165
  if (my_b_write(cache,(unsigned char*) exchange->line_start->ptr(),
1161
1166
                 exchange->line_start->length()))
1344
1349
 
1345
1350
bool select_dump::send_data(List<Item> &items)
1346
1351
{
1347
 
  List<Item>::iterator li(items.begin());
 
1352
  List_iterator_fast<Item> li(items);
1348
1353
  char buff[MAX_FIELD_WIDTH];
1349
1354
  String tmp(buff,sizeof(buff),&my_charset_bin),*res;
1350
1355
  tmp.length(0);
1397
1402
    unit->offset_limit_cnt--;
1398
1403
    return(0);
1399
1404
  }
1400
 
  List<Item>::iterator li(items.begin());
 
1405
  List_iterator_fast<Item> li(items);
1401
1406
  Item *val_item;
1402
1407
  for (uint32_t i= 0; (val_item= li++); i++)
1403
1408
    it->store(i, val_item);
1415
1420
bool select_max_min_finder_subselect::send_data(List<Item> &items)
1416
1421
{
1417
1422
  Item_maxmin_subselect *it= (Item_maxmin_subselect *)item;
1418
 
  List<Item>::iterator li(items.begin());
 
1423
  List_iterator_fast<Item> li(items);
1419
1424
  Item *val_item= li++;
1420
1425
  it->register_value();
1421
1426
  if (it->assigned())
1485
1490
bool select_max_min_finder_subselect::cmp_decimal()
1486
1491
{
1487
1492
  Item *maxmin= ((Item_singlerow_subselect *)item)->element_index(0);
1488
 
  type::Decimal cval, *cvalue= cache->val_decimal(&cval);
1489
 
  type::Decimal mval, *mvalue= maxmin->val_decimal(&mval);
 
1493
  my_decimal cval, *cvalue= cache->val_decimal(&cval);
 
1494
  my_decimal mval, *mvalue= maxmin->val_decimal(&mval);
1490
1495
  if (fmax)
1491
1496
    return (cache->null_value && !maxmin->null_value) ||
1492
1497
      (!cache->null_value && !maxmin->null_value &&
1493
 
       class_decimal_cmp(cvalue, mvalue) > 0) ;
 
1498
       my_decimal_cmp(cvalue, mvalue) > 0) ;
1494
1499
  return (maxmin->null_value && !cache->null_value) ||
1495
1500
    (!cache->null_value && !maxmin->null_value &&
1496
 
     class_decimal_cmp(cvalue,mvalue) < 0);
 
1501
     my_decimal_cmp(cvalue,mvalue) < 0);
1497
1502
}
1498
1503
 
1499
1504
bool select_max_min_finder_subselect::cmp_str()
1542
1547
 
1543
1548
bool Session::copy_db_to(char **p_db, size_t *p_db_length)
1544
1549
{
1545
 
  assert(_schema);
1546
 
  if (_schema and _schema->empty())
1547
 
  {
1548
 
    my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
1549
 
    return true;
1550
 
  }
1551
 
  else if (not _schema)
1552
 
  {
1553
 
    my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
1554
 
    return true;
1555
 
  }
1556
 
  assert(_schema);
1557
 
 
1558
 
  *p_db= strmake(_schema->c_str(), _schema->size());
1559
 
  *p_db_length= _schema->size();
1560
 
 
 
1550
  if (db.empty())
 
1551
  {
 
1552
    my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
 
1553
    return true;
 
1554
  }
 
1555
  *p_db= strmake(db.c_str(), db.length());
 
1556
  *p_db_length= db.length();
1561
1557
  return false;
1562
1558
}
1563
1559
 
1579
1575
  /* Fix for Intel compiler */
1580
1576
  if (copy_field)
1581
1577
  {
1582
 
    boost::checked_array_delete(copy_field);
1583
 
    save_copy_field= save_copy_field_end= copy_field= copy_field_end= 0;
 
1578
    delete [] copy_field;
 
1579
    save_copy_field= copy_field= 0;
1584
1580
  }
1585
1581
}
1586
1582
 
1587
1583
void Session::send_kill_message() const
1588
1584
{
1589
 
  drizzled::error_t err= static_cast<drizzled::error_t>(killed_errno());
1590
 
  if (err != EE_OK)
 
1585
  int err= killed_errno();
 
1586
  if (err)
1591
1587
    my_message(err, ER(err), MYF(0));
1592
1588
}
1593
1589
 
1597
1593
}
1598
1594
 
1599
1595
 
1600
 
void Session::set_db(const std::string &new_db)
 
1596
bool Session::set_db(const std::string &new_db)
1601
1597
{
1602
1598
  /* Do not reallocate memory if current chunk is big enough. */
1603
1599
  if (new_db.length())
1604
 
  {
1605
 
    _schema.reset(new std::string(new_db));
1606
 
  }
 
1600
    db= new_db;
1607
1601
  else
1608
 
  {
1609
 
    _schema.reset(new std::string(""));
1610
 
  }
 
1602
    db.clear();
 
1603
 
 
1604
  return false;
1611
1605
}
1612
1606
 
1613
1607
 
1617
1611
  @param  session   Thread handle
1618
1612
  @param  all   true <=> rollback main transaction.
1619
1613
*/
1620
 
void Session::markTransactionForRollback(bool all)
 
1614
void mark_transaction_to_rollback(Session *session, bool all)
1621
1615
{
1622
 
  is_fatal_sub_stmt_error= true;
1623
 
  transaction_rollback_request= all;
 
1616
  if (session)
 
1617
  {
 
1618
    session->is_fatal_sub_stmt_error= true;
 
1619
    session->transaction_rollback_request= all;
 
1620
  }
1624
1621
}
1625
1622
 
1626
 
void Session::disconnect(enum error_t errcode)
 
1623
void Session::disconnect(uint32_t errcode, bool should_lock)
1627
1624
{
1628
1625
  /* Allow any plugins to cleanup their session variables */
1629
1626
  plugin_sessionvar_cleanup(this);
1638
1635
  {
1639
1636
    if (not getKilled() && variables.log_warnings > 1)
1640
1637
    {
1641
 
      errmsg_printf(error::WARN, ER(ER_NEW_ABORTING_CONNECTION)
 
1638
      SecurityContext *sctx= &security_ctx;
 
1639
 
 
1640
      errmsg_printf(ERRMSG_LVL_WARN, ER(ER_NEW_ABORTING_CONNECTION)
1642
1641
                  , thread_id
1643
 
                  , (_schema->empty() ? "unconnected" : _schema->c_str())
1644
 
                  , security_ctx->username().empty() == false ? security_ctx->username().c_str() : "unauthenticated"
1645
 
                  , security_ctx->address().c_str()
 
1642
                  , (db.empty() ? "unconnected" : db.c_str())
 
1643
                  , sctx->getUser().empty() == false ? sctx->getUser().c_str() : "unauthenticated"
 
1644
                  , sctx->getIp().c_str()
1646
1645
                  , (main_da.is_error() ? main_da.message() : ER(ER_UNKNOWN_ERROR)));
1647
1646
    }
1648
1647
  }
1649
1648
 
 
1649
  /* Close out our connection to the client */
 
1650
  if (should_lock)
 
1651
    session::Cache::singleton().mutex().lock();
 
1652
 
1650
1653
  setKilled(Session::KILL_CONNECTION);
1651
1654
 
1652
1655
  if (client->isConnected())
1653
1656
  {
1654
 
    if (errcode != EE_OK)
 
1657
    if (errcode)
1655
1658
    {
1656
1659
      /*my_error(errcode, ER(errcode));*/
1657
1660
      client->sendError(errcode, ER(errcode));
1658
1661
    }
1659
1662
    client->close();
1660
1663
  }
 
1664
 
 
1665
  if (should_lock)
 
1666
  {
 
1667
    session::Cache::singleton().mutex().unlock();
 
1668
  }
1661
1669
}
1662
1670
 
1663
1671
void Session::reset_for_next_command()
1748
1756
  table->free_io_cache();
1749
1757
  table->delete_table();
1750
1758
 
1751
 
  identifier::Table identifier(table->getShare()->getSchemaName(), table->getShare()->getTableName(), table->getShare()->getPath());
 
1759
  TableIdentifier identifier(table->getShare()->getSchemaName(), table->getShare()->getTableName(), table->getShare()->getPath());
1752
1760
  rm_temporary_table(table_type, identifier);
1753
1761
 
1754
 
  boost::checked_delete(table->getMutableShare());
 
1762
  delete table->getMutableShare();
1755
1763
 
1756
 
  boost::checked_delete(table);
 
1764
  /* This makes me sad, but we're allocating it via malloc */
 
1765
  delete table;
1757
1766
}
1758
1767
 
1759
1768
/** Clear most status variables. */
1776
1785
 
1777
1786
user_var_entry *Session::getVariable(const std::string  &name, bool create_if_not_exists)
1778
1787
{
1779
 
  if (cleanup_done)
1780
 
    return NULL;
 
1788
  UserVarsRange ppp= user_vars.equal_range(name);
1781
1789
 
1782
 
  UserVars::iterator iter= user_vars.find(name);
1783
 
  if (iter != user_vars.end())
 
1790
  for (UserVars::iterator iter= ppp.first;
 
1791
       iter != ppp.second; ++iter)
 
1792
  {
1784
1793
    return (*iter).second;
 
1794
  }
1785
1795
 
1786
1796
  if (not create_if_not_exists)
1787
1797
    return NULL;
1796
1806
 
1797
1807
  if (not returnable.second)
1798
1808
  {
1799
 
    boost::checked_delete(entry);
 
1809
    delete entry;
1800
1810
  }
1801
1811
 
1802
1812
  return entry;
1805
1815
void Session::setVariable(const std::string &name, const std::string &value)
1806
1816
{
1807
1817
  user_var_entry *updateable_var= getVariable(name.c_str(), true);
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
 
  }
 
1818
 
 
1819
  updateable_var->update_hash(false,
 
1820
                              (void*)value.c_str(),
 
1821
                              static_cast<uint32_t>(value.length()), STRING_RESULT,
 
1822
                              &my_charset_bin,
 
1823
                              DERIVATION_IMPLICIT, false);
1816
1824
}
1817
1825
 
1818
1826
void Open_tables_state::mark_temp_tables_as_free_for_reuse()
1867
1875
  {
1868
1876
    TransactionServices &transaction_services= TransactionServices::singleton();
1869
1877
    main_da.can_overwrite_status= true;
1870
 
    transaction_services.autocommitOrRollback(*this, is_error());
 
1878
    transaction_services.autocommitOrRollback(this, is_error());
1871
1879
    main_da.can_overwrite_status= false;
1872
1880
    transaction.stmt.reset();
1873
1881
  }
1889
1897
  /*
1890
1898
    Note that we need to hold table::Cache::singleton().mutex() while changing the
1891
1899
    open_tables list. Another thread may work on it.
1892
 
    (See: table::Cache::singleton().removeTable(), wait_completed_table())
 
1900
    (See: table::Cache::singleton().removeTable(), mysql_wait_completed_table())
1893
1901
    Closing a MERGE child before the parent would be fatal if the
1894
1902
    other thread tries to abort the MERGE lock in between.
1895
1903
  */
1923
1931
 
1924
1932
    if (not lock_tables(tables, counter, &need_reopen))
1925
1933
      break;
1926
 
 
1927
1934
    if (not need_reopen)
1928
1935
      return true;
1929
 
 
1930
1936
    close_tables_for_reopen(&tables);
1931
1937
  }
1932
 
 
1933
 
  if ((handle_derived(lex, &derived_prepare) || (handle_derived(lex, &derived_filling))))
 
1938
  if ((mysql_handle_derived(lex, &mysql_derived_prepare) ||
 
1939
       (
 
1940
        mysql_handle_derived(lex, &mysql_derived_filling))))
1934
1941
    return true;
1935
1942
 
1936
1943
  return false;
1942
1949
  might be an issue (lame engines).
1943
1950
*/
1944
1951
 
1945
 
bool Open_tables_state::rm_temporary_table(const identifier::Table &identifier, bool best_effort)
 
1952
bool Open_tables_state::rm_temporary_table(const TableIdentifier &identifier, bool best_effort)
1946
1953
{
1947
 
  if (not plugin::StorageEngine::dropTable(*static_cast<Session *>(this), identifier))
 
1954
  if (plugin::StorageEngine::dropTable(*static_cast<Session *>(this), identifier))
1948
1955
  {
1949
1956
    if (not best_effort)
1950
1957
    {
1951
1958
      std::string path;
1952
1959
      identifier.getSQLPath(path);
1953
 
      errmsg_printf(error::WARN, _("Could not remove temporary table: '%s', error: %d"),
 
1960
      errmsg_printf(ERRMSG_LVL_WARN, _("Could not remove temporary table: '%s', error: %d"),
1954
1961
                    path.c_str(), errno);
1955
1962
    }
1956
1963
 
1960
1967
  return false;
1961
1968
}
1962
1969
 
1963
 
bool Open_tables_state::rm_temporary_table(plugin::StorageEngine *base, const identifier::Table &identifier)
 
1970
bool Open_tables_state::rm_temporary_table(plugin::StorageEngine *base, const TableIdentifier &identifier)
1964
1971
{
1965
 
  drizzled::error_t error;
1966
1972
  assert(base);
1967
1973
 
1968
 
  if (not plugin::StorageEngine::dropTable(*static_cast<Session *>(this), *base, identifier, error))
 
1974
  if (plugin::StorageEngine::dropTable(*static_cast<Session *>(this), *base, identifier))
1969
1975
  {
1970
1976
    std::string path;
1971
1977
    identifier.getSQLPath(path);
1972
 
    errmsg_printf(error::WARN, _("Could not remove temporary table: '%s', error: %d"),
1973
 
                  path.c_str(), error);
 
1978
    errmsg_printf(ERRMSG_LVL_WARN, _("Could not remove temporary table: '%s', error: %d"),
 
1979
                  path.c_str(), errno);
1974
1980
 
1975
1981
    return true;
1976
1982
  }
1994
2000
  {
1995
2001
    bool have_proto= false;
1996
2002
 
1997
 
    message::Table *proto= table->getShare()->getTableMessage();
1998
 
    if (table->getShare()->getTableMessage())
 
2003
    message::Table *proto= table->getShare()->getTableProto();
 
2004
    if (table->getShare()->getTableProto())
1999
2005
      have_proto= true;
2000
2006
 
2001
2007
    const char *answer= have_proto ? "true" : "false";
2006
2012
      cerr << "\t\t Proto " << proto->schema() << " " << proto->name() << "\n";
2007
2013
    }
2008
2014
    else
2009
 
    {
2010
2015
      cerr << "\tTabl;e Name " << table->getShare()->getSchemaName() << "." << table->getShare()->getTableName() << " : " << answer << "\n";
2011
 
    }
2012
 
  }
2013
 
}
2014
 
 
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();
 
2016
  }
 
2017
}
 
2018
 
 
2019
bool Session::TableMessages::storeTableMessage(const TableIdentifier &identifier, message::Table &table_message)
 
2020
{
 
2021
  table_message_cache.insert(make_pair(identifier.getPath(), table_message));
 
2022
 
 
2023
  return true;
 
2024
}
 
2025
 
 
2026
bool Session::TableMessages::removeTableMessage(const TableIdentifier &identifier)
 
2027
{
 
2028
  TableMessageCache::iterator iter;
 
2029
 
 
2030
  iter= table_message_cache.find(identifier.getPath());
 
2031
 
 
2032
  if (iter == table_message_cache.end())
 
2033
    return false;
 
2034
 
 
2035
  table_message_cache.erase(iter);
 
2036
 
 
2037
  return true;
 
2038
}
 
2039
 
 
2040
bool Session::TableMessages::getTableMessage(const TableIdentifier &identifier, message::Table &table_message)
 
2041
{
 
2042
  TableMessageCache::iterator iter;
 
2043
 
 
2044
  iter= table_message_cache.find(identifier.getPath());
 
2045
 
 
2046
  if (iter == table_message_cache.end())
 
2047
    return false;
 
2048
 
 
2049
  table_message.CopyFrom(((*iter).second));
 
2050
 
 
2051
  return true;
 
2052
}
 
2053
 
 
2054
bool Session::TableMessages::doesTableMessageExist(const TableIdentifier &identifier)
 
2055
{
 
2056
  TableMessageCache::iterator iter;
 
2057
 
 
2058
  iter= table_message_cache.find(identifier.getPath());
 
2059
 
 
2060
  if (iter == table_message_cache.end())
 
2061
  {
 
2062
    return false;
 
2063
  }
 
2064
 
 
2065
  return true;
 
2066
}
 
2067
 
 
2068
bool Session::TableMessages::renameTableMessage(const TableIdentifier &from, const TableIdentifier &to)
 
2069
{
 
2070
  TableMessageCache::iterator iter;
 
2071
 
 
2072
  table_message_cache[to.getPath()]= table_message_cache[from.getPath()];
 
2073
 
 
2074
  iter= table_message_cache.find(to.getPath());
 
2075
 
 
2076
  if (iter == table_message_cache.end())
 
2077
  {
 
2078
    return false;
 
2079
  }
 
2080
 
 
2081
  (*iter).second.set_schema(to.getSchemaName());
 
2082
  (*iter).second.set_name(to.getTableName());
 
2083
 
 
2084
  return true;
 
2085
}
 
2086
 
 
2087
table::Instance *Session::getInstanceTable()
 
2088
{
 
2089
  temporary_shares.push_back(new table::Instance()); // This will not go into the tableshare cache, so no key is used.
 
2090
 
 
2091
  table::Instance *tmp_share= temporary_shares.back();
2020
2092
 
2021
2093
  assert(tmp_share);
2022
2094
 
2042
2114
  @return
2043
2115
    0 if out of memory, Table object in case of success
2044
2116
*/
2045
 
table::Singular *Session::getInstanceTable(List<CreateField> &field_list)
 
2117
table::Instance *Session::getInstanceTable(List<CreateField> &field_list)
2046
2118
{
2047
 
  temporary_shares.push_back(new table::Singular(this, field_list)); // This will not go into the tableshare cache, so no key is used.
 
2119
  temporary_shares.push_back(new table::Instance(this, field_list)); // This will not go into the tableshare cache, so no key is used.
2048
2120
 
2049
 
  table::Singular *tmp_share= temporary_shares.back();
 
2121
  table::Instance *tmp_share= temporary_shares.back();
2050
2122
 
2051
2123
  assert(tmp_share);
2052
2124