~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/session.cc

  • Committer: Andrew Hutchings
  • Date: 2010-10-20 15:31:27 UTC
  • mto: This revision was merged to the branch mainline in revision 1907.
  • Revision ID: andrew@linuxjedi.co.uk-20101020153127-w9djuz9omzezg2kz
Add error message for global sort buffer constraint

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
  query(),
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
1145
1134
  if (unit->offset_limit_cnt)
1146
1135
  {                                             // using limit offset,count
1147
1136
    unit->offset_limit_cnt--;
1148
 
    return false;
 
1137
    return(0);
1149
1138
  }
1150
1139
  row_count++;
1151
1140
  Item *item;
1154
1143
 
1155
1144
  if (my_b_write(cache,(unsigned char*) exchange->line_start->ptr(),
1156
1145
                 exchange->line_start->length()))
1157
 
    return true;
1158
 
 
 
1146
    goto err;
1159
1147
  while ((item=li++))
1160
1148
  {
1161
1149
    Item_result result_type=item->result_type();
1166
1154
    {
1167
1155
      if (my_b_write(cache,(unsigned char*) exchange->enclosed->ptr(),
1168
1156
                     exchange->enclosed->length()))
1169
 
        return true;
 
1157
        goto err;
1170
1158
    }
1171
1159
    if (!res)
1172
1160
    {                                           // NULL
1177
1165
          null_buff[0]=escape_char;
1178
1166
          null_buff[1]='N';
1179
1167
          if (my_b_write(cache,(unsigned char*) null_buff,2))
1180
 
            return true;
 
1168
            goto err;
1181
1169
        }
1182
1170
        else if (my_b_write(cache,(unsigned char*) "NULL",4))
1183
 
          return true;
 
1171
          goto err;
1184
1172
      }
1185
1173
      else
1186
1174
      {
1271
1259
            tmp_buff[1]= *pos ? *pos : '0';
1272
1260
            if (my_b_write(cache,(unsigned char*) start,(uint32_t) (pos-start)) ||
1273
1261
                my_b_write(cache,(unsigned char*) tmp_buff,2))
1274
 
              return true;
 
1262
              goto err;
1275
1263
            start=pos+1;
1276
1264
          }
1277
1265
        }
1278
1266
        if (my_b_write(cache,(unsigned char*) start,(uint32_t) (pos-start)))
1279
 
          return true;
 
1267
          goto err;
1280
1268
      }
1281
1269
      else if (my_b_write(cache,(unsigned char*) res->ptr(),used_length))
1282
 
        return true;
 
1270
        goto err;
1283
1271
    }
1284
1272
    if (fixed_row_size)
1285
1273
    {                                           // Fill with space
1295
1283
        for (; length > sizeof(space) ; length-=sizeof(space))
1296
1284
        {
1297
1285
          if (my_b_write(cache,(unsigned char*) space,sizeof(space)))
1298
 
            return true;
 
1286
            goto err;
1299
1287
        }
1300
1288
        if (my_b_write(cache,(unsigned char*) space,length))
1301
 
          return true;
 
1289
          goto err;
1302
1290
      }
1303
1291
    }
1304
1292
    if (res && enclosed)
1305
1293
    {
1306
1294
      if (my_b_write(cache, (unsigned char*) exchange->enclosed->ptr(),
1307
1295
                     exchange->enclosed->length()))
1308
 
        return true;
 
1296
        goto err;
1309
1297
    }
1310
1298
    if (--items_left)
1311
1299
    {
1312
1300
      if (my_b_write(cache, (unsigned char*) exchange->field_term->ptr(),
1313
1301
                     field_term_length))
1314
 
        return true;
 
1302
        goto err;
1315
1303
    }
1316
1304
  }
1317
1305
  if (my_b_write(cache,(unsigned char*) exchange->line_term->ptr(),
1318
1306
                 exchange->line_term->length()))
1319
 
  {
1320
 
    return true;
1321
 
  }
1322
 
 
1323
 
  return false;
 
1307
    goto err;
 
1308
  return(0);
 
1309
err:
 
1310
  return(1);
1324
1311
}
1325
1312
 
1326
1313
 
1480
1467
bool select_max_min_finder_subselect::cmp_decimal()
1481
1468
{
1482
1469
  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);
 
1470
  my_decimal cval, *cvalue= cache->val_decimal(&cval);
 
1471
  my_decimal mval, *mvalue= maxmin->val_decimal(&mval);
1485
1472
  if (fmax)
1486
1473
    return (cache->null_value && !maxmin->null_value) ||
1487
1474
      (!cache->null_value && !maxmin->null_value &&
1488
 
       class_decimal_cmp(cvalue, mvalue) > 0) ;
 
1475
       my_decimal_cmp(cvalue, mvalue) > 0) ;
1489
1476
  return (maxmin->null_value && !cache->null_value) ||
1490
1477
    (!cache->null_value && !maxmin->null_value &&
1491
 
     class_decimal_cmp(cvalue,mvalue) < 0);
 
1478
     my_decimal_cmp(cvalue,mvalue) < 0);
1492
1479
}
1493
1480
 
1494
1481
bool select_max_min_finder_subselect::cmp_str()
1530
1517
void Session::end_statement()
1531
1518
{
1532
1519
  /* Cleanup SQL processing state to reuse this statement in next query. */
1533
 
  lex->end();
 
1520
  lex_end(lex);
1534
1521
  query_cache_key= ""; // reset the cache key
1535
1522
  resetResultsetMessage();
1536
1523
}
1537
1524
 
1538
1525
bool Session::copy_db_to(char **p_db, size_t *p_db_length)
1539
1526
{
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
 
 
 
1527
  if (db.empty())
 
1528
  {
 
1529
    my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
 
1530
    return true;
 
1531
  }
 
1532
  *p_db= strmake(db.c_str(), db.length());
 
1533
  *p_db_length= db.length();
1556
1534
  return false;
1557
1535
}
1558
1536
 
1574
1552
  /* Fix for Intel compiler */
1575
1553
  if (copy_field)
1576
1554
  {
1577
 
    boost::checked_array_delete(copy_field);
1578
 
    save_copy_field= save_copy_field_end= copy_field= copy_field_end= 0;
 
1555
    delete [] copy_field;
 
1556
    save_copy_field= copy_field= 0;
1579
1557
  }
1580
1558
}
1581
1559
 
1582
1560
void Session::send_kill_message() const
1583
1561
{
1584
 
  drizzled::error_t err= static_cast<drizzled::error_t>(killed_errno());
1585
 
  if (err != EE_OK)
 
1562
  int err= killed_errno();
 
1563
  if (err)
1586
1564
    my_message(err, ER(err), MYF(0));
1587
1565
}
1588
1566
 
1592
1570
}
1593
1571
 
1594
1572
 
1595
 
void Session::set_db(const std::string &new_db)
 
1573
bool Session::set_db(const std::string &new_db)
1596
1574
{
1597
1575
  /* Do not reallocate memory if current chunk is big enough. */
1598
1576
  if (new_db.length())
1599
 
  {
1600
 
    _schema.reset(new std::string(new_db));
1601
 
  }
 
1577
    db= new_db;
1602
1578
  else
1603
 
  {
1604
 
    _schema.reset(new std::string(""));
1605
 
  }
1606
 
}
1607
 
 
 
1579
    db.clear();
 
1580
 
 
1581
  return false;
 
1582
}
 
1583
 
 
1584
 
 
1585
 
 
1586
 
 
1587
/**
 
1588
  Check the killed state of a user thread
 
1589
  @param session  user thread
 
1590
  @retval 0 the user thread is active
 
1591
  @retval 1 the user thread has been killed
 
1592
*/
 
1593
int session_killed(const Session *session)
 
1594
{
 
1595
  return(session->killed);
 
1596
}
 
1597
 
 
1598
 
 
1599
const struct charset_info_st *session_charset(Session *session)
 
1600
{
 
1601
  return(session->charset());
 
1602
}
1608
1603
 
1609
1604
/**
1610
1605
  Mark transaction to rollback and mark error as fatal to a sub-statement.
1612
1607
  @param  session   Thread handle
1613
1608
  @param  all   true <=> rollback main transaction.
1614
1609
*/
1615
 
void Session::markTransactionForRollback(bool all)
 
1610
void mark_transaction_to_rollback(Session *session, bool all)
1616
1611
{
1617
 
  is_fatal_sub_stmt_error= true;
1618
 
  transaction_rollback_request= all;
 
1612
  if (session)
 
1613
  {
 
1614
    session->is_fatal_sub_stmt_error= true;
 
1615
    session->transaction_rollback_request= all;
 
1616
  }
1619
1617
}
1620
1618
 
1621
 
void Session::disconnect(enum error_t errcode)
 
1619
void Session::disconnect(uint32_t errcode, bool should_lock)
1622
1620
{
1623
1621
  /* Allow any plugins to cleanup their session variables */
1624
1622
  plugin_sessionvar_cleanup(this);
1625
1623
 
1626
1624
  /* If necessary, log any aborted or unauthorized connections */
1627
 
  if (getKilled() || client->wasAborted())
 
1625
  if (killed || client->wasAborted())
1628
1626
  {
1629
1627
    status_var.aborted_threads++;
1630
1628
  }
1631
1629
 
1632
1630
  if (client->wasAborted())
1633
1631
  {
1634
 
    if (not getKilled() && variables.log_warnings > 1)
 
1632
    if (! killed && variables.log_warnings > 1)
1635
1633
    {
1636
 
      errmsg_printf(error::WARN, ER(ER_NEW_ABORTING_CONNECTION)
 
1634
      SecurityContext *sctx= &security_ctx;
 
1635
 
 
1636
      errmsg_printf(ERRMSG_LVL_WARN, ER(ER_NEW_ABORTING_CONNECTION)
1637
1637
                  , 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()
 
1638
                  , (db.empty() ? "unconnected" : db.c_str())
 
1639
                  , sctx->getUser().empty() == false ? sctx->getUser().c_str() : "unauthenticated"
 
1640
                  , sctx->getIp().c_str()
1641
1641
                  , (main_da.is_error() ? main_da.message() : ER(ER_UNKNOWN_ERROR)));
1642
1642
    }
1643
1643
  }
1644
1644
 
1645
 
  setKilled(Session::KILL_CONNECTION);
1646
 
 
 
1645
  /* Close out our connection to the client */
 
1646
  if (should_lock)
 
1647
    LOCK_thread_count.lock();
 
1648
  killed= Session::KILL_CONNECTION;
1647
1649
  if (client->isConnected())
1648
1650
  {
1649
 
    if (errcode != EE_OK)
 
1651
    if (errcode)
1650
1652
    {
1651
1653
      /*my_error(errcode, ER(errcode));*/
1652
1654
      client->sendError(errcode, ER(errcode));
1653
1655
    }
1654
1656
    client->close();
1655
1657
  }
 
1658
  if (should_lock)
 
1659
    (void) LOCK_thread_count.unlock();
1656
1660
}
1657
1661
 
1658
1662
void Session::reset_for_next_command()
1680
1684
  Close all temporary tables created by 'CREATE TEMPORARY TABLE' for thread
1681
1685
*/
1682
1686
 
1683
 
void Open_tables_state::close_temporary_tables()
 
1687
void Session::close_temporary_tables()
1684
1688
{
1685
1689
  Table *table;
1686
1690
  Table *tmp_next;
1700
1704
  unlink from session->temporary tables and close temporary table
1701
1705
*/
1702
1706
 
1703
 
void Open_tables_state::close_temporary_table(Table *table)
 
1707
void Session::close_temporary_table(Table *table)
1704
1708
{
1705
1709
  if (table->getPrev())
1706
1710
  {
1736
1740
  If this is needed, use close_temporary_table()
1737
1741
*/
1738
1742
 
1739
 
void Open_tables_state::nukeTable(Table *table)
 
1743
void Session::nukeTable(Table *table)
1740
1744
{
1741
1745
  plugin::StorageEngine *table_type= table->getShare()->db_type();
1742
1746
 
1743
1747
  table->free_io_cache();
1744
1748
  table->delete_table();
1745
1749
 
1746
 
  identifier::Table identifier(table->getShare()->getSchemaName(), table->getShare()->getTableName(), table->getShare()->getPath());
 
1750
  TableIdentifier identifier(table->getShare()->getSchemaName(), table->getShare()->getTableName(), table->getShare()->getPath());
1747
1751
  rm_temporary_table(table_type, identifier);
1748
1752
 
1749
 
  boost::checked_delete(table->getMutableShare());
 
1753
  delete table->getMutableShare();
1750
1754
 
1751
 
  boost::checked_delete(table);
 
1755
  /* This makes me sad, but we're allocating it via malloc */
 
1756
  delete table;
1752
1757
}
1753
1758
 
1754
1759
/** Clear most status variables. */
1771
1776
 
1772
1777
user_var_entry *Session::getVariable(const std::string  &name, bool create_if_not_exists)
1773
1778
{
1774
 
  if (cleanup_done)
1775
 
    return NULL;
 
1779
  UserVarsRange ppp= user_vars.equal_range(name);
1776
1780
 
1777
 
  UserVars::iterator iter= user_vars.find(name);
1778
 
  if (iter != user_vars.end())
 
1781
  for (UserVars::iterator iter= ppp.first;
 
1782
       iter != ppp.second; ++iter)
 
1783
  {
1779
1784
    return (*iter).second;
 
1785
  }
1780
1786
 
1781
1787
  if (not create_if_not_exists)
1782
1788
    return NULL;
1791
1797
 
1792
1798
  if (not returnable.second)
1793
1799
  {
1794
 
    boost::checked_delete(entry);
 
1800
    delete entry;
1795
1801
  }
1796
1802
 
1797
1803
  return entry;
1800
1806
void Session::setVariable(const std::string &name, const std::string &value)
1801
1807
{
1802
1808
  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
 
  }
 
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);
1811
1815
}
1812
1816
 
1813
 
void Open_tables_state::mark_temp_tables_as_free_for_reuse()
 
1817
void Session::mark_temp_tables_as_free_for_reuse()
1814
1818
{
1815
1819
  for (Table *table= temporary_tables ; table ; table= table->getNext())
1816
1820
  {
1817
 
    if (table->query_id == getQueryId())
 
1821
    if (table->query_id == query_id)
1818
1822
    {
1819
1823
      table->query_id= 0;
1820
1824
      table->cursor->ha_reset();
1826
1830
{
1827
1831
  for (; table ; table= table->getNext())
1828
1832
  {
1829
 
    if (table->query_id == getQueryId())
 
1833
    if (table->query_id == query_id)
1830
1834
    {
1831
1835
      table->query_id= 0;
1832
1836
      table->cursor->ha_reset();
1845
1849
*/
1846
1850
void Session::close_thread_tables()
1847
1851
{
1848
 
  clearDerivedTables();
 
1852
  if (derived_tables)
 
1853
    derived_tables= NULL; // They should all be invalid by this point
1849
1854
 
1850
1855
  /*
1851
1856
    Mark all temporary tables used by this statement as free for reuse.
1862
1867
  {
1863
1868
    TransactionServices &transaction_services= TransactionServices::singleton();
1864
1869
    main_da.can_overwrite_status= true;
1865
 
    transaction_services.autocommitOrRollback(*this, is_error());
 
1870
    transaction_services.autocommitOrRollback(this, is_error());
1866
1871
    main_da.can_overwrite_status= false;
1867
1872
    transaction.stmt.reset();
1868
1873
  }
1878
1883
      handled either before writing a query log event (inside
1879
1884
      binlog_query()) or when preparing a pending event.
1880
1885
     */
1881
 
    unlockTables(lock);
 
1886
    mysql_unlock_tables(this, lock);
1882
1887
    lock= 0;
1883
1888
  }
1884
1889
  /*
1885
 
    Note that we need to hold table::Cache::singleton().mutex() while changing the
 
1890
    Note that we need to hold LOCK_open while changing the
1886
1891
    open_tables list. Another thread may work on it.
1887
 
    (See: table::Cache::singleton().removeTable(), wait_completed_table())
 
1892
    (See: remove_table_from_cache(), mysql_wait_completed_table())
1888
1893
    Closing a MERGE child before the parent would be fatal if the
1889
1894
    other thread tries to abort the MERGE lock in between.
1890
1895
  */
1918
1923
 
1919
1924
    if (not lock_tables(tables, counter, &need_reopen))
1920
1925
      break;
1921
 
 
1922
1926
    if (not need_reopen)
1923
1927
      return true;
1924
 
 
1925
1928
    close_tables_for_reopen(&tables);
1926
1929
  }
1927
 
 
1928
 
  if ((handle_derived(lex, &derived_prepare) || (handle_derived(lex, &derived_filling))))
 
1930
  if ((mysql_handle_derived(lex, &mysql_derived_prepare) ||
 
1931
       (
 
1932
        mysql_handle_derived(lex, &mysql_derived_filling))))
1929
1933
    return true;
1930
1934
 
1931
1935
  return false;
1937
1941
  might be an issue (lame engines).
1938
1942
*/
1939
1943
 
1940
 
bool Open_tables_state::rm_temporary_table(const identifier::Table &identifier, bool best_effort)
 
1944
bool Session::rm_temporary_table(TableIdentifier &identifier, bool best_effort)
1941
1945
{
1942
 
  if (not plugin::StorageEngine::dropTable(*static_cast<Session *>(this), identifier))
 
1946
  if (plugin::StorageEngine::dropTable(*this, identifier))
1943
1947
  {
1944
1948
    if (not best_effort)
1945
1949
    {
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);
 
1950
      errmsg_printf(ERRMSG_LVL_WARN, _("Could not remove temporary table: '%s', error: %d"),
 
1951
                    identifier.getSQLPath().c_str(), errno);
1950
1952
    }
1951
1953
 
1952
1954
    return true;
1955
1957
  return false;
1956
1958
}
1957
1959
 
1958
 
bool Open_tables_state::rm_temporary_table(plugin::StorageEngine *base, const identifier::Table &identifier)
 
1960
bool Session::rm_temporary_table(plugin::StorageEngine *base, TableIdentifier &identifier)
1959
1961
{
1960
 
  drizzled::error_t error;
1961
1962
  assert(base);
1962
1963
 
1963
 
  if (not plugin::StorageEngine::dropTable(*static_cast<Session *>(this), *base, identifier, error))
 
1964
  if (plugin::StorageEngine::dropTable(*this, *base, identifier))
1964
1965
  {
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);
 
1966
    errmsg_printf(ERRMSG_LVL_WARN, _("Could not remove temporary table: '%s', error: %d"),
 
1967
                  identifier.getSQLPath().c_str(), errno);
1969
1968
 
1970
1969
    return true;
1971
1970
  }
1977
1976
  @note this will be removed, I am looking through Hudson to see if it is finding
1978
1977
  any tables that are missed during cleanup.
1979
1978
*/
1980
 
void Open_tables_state::dumpTemporaryTableNames(const char *foo)
 
1979
void Session::dumpTemporaryTableNames(const char *foo)
1981
1980
{
1982
1981
  Table *table;
1983
1982
 
1989
1988
  {
1990
1989
    bool have_proto= false;
1991
1990
 
1992
 
    message::Table *proto= table->getShare()->getTableMessage();
1993
 
    if (table->getShare()->getTableMessage())
 
1991
    message::Table *proto= table->getShare()->getTableProto();
 
1992
    if (table->getShare()->getTableProto())
1994
1993
      have_proto= true;
1995
1994
 
1996
1995
    const char *answer= have_proto ? "true" : "false";
2001
2000
      cerr << "\t\t Proto " << proto->schema() << " " << proto->name() << "\n";
2002
2001
    }
2003
2002
    else
2004
 
    {
2005
2003
      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();
2015
 
 
2016
 
  assert(tmp_share);
2017
 
 
2018
 
  return tmp_share;
2019
 
}
2020
 
 
2021
 
 
2022
 
/**
2023
 
  Create a reduced Table object with properly set up Field list from a
2024
 
  list of field definitions.
2025
 
 
2026
 
    The created table doesn't have a table Cursor associated with
2027
 
    it, has no keys, no group/distinct, no copy_funcs array.
2028
 
    The sole purpose of this Table object is to use the power of Field
2029
 
    class to read/write data to/from table->getInsertRecord(). Then one can store
2030
 
    the record in any container (RB tree, hash, etc).
2031
 
    The table is created in Session mem_root, so are the table's fields.
2032
 
    Consequently, if you don't BLOB fields, you don't need to free it.
2033
 
 
2034
 
  @param session         connection handle
2035
 
  @param field_list  list of column definitions
2036
 
 
2037
 
  @return
2038
 
    0 if out of memory, Table object in case of success
2039
 
*/
2040
 
table::Singular *Session::getInstanceTable(List<CreateField> &field_list)
2041
 
{
2042
 
  temporary_shares.push_back(new table::Singular(this, field_list)); // This will not go into the tableshare cache, so no key is used.
2043
 
 
2044
 
  table::Singular *tmp_share= temporary_shares.back();
2045
 
 
2046
 
  assert(tmp_share);
2047
 
 
2048
 
  return tmp_share;
2049
 
}
2050
 
 
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 */
 
2004
  }
 
2005
}
 
2006
 
 
2007
bool Session::storeTableMessage(const TableIdentifier &identifier, message::Table &table_message)
 
2008
{
 
2009
  table_message_cache.insert(make_pair(identifier.getPath(), table_message));
 
2010
 
 
2011
  return true;
 
2012
}
 
2013
 
 
2014
bool Session::removeTableMessage(const TableIdentifier &identifier)
 
2015
{
 
2016
  TableMessageCache::iterator iter;
 
2017
 
 
2018
  iter= table_message_cache.find(identifier.getPath());
 
2019
 
 
2020
  if (iter == table_message_cache.end())
 
2021
    return false;
 
2022
 
 
2023
  table_message_cache.erase(iter);
 
2024
 
 
2025
  return true;
 
2026
}
 
2027
 
 
2028
bool Session::getTableMessage(const TableIdentifier &identifier, message::Table &table_message)
 
2029
{
 
2030
  TableMessageCache::iterator iter;
 
2031
 
 
2032
  iter= table_message_cache.find(identifier.getPath());
 
2033
 
 
2034
  if (iter == table_message_cache.end())
 
2035
    return false;
 
2036
 
 
2037
  table_message.CopyFrom(((*iter).second));
 
2038
 
 
2039
  return true;
 
2040
}
 
2041
 
 
2042
bool Session::doesTableMessageExist(const TableIdentifier &identifier)
 
2043
{
 
2044
  TableMessageCache::iterator iter;
 
2045
 
 
2046
  iter= table_message_cache.find(identifier.getPath());
 
2047
 
 
2048
  if (iter == table_message_cache.end())
 
2049
  {
 
2050
    return false;
 
2051
  }
 
2052
 
 
2053
  return true;
 
2054
}
 
2055
 
 
2056
bool Session::renameTableMessage(const TableIdentifier &from, const TableIdentifier &to)
 
2057
{
 
2058
  TableMessageCache::iterator iter;
 
2059
 
 
2060
  table_message_cache[to.getPath()]= table_message_cache[from.getPath()];
 
2061
 
 
2062
  iter= table_message_cache.find(to.getPath());
 
2063
 
 
2064
  if (iter == table_message_cache.end())
 
2065
  {
 
2066
    return false;
 
2067
  }
 
2068
 
 
2069
  (*iter).second.set_schema(to.getSchemaName());
 
2070
  (*iter).second.set_name(to.getTableName());
 
2071
 
 
2072
  return true;
 
2073
}
 
2074
 
 
2075
table::Instance *Session::getInstanceTable()
 
2076
{
 
2077
  temporary_shares.push_back(new table::Instance()); // This will not go into the tableshare cache, so no key is used.
 
2078
 
 
2079
  table::Instance *tmp_share= temporary_shares.back();
 
2080
 
 
2081
  assert(tmp_share);
 
2082
 
 
2083
  return tmp_share;
 
2084
}
2076
2085
 
2077
2086
} /* namespace drizzled */