~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/session.cc

  • Committer: Brian Aker
  • Date: 2010-10-27 21:00:49 UTC
  • mto: This revision was merged to the branch mainline in revision 1886.
  • Revision ID: brian@tangent.org-20101027210049-zfpgx2cfbrh8maq9
A couple of fixes to documentation.

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
22
22
 */
23
23
 
24
24
#include "config.h"
25
 
 
26
 
#include <drizzled/copy_field.h>
27
 
#include "drizzled/session.h"
28
 
#include "drizzled/session/cache.h"
29
 
#include "drizzled/error.h"
30
 
#include "drizzled/gettext.h"
31
 
#include "drizzled/query_id.h"
32
 
#include "drizzled/data_home.h"
33
 
#include "drizzled/sql_base.h"
34
 
#include "drizzled/lock.h"
35
 
#include "drizzled/item/cache.h"
36
 
#include "drizzled/item/float.h"
37
 
#include "drizzled/item/return_int.h"
38
 
#include "drizzled/item/empty_string.h"
39
 
#include "drizzled/show.h"
40
 
#include "drizzled/plugin/client.h"
 
25
#include <drizzled/session.h>
 
26
#include "drizzled/session_list.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>
41
40
#include "drizzled/plugin/scheduler.h"
42
41
#include "drizzled/plugin/authentication.h"
43
42
#include "drizzled/plugin/logging.h"
44
43
#include "drizzled/plugin/transactional_storage_engine.h"
45
 
#include "drizzled/plugin/query_rewrite.h"
46
44
#include "drizzled/probes.h"
47
45
#include "drizzled/table_proto.h"
48
46
#include "drizzled/db.h"
50
48
#include "drizzled/transaction_services.h"
51
49
#include "drizzled/drizzled.h"
52
50
 
53
 
#include "drizzled/identifier.h"
54
 
 
55
 
#include <drizzled/refresh_version.h>
56
 
 
57
 
#include "drizzled/table/singular.h"
 
51
#include "drizzled/table/instance.h"
58
52
 
59
53
#include "plugin/myisam/myisam.h"
60
54
#include "drizzled/internal/iocache.h"
63
57
 
64
58
#include "drizzled/util/functors.h"
65
59
 
66
 
#include "drizzled/display.h"
67
 
 
 
60
#include <fcntl.h>
68
61
#include <algorithm>
69
62
#include <climits>
70
 
#include <fcntl.h>
71
 
#include <sys/stat.h>
72
 
 
73
 
#include <boost/filesystem.hpp>
74
 
#include <boost/checked_delete.hpp>
75
 
 
76
 
#include "drizzled/util/backtrace.h"
 
63
#include "boost/filesystem.hpp" 
77
64
 
78
65
using namespace std;
79
66
 
94
81
{
95
82
  return length == other.length &&
96
83
         field_name.length == other.field_name.length &&
97
 
    !my_strcasecmp(system_charset_info, field_name.str, other.field_name.str);
 
84
         !strcmp(field_name.str, other.field_name.str);
98
85
}
99
86
 
100
87
Open_tables_state::Open_tables_state(uint64_t version_arg) :
107
94
/*
108
95
  The following functions form part of the C plugin API
109
96
*/
110
 
int tmpfile(const char *prefix)
 
97
int mysql_tmpfile(const char *prefix)
111
98
{
112
99
  char filename[FN_REFLEN];
113
100
  int fd = internal::create_temp_file(filename, drizzle_tmpdir.c_str(), prefix, MYF(MY_WME));
118
105
  return fd;
119
106
}
120
107
 
 
108
int session_tablespace_op(const Session *session)
 
109
{
 
110
  return test(session->tablespace_op);
 
111
}
 
112
 
 
113
/**
 
114
   Set the process info field of the Session structure.
 
115
 
 
116
   This function is used by plug-ins. Internally, the
 
117
   Session::set_proc_info() function should be used.
 
118
 
 
119
   @see Session::set_proc_info
 
120
 */
 
121
void set_session_proc_info(Session *session, const char *info)
 
122
{
 
123
  session->set_proc_info(info);
 
124
}
 
125
 
 
126
const char *get_session_proc_info(Session *session)
 
127
{
 
128
  return session->get_proc_info();
 
129
}
 
130
 
121
131
void **Session::getEngineData(const plugin::MonitoredInTransaction *monitored)
122
132
{
123
133
  return static_cast<void **>(&ha_data[monitored->getId()].ha_ptr);
134
144
  return session->options & test_options;
135
145
}
136
146
 
137
 
Session::Session(plugin::Client *client_arg, catalog::Instance::shared_ptr catalog_arg) :
 
147
int session_sql_command(const Session *session)
 
148
{
 
149
  return (int) session->lex->sql_command;
 
150
}
 
151
 
 
152
enum_tx_isolation session_tx_isolation(const Session *session)
 
153
{
 
154
  return (enum_tx_isolation)session->variables.tx_isolation;
 
155
}
 
156
 
 
157
Session::Session(plugin::Client *client_arg) :
138
158
  Open_tables_state(refresh_version),
139
159
  mem_root(&main_mem_root),
140
 
  xa_id(0),
141
160
  lex(&main_lex),
142
 
  query(new std::string),
143
 
  _schema(new std::string("")),
 
161
  catalog("LOCAL"),
144
162
  client(client_arg),
145
163
  scheduler(NULL),
146
164
  scheduler_arg(NULL),
147
165
  lock_id(&main_lock_id),
148
 
  thread_stack(NULL),
149
 
  security_ctx(identifier::User::make_shared()),
150
 
  _where(Session::DEFAULT_WHERE),
151
 
  dbug_sentry(Session_SENTRY_MAGIC),
152
 
  mysys_var(0),
153
 
  command(COM_CONNECT),
154
 
  file_id(0),
155
 
  _epoch(boost::gregorian::date(1970,1,1)),
156
 
  _connect_time(boost::posix_time::microsec_clock::universal_time()),
157
 
  utime_after_lock(0),
 
166
  user_time(0),
158
167
  ha_data(plugin::num_trx_monitored_objects),
159
 
  query_id(0),
160
 
  warn_query_id(0),
161
 
  concurrent_execute_allowed(true),
162
168
  arg_of_last_insert_id_function(false),
163
169
  first_successful_insert_id_in_prev_stmt(0),
164
170
  first_successful_insert_id_in_cur_stmt(0),
165
171
  limit_found_rows(0),
166
 
  options(session_startup_options),
167
 
  row_count_func(-1),
168
 
  sent_row_count(0),
169
 
  examined_row_count(0),
170
 
  used_tables(0),
171
 
  total_warn_count(0),
172
 
  col_access(0),
173
 
  statement_id_counter(0),
174
 
  row_count(0),
175
 
  thread_id(0),
176
 
  tmp_table(0),
177
 
  _global_read_lock(NONE),
178
 
  count_cuted_fields(CHECK_FIELD_ERROR_FOR_NULL),
179
 
  _killed(NOT_KILLED),
 
172
  global_read_lock(0),
180
173
  some_tables_deleted(false),
181
174
  no_errors(false),
182
175
  password(false),
183
176
  is_fatal_error(false),
184
177
  transaction_rollback_request(false),
185
178
  is_fatal_sub_stmt_error(0),
 
179
  derived_tables_processing(false),
186
180
  tablespace_op(false),
187
 
  derived_tables_processing(false),
188
181
  m_lip(NULL),
189
182
  cached_table(0),
190
183
  transaction_message(NULL),
191
184
  statement_message(NULL),
192
185
  session_event_observers(NULL),
193
 
  _catalog(catalog_arg),
194
186
  use_usage(false)
195
187
{
 
188
  memset(process_list_info, 0, PROCESS_LIST_WIDTH);
196
189
  client->setSession(this);
197
190
 
198
191
  /*
201
194
    will be re-initialized in init_for_queries().
202
195
  */
203
196
  memory::init_sql_alloc(&main_mem_root, memory::ROOT_MIN_BLOCK_SIZE, 0);
 
197
  thread_stack= NULL;
 
198
  count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;
 
199
  killed= NOT_KILLED;
 
200
  col_access= 0;
 
201
  tmp_table= 0;
 
202
  used_tables= 0;
204
203
  cuted_fields= sent_row_count= row_count= 0L;
 
204
  row_count_func= -1;
 
205
  statement_id_counter= 0UL;
205
206
  // Must be reset to handle error with Session's created for init of mysqld
206
207
  lex->current_select= 0;
 
208
  start_time=(time_t) 0;
 
209
  start_utime= 0L;
 
210
  utime_after_lock= 0L;
207
211
  memset(&variables, 0, sizeof(variables));
 
212
  thread_id= 0;
 
213
  file_id = 0;
 
214
  query_id= 0;
 
215
  warn_query_id= 0;
 
216
  mysys_var= 0;
208
217
  scoreboard_index= -1;
 
218
  dbug_sentry=Session_SENTRY_MAGIC;
209
219
  cleanup_done= abort_on_warning= no_warnings_for_error= false;  
210
220
 
211
221
  /* query_cache init */
214
224
 
215
225
  /* Variables with default values */
216
226
  proc_info="login";
 
227
  where= Session::DEFAULT_WHERE;
 
228
  command= COM_CONNECT;
217
229
 
218
230
  plugin_sessionvar_init(this);
219
231
  /*
223
235
  */
224
236
  variables.pseudo_thread_id= thread_id;
225
237
  server_status= SERVER_STATUS_AUTOCOMMIT;
 
238
  options= session_startup_options;
226
239
 
227
240
  if (variables.max_join_size == HA_POS_ERROR)
228
241
    options |= OPTION_BIG_SELECTS;
234
247
  session_tx_isolation= (enum_tx_isolation) variables.tx_isolation;
235
248
  warn_list.empty();
236
249
  memset(warn_count, 0, sizeof(warn_count));
 
250
  total_warn_count= 0;
237
251
  memset(&status_var, 0, sizeof(status_var));
238
252
 
239
253
  /* Initialize sub structures */
269
283
  m_internal_handler= handler;
270
284
}
271
285
 
272
 
bool Session::handle_error(drizzled::error_t sql_errno, const char *message,
273
 
                           DRIZZLE_ERROR::enum_warning_level level)
 
286
bool Session::handle_error(uint32_t sql_errno, const char *message,
 
287
                       DRIZZLE_ERROR::enum_warning_level level)
274
288
{
275
289
  if (m_internal_handler)
276
290
  {
317
331
{
318
332
  assert(cleanup_done == false);
319
333
 
320
 
  setKilled(KILL_CONNECTION);
 
334
  killed= KILL_CONNECTION;
321
335
#ifdef ENABLE_WHEN_BINLOG_WILL_BE_ABLE_TO_PREPARE
322
336
  if (transaction.xid_state.xa_state == XA_PREPARED)
323
337
  {
326
340
#endif
327
341
  {
328
342
    TransactionServices &transaction_services= TransactionServices::singleton();
329
 
    transaction_services.rollbackTransaction(*this, true);
 
343
    transaction_services.rollbackTransaction(this, true);
330
344
    xid_cache_delete(&transaction.xid_state);
331
345
  }
332
346
 
335
349
       iter++)
336
350
  {
337
351
    user_var_entry *entry= (*iter).second;
338
 
    boost::checked_delete(entry);
 
352
    delete entry;
339
353
  }
340
354
  user_vars.clear();
341
355
 
343
357
  close_temporary_tables();
344
358
 
345
359
  if (global_read_lock)
346
 
  {
347
 
    unlockGlobalReadLock();
348
 
  }
 
360
    unlock_global_read_lock(this);
349
361
 
350
362
  cleanup_done= true;
351
363
}
354
366
{
355
367
  this->checkSentry();
356
368
 
357
 
  if (client and client->isConnected())
 
369
  if (client->isConnected())
358
370
  {
359
 
    assert(security_ctx);
360
371
    if (global_system_variables.log_warnings)
361
 
    {
362
 
      errmsg_printf(error::WARN, ER(ER_FORCING_CLOSE),
363
 
                    internal::my_progname,
364
 
                    thread_id,
365
 
                    security_ctx->username().c_str());
366
 
    }
367
 
 
368
 
    disconnect();
 
372
        errmsg_printf(ERRMSG_LVL_WARN, ER(ER_FORCING_CLOSE),internal::my_progname,
 
373
                      thread_id,
 
374
                      (getSecurityContext().getUser().c_str() ?
 
375
                       getSecurityContext().getUser().c_str() : ""));
 
376
    disconnect(0, false);
369
377
  }
370
378
 
371
379
  /* Close connection */
372
 
  if (client)
373
 
  {
374
 
    client->close();
375
 
    boost::checked_delete(client);
376
 
    client= NULL;
377
 
  }
 
380
  client->close();
 
381
  delete client;
378
382
 
379
383
  if (cleanup_done == false)
380
384
    cleanup();
392
396
 
393
397
  plugin::Logging::postEndDo(this);
394
398
  plugin::EventObserver::deregisterSessionEvents(*this); 
395
 
}
396
 
 
397
 
void Session::setClient(plugin::Client *client_arg)
398
 
{
399
 
  client= client_arg;
400
 
  client->setSession(this);
401
 
}
402
 
 
403
 
void Session::awake(Session::killed_state_t state_to_set)
404
 
{
405
 
  if ((state_to_set == Session::KILL_QUERY) and (command == COM_SLEEP))
406
 
    return;
407
 
 
 
399
 
 
400
  for (PropertyMap::iterator iter= life_properties.begin(); iter != life_properties.end(); iter++)
 
401
  {
 
402
    delete (*iter).second;
 
403
  }
 
404
  life_properties.clear();
 
405
 
 
406
  /* Ensure that no one is using Session */
 
407
  LOCK_delete.unlock();
 
408
}
 
409
 
 
410
void Session::awake(Session::killed_state state_to_set)
 
411
{
408
412
  this->checkSentry();
409
 
 
410
 
  setKilled(state_to_set);
411
 
  scheduler->killSession(this);
412
 
 
 
413
  safe_mutex_assert_owner(&LOCK_delete);
 
414
 
 
415
  killed= state_to_set;
413
416
  if (state_to_set != Session::KILL_QUERY)
414
417
  {
 
418
    scheduler->killSession(this);
415
419
    DRIZZLE_CONNECTION_DONE(thread_id);
416
420
  }
417
 
 
418
421
  if (mysys_var)
419
422
  {
420
423
    boost_unique_lock_t scopedLock(mysys_var->mutex);
510
513
{
511
514
  if (storeGlobals())
512
515
  {
513
 
    disconnect(ER_OUT_OF_RESOURCES);
 
516
    disconnect(ER_OUT_OF_RESOURCES, true);
514
517
    status_var.aborted_connects++;
515
518
    return true;
516
519
  }
521
524
{
522
525
  if (initGlobals() || authenticate())
523
526
  {
524
 
    disconnect();
 
527
    disconnect(0, true);
525
528
    return;
526
529
  }
527
530
 
528
531
  prepareForQueries();
529
532
 
530
 
  while (not client->haveError() && getKilled() != KILL_CONNECTION)
 
533
  while (! client->haveError() && killed != KILL_CONNECTION)
531
534
  {
532
 
    if (not executeStatement())
 
535
    if (! executeStatement())
533
536
      break;
534
537
  }
535
538
 
536
 
  disconnect();
 
539
  disconnect(0, true);
537
540
}
538
541
 
539
 
bool Session::schedule(Session::shared_ptr &arg)
 
542
bool Session::schedule()
540
543
{
541
 
  arg->scheduler= plugin::Scheduler::getScheduler();
542
 
  assert(arg->scheduler);
543
 
 
544
 
  ++connection_count;
545
 
 
546
 
  long current_connections= connection_count;
547
 
 
548
 
  if (current_connections > 0 and static_cast<uint64_t>(current_connections) > current_global_counters.max_used_connections)
 
544
  scheduler= plugin::Scheduler::getScheduler();
 
545
  assert(scheduler);
 
546
 
 
547
  connection_count.increment();
 
548
 
 
549
  if (connection_count > current_global_counters.max_used_connections)
549
550
  {
550
 
    current_global_counters.max_used_connections= static_cast<uint64_t>(connection_count);
 
551
    current_global_counters.max_used_connections= connection_count;
551
552
  }
552
553
 
553
554
  current_global_counters.connections++;
554
 
  arg->thread_id= arg->variables.pseudo_thread_id= global_thread_id++;
555
 
 
556
 
  session::Cache::singleton().insert(arg);
557
 
 
558
 
  if (unlikely(plugin::EventObserver::connectSession(*arg)))
559
 
  {
560
 
    // We should do something about an error...
561
 
  }
562
 
 
563
 
  if (plugin::Scheduler::getScheduler()->addSession(arg))
564
 
  {
565
 
    DRIZZLE_CONNECTION_START(arg->getSessionId());
 
555
  thread_id= variables.pseudo_thread_id= global_thread_id++;
 
556
 
 
557
  {
 
558
    boost::mutex::scoped_lock scoped(LOCK_thread_count);
 
559
    getSessionList().push_back(this);
 
560
  }
 
561
 
 
562
  if (unlikely(plugin::EventObserver::connectSession(*this)))
 
563
  {
 
564
    // We should do something about an error...
 
565
  }
 
566
 
 
567
  if (unlikely(plugin::EventObserver::connectSession(*this)))
 
568
  {
 
569
    // We should do something about an error...
 
570
  }
 
571
 
 
572
  if (scheduler->addSession(this))
 
573
  {
 
574
    DRIZZLE_CONNECTION_START(thread_id);
566
575
    char error_message_buff[DRIZZLE_ERRMSG_SIZE];
567
576
 
568
 
    arg->setKilled(Session::KILL_CONNECTION);
 
577
    killed= Session::KILL_CONNECTION;
569
578
 
570
 
    arg->status_var.aborted_connects++;
 
579
    status_var.aborted_connects++;
571
580
 
572
581
    /* Can't use my_error() since store_globals has not been called. */
573
582
    /* TODO replace will better error message */
574
583
    snprintf(error_message_buff, sizeof(error_message_buff),
575
584
             ER(ER_CANT_CREATE_THREAD), 1);
576
 
    arg->client->sendError(ER_CANT_CREATE_THREAD, error_message_buff);
577
 
 
 
585
    client->sendError(ER_CANT_CREATE_THREAD, error_message_buff);
578
586
    return true;
579
587
  }
580
588
 
582
590
}
583
591
 
584
592
 
585
 
/*
586
 
  Is this session viewable by the current user?
587
 
*/
588
 
bool Session::isViewable(identifier::User::const_reference user_arg) const
589
 
{
590
 
  return plugin::Authorization::isAuthorized(user_arg, this, false);
591
 
}
592
 
 
593
 
 
594
593
const char* Session::enter_cond(boost::condition_variable_any &cond, boost::mutex &mutex, const char* msg)
595
594
{
596
595
  const char* old_msg = get_proc_info();
618
617
 
619
618
bool Session::authenticate()
620
619
{
 
620
  lex_start(this);
621
621
  if (client->authenticate())
622
622
    return false;
623
623
 
630
630
                        const std::string &in_db)
631
631
{
632
632
  bool is_authenticated=
633
 
    plugin::Authentication::isAuthenticated(user(), passwd_str);
 
633
    plugin::Authentication::isAuthenticated(getSecurityContext(),
 
634
                                            passwd_str);
634
635
 
635
636
  if (is_authenticated != true)
636
637
  {
642
643
  /* Change database if necessary */
643
644
  if (not in_db.empty())
644
645
  {
645
 
    identifier::Schema identifier(in_db);
646
 
    if (change_db(this, identifier))
 
646
    SchemaIdentifier identifier(in_db);
 
647
    if (mysql_change_db(this, identifier))
647
648
    {
648
 
      /* change_db() has pushed the error message. */
 
649
      /* mysql_change_db() has pushed the error message. */
649
650
      return false;
650
651
    }
651
652
  }
672
673
  main_da.reset_diagnostics_area();
673
674
 
674
675
  if (client->readCommand(&l_packet, &packet_length) == false)
675
 
  {
676
676
    return false;
677
 
  }
678
677
 
679
 
  if (getKilled() == KILL_CONNECTION)
 
678
  if (killed == KILL_CONNECTION)
680
679
    return false;
681
680
 
682
681
  if (packet_length == 0)
683
682
    return true;
684
683
 
685
 
  l_command= static_cast<enum_server_command>(l_packet[0]);
 
684
  l_command= (enum enum_server_command) (unsigned char) l_packet[0];
686
685
 
687
686
  if (command >= COM_END)
688
687
    command= COM_END;                           // Wrong command
689
688
 
690
689
  assert(packet_length);
691
 
  return not dispatch_command(l_command, this, l_packet+1, (uint32_t) (packet_length-1));
 
690
  return ! dispatch_command(l_command, this, l_packet+1, (uint32_t) (packet_length-1));
692
691
}
693
692
 
694
693
bool Session::readAndStoreQuery(const char *in_packet, uint32_t in_packet_length)
700
699
    in_packet_length--;
701
700
  }
702
701
  const char *pos= in_packet + in_packet_length; /* Point at end null */
703
 
  while (in_packet_length > 0 && (pos[-1] == ';' || my_isspace(charset() ,pos[-1])))
 
702
  while (in_packet_length > 0 &&
 
703
         (pos[-1] == ';' || my_isspace(charset() ,pos[-1])))
704
704
  {
705
705
    pos--;
706
706
    in_packet_length--;
707
707
  }
708
708
 
709
 
  std::string *new_query= new std::string(in_packet, in_packet + in_packet_length);
710
 
  // We can not be entirely sure _schema has a value
711
 
  if (_schema)
712
 
  {
713
 
    plugin::QueryRewriter::rewriteQuery(*_schema, *new_query);
714
 
  }
715
 
  query.reset(new_query);
716
 
  _state.reset(new session::State(in_packet, in_packet_length));
 
709
  query.assign(in_packet, in_packet + in_packet_length);
717
710
 
718
711
  return true;
719
712
}
738
731
       * (Which of course should never happen...)
739
732
       */
740
733
      server_status&= ~SERVER_STATUS_IN_TRANS;
741
 
      if (transaction_services.commitTransaction(*this, true))
 
734
      if (transaction_services.commitTransaction(this, true))
742
735
        result= false;
743
736
      options&= ~(OPTION_BEGIN);
744
737
      break;
755
748
    case ROLLBACK_AND_CHAIN:
756
749
    {
757
750
      server_status&= ~SERVER_STATUS_IN_TRANS;
758
 
      if (transaction_services.rollbackTransaction(*this, true))
 
751
      if (transaction_services.rollbackTransaction(this, true))
759
752
        result= false;
760
753
      options&= ~(OPTION_BEGIN);
761
754
      if (result == true && (completion == ROLLBACK_AND_CHAIN))
768
761
  }
769
762
 
770
763
  if (result == false)
771
 
  {
772
 
    my_error(static_cast<drizzled::error_t>(killed_errno()), MYF(0));
773
 
  }
 
764
    my_error(killed_errno(), MYF(0));
774
765
  else if ((result == true) && do_release)
775
 
  {
776
 
    setKilled(Session::KILL_CONNECTION);
777
 
  }
 
766
    killed= Session::KILL_CONNECTION;
778
767
 
779
768
  return result;
780
769
}
792
781
  if (options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
793
782
  {
794
783
    server_status&= ~SERVER_STATUS_IN_TRANS;
795
 
    if (transaction_services.commitTransaction(*this, true))
 
784
    if (transaction_services.commitTransaction(this, true))
796
785
      result= false;
797
786
  }
798
787
  options&= ~(OPTION_BEGIN);
803
792
{
804
793
  bool result= true;
805
794
 
806
 
  assert(! inTransaction());
807
 
 
808
 
  options|= OPTION_BEGIN;
809
 
  server_status|= SERVER_STATUS_IN_TRANS;
810
 
 
811
 
  if (plugin::TransactionalStorageEngine::notifyStartTransaction(this, opt))
 
795
  if (! endActiveTransaction())
812
796
  {
813
797
    result= false;
814
798
  }
 
799
  else
 
800
  {
 
801
    options|= OPTION_BEGIN;
 
802
    server_status|= SERVER_STATUS_IN_TRANS;
 
803
 
 
804
    if (plugin::TransactionalStorageEngine::notifyStartTransaction(this, opt))
 
805
    {
 
806
      result= false;
 
807
    }
 
808
  }
815
809
 
816
810
  return result;
817
811
}
833
827
    first_successful_insert_id_in_cur_stmt= 0;
834
828
    substitute_null_with_insert_id= true;
835
829
  }
836
 
 
837
830
  arg_of_last_insert_id_function= false;
838
 
 
839
831
  /* Free Items that were created during this execution */
840
832
  free_items();
841
 
 
842
 
  /* Reset _where. */
843
 
  _where= Session::DEFAULT_WHERE;
 
833
  /* Reset where. */
 
834
  where= Session::DEFAULT_WHERE;
844
835
 
845
836
  /* Reset the temporary shares we built */
846
837
  for_each(temporary_shares.begin(),
871
862
                                     bool allocate_lex_string)
872
863
{
873
864
  if (allocate_lex_string)
874
 
    if (!(lex_str= (LEX_STRING *)getMemRoot()->allocate(sizeof(LEX_STRING))))
 
865
    if (!(lex_str= (LEX_STRING *)alloc(sizeof(LEX_STRING))))
875
866
      return 0;
876
867
  if (!(lex_str->str= mem_root->strmake_root(str, length)))
877
868
    return 0;
917
908
  return (result->send_fields(field_list));
918
909
}
919
910
 
920
 
void select_result::send_error(drizzled::error_t errcode, const char *err)
 
911
void select_result::send_error(uint32_t errcode, const char *err)
921
912
{
922
913
  my_message(errcode, err, MYF(0));
923
914
}
926
917
  Handling writing to file
927
918
************************************************************************/
928
919
 
929
 
void select_to_file::send_error(drizzled::error_t errcode,const char *err)
 
920
void select_to_file::send_error(uint32_t errcode,const char *err)
930
921
{
931
922
  my_message(errcode, err, MYF(0));
932
923
  if (file > 0)
933
924
  {
934
 
    (void) cache->end_io_cache();
 
925
    (void) end_io_cache(cache);
935
926
    (void) internal::my_close(file, MYF(0));
936
927
    (void) internal::my_delete(path.file_string().c_str(), MYF(0));             // Delete file on error
937
928
    file= -1;
941
932
 
942
933
bool select_to_file::send_eof()
943
934
{
944
 
  int error= test(cache->end_io_cache());
 
935
  int error= test(end_io_cache(cache));
945
936
  if (internal::my_close(file, MYF(MY_WME)))
946
937
    error= 1;
947
938
  if (!error)
963
954
  /* In case of error send_eof() may be not called: close the file here. */
964
955
  if (file >= 0)
965
956
  {
966
 
    (void) cache->end_io_cache();
 
957
    (void) end_io_cache(cache);
967
958
    (void) internal::my_close(file, MYF(0));
968
959
    file= -1;
969
960
  }
1022
1013
  if (not to_file.has_root_directory())
1023
1014
  {
1024
1015
    target_path= fs::system_complete(getDataHomeCatalog());
1025
 
    util::string::const_shared_ptr schema(session->schema());
1026
 
    if (schema and not schema->empty())
 
1016
    if (not session->db.empty())
1027
1017
    {
1028
1018
      int count_elements= 0;
1029
1019
      for (fs::path::iterator iter= to_file.begin();
1033
1023
 
1034
1024
      if (count_elements == 1)
1035
1025
      {
1036
 
        target_path /= *schema;
 
1026
        target_path /= session->db;
1037
1027
      }
1038
1028
    }
1039
1029
    target_path /= to_file;
1062
1052
  if ((file= internal::my_create(target_path.file_string().c_str(), 0666, O_WRONLY|O_EXCL, MYF(MY_WME))) < 0)
1063
1053
    return file;
1064
1054
  (void) fchmod(file, 0666);                    // Because of umask()
1065
 
  if (cache->init_io_cache(file, 0L, internal::WRITE_CACHE, 0L, 1, MYF(MY_WME)))
 
1055
  if (init_io_cache(cache, file, 0L, internal::WRITE_CACHE, 0L, 1, MYF(MY_WME)))
1066
1056
  {
1067
1057
    internal::my_close(file, MYF(0));
1068
1058
    internal::my_delete(target_path.file_string().c_str(), MYF(0));  // Delete file on error, it was just created
1091
1081
    {
1092
1082
      if (item->max_length >= MAX_BLOB_WIDTH)
1093
1083
      {
1094
 
        blob_flag=1;
1095
 
        break;
 
1084
        blob_flag=1;
 
1085
        break;
1096
1086
      }
1097
 
 
1098
1087
      if (item->result_type() == STRING_RESULT)
1099
1088
        string_results= true;
1100
1089
      else
1480
1469
bool select_max_min_finder_subselect::cmp_decimal()
1481
1470
{
1482
1471
  Item *maxmin= ((Item_singlerow_subselect *)item)->element_index(0);
1483
 
  type::Decimal cval, *cvalue= cache->val_decimal(&cval);
1484
 
  type::Decimal mval, *mvalue= maxmin->val_decimal(&mval);
 
1472
  my_decimal cval, *cvalue= cache->val_decimal(&cval);
 
1473
  my_decimal mval, *mvalue= maxmin->val_decimal(&mval);
1485
1474
  if (fmax)
1486
1475
    return (cache->null_value && !maxmin->null_value) ||
1487
1476
      (!cache->null_value && !maxmin->null_value &&
1488
 
       class_decimal_cmp(cvalue, mvalue) > 0) ;
 
1477
       my_decimal_cmp(cvalue, mvalue) > 0) ;
1489
1478
  return (maxmin->null_value && !cache->null_value) ||
1490
1479
    (!cache->null_value && !maxmin->null_value &&
1491
 
     class_decimal_cmp(cvalue,mvalue) < 0);
 
1480
     my_decimal_cmp(cvalue,mvalue) < 0);
1492
1481
}
1493
1482
 
1494
1483
bool select_max_min_finder_subselect::cmp_str()
1530
1519
void Session::end_statement()
1531
1520
{
1532
1521
  /* Cleanup SQL processing state to reuse this statement in next query. */
1533
 
  lex->end();
 
1522
  lex_end(lex);
1534
1523
  query_cache_key= ""; // reset the cache key
1535
1524
  resetResultsetMessage();
1536
1525
}
1537
1526
 
1538
1527
bool Session::copy_db_to(char **p_db, size_t *p_db_length)
1539
1528
{
1540
 
  assert(_schema);
1541
 
  if (_schema and _schema->empty())
1542
 
  {
1543
 
    my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
1544
 
    return true;
1545
 
  }
1546
 
  else if (not _schema)
1547
 
  {
1548
 
    my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
1549
 
    return true;
1550
 
  }
1551
 
  assert(_schema);
1552
 
 
1553
 
  *p_db= strmake(_schema->c_str(), _schema->size());
1554
 
  *p_db_length= _schema->size();
1555
 
 
 
1529
  if (db.empty())
 
1530
  {
 
1531
    my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
 
1532
    return true;
 
1533
  }
 
1534
  *p_db= strmake(db.c_str(), db.length());
 
1535
  *p_db_length= db.length();
1556
1536
  return false;
1557
1537
}
1558
1538
 
1574
1554
  /* Fix for Intel compiler */
1575
1555
  if (copy_field)
1576
1556
  {
1577
 
    boost::checked_array_delete(copy_field);
1578
 
    save_copy_field= save_copy_field_end= copy_field= copy_field_end= 0;
 
1557
    delete [] copy_field;
 
1558
    save_copy_field= copy_field= 0;
1579
1559
  }
1580
1560
}
1581
1561
 
1582
1562
void Session::send_kill_message() const
1583
1563
{
1584
 
  drizzled::error_t err= static_cast<drizzled::error_t>(killed_errno());
1585
 
  if (err != EE_OK)
 
1564
  int err= killed_errno();
 
1565
  if (err)
1586
1566
    my_message(err, ER(err), MYF(0));
1587
1567
}
1588
1568
 
1592
1572
}
1593
1573
 
1594
1574
 
1595
 
void Session::set_db(const std::string &new_db)
 
1575
bool Session::set_db(const std::string &new_db)
1596
1576
{
1597
1577
  /* Do not reallocate memory if current chunk is big enough. */
1598
1578
  if (new_db.length())
1599
 
  {
1600
 
    _schema.reset(new std::string(new_db));
1601
 
  }
 
1579
    db= new_db;
1602
1580
  else
1603
 
  {
1604
 
    _schema.reset(new std::string(""));
1605
 
  }
1606
 
}
1607
 
 
 
1581
    db.clear();
 
1582
 
 
1583
  return false;
 
1584
}
 
1585
 
 
1586
 
 
1587
 
 
1588
 
 
1589
/**
 
1590
  Check the killed state of a user thread
 
1591
  @param session  user thread
 
1592
  @retval 0 the user thread is active
 
1593
  @retval 1 the user thread has been killed
 
1594
*/
 
1595
int session_killed(const Session *session)
 
1596
{
 
1597
  return(session->killed);
 
1598
}
 
1599
 
 
1600
 
 
1601
const struct charset_info_st *session_charset(Session *session)
 
1602
{
 
1603
  return(session->charset());
 
1604
}
1608
1605
 
1609
1606
/**
1610
1607
  Mark transaction to rollback and mark error as fatal to a sub-statement.
1612
1609
  @param  session   Thread handle
1613
1610
  @param  all   true <=> rollback main transaction.
1614
1611
*/
1615
 
void Session::markTransactionForRollback(bool all)
 
1612
void mark_transaction_to_rollback(Session *session, bool all)
1616
1613
{
1617
 
  is_fatal_sub_stmt_error= true;
1618
 
  transaction_rollback_request= all;
 
1614
  if (session)
 
1615
  {
 
1616
    session->is_fatal_sub_stmt_error= true;
 
1617
    session->transaction_rollback_request= all;
 
1618
  }
1619
1619
}
1620
1620
 
1621
 
void Session::disconnect(enum error_t errcode)
 
1621
void Session::disconnect(uint32_t errcode, bool should_lock)
1622
1622
{
1623
1623
  /* Allow any plugins to cleanup their session variables */
1624
1624
  plugin_sessionvar_cleanup(this);
1625
1625
 
1626
1626
  /* If necessary, log any aborted or unauthorized connections */
1627
 
  if (getKilled() || client->wasAborted())
 
1627
  if (killed || client->wasAborted())
1628
1628
  {
1629
1629
    status_var.aborted_threads++;
1630
1630
  }
1631
1631
 
1632
1632
  if (client->wasAborted())
1633
1633
  {
1634
 
    if (not getKilled() && variables.log_warnings > 1)
 
1634
    if (! killed && variables.log_warnings > 1)
1635
1635
    {
1636
 
      errmsg_printf(error::WARN, ER(ER_NEW_ABORTING_CONNECTION)
 
1636
      SecurityContext *sctx= &security_ctx;
 
1637
 
 
1638
      errmsg_printf(ERRMSG_LVL_WARN, ER(ER_NEW_ABORTING_CONNECTION)
1637
1639
                  , thread_id
1638
 
                  , (_schema->empty() ? "unconnected" : _schema->c_str())
1639
 
                  , security_ctx->username().empty() == false ? security_ctx->username().c_str() : "unauthenticated"
1640
 
                  , security_ctx->address().c_str()
 
1640
                  , (db.empty() ? "unconnected" : db.c_str())
 
1641
                  , sctx->getUser().empty() == false ? sctx->getUser().c_str() : "unauthenticated"
 
1642
                  , sctx->getIp().c_str()
1641
1643
                  , (main_da.is_error() ? main_da.message() : ER(ER_UNKNOWN_ERROR)));
1642
1644
    }
1643
1645
  }
1644
1646
 
1645
 
  setKilled(Session::KILL_CONNECTION);
1646
 
 
 
1647
  /* Close out our connection to the client */
 
1648
  if (should_lock)
 
1649
    LOCK_thread_count.lock();
 
1650
  killed= Session::KILL_CONNECTION;
1647
1651
  if (client->isConnected())
1648
1652
  {
1649
 
    if (errcode != EE_OK)
 
1653
    if (errcode)
1650
1654
    {
1651
1655
      /*my_error(errcode, ER(errcode));*/
1652
1656
      client->sendError(errcode, ER(errcode));
1653
1657
    }
1654
1658
    client->close();
1655
1659
  }
 
1660
  if (should_lock)
 
1661
    (void) LOCK_thread_count.unlock();
1656
1662
}
1657
1663
 
1658
1664
void Session::reset_for_next_command()
1680
1686
  Close all temporary tables created by 'CREATE TEMPORARY TABLE' for thread
1681
1687
*/
1682
1688
 
1683
 
void Open_tables_state::close_temporary_tables()
 
1689
void Session::close_temporary_tables()
1684
1690
{
1685
1691
  Table *table;
1686
1692
  Table *tmp_next;
1700
1706
  unlink from session->temporary tables and close temporary table
1701
1707
*/
1702
1708
 
1703
 
void Open_tables_state::close_temporary_table(Table *table)
 
1709
void Session::close_temporary_table(Table *table)
1704
1710
{
1705
1711
  if (table->getPrev())
1706
1712
  {
1736
1742
  If this is needed, use close_temporary_table()
1737
1743
*/
1738
1744
 
1739
 
void Open_tables_state::nukeTable(Table *table)
 
1745
void Session::nukeTable(Table *table)
1740
1746
{
1741
1747
  plugin::StorageEngine *table_type= table->getShare()->db_type();
1742
1748
 
1743
1749
  table->free_io_cache();
1744
1750
  table->delete_table();
1745
1751
 
1746
 
  identifier::Table identifier(table->getShare()->getSchemaName(), table->getShare()->getTableName(), table->getShare()->getPath());
 
1752
  TableIdentifier identifier(table->getShare()->getSchemaName(), table->getShare()->getTableName(), table->getShare()->getPath());
1747
1753
  rm_temporary_table(table_type, identifier);
1748
1754
 
1749
 
  boost::checked_delete(table->getMutableShare());
 
1755
  delete table->getMutableShare();
1750
1756
 
1751
 
  boost::checked_delete(table);
 
1757
  /* This makes me sad, but we're allocating it via malloc */
 
1758
  delete table;
1752
1759
}
1753
1760
 
1754
1761
/** Clear most status variables. */
1771
1778
 
1772
1779
user_var_entry *Session::getVariable(const std::string  &name, bool create_if_not_exists)
1773
1780
{
1774
 
  if (cleanup_done)
1775
 
    return NULL;
 
1781
  UserVarsRange ppp= user_vars.equal_range(name);
1776
1782
 
1777
 
  UserVars::iterator iter= user_vars.find(name);
1778
 
  if (iter != user_vars.end())
 
1783
  for (UserVars::iterator iter= ppp.first;
 
1784
       iter != ppp.second; ++iter)
 
1785
  {
1779
1786
    return (*iter).second;
 
1787
  }
1780
1788
 
1781
1789
  if (not create_if_not_exists)
1782
1790
    return NULL;
1791
1799
 
1792
1800
  if (not returnable.second)
1793
1801
  {
1794
 
    boost::checked_delete(entry);
 
1802
    delete entry;
1795
1803
  }
1796
1804
 
1797
1805
  return entry;
1800
1808
void Session::setVariable(const std::string &name, const std::string &value)
1801
1809
{
1802
1810
  user_var_entry *updateable_var= getVariable(name.c_str(), true);
1803
 
  if (updateable_var)
1804
 
  {
1805
 
    updateable_var->update_hash(false,
1806
 
                                (void*)value.c_str(),
1807
 
                                static_cast<uint32_t>(value.length()), STRING_RESULT,
1808
 
                                &my_charset_bin,
1809
 
                                DERIVATION_IMPLICIT, false);
1810
 
  }
 
1811
 
 
1812
  updateable_var->update_hash(false,
 
1813
                              (void*)value.c_str(),
 
1814
                              static_cast<uint32_t>(value.length()), STRING_RESULT,
 
1815
                              &my_charset_bin,
 
1816
                              DERIVATION_IMPLICIT, false);
1811
1817
}
1812
1818
 
1813
 
void Open_tables_state::mark_temp_tables_as_free_for_reuse()
 
1819
void Session::mark_temp_tables_as_free_for_reuse()
1814
1820
{
1815
1821
  for (Table *table= temporary_tables ; table ; table= table->getNext())
1816
1822
  {
1817
 
    if (table->query_id == getQueryId())
 
1823
    if (table->query_id == query_id)
1818
1824
    {
1819
1825
      table->query_id= 0;
1820
1826
      table->cursor->ha_reset();
1826
1832
{
1827
1833
  for (; table ; table= table->getNext())
1828
1834
  {
1829
 
    if (table->query_id == getQueryId())
 
1835
    if (table->query_id == query_id)
1830
1836
    {
1831
1837
      table->query_id= 0;
1832
1838
      table->cursor->ha_reset();
1845
1851
*/
1846
1852
void Session::close_thread_tables()
1847
1853
{
1848
 
  clearDerivedTables();
 
1854
  if (derived_tables)
 
1855
    derived_tables= NULL; // They should all be invalid by this point
1849
1856
 
1850
1857
  /*
1851
1858
    Mark all temporary tables used by this statement as free for reuse.
1862
1869
  {
1863
1870
    TransactionServices &transaction_services= TransactionServices::singleton();
1864
1871
    main_da.can_overwrite_status= true;
1865
 
    transaction_services.autocommitOrRollback(*this, is_error());
 
1872
    transaction_services.autocommitOrRollback(this, is_error());
1866
1873
    main_da.can_overwrite_status= false;
1867
1874
    transaction.stmt.reset();
1868
1875
  }
1878
1885
      handled either before writing a query log event (inside
1879
1886
      binlog_query()) or when preparing a pending event.
1880
1887
     */
1881
 
    unlockTables(lock);
 
1888
    mysql_unlock_tables(this, lock);
1882
1889
    lock= 0;
1883
1890
  }
1884
1891
  /*
1885
 
    Note that we need to hold table::Cache::singleton().mutex() while changing the
 
1892
    Note that we need to hold LOCK_open while changing the
1886
1893
    open_tables list. Another thread may work on it.
1887
 
    (See: table::Cache::singleton().removeTable(), wait_completed_table())
 
1894
    (See: remove_table_from_cache(), mysql_wait_completed_table())
1888
1895
    Closing a MERGE child before the parent would be fatal if the
1889
1896
    other thread tries to abort the MERGE lock in between.
1890
1897
  */
1918
1925
 
1919
1926
    if (not lock_tables(tables, counter, &need_reopen))
1920
1927
      break;
1921
 
 
1922
1928
    if (not need_reopen)
1923
1929
      return true;
1924
 
 
1925
1930
    close_tables_for_reopen(&tables);
1926
1931
  }
1927
 
 
1928
 
  if ((handle_derived(lex, &derived_prepare) || (handle_derived(lex, &derived_filling))))
 
1932
  if ((mysql_handle_derived(lex, &mysql_derived_prepare) ||
 
1933
       (
 
1934
        mysql_handle_derived(lex, &mysql_derived_filling))))
1929
1935
    return true;
1930
1936
 
1931
1937
  return false;
1937
1943
  might be an issue (lame engines).
1938
1944
*/
1939
1945
 
1940
 
bool Open_tables_state::rm_temporary_table(const identifier::Table &identifier, bool best_effort)
 
1946
bool Session::rm_temporary_table(TableIdentifier &identifier, bool best_effort)
1941
1947
{
1942
 
  if (not plugin::StorageEngine::dropTable(*static_cast<Session *>(this), identifier))
 
1948
  if (plugin::StorageEngine::dropTable(*this, identifier))
1943
1949
  {
1944
1950
    if (not best_effort)
1945
1951
    {
1946
 
      std::string path;
1947
 
      identifier.getSQLPath(path);
1948
 
      errmsg_printf(error::WARN, _("Could not remove temporary table: '%s', error: %d"),
1949
 
                    path.c_str(), errno);
 
1952
      errmsg_printf(ERRMSG_LVL_WARN, _("Could not remove temporary table: '%s', error: %d"),
 
1953
                    identifier.getSQLPath().c_str(), errno);
1950
1954
    }
1951
1955
 
1952
1956
    return true;
1955
1959
  return false;
1956
1960
}
1957
1961
 
1958
 
bool Open_tables_state::rm_temporary_table(plugin::StorageEngine *base, const identifier::Table &identifier)
 
1962
bool Session::rm_temporary_table(plugin::StorageEngine *base, TableIdentifier &identifier)
1959
1963
{
1960
 
  drizzled::error_t error;
1961
1964
  assert(base);
1962
1965
 
1963
 
  if (not plugin::StorageEngine::dropTable(*static_cast<Session *>(this), *base, identifier, error))
 
1966
  if (plugin::StorageEngine::dropTable(*this, *base, identifier))
1964
1967
  {
1965
 
    std::string path;
1966
 
    identifier.getSQLPath(path);
1967
 
    errmsg_printf(error::WARN, _("Could not remove temporary table: '%s', error: %d"),
1968
 
                  path.c_str(), error);
 
1968
    errmsg_printf(ERRMSG_LVL_WARN, _("Could not remove temporary table: '%s', error: %d"),
 
1969
                  identifier.getSQLPath().c_str(), errno);
1969
1970
 
1970
1971
    return true;
1971
1972
  }
1977
1978
  @note this will be removed, I am looking through Hudson to see if it is finding
1978
1979
  any tables that are missed during cleanup.
1979
1980
*/
1980
 
void Open_tables_state::dumpTemporaryTableNames(const char *foo)
 
1981
void Session::dumpTemporaryTableNames(const char *foo)
1981
1982
{
1982
1983
  Table *table;
1983
1984
 
1989
1990
  {
1990
1991
    bool have_proto= false;
1991
1992
 
1992
 
    message::Table *proto= table->getShare()->getTableMessage();
1993
 
    if (table->getShare()->getTableMessage())
 
1993
    message::Table *proto= table->getShare()->getTableProto();
 
1994
    if (table->getShare()->getTableProto())
1994
1995
      have_proto= true;
1995
1996
 
1996
1997
    const char *answer= have_proto ? "true" : "false";
2001
2002
      cerr << "\t\t Proto " << proto->schema() << " " << proto->name() << "\n";
2002
2003
    }
2003
2004
    else
2004
 
    {
2005
2005
      cerr << "\tTabl;e Name " << table->getShare()->getSchemaName() << "." << table->getShare()->getTableName() << " : " << answer << "\n";
2006
 
    }
2007
 
  }
2008
 
}
2009
 
 
2010
 
table::Singular *Session::getInstanceTable()
2011
 
{
2012
 
  temporary_shares.push_back(new table::Singular()); // This will not go into the tableshare cache, so no key is used.
2013
 
 
2014
 
  table::Singular *tmp_share= temporary_shares.back();
 
2006
  }
 
2007
}
 
2008
 
 
2009
bool Session::storeTableMessage(const TableIdentifier &identifier, message::Table &table_message)
 
2010
{
 
2011
  table_message_cache.insert(make_pair(identifier.getPath(), table_message));
 
2012
 
 
2013
  return true;
 
2014
}
 
2015
 
 
2016
bool Session::removeTableMessage(const TableIdentifier &identifier)
 
2017
{
 
2018
  TableMessageCache::iterator iter;
 
2019
 
 
2020
  iter= table_message_cache.find(identifier.getPath());
 
2021
 
 
2022
  if (iter == table_message_cache.end())
 
2023
    return false;
 
2024
 
 
2025
  table_message_cache.erase(iter);
 
2026
 
 
2027
  return true;
 
2028
}
 
2029
 
 
2030
bool Session::getTableMessage(const TableIdentifier &identifier, message::Table &table_message)
 
2031
{
 
2032
  TableMessageCache::iterator iter;
 
2033
 
 
2034
  iter= table_message_cache.find(identifier.getPath());
 
2035
 
 
2036
  if (iter == table_message_cache.end())
 
2037
    return false;
 
2038
 
 
2039
  table_message.CopyFrom(((*iter).second));
 
2040
 
 
2041
  return true;
 
2042
}
 
2043
 
 
2044
bool Session::doesTableMessageExist(const TableIdentifier &identifier)
 
2045
{
 
2046
  TableMessageCache::iterator iter;
 
2047
 
 
2048
  iter= table_message_cache.find(identifier.getPath());
 
2049
 
 
2050
  if (iter == table_message_cache.end())
 
2051
  {
 
2052
    return false;
 
2053
  }
 
2054
 
 
2055
  return true;
 
2056
}
 
2057
 
 
2058
bool Session::renameTableMessage(const TableIdentifier &from, const TableIdentifier &to)
 
2059
{
 
2060
  TableMessageCache::iterator iter;
 
2061
 
 
2062
  table_message_cache[to.getPath()]= table_message_cache[from.getPath()];
 
2063
 
 
2064
  iter= table_message_cache.find(to.getPath());
 
2065
 
 
2066
  if (iter == table_message_cache.end())
 
2067
  {
 
2068
    return false;
 
2069
  }
 
2070
 
 
2071
  (*iter).second.set_schema(to.getSchemaName());
 
2072
  (*iter).second.set_name(to.getTableName());
 
2073
 
 
2074
  return true;
 
2075
}
 
2076
 
 
2077
table::Instance *Session::getInstanceTable()
 
2078
{
 
2079
  temporary_shares.push_back(new table::Instance()); // This will not go into the tableshare cache, so no key is used.
 
2080
 
 
2081
  table::Instance *tmp_share= temporary_shares.back();
2015
2082
 
2016
2083
  assert(tmp_share);
2017
2084
 
2037
2104
  @return
2038
2105
    0 if out of memory, Table object in case of success
2039
2106
*/
2040
 
table::Singular *Session::getInstanceTable(List<CreateField> &field_list)
 
2107
table::Instance *Session::getInstanceTable(List<CreateField> &field_list)
2041
2108
{
2042
 
  temporary_shares.push_back(new table::Singular(this, field_list)); // This will not go into the tableshare cache, so no key is used.
 
2109
  temporary_shares.push_back(new table::Instance(this, field_list)); // This will not go into the tableshare cache, so no key is used.
2043
2110
 
2044
 
  table::Singular *tmp_share= temporary_shares.back();
 
2111
  table::Instance *tmp_share= temporary_shares.back();
2045
2112
 
2046
2113
  assert(tmp_share);
2047
2114
 
2048
2115
  return tmp_share;
2049
2116
}
2050
2117
 
2051
 
namespace display  {
2052
 
 
2053
 
static const std::string NONE= "NONE";
2054
 
static const std::string GOT_GLOBAL_READ_LOCK= "HAS GLOBAL READ LOCK";
2055
 
static const std::string MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT= "HAS GLOBAL READ LOCK WITH BLOCKING COMMIT";
2056
 
 
2057
 
const std::string &type(drizzled::Session::global_read_lock_t type)
2058
 
{
2059
 
  switch (type) {
2060
 
    default:
2061
 
    case Session::NONE:
2062
 
      return NONE;
2063
 
    case Session::GOT_GLOBAL_READ_LOCK:
2064
 
      return GOT_GLOBAL_READ_LOCK;
2065
 
    case Session::MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT:
2066
 
      return MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT;
2067
 
  }
2068
 
}
2069
 
 
2070
 
size_t max_string_length(drizzled::Session::global_read_lock_t)
2071
 
{
2072
 
  return MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT.size();
2073
 
}
2074
 
 
2075
 
} /* namespace display */
2076
 
 
2077
2118
} /* namespace drizzled */