~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/session.cc

  • Committer: Brian Aker
  • Date: 2009-01-07 09:27:07 UTC
  • Revision ID: brian@tangent.org-20090107092707-bn67qpdllfcyh3j9
Removing dead field translator code.

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
18
 */
19
19
 
20
 
/**
21
 
 * @file Implementation of the Session class and API
22
 
 */
23
20
 
24
 
#include "config.h"
25
 
#include "drizzled/session.h"
26
 
#include "drizzled/session/cache.h"
 
21
/*****************************************************************************
 
22
**
 
23
** This file implements classes defined in session.h
 
24
** Especially the classes to handle a result from a select
 
25
**
 
26
*****************************************************************************/
 
27
#include <drizzled/server_includes.h>
 
28
#include <drizzled/session.h>
 
29
#include <drizzled/replication/rli.h>
 
30
#include <drizzled/replication/record.h>
 
31
#include <drizzled/log_event.h>
27
32
#include <sys/stat.h>
28
 
#include "drizzled/error.h"
29
 
#include "drizzled/gettext.h"
30
 
#include "drizzled/query_id.h"
31
 
#include "drizzled/data_home.h"
32
 
#include "drizzled/sql_base.h"
33
 
#include "drizzled/lock.h"
34
 
#include "drizzled/item/cache.h"
35
 
#include "drizzled/item/float.h"
36
 
#include "drizzled/item/return_int.h"
37
 
#include "drizzled/item/empty_string.h"
38
 
#include "drizzled/show.h"
39
 
#include "drizzled/plugin/client.h"
40
 
#include "drizzled/plugin/scheduler.h"
41
 
#include "drizzled/plugin/authentication.h"
42
 
#include "drizzled/plugin/logging.h"
43
 
#include "drizzled/plugin/transactional_storage_engine.h"
44
 
#include "drizzled/plugin/query_rewrite.h"
45
 
#include "drizzled/probes.h"
46
 
#include "drizzled/table_proto.h"
47
 
#include "drizzled/db.h"
48
 
#include "drizzled/pthread_globals.h"
49
 
#include "drizzled/transaction_services.h"
50
 
#include "drizzled/drizzled.h"
51
 
 
52
 
#include "drizzled/table/instance.h"
53
 
 
54
 
#include "plugin/myisam/myisam.h"
55
 
#include "drizzled/internal/iocache.h"
56
 
#include "drizzled/internal/thread_var.h"
57
 
#include "drizzled/plugin/event_observer.h"
58
 
 
59
 
#include "drizzled/util/functors.h"
60
 
 
61
 
#include "drizzled/display.h"
62
 
 
63
 
#include <fcntl.h>
64
 
#include <algorithm>
65
 
#include <climits>
66
 
#include <boost/filesystem.hpp>
67
 
 
68
 
#include "drizzled/util/backtrace.h"
69
 
 
70
 
using namespace std;
71
 
 
72
 
namespace fs=boost::filesystem;
73
 
namespace drizzled
74
 
{
75
 
 
 
33
#include <mysys/thr_alarm.h>
 
34
#include <mysys/mysys_err.h>
 
35
#include <drizzled/error.h>
 
36
#include <drizzled/query_id.h>
 
37
#include <drizzled/data_home.h>
 
38
#include <drizzled/sql_base.h>
 
39
#include <drizzled/lock.h>
 
40
#include <drizzled/item/cache.h>
 
41
#include <drizzled/item/float.h>
 
42
#include <drizzled/item/return_int.h>
 
43
#include <drizzled/item/empty_string.h>
 
44
 
 
45
extern scheduler_functions thread_scheduler;
76
46
/*
77
47
  The following is used to initialise Table_ident with a internal
78
48
  table name
81
51
char empty_c_string[1]= {0};    /* used for not defined db */
82
52
 
83
53
const char * const Session::DEFAULT_WHERE= "field list";
 
54
extern pthread_key_t THR_Session;
 
55
extern pthread_key_t THR_Mem_root;
 
56
 
 
57
 
 
58
/*****************************************************************************
 
59
** Instansiate templates
 
60
*****************************************************************************/
 
61
 
 
62
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
 
63
/* Used templates */
 
64
template class List<Key>;
 
65
template class List_iterator<Key>;
 
66
template class List<Key_part_spec>;
 
67
template class List_iterator<Key_part_spec>;
 
68
template class List<Alter_drop>;
 
69
template class List_iterator<Alter_drop>;
 
70
template class List<Alter_column>;
 
71
template class List_iterator<Alter_column>;
 
72
#endif
 
73
 
 
74
 
 
75
/****************************************************************************
 
76
** User variables
 
77
****************************************************************************/
 
78
 
 
79
extern "C" unsigned char *get_var_key(user_var_entry *entry, size_t *length,
 
80
                              bool not_used __attribute__((unused)))
 
81
{
 
82
  *length= entry->name.length;
 
83
  return (unsigned char*) entry->name.str;
 
84
}
 
85
 
 
86
extern "C" void free_user_var(user_var_entry *entry)
 
87
{
 
88
  char *pos= (char*) entry+ALIGN_SIZE(sizeof(*entry));
 
89
  if (entry->value && entry->value != pos)
 
90
    free(entry->value);
 
91
  free((char*) entry);
 
92
}
84
93
 
85
94
bool Key_part_spec::operator==(const Key_part_spec& other) const
86
95
{
87
96
  return length == other.length &&
88
97
         field_name.length == other.field_name.length &&
89
 
    !my_strcasecmp(system_charset_info, field_name.str, other.field_name.str);
90
 
}
91
 
 
92
 
Open_tables_state::Open_tables_state(uint64_t version_arg) :
93
 
  version(version_arg)
94
 
{
95
 
  open_tables= temporary_tables= derived_tables= NULL;
96
 
  extra_lock= lock= NULL;
 
98
         !strcmp(field_name.str, other.field_name.str);
 
99
}
 
100
 
 
101
/**
 
102
  Construct an (almost) deep copy of this key. Only those
 
103
  elements that are known to never change are not copied.
 
104
  If out of memory, a partial copy is returned and an error is set
 
105
  in Session.
 
106
*/
 
107
 
 
108
Key::Key(const Key &rhs, MEM_ROOT *mem_root)
 
109
  :type(rhs.type),
 
110
  key_create_info(rhs.key_create_info),
 
111
  columns(rhs.columns, mem_root),
 
112
  name(rhs.name),
 
113
  generated(rhs.generated)
 
114
{
 
115
  list_copy_and_replace_each_value(columns, mem_root);
 
116
}
 
117
 
 
118
/**
 
119
  Construct an (almost) deep copy of this foreign key. Only those
 
120
  elements that are known to never change are not copied.
 
121
  If out of memory, a partial copy is returned and an error is set
 
122
  in Session.
 
123
*/
 
124
 
 
125
Foreign_key::Foreign_key(const Foreign_key &rhs, MEM_ROOT *mem_root)
 
126
  :Key(rhs),
 
127
  ref_table(rhs.ref_table),
 
128
  ref_columns(rhs.ref_columns),
 
129
  delete_opt(rhs.delete_opt),
 
130
  update_opt(rhs.update_opt),
 
131
  match_opt(rhs.match_opt)
 
132
{
 
133
  list_copy_and_replace_each_value(ref_columns, mem_root);
 
134
}
 
135
 
 
136
/*
 
137
  Test if a foreign key (= generated key) is a prefix of the given key
 
138
  (ignoring key name, key type and order of columns)
 
139
 
 
140
  NOTES:
 
141
    This is only used to test if an index for a FOREIGN KEY exists
 
142
 
 
143
  IMPLEMENTATION
 
144
    We only compare field names
 
145
 
 
146
  RETURN
 
147
    0   Generated key is a prefix of other key
 
148
    1   Not equal
 
149
*/
 
150
 
 
151
bool foreign_key_prefix(Key *a, Key *b)
 
152
{
 
153
  /* Ensure that 'a' is the generated key */
 
154
  if (a->generated)
 
155
  {
 
156
    if (b->generated && a->columns.elements > b->columns.elements)
 
157
      std::swap(a, b);                       // Put shorter key in 'a'
 
158
  }
 
159
  else
 
160
  {
 
161
    if (!b->generated)
 
162
      return true;                              // No foreign key
 
163
    std::swap(a, b);                       // Put generated key in 'a'
 
164
  }
 
165
 
 
166
  /* Test if 'a' is a prefix of 'b' */
 
167
  if (a->columns.elements > b->columns.elements)
 
168
    return true;                                // Can't be prefix
 
169
 
 
170
  List_iterator<Key_part_spec> col_it1(a->columns);
 
171
  List_iterator<Key_part_spec> col_it2(b->columns);
 
172
  const Key_part_spec *col1, *col2;
 
173
 
 
174
#ifdef ENABLE_WHEN_INNODB_CAN_HANDLE_SWAPED_FOREIGN_KEY_COLUMNS
 
175
  while ((col1= col_it1++))
 
176
  {
 
177
    bool found= 0;
 
178
    col_it2.rewind();
 
179
    while ((col2= col_it2++))
 
180
    {
 
181
      if (*col1 == *col2)
 
182
      {
 
183
        found= true;
 
184
        break;
 
185
      }
 
186
    }
 
187
    if (!found)
 
188
      return true;                              // Error
 
189
  }
 
190
  return false;                                 // Is prefix
 
191
#else
 
192
  while ((col1= col_it1++))
 
193
  {
 
194
    col2= col_it2++;
 
195
    if (!(*col1 == *col2))
 
196
      return true;
 
197
  }
 
198
  return false;                                 // Is prefix
 
199
#endif
 
200
}
 
201
 
 
202
 
 
203
/*
 
204
  Check if the foreign key options are compatible with columns
 
205
  on which the FK is created.
 
206
 
 
207
  RETURN
 
208
    0   Key valid
 
209
    1   Key invalid
 
210
*/
 
211
bool Foreign_key::validate(List<Create_field> &table_fields)
 
212
{
 
213
  Create_field  *sql_field;
 
214
  Key_part_spec *column;
 
215
  List_iterator<Key_part_spec> cols(columns);
 
216
  List_iterator<Create_field> it(table_fields);
 
217
  while ((column= cols++))
 
218
  {
 
219
    it.rewind();
 
220
    while ((sql_field= it++) &&
 
221
           my_strcasecmp(system_charset_info,
 
222
                         column->field_name.str,
 
223
                         sql_field->field_name)) {}
 
224
    if (!sql_field)
 
225
    {
 
226
      my_error(ER_KEY_COLUMN_DOES_NOT_EXITS, MYF(0), column->field_name.str);
 
227
      return true;
 
228
    }
 
229
    if (type == Key::FOREIGN_KEY && sql_field->vcol_info)
 
230
    {
 
231
      if (delete_opt == FK_OPTION_SET_NULL)
 
232
      {
 
233
        my_error(ER_WRONG_FK_OPTION_FOR_VIRTUAL_COLUMN, MYF(0),
 
234
                 "ON DELETE SET NULL");
 
235
        return true;
 
236
      }
 
237
      if (update_opt == FK_OPTION_SET_NULL)
 
238
      {
 
239
        my_error(ER_WRONG_FK_OPTION_FOR_VIRTUAL_COLUMN, MYF(0),
 
240
                 "ON UPDATE SET NULL");
 
241
        return true;
 
242
      }
 
243
      if (update_opt == FK_OPTION_CASCADE)
 
244
      {
 
245
        my_error(ER_WRONG_FK_OPTION_FOR_VIRTUAL_COLUMN, MYF(0),
 
246
                 "ON UPDATE CASCADE");
 
247
        return true;
 
248
      }
 
249
    }
 
250
  }
 
251
  return false;
 
252
}
 
253
 
 
254
 
 
255
/****************************************************************************
 
256
** Thread specific functions
 
257
****************************************************************************/
 
258
 
 
259
Open_tables_state::Open_tables_state(ulong version_arg)
 
260
  :version(version_arg), state_flags(0U)
 
261
{
 
262
  reset_open_tables_state();
97
263
}
98
264
 
99
265
/*
100
266
  The following functions form part of the C plugin API
101
267
*/
102
 
int mysql_tmpfile(const char *prefix)
 
268
 
 
269
extern "C" int mysql_tmpfile(const char *prefix)
103
270
{
104
271
  char filename[FN_REFLEN];
105
 
  int fd = internal::create_temp_file(filename, drizzle_tmpdir.c_str(), prefix, MYF(MY_WME));
 
272
  File fd = create_temp_file(filename, drizzle_tmpdir, prefix,
 
273
                             O_CREAT | O_EXCL | O_RDWR,
 
274
                             MYF(MY_WME));
106
275
  if (fd >= 0) {
107
276
    unlink(filename);
108
277
  }
110
279
  return fd;
111
280
}
112
281
 
 
282
 
 
283
extern "C"
 
284
int session_in_lock_tables(const Session *session)
 
285
{
 
286
  return test(session->in_lock_tables);
 
287
}
 
288
 
 
289
 
 
290
extern "C"
113
291
int session_tablespace_op(const Session *session)
114
292
{
115
293
  return test(session->tablespace_op);
116
294
}
117
295
 
 
296
 
118
297
/**
119
298
   Set the process info field of the Session structure.
120
299
 
123
302
 
124
303
   @see Session::set_proc_info
125
304
 */
126
 
void set_session_proc_info(Session *session, const char *info)
 
305
extern "C" void
 
306
set_session_proc_info(Session *session, const char *info)
127
307
{
128
308
  session->set_proc_info(info);
129
309
}
130
310
 
 
311
extern "C"
131
312
const char *get_session_proc_info(Session *session)
132
313
{
133
314
  return session->get_proc_info();
134
315
}
135
316
 
136
 
void **Session::getEngineData(const plugin::MonitoredInTransaction *monitored)
137
 
{
138
 
  return static_cast<void **>(&ha_data[monitored->getId()].ha_ptr);
139
 
}
140
 
 
141
 
ResourceContext *Session::getResourceContext(const plugin::MonitoredInTransaction *monitored,
142
 
                                             size_t index)
143
 
{
144
 
  return &ha_data[monitored->getId()].resource_context[index];
145
 
}
146
 
 
 
317
extern "C"
 
318
void **session_ha_data(const Session *session, const struct handlerton *hton)
 
319
{
 
320
  return (void **) &session->ha_data[hton->slot].ha_ptr;
 
321
}
 
322
 
 
323
extern "C"
147
324
int64_t session_test_options(const Session *session, int64_t test_options)
148
325
{
149
326
  return session->options & test_options;
150
327
}
151
328
 
 
329
extern "C"
152
330
int session_sql_command(const Session *session)
153
331
{
154
332
  return (int) session->lex->sql_command;
155
333
}
156
334
 
157
 
enum_tx_isolation session_tx_isolation(const Session *session)
158
 
{
159
 
  return (enum_tx_isolation)session->variables.tx_isolation;
160
 
}
161
 
 
162
 
Session::Session(plugin::Client *client_arg) :
163
 
  Open_tables_state(refresh_version),
164
 
  mem_root(&main_mem_root),
165
 
  xa_id(0),
166
 
  lex(&main_lex),
167
 
  query(new std::string),
168
 
  _schema(new std::string("")),
169
 
  catalog("LOCAL"),
170
 
  client(client_arg),
171
 
  scheduler(NULL),
172
 
  scheduler_arg(NULL),
173
 
  lock_id(&main_lock_id),
174
 
  user_time(0),
175
 
  ha_data(plugin::num_trx_monitored_objects),
176
 
  concurrent_execute_allowed(true),
177
 
  arg_of_last_insert_id_function(false),
178
 
  first_successful_insert_id_in_prev_stmt(0),
179
 
  first_successful_insert_id_in_cur_stmt(0),
180
 
  limit_found_rows(0),
181
 
  _global_read_lock(NONE),
182
 
  _killed(NOT_KILLED),
183
 
  some_tables_deleted(false),
184
 
  no_errors(false),
185
 
  password(false),
186
 
  is_fatal_error(false),
187
 
  transaction_rollback_request(false),
188
 
  is_fatal_sub_stmt_error(0),
189
 
  derived_tables_processing(false),
190
 
  tablespace_op(false),
191
 
  m_lip(NULL),
192
 
  cached_table(0),
193
 
  transaction_message(NULL),
194
 
  statement_message(NULL),
195
 
  session_event_observers(NULL),
196
 
  use_usage(false)
197
 
{
198
 
  client->setSession(this);
 
335
extern "C"
 
336
int session_tx_isolation(const Session *session)
 
337
{
 
338
  return (int) session->variables.tx_isolation;
 
339
}
 
340
 
 
341
extern "C"
 
342
void session_inc_row_count(Session *session)
 
343
{
 
344
  session->row_count++;
 
345
}
 
346
 
 
347
/**
 
348
  Clear this diagnostics area.
 
349
 
 
350
  Normally called at the end of a statement.
 
351
*/
 
352
 
 
353
void
 
354
Diagnostics_area::reset_diagnostics_area()
 
355
{
 
356
  can_overwrite_status= false;
 
357
  /** Don't take chances in production */
 
358
  m_message[0]= '\0';
 
359
  m_sql_errno= 0;
 
360
  m_server_status= 0;
 
361
  m_affected_rows= 0;
 
362
  m_last_insert_id= 0;
 
363
  m_total_warn_count= 0;
 
364
  is_sent= false;
 
365
  /** Tiny reset in debug mode to see garbage right away */
 
366
  m_status= DA_EMPTY;
 
367
}
 
368
 
 
369
 
 
370
/**
 
371
  Set OK status -- ends commands that do not return a
 
372
  result set, e.g. INSERT/UPDATE/DELETE.
 
373
*/
 
374
 
 
375
void
 
376
Diagnostics_area::set_ok_status(Session *session, ha_rows affected_rows_arg,
 
377
                                uint64_t last_insert_id_arg,
 
378
                                const char *message_arg)
 
379
{
 
380
  assert(! is_set());
 
381
  /*
 
382
    In production, refuse to overwrite an error or a custom response
 
383
    with an OK packet.
 
384
  */
 
385
  if (is_error() || is_disabled())
 
386
    return;
 
387
  /** Only allowed to report success if has not yet reported an error */
 
388
 
 
389
  m_server_status= session->server_status;
 
390
  m_total_warn_count= session->total_warn_count;
 
391
  m_affected_rows= affected_rows_arg;
 
392
  m_last_insert_id= last_insert_id_arg;
 
393
  if (message_arg)
 
394
    strncpy(m_message, message_arg, sizeof(m_message) - 1);
 
395
  else
 
396
    m_message[0]= '\0';
 
397
  m_status= DA_OK;
 
398
}
 
399
 
 
400
 
 
401
/**
 
402
  Set EOF status.
 
403
*/
 
404
 
 
405
void
 
406
Diagnostics_area::set_eof_status(Session *session)
 
407
{
 
408
  /** Only allowed to report eof if has not yet reported an error */
 
409
 
 
410
  assert(! is_set());
 
411
  /*
 
412
    In production, refuse to overwrite an error or a custom response
 
413
    with an EOF packet.
 
414
  */
 
415
  if (is_error() || is_disabled())
 
416
    return;
 
417
 
 
418
  m_server_status= session->server_status;
 
419
  /*
 
420
    If inside a stored procedure, do not return the total
 
421
    number of warnings, since they are not available to the client
 
422
    anyway.
 
423
  */
 
424
  m_total_warn_count= session->total_warn_count;
 
425
 
 
426
  m_status= DA_EOF;
 
427
}
 
428
 
 
429
/**
 
430
  Set ERROR status.
 
431
*/
 
432
 
 
433
void
 
434
Diagnostics_area::set_error_status(Session *session __attribute__((unused)),
 
435
                                   uint32_t sql_errno_arg,
 
436
                                   const char *message_arg)
 
437
{
 
438
  /*
 
439
    Only allowed to report error if has not yet reported a success
 
440
    The only exception is when we flush the message to the client,
 
441
    an error can happen during the flush.
 
442
  */
 
443
  assert(! is_set() || can_overwrite_status);
 
444
  /*
 
445
    In production, refuse to overwrite a custom response with an
 
446
    ERROR packet.
 
447
  */
 
448
  if (is_disabled())
 
449
    return;
 
450
 
 
451
  m_sql_errno= sql_errno_arg;
 
452
  strncpy(m_message, message_arg, sizeof(m_message) - 1);
 
453
 
 
454
  m_status= DA_ERROR;
 
455
}
 
456
 
 
457
 
 
458
/**
 
459
  Mark the diagnostics area as 'DISABLED'.
 
460
 
 
461
  This is used in rare cases when the COM_ command at hand sends a response
 
462
  in a custom format. One example is the query cache, another is
 
463
  COM_STMT_PREPARE.
 
464
*/
 
465
 
 
466
void
 
467
Diagnostics_area::disable_status()
 
468
{
 
469
  assert(! is_set());
 
470
  m_status= DA_DISABLED;
 
471
}
 
472
 
 
473
 
 
474
Session::Session()
 
475
   :Statement(&main_lex, &main_mem_root,
 
476
              /* statement id */ 0),
 
477
   Open_tables_state(refresh_version), rli_fake(0),
 
478
   lock_id(&main_lock_id),
 
479
   user_time(0),
 
480
   arg_of_last_insert_id_function(false),
 
481
   first_successful_insert_id_in_prev_stmt(0),
 
482
   first_successful_insert_id_in_cur_stmt(0),
 
483
   global_read_lock(0),
 
484
   is_fatal_error(0),
 
485
   transaction_rollback_request(0),
 
486
   is_fatal_sub_stmt_error(0),
 
487
   in_lock_tables(0),
 
488
   derived_tables_processing(false),
 
489
   m_lip(NULL)
 
490
{
 
491
  ulong tmp;
199
492
 
200
493
  /*
201
494
    Pass nominal parameters to init_alloc_root only to ensure that
202
495
    the destructor works OK in case of an error. The main_mem_root
203
496
    will be re-initialized in init_for_queries().
204
497
  */
205
 
  memory::init_sql_alloc(&main_mem_root, memory::ROOT_MIN_BLOCK_SIZE, 0);
206
 
  thread_stack= NULL;
207
 
  count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;
208
 
  col_access= 0;
209
 
  tmp_table= 0;
210
 
  used_tables= 0;
 
498
  init_sql_alloc(&main_mem_root, ALLOC_ROOT_MIN_BLOCK_SIZE, 0);
 
499
  thread_stack= 0;
 
500
  catalog= (char*)"std"; // the only catalog we have for now
 
501
  some_tables_deleted=no_errors=password= 0;
 
502
  count_cuted_fields= CHECK_FIELD_IGNORE;
 
503
  killed= NOT_KILLED;
 
504
  col_access=0;
 
505
  is_slave_error= thread_specific_used= false;
 
506
  hash_clear(&handler_tables_hash);
 
507
  tmp_table=0;
 
508
  used_tables=0;
211
509
  cuted_fields= sent_row_count= row_count= 0L;
 
510
  limit_found_rows= 0;
212
511
  row_count_func= -1;
213
512
  statement_id_counter= 0UL;
214
513
  // Must be reset to handle error with Session's created for init of mysqld
216
515
  start_time=(time_t) 0;
217
516
  start_utime= 0L;
218
517
  utime_after_lock= 0L;
 
518
  current_linfo =  0;
 
519
  slave_thread = 0;
219
520
  memset(&variables, 0, sizeof(variables));
220
521
  thread_id= 0;
221
522
  file_id = 0;
222
523
  query_id= 0;
223
 
  warn_query_id= 0;
224
 
  mysys_var= 0;
225
 
  scoreboard_index= -1;
 
524
  warn_id= 0;
 
525
  db_charset= global_system_variables.collation_database;
 
526
  memset(ha_data, 0, sizeof(ha_data));
 
527
  replication_data= 0;
 
528
  mysys_var=0;
 
529
  binlog_evt_union.do_union= false;
226
530
  dbug_sentry=Session_SENTRY_MAGIC;
227
 
  cleanup_done= abort_on_warning= no_warnings_for_error= false;  
228
 
 
229
 
  /* query_cache init */
230
 
  query_cache_key= "";
231
 
  resultset= NULL;
 
531
  net.vio= 0;
 
532
  client_capabilities= 0;                       // minimalistic client
 
533
  system_thread= NON_SYSTEM_THREAD;
 
534
  cleanup_done= abort_on_warning= no_warnings_for_error= 0;
 
535
  peer_port= 0;                                 // For SHOW PROCESSLIST
 
536
  transaction.m_pending_rows_event= 0;
 
537
  transaction.on= 1;
 
538
  pthread_mutex_init(&LOCK_delete, MY_MUTEX_INIT_FAST);
232
539
 
233
540
  /* Variables with default values */
234
541
  proc_info="login";
235
542
  where= Session::DEFAULT_WHERE;
236
 
  command= COM_CONNECT;
237
 
 
238
 
  plugin_sessionvar_init(this);
239
 
  /*
240
 
    variables= global_system_variables above has reset
241
 
    variables.pseudo_thread_id to 0. We need to correct it here to
242
 
    avoid temporary tables replication failure.
243
 
  */
244
 
  variables.pseudo_thread_id= thread_id;
245
 
  server_status= SERVER_STATUS_AUTOCOMMIT;
246
 
  options= session_startup_options;
247
 
 
248
 
  if (variables.max_join_size == HA_POS_ERROR)
249
 
    options |= OPTION_BIG_SELECTS;
250
 
  else
251
 
    options &= ~OPTION_BIG_SELECTS;
252
 
 
253
 
  open_options=ha_open_options;
254
 
  update_lock_default= TL_WRITE;
255
 
  session_tx_isolation= (enum_tx_isolation) variables.tx_isolation;
256
 
  warn_list.empty();
257
 
  memset(warn_count, 0, sizeof(warn_count));
258
 
  total_warn_count= 0;
259
 
  memset(&status_var, 0, sizeof(status_var));
260
 
 
 
543
  server_id = ::server_id;
 
544
  slave_net= NULL;
 
545
  command=COM_CONNECT;
 
546
  *scramble= '\0';
 
547
 
 
548
  init();
261
549
  /* Initialize sub structures */
262
 
  memory::init_sql_alloc(&warn_root, WARN_ALLOC_BLOCK_SIZE, WARN_ALLOC_PREALLOC_SIZE);
263
 
 
 
550
  init_sql_alloc(&warn_root, WARN_ALLOC_BLOCK_SIZE, WARN_ALLOC_PREALLOC_SIZE);
 
551
  user_connect=(USER_CONN *)0;
 
552
  hash_init(&user_vars, system_charset_info, USER_VARS_HASH_SIZE, 0, 0,
 
553
            (hash_get_key) get_var_key,
 
554
            (hash_free_key) free_user_var, 0);
 
555
 
 
556
  /* For user vars replication*/
 
557
  if (opt_bin_log)
 
558
    my_init_dynamic_array(&user_var_events,
 
559
                          sizeof(BINLOG_USER_VAR_EVENT *), 16, 16);
 
560
  else
 
561
    memset(&user_var_events, 0, sizeof(user_var_events));
 
562
 
 
563
  /* Protocol */
 
564
  protocol= &protocol_text;                     // Default protocol
 
565
  protocol_text.init(this);
 
566
 
 
567
  const Query_id& query_id= Query_id::get_query_id();
 
568
  tablespace_op= false;
 
569
  tmp= sql_rnd();
 
570
  randominit(&rand, tmp + (ulong) &rand, tmp + query_id.value());
264
571
  substitute_null_with_insert_id = false;
265
 
  lock_info.init(); /* safety: will be reset after start */
 
572
  thr_lock_info_init(&lock_info); /* safety: will be reset after start */
266
573
  thr_lock_owner_init(&main_lock_id, &lock_info);
267
574
 
268
575
  m_internal_handler= NULL;
269
 
  
270
 
  plugin::EventObserver::registerSessionEvents(*this); 
271
576
}
272
577
 
273
 
void Session::free_items()
274
 
{
275
 
  Item *next;
276
 
  /* This works because items are allocated with memory::sql_alloc() */
277
 
  for (; free_list; free_list= next)
278
 
  {
279
 
    next= free_list->next;
280
 
    free_list->delete_self();
281
 
  }
282
 
}
283
578
 
284
579
void Session::push_internal_handler(Internal_error_handler *handler)
285
580
{
291
586
  m_internal_handler= handler;
292
587
}
293
588
 
 
589
 
294
590
bool Session::handle_error(uint32_t sql_errno, const char *message,
295
591
                       DRIZZLE_ERROR::enum_warning_level level)
296
592
{
302
598
  return false;                                 // 'false', as per coding style
303
599
}
304
600
 
305
 
void Session::setAbort(bool arg)
306
 
{
307
 
  mysys_var->abort= arg;
308
 
}
309
 
 
310
 
void Session::lockOnSys()
311
 
{
312
 
  if (not mysys_var)
313
 
    return;
314
 
 
315
 
  setAbort(true);
316
 
  boost_unique_lock_t scopedLock(mysys_var->mutex);
317
 
  if (mysys_var->current_cond)
318
 
  {
319
 
    mysys_var->current_mutex->lock();
320
 
    mysys_var->current_cond->notify_all();
321
 
    mysys_var->current_mutex->unlock();
322
 
  }
323
 
}
324
601
 
325
602
void Session::pop_internal_handler()
326
603
{
328
605
  m_internal_handler= NULL;
329
606
}
330
607
 
331
 
void Session::get_xid(DRIZZLE_XID *xid)
332
 
{
333
 
  *xid = *(DRIZZLE_XID *) &transaction.xid_state.xid;
334
 
}
 
608
#if defined(__cplusplus)
 
609
extern "C" {
 
610
#endif
 
611
 
 
612
void *session_alloc(Session *session, unsigned int size)
 
613
{
 
614
  return session->alloc(size);
 
615
}
 
616
 
 
617
void *session_calloc(Session *session, unsigned int size)
 
618
{
 
619
  return session->calloc(size);
 
620
}
 
621
 
 
622
char *session_strdup(Session *session, const char *str)
 
623
{
 
624
  return session->strdup(str);
 
625
}
 
626
 
 
627
char *session_strmake(Session *session, const char *str, unsigned int size)
 
628
{
 
629
  return session->strmake(str, size);
 
630
}
 
631
 
 
632
void *session_memdup(Session *session, const void* str, unsigned int size)
 
633
{
 
634
  return session->memdup(str, size);
 
635
}
 
636
 
 
637
void session_get_xid(const Session *session, DRIZZLE_XID *xid)
 
638
{
 
639
  *xid = *(DRIZZLE_XID *) &session->transaction.xid_state.xid;
 
640
}
 
641
 
 
642
#if defined(__cplusplus)
 
643
}
 
644
#endif
 
645
 
 
646
/*
 
647
  Init common variables that has to be reset on start and on change_user
 
648
*/
 
649
 
 
650
void Session::init(void)
 
651
{
 
652
  pthread_mutex_lock(&LOCK_global_system_variables);
 
653
  plugin_sessionvar_init(this);
 
654
  variables.time_format= date_time_format_copy((Session*) 0,
 
655
                                               variables.time_format);
 
656
  variables.date_format= date_time_format_copy((Session*) 0,
 
657
                                               variables.date_format);
 
658
  variables.datetime_format= date_time_format_copy((Session*) 0,
 
659
                                                   variables.datetime_format);
 
660
  /*
 
661
    variables= global_system_variables above has reset
 
662
    variables.pseudo_thread_id to 0. We need to correct it here to
 
663
    avoid temporary tables replication failure.
 
664
  */
 
665
  variables.pseudo_thread_id= thread_id;
 
666
  pthread_mutex_unlock(&LOCK_global_system_variables);
 
667
  server_status= SERVER_STATUS_AUTOCOMMIT;
 
668
  options= session_startup_options;
 
669
 
 
670
  if (variables.max_join_size == HA_POS_ERROR)
 
671
    options |= OPTION_BIG_SELECTS;
 
672
  else
 
673
    options &= ~OPTION_BIG_SELECTS;
 
674
 
 
675
  transaction.all.modified_non_trans_table= transaction.stmt.modified_non_trans_table= false;
 
676
  open_options=ha_open_options;
 
677
  update_lock_default= TL_WRITE;
 
678
  session_tx_isolation= (enum_tx_isolation) variables.tx_isolation;
 
679
  warn_list.empty();
 
680
  memset(warn_count, 0, sizeof(warn_count));
 
681
  total_warn_count= 0;
 
682
  update_charset();
 
683
  memset(&status_var, 0, sizeof(status_var));
 
684
}
 
685
 
 
686
 
 
687
/*
 
688
  Init Session for query processing.
 
689
  This has to be called once before we call mysql_parse.
 
690
  See also comments in session.h.
 
691
*/
 
692
 
 
693
void Session::init_for_queries()
 
694
{
 
695
  set_time();
 
696
  ha_enable_transaction(this,true);
 
697
 
 
698
  reset_root_defaults(mem_root, variables.query_alloc_block_size,
 
699
                      variables.query_prealloc_size);
 
700
  reset_root_defaults(&transaction.mem_root,
 
701
                      variables.trans_alloc_block_size,
 
702
                      variables.trans_prealloc_size);
 
703
  transaction.xid_state.xid.null();
 
704
  transaction.xid_state.in_session=1;
 
705
}
 
706
 
335
707
 
336
708
/* Do operations that may take a long time */
337
709
 
338
710
void Session::cleanup(void)
339
711
{
340
 
  assert(cleanup_done == false);
 
712
  assert(cleanup_done == 0);
341
713
 
342
 
  setKilled(KILL_CONNECTION);
 
714
  killed= KILL_CONNECTION;
343
715
#ifdef ENABLE_WHEN_BINLOG_WILL_BE_ABLE_TO_PREPARE
344
716
  if (transaction.xid_state.xa_state == XA_PREPARED)
345
717
  {
347
719
  }
348
720
#endif
349
721
  {
350
 
    TransactionServices &transaction_services= TransactionServices::singleton();
351
 
    transaction_services.rollbackTransaction(this, true);
 
722
    ha_rollback(this);
352
723
    xid_cache_delete(&transaction.xid_state);
353
724
  }
354
 
 
355
 
  for (UserVars::iterator iter= user_vars.begin();
356
 
       iter != user_vars.end();
357
 
       iter++)
 
725
  if (locked_tables)
358
726
  {
359
 
    user_var_entry *entry= (*iter).second;
360
 
    delete entry;
 
727
    lock=locked_tables; locked_tables=0;
 
728
    close_thread_tables(this);
361
729
  }
362
 
  user_vars.clear();
363
 
 
364
 
 
365
 
  close_temporary_tables();
 
730
  mysql_ha_cleanup(this);
 
731
  delete_dynamic(&user_var_events);
 
732
  hash_free(&user_vars);
 
733
  close_temporary_tables(this);
 
734
  free((char*) variables.time_format);
 
735
  free((char*) variables.date_format);
 
736
  free((char*) variables.datetime_format);
366
737
 
367
738
  if (global_read_lock)
368
 
  {
369
 
    unlockGlobalReadLock();
370
 
  }
 
739
    unlock_global_read_lock(this);
371
740
 
372
 
  cleanup_done= true;
 
741
  cleanup_done=1;
 
742
  return;
373
743
}
374
744
 
375
745
Session::~Session()
376
746
{
377
 
  this->checkSentry();
378
 
 
379
 
  if (client->isConnected())
380
 
  {
381
 
    if (global_system_variables.log_warnings)
382
 
        errmsg_printf(ERRMSG_LVL_WARN, ER(ER_FORCING_CLOSE),internal::my_progname,
383
 
                      thread_id,
384
 
                      (getSecurityContext().getUser().c_str() ?
385
 
                       getSecurityContext().getUser().c_str() : ""));
386
 
    disconnect(0, false);
387
 
  }
 
747
  Session_CHECK_SENTRY(this);
 
748
  /* Ensure that no one is using Session */
 
749
  pthread_mutex_lock(&LOCK_delete);
 
750
  pthread_mutex_unlock(&LOCK_delete);
 
751
  add_to_status(&global_status_var, &status_var);
388
752
 
389
753
  /* Close connection */
390
 
  client->close();
391
 
  delete client;
392
 
 
393
 
  if (cleanup_done == false)
 
754
  if (net.vio)
 
755
  {
 
756
    net_close(&net);
 
757
    net_end(&net);
 
758
  }
 
759
  if (!cleanup_done)
394
760
    cleanup();
395
761
 
396
 
  plugin::StorageEngine::closeConnection(this);
 
762
  ha_close_connection(this);
397
763
  plugin_sessionvar_cleanup(this);
398
764
 
399
 
  warn_root.free_root(MYF(0));
 
765
  if (db)
 
766
  {
 
767
    free(db);
 
768
    db= NULL;
 
769
  }
 
770
  free_root(&warn_root,MYF(0));
 
771
  free_root(&transaction.mem_root,MYF(0));
400
772
  mysys_var=0;                                  // Safety (shouldn't be needed)
 
773
  pthread_mutex_destroy(&LOCK_delete);
401
774
  dbug_sentry= Session_SENTRY_GONE;
402
 
 
403
 
  main_mem_root.free_root(MYF(0));
404
 
  currentMemRoot().release();
405
 
  currentSession().release();
406
 
 
407
 
  plugin::Logging::postEndDo(this);
408
 
  plugin::EventObserver::deregisterSessionEvents(*this); 
409
 
 
410
 
  for (PropertyMap::iterator iter= life_properties.begin(); iter != life_properties.end(); iter++)
 
775
  if (rli_fake)
411
776
  {
412
 
    delete (*iter).second;
 
777
    delete rli_fake;
 
778
    rli_fake= NULL;
413
779
  }
414
 
  life_properties.clear();
415
 
}
416
 
 
417
 
void Session::setClient(plugin::Client *client_arg)
418
 
{
419
 
  client= client_arg;
420
 
  client->setSession(this);
421
 
}
422
 
 
423
 
void Session::awake(Session::killed_state_t state_to_set)
424
 
{
425
 
  if ((state_to_set == Session::KILL_QUERY) and (command == COM_SLEEP))
426
 
    return;
427
 
 
428
 
  this->checkSentry();
429
 
 
430
 
  setKilled(state_to_set);
431
 
  scheduler->killSession(this);
432
 
 
 
780
 
 
781
  free_root(&main_mem_root, MYF(0));
 
782
  pthread_setspecific(THR_Session,  0);
 
783
  return;
 
784
}
 
785
 
 
786
 
 
787
/*
 
788
  Add all status variables to another status variable array
 
789
 
 
790
  SYNOPSIS
 
791
   add_to_status()
 
792
   to_var       add to this array
 
793
   from_var     from this array
 
794
 
 
795
  NOTES
 
796
    This function assumes that all variables are long/ulong.
 
797
    If this assumption will change, then we have to explictely add
 
798
    the other variables after the while loop
 
799
*/
 
800
 
 
801
void add_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var)
 
802
{
 
803
  ulong *end= (ulong*) ((unsigned char*) to_var +
 
804
                        offsetof(STATUS_VAR, last_system_status_var) +
 
805
                        sizeof(ulong));
 
806
  ulong *to= (ulong*) to_var, *from= (ulong*) from_var;
 
807
 
 
808
  while (to != end)
 
809
    *(to++)+= *(from++);
 
810
}
 
811
 
 
812
/*
 
813
  Add the difference between two status variable arrays to another one.
 
814
 
 
815
  SYNOPSIS
 
816
    add_diff_to_status
 
817
    to_var       add to this array
 
818
    from_var     from this array
 
819
    dec_var      minus this array
 
820
 
 
821
  NOTE
 
822
    This function assumes that all variables are long/ulong.
 
823
*/
 
824
 
 
825
void add_diff_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var,
 
826
                        STATUS_VAR *dec_var)
 
827
{
 
828
  ulong *end= (ulong*) ((unsigned char*) to_var + offsetof(STATUS_VAR,
 
829
                                                  last_system_status_var) +
 
830
                        sizeof(ulong));
 
831
  ulong *to= (ulong*) to_var, *from= (ulong*) from_var, *dec= (ulong*) dec_var;
 
832
 
 
833
  while (to != end)
 
834
    *(to++)+= *(from++) - *(dec++);
 
835
}
 
836
 
 
837
 
 
838
void Session::awake(Session::killed_state state_to_set)
 
839
{
 
840
  Session_CHECK_SENTRY(this);
 
841
  safe_mutex_assert_owner(&LOCK_delete);
 
842
 
 
843
  killed= state_to_set;
433
844
  if (state_to_set != Session::KILL_QUERY)
434
845
  {
435
 
    DRIZZLE_CONNECTION_DONE(thread_id);
 
846
    thr_alarm_kill(thread_id);
 
847
    if (!slave_thread)
 
848
      thread_scheduler.post_kill_notification(this);
436
849
  }
437
 
 
438
850
  if (mysys_var)
439
851
  {
440
 
    boost_unique_lock_t scopedLock(mysys_var->mutex);
 
852
    pthread_mutex_lock(&mysys_var->mutex);
 
853
    if (!system_thread)         // Don't abort locks
 
854
      mysys_var->abort=1;
441
855
    /*
442
 
      "
443
856
      This broadcast could be up in the air if the victim thread
444
857
      exits the cond in the time between read and broadcast, but that is
445
858
      ok since all we want to do is to make the victim thread get out
460
873
    */
461
874
    if (mysys_var->current_cond && mysys_var->current_mutex)
462
875
    {
463
 
      mysys_var->current_mutex->lock();
464
 
      mysys_var->current_cond->notify_all();
465
 
      mysys_var->current_mutex->unlock();
 
876
      pthread_mutex_lock(mysys_var->current_mutex);
 
877
      pthread_cond_broadcast(mysys_var->current_cond);
 
878
      pthread_mutex_unlock(mysys_var->current_mutex);
466
879
    }
 
880
    pthread_mutex_unlock(&mysys_var->mutex);
467
881
  }
 
882
  return;
468
883
}
469
884
 
470
885
/*
471
886
  Remember the location of thread info, the structure needed for
472
 
  memory::sql_alloc() and the structure for the net buffer
 
887
  sql_alloc() and the structure for the net buffer
473
888
*/
474
 
bool Session::storeGlobals()
 
889
 
 
890
bool Session::store_globals()
475
891
{
476
892
  /*
477
893
    Assert that thread_stack is initialized: it's necessary to be able
479
895
  */
480
896
  assert(thread_stack);
481
897
 
482
 
  currentSession().release();
483
 
  currentSession().reset(this);
484
 
 
485
 
  currentMemRoot().release();
486
 
  currentMemRoot().reset(&mem_root);
487
 
 
 
898
  if (pthread_setspecific(THR_Session,  this) ||
 
899
      pthread_setspecific(THR_Mem_root, &mem_root))
 
900
    return 1;
488
901
  mysys_var=my_thread_var;
489
 
 
490
902
  /*
491
903
    Let mysqld define the thread id (not mysys)
492
904
    This allows us to move Session to different threads if needed.
493
905
  */
494
906
  mysys_var->id= thread_id;
 
907
  real_id= pthread_self();                      // For debugging
495
908
 
496
909
  /*
497
910
    We have to call thr_lock_info_init() again here as Session may have been
498
911
    created in another thread
499
912
  */
500
 
  lock_info.init();
501
 
 
502
 
  return false;
503
 
}
504
 
 
505
 
/*
506
 
  Init Session for query processing.
507
 
  This has to be called once before we call mysql_parse.
508
 
  See also comments in session.h.
509
 
*/
510
 
 
511
 
void Session::prepareForQueries()
512
 
{
513
 
  if (variables.max_join_size == HA_POS_ERROR)
514
 
    options |= OPTION_BIG_SELECTS;
515
 
 
516
 
  version= refresh_version;
517
 
  set_proc_info(NULL);
518
 
  command= COM_SLEEP;
519
 
  set_time();
520
 
 
521
 
  mem_root->reset_root_defaults(variables.query_alloc_block_size,
522
 
                                variables.query_prealloc_size);
523
 
  transaction.xid_state.xid.null();
524
 
  transaction.xid_state.in_session=1;
525
 
  if (use_usage)
526
 
    resetUsage();
527
 
}
528
 
 
529
 
bool Session::initGlobals()
530
 
{
531
 
  if (storeGlobals())
532
 
  {
533
 
    disconnect(ER_OUT_OF_RESOURCES, true);
534
 
    status_var.aborted_connects++;
535
 
    return true;
536
 
  }
537
 
  return false;
538
 
}
539
 
 
540
 
void Session::run()
541
 
{
542
 
  if (initGlobals() || authenticate())
543
 
  {
544
 
    disconnect(0, true);
545
 
    return;
546
 
  }
547
 
 
548
 
  prepareForQueries();
549
 
 
550
 
  while (not client->haveError() && getKilled() != KILL_CONNECTION)
551
 
  {
552
 
    if (not executeStatement())
553
 
      break;
554
 
  }
555
 
 
556
 
  disconnect(0, true);
557
 
}
558
 
 
559
 
bool Session::schedule(Session::shared_ptr &arg)
560
 
{
561
 
  arg->scheduler= plugin::Scheduler::getScheduler();
562
 
  assert(arg->scheduler);
563
 
 
564
 
  connection_count.increment();
565
 
 
566
 
  if (connection_count > current_global_counters.max_used_connections)
567
 
  {
568
 
    current_global_counters.max_used_connections= connection_count;
569
 
  }
570
 
 
571
 
  current_global_counters.connections++;
572
 
  arg->thread_id= arg->variables.pseudo_thread_id= global_thread_id++;
573
 
 
574
 
  session::Cache::singleton().insert(arg);
575
 
 
576
 
  if (unlikely(plugin::EventObserver::connectSession(*arg)))
577
 
  {
578
 
    // We should do something about an error...
579
 
  }
580
 
 
581
 
  if (plugin::Scheduler::getScheduler()->addSession(arg))
582
 
  {
583
 
    DRIZZLE_CONNECTION_START(arg->getSessionId());
584
 
    char error_message_buff[DRIZZLE_ERRMSG_SIZE];
585
 
 
586
 
    arg->setKilled(Session::KILL_CONNECTION);
587
 
 
588
 
    arg->status_var.aborted_connects++;
589
 
 
590
 
    /* Can't use my_error() since store_globals has not been called. */
591
 
    /* TODO replace will better error message */
592
 
    snprintf(error_message_buff, sizeof(error_message_buff),
593
 
             ER(ER_CANT_CREATE_THREAD), 1);
594
 
    arg->client->sendError(ER_CANT_CREATE_THREAD, error_message_buff);
595
 
 
596
 
    return true;
597
 
  }
598
 
 
599
 
  return false;
600
 
}
601
 
 
602
 
 
603
 
/*
604
 
  Is this session viewable by the current user?
605
 
*/
606
 
bool Session::isViewable() const
607
 
{
608
 
  return plugin::Authorization::isAuthorized(current_session->getSecurityContext(),
609
 
                                             this,
610
 
                                             false);
611
 
}
612
 
 
613
 
 
614
 
const char* Session::enter_cond(boost::condition_variable_any &cond, boost::mutex &mutex, const char* msg)
615
 
{
616
 
  const char* old_msg = get_proc_info();
617
 
  safe_mutex_assert_owner(mutex);
618
 
  mysys_var->current_mutex = &mutex;
619
 
  mysys_var->current_cond = &cond;
620
 
  this->set_proc_info(msg);
621
 
  return old_msg;
622
 
}
623
 
 
624
 
void Session::exit_cond(const char* old_msg)
625
 
{
626
 
  /*
627
 
    Putting the mutex unlock in exit_cond() ensures that
628
 
    mysys_var->current_mutex is always unlocked _before_ mysys_var->mutex is
629
 
    locked (if that would not be the case, you'll get a deadlock if someone
630
 
    does a Session::awake() on you).
631
 
  */
632
 
  mysys_var->current_mutex->unlock();
633
 
  boost_unique_lock_t scopedLock(mysys_var->mutex);
634
 
  mysys_var->current_mutex = 0;
635
 
  mysys_var->current_cond = 0;
636
 
  this->set_proc_info(old_msg);
637
 
}
638
 
 
639
 
bool Session::authenticate()
640
 
{
641
 
  lex->start(this);
642
 
  if (client->authenticate())
643
 
    return false;
644
 
 
645
 
  status_var.aborted_connects++;
646
 
 
647
 
  return true;
648
 
}
649
 
 
650
 
bool Session::checkUser(const std::string &passwd_str,
651
 
                        const std::string &in_db)
652
 
{
653
 
  bool is_authenticated=
654
 
    plugin::Authentication::isAuthenticated(getSecurityContext(),
655
 
                                            passwd_str);
656
 
 
657
 
  if (is_authenticated != true)
658
 
  {
659
 
    status_var.access_denied++;
660
 
    /* isAuthenticated has pushed the error message */
661
 
    return false;
662
 
  }
663
 
 
664
 
  /* Change database if necessary */
665
 
  if (not in_db.empty())
666
 
  {
667
 
    SchemaIdentifier identifier(in_db);
668
 
    if (mysql_change_db(this, identifier))
669
 
    {
670
 
      /* mysql_change_db() has pushed the error message. */
671
 
      return false;
672
 
    }
673
 
  }
674
 
  my_ok();
675
 
  password= not passwd_str.empty();
676
 
 
677
 
  /* Ready to handle queries */
678
 
  return true;
679
 
}
680
 
 
681
 
bool Session::executeStatement()
682
 
{
683
 
  char *l_packet= 0;
684
 
  uint32_t packet_length;
685
 
 
686
 
  enum enum_server_command l_command;
687
 
 
688
 
  /*
689
 
    indicator of uninitialized lex => normal flow of errors handling
690
 
    (see my_message_sql)
691
 
  */
692
 
  lex->current_select= 0;
693
 
  clear_error();
694
 
  main_da.reset_diagnostics_area();
695
 
 
696
 
  if (client->readCommand(&l_packet, &packet_length) == false)
697
 
  {
698
 
    return false;
699
 
  }
700
 
 
701
 
  if (getKilled() == KILL_CONNECTION)
702
 
    return false;
703
 
 
704
 
  if (packet_length == 0)
705
 
    return true;
706
 
 
707
 
  l_command= static_cast<enum_server_command>(l_packet[0]);
708
 
 
709
 
  if (command >= COM_END)
710
 
    command= COM_END;                           // Wrong command
711
 
 
712
 
  assert(packet_length);
713
 
  return not dispatch_command(l_command, this, l_packet+1, (uint32_t) (packet_length-1));
714
 
}
715
 
 
716
 
bool Session::readAndStoreQuery(const char *in_packet, uint32_t in_packet_length)
717
 
{
718
 
  /* Remove garbage at start and end of query */
719
 
  while (in_packet_length > 0 && my_isspace(charset(), in_packet[0]))
720
 
  {
721
 
    in_packet++;
722
 
    in_packet_length--;
723
 
  }
724
 
  const char *pos= in_packet + in_packet_length; /* Point at end null */
725
 
  while (in_packet_length > 0 && (pos[-1] == ';' || my_isspace(charset() ,pos[-1])))
726
 
  {
727
 
    pos--;
728
 
    in_packet_length--;
729
 
  }
730
 
 
731
 
  std::string *new_query= new std::string(in_packet, in_packet + in_packet_length);
732
 
  // We can not be entirely sure _schema has a value
733
 
  if (_schema)
734
 
  {
735
 
    plugin::QueryRewriter::rewriteQuery(*_schema, *new_query);
736
 
  }
737
 
  query.reset(new_query);
738
 
  _state.reset(new State(in_packet, in_packet_length));
739
 
 
740
 
  return true;
741
 
}
742
 
 
743
 
bool Session::endTransaction(enum enum_mysql_completiontype completion)
744
 
{
745
 
  bool do_release= 0;
746
 
  bool result= true;
747
 
  TransactionServices &transaction_services= TransactionServices::singleton();
748
 
 
749
 
  if (transaction.xid_state.xa_state != XA_NOTR)
750
 
  {
751
 
    my_error(ER_XAER_RMFAIL, MYF(0), xa_state_names[transaction.xid_state.xa_state]);
752
 
    return false;
753
 
  }
754
 
  switch (completion)
755
 
  {
756
 
    case COMMIT:
757
 
      /*
758
 
       * We don't use endActiveTransaction() here to ensure that this works
759
 
       * even if there is a problem with the OPTION_AUTO_COMMIT flag
760
 
       * (Which of course should never happen...)
761
 
       */
762
 
      server_status&= ~SERVER_STATUS_IN_TRANS;
763
 
      if (transaction_services.commitTransaction(this, true))
764
 
        result= false;
765
 
      options&= ~(OPTION_BEGIN);
766
 
      break;
767
 
    case COMMIT_RELEASE:
768
 
      do_release= 1; /* fall through */
769
 
    case COMMIT_AND_CHAIN:
770
 
      result= endActiveTransaction();
771
 
      if (result == true && completion == COMMIT_AND_CHAIN)
772
 
        result= startTransaction();
773
 
      break;
774
 
    case ROLLBACK_RELEASE:
775
 
      do_release= 1; /* fall through */
776
 
    case ROLLBACK:
777
 
    case ROLLBACK_AND_CHAIN:
778
 
    {
779
 
      server_status&= ~SERVER_STATUS_IN_TRANS;
780
 
      if (transaction_services.rollbackTransaction(this, true))
781
 
        result= false;
782
 
      options&= ~(OPTION_BEGIN);
783
 
      if (result == true && (completion == ROLLBACK_AND_CHAIN))
784
 
        result= startTransaction();
785
 
      break;
786
 
    }
787
 
    default:
788
 
      my_error(ER_UNKNOWN_COM_ERROR, MYF(0));
789
 
      return false;
790
 
  }
791
 
 
792
 
  if (result == false)
793
 
  {
794
 
    my_error(killed_errno(), MYF(0));
795
 
  }
796
 
  else if ((result == true) && do_release)
797
 
  {
798
 
    setKilled(Session::KILL_CONNECTION);
799
 
  }
800
 
 
801
 
  return result;
802
 
}
803
 
 
804
 
bool Session::endActiveTransaction()
805
 
{
806
 
  bool result= true;
807
 
  TransactionServices &transaction_services= TransactionServices::singleton();
808
 
 
809
 
  if (transaction.xid_state.xa_state != XA_NOTR)
810
 
  {
811
 
    my_error(ER_XAER_RMFAIL, MYF(0), xa_state_names[transaction.xid_state.xa_state]);
812
 
    return false;
813
 
  }
814
 
  if (options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
815
 
  {
816
 
    server_status&= ~SERVER_STATUS_IN_TRANS;
817
 
    if (transaction_services.commitTransaction(this, true))
818
 
      result= false;
819
 
  }
820
 
  options&= ~(OPTION_BEGIN);
821
 
  return result;
822
 
}
823
 
 
824
 
bool Session::startTransaction(start_transaction_option_t opt)
825
 
{
826
 
  bool result= true;
827
 
 
828
 
  if (! endActiveTransaction())
829
 
  {
830
 
    result= false;
831
 
  }
832
 
  else
833
 
  {
834
 
    options|= OPTION_BEGIN;
835
 
    server_status|= SERVER_STATUS_IN_TRANS;
836
 
 
837
 
    if (plugin::TransactionalStorageEngine::notifyStartTransaction(this, opt))
838
 
    {
839
 
      result= false;
840
 
    }
841
 
  }
842
 
 
843
 
  return result;
844
 
}
 
913
  thr_lock_info_init(&lock_info);
 
914
  return 0;
 
915
}
 
916
 
 
917
 
 
918
/*
 
919
  Cleanup after query.
 
920
 
 
921
  SYNOPSIS
 
922
    Session::cleanup_after_query()
 
923
 
 
924
  DESCRIPTION
 
925
    This function is used to reset thread data to its default state.
 
926
 
 
927
  NOTE
 
928
    This function is not suitable for setting thread data to some
 
929
    non-default values, as there is only one replication thread, so
 
930
    different master threads may overwrite data of each other on
 
931
    slave.
 
932
*/
845
933
 
846
934
void Session::cleanup_after_query()
847
935
{
856
944
  if (first_successful_insert_id_in_cur_stmt > 0)
857
945
  {
858
946
    /* set what LAST_INSERT_ID() will return */
859
 
    first_successful_insert_id_in_prev_stmt= first_successful_insert_id_in_cur_stmt;
 
947
    first_successful_insert_id_in_prev_stmt=
 
948
      first_successful_insert_id_in_cur_stmt;
860
949
    first_successful_insert_id_in_cur_stmt= 0;
861
950
    substitute_null_with_insert_id= true;
862
951
  }
863
 
  arg_of_last_insert_id_function= false;
 
952
  arg_of_last_insert_id_function= 0;
864
953
  /* Free Items that were created during this execution */
865
954
  free_items();
866
955
  /* Reset where. */
867
956
  where= Session::DEFAULT_WHERE;
868
 
 
869
 
  /* Reset the temporary shares we built */
870
 
  for_each(temporary_shares.begin(),
871
 
           temporary_shares.end(),
872
 
           DeletePtr());
873
 
  temporary_shares.clear();
874
957
}
875
958
 
 
959
 
876
960
/**
877
961
  Create a LEX_STRING in this connection.
878
962
 
884
968
  @return  NULL on failure, or pointer to the LEX_STRING object
885
969
*/
886
970
LEX_STRING *Session::make_lex_string(LEX_STRING *lex_str,
887
 
                                     const std::string &str,
888
 
                                     bool allocate_lex_string)
889
 
{
890
 
  return make_lex_string(lex_str, str.c_str(), str.length(), allocate_lex_string);
891
 
}
892
 
 
893
 
LEX_STRING *Session::make_lex_string(LEX_STRING *lex_str,
894
 
                                     const char* str, uint32_t length,
895
 
                                     bool allocate_lex_string)
 
971
                                 const char* str, uint32_t length,
 
972
                                 bool allocate_lex_string)
896
973
{
897
974
  if (allocate_lex_string)
898
975
    if (!(lex_str= (LEX_STRING *)alloc(sizeof(LEX_STRING))))
899
976
      return 0;
900
 
  if (!(lex_str->str= mem_root->strmake_root(str, length)))
 
977
  if (!(lex_str->str= strmake_root(mem_root, str, length)))
901
978
    return 0;
902
979
  lex_str->length= length;
903
980
  return lex_str;
904
981
}
905
982
 
 
983
 
 
984
/*
 
985
  Convert a string to another character set
 
986
 
 
987
  SYNOPSIS
 
988
    convert_string()
 
989
    to                          Store new allocated string here
 
990
    to_cs                       New character set for allocated string
 
991
    from                        String to convert
 
992
    from_length                 Length of string to convert
 
993
    from_cs                     Original character set
 
994
 
 
995
  NOTES
 
996
    to will be 0-terminated to make it easy to pass to system funcs
 
997
 
 
998
  RETURN
 
999
    0   ok
 
1000
    1   End of memory.
 
1001
        In this case to->str will point to 0 and to->length will be 0.
 
1002
*/
 
1003
 
 
1004
bool Session::convert_string(LEX_STRING *to, const CHARSET_INFO * const to_cs,
 
1005
                         const char *from, uint32_t from_length,
 
1006
                         const CHARSET_INFO * const from_cs)
 
1007
{
 
1008
  size_t new_length= to_cs->mbmaxlen * from_length;
 
1009
  uint32_t dummy_errors;
 
1010
  if (!(to->str= (char*) alloc(new_length+1)))
 
1011
  {
 
1012
    to->length= 0;                              // Safety fix
 
1013
    return(1);                          // EOM
 
1014
  }
 
1015
  to->length= copy_and_convert((char*) to->str, new_length, to_cs,
 
1016
                               from, from_length, from_cs, &dummy_errors);
 
1017
  to->str[to->length]=0;                        // Safety
 
1018
  return(0);
 
1019
}
 
1020
 
 
1021
 
 
1022
/*
 
1023
  Convert string from source character set to target character set inplace.
 
1024
 
 
1025
  SYNOPSIS
 
1026
    Session::convert_string
 
1027
 
 
1028
  DESCRIPTION
 
1029
    Convert string using convert_buffer - buffer for character set
 
1030
    conversion shared between all protocols.
 
1031
 
 
1032
  RETURN
 
1033
    0   ok
 
1034
   !0   out of memory
 
1035
*/
 
1036
 
 
1037
bool Session::convert_string(String *s, const CHARSET_INFO * const from_cs,
 
1038
                         const CHARSET_INFO * const to_cs)
 
1039
{
 
1040
  uint32_t dummy_errors;
 
1041
  if (convert_buffer.copy(s->ptr(), s->length(), from_cs, to_cs, &dummy_errors))
 
1042
    return true;
 
1043
  /* If convert_buffer >> s copying is more efficient long term */
 
1044
  if (convert_buffer.alloced_length() >= convert_buffer.length() * 2 ||
 
1045
      !s->is_alloced())
 
1046
  {
 
1047
    return s->copy(convert_buffer);
 
1048
  }
 
1049
  s->swap(convert_buffer);
 
1050
  return false;
 
1051
}
 
1052
 
 
1053
 
 
1054
/*
 
1055
  Update some cache variables when character set changes
 
1056
*/
 
1057
 
 
1058
void Session::update_charset()
 
1059
{
 
1060
  uint32_t not_used;
 
1061
  charset_is_system_charset= !String::needs_conversion(0,charset(),
 
1062
                                                       system_charset_info,
 
1063
                                                       &not_used);
 
1064
  charset_is_collation_connection=
 
1065
    !String::needs_conversion(0,charset(),variables.getCollation(),
 
1066
                              &not_used);
 
1067
  charset_is_character_set_filesystem=
 
1068
    !String::needs_conversion(0, charset(),
 
1069
                              variables.character_set_filesystem, &not_used);
 
1070
}
 
1071
 
 
1072
 
 
1073
/* routings to adding tables to list of changed in transaction tables */
 
1074
 
 
1075
inline static void list_include(CHANGED_TableList** prev,
 
1076
                                CHANGED_TableList* curr,
 
1077
                                CHANGED_TableList* new_table)
 
1078
{
 
1079
  if (new_table)
 
1080
  {
 
1081
    *prev = new_table;
 
1082
    (*prev)->next = curr;
 
1083
  }
 
1084
}
 
1085
 
 
1086
/* add table to list of changed in transaction tables */
 
1087
 
 
1088
void Session::add_changed_table(Table *table)
 
1089
{
 
1090
  assert((options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) &&
 
1091
              table->file->has_transactions());
 
1092
  add_changed_table(table->s->table_cache_key.str,
 
1093
                    (long) table->s->table_cache_key.length);
 
1094
  return;
 
1095
}
 
1096
 
 
1097
 
 
1098
void Session::add_changed_table(const char *key, long key_length)
 
1099
{
 
1100
  CHANGED_TableList **prev_changed = &transaction.changed_tables;
 
1101
  CHANGED_TableList *curr = transaction.changed_tables;
 
1102
 
 
1103
  for (; curr; prev_changed = &(curr->next), curr = curr->next)
 
1104
  {
 
1105
    int cmp =  (long)curr->key_length - (long)key_length;
 
1106
    if (cmp < 0)
 
1107
    {
 
1108
      list_include(prev_changed, curr, changed_table_dup(key, key_length));
 
1109
      return;
 
1110
    }
 
1111
    else if (cmp == 0)
 
1112
    {
 
1113
      cmp = memcmp(curr->key, key, curr->key_length);
 
1114
      if (cmp < 0)
 
1115
      {
 
1116
        list_include(prev_changed, curr, changed_table_dup(key, key_length));
 
1117
        return;
 
1118
      }
 
1119
      else if (cmp == 0)
 
1120
      {
 
1121
        return;
 
1122
      }
 
1123
    }
 
1124
  }
 
1125
  *prev_changed = changed_table_dup(key, key_length);
 
1126
  return;
 
1127
}
 
1128
 
 
1129
 
 
1130
CHANGED_TableList* Session::changed_table_dup(const char *key, long key_length)
 
1131
{
 
1132
  CHANGED_TableList* new_table =
 
1133
    (CHANGED_TableList*) trans_alloc(ALIGN_SIZE(sizeof(CHANGED_TableList))+
 
1134
                                      key_length + 1);
 
1135
  if (!new_table)
 
1136
  {
 
1137
    my_error(EE_OUTOFMEMORY, MYF(ME_BELL),
 
1138
             ALIGN_SIZE(sizeof(TableList)) + key_length + 1);
 
1139
    killed= KILL_CONNECTION;
 
1140
    return 0;
 
1141
  }
 
1142
 
 
1143
  new_table->key= ((char*)new_table)+ ALIGN_SIZE(sizeof(CHANGED_TableList));
 
1144
  new_table->next = 0;
 
1145
  new_table->key_length = key_length;
 
1146
  ::memcpy(new_table->key, key, key_length);
 
1147
  return new_table;
 
1148
}
 
1149
 
 
1150
 
906
1151
int Session::send_explain_fields(select_result *result)
907
1152
{
908
1153
  List<Item> field_list;
938
1183
  }
939
1184
  item->maybe_null= 1;
940
1185
  field_list.push_back(new Item_empty_string("Extra", 255, cs));
941
 
  return (result->send_fields(field_list));
942
 
}
943
 
 
944
 
void select_result::send_error(uint32_t errcode, const char *err)
 
1186
  return (result->send_fields(field_list,
 
1187
                              Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF));
 
1188
}
 
1189
 
 
1190
 
 
1191
struct Item_change_record: public ilink
 
1192
{
 
1193
  Item **place;
 
1194
  Item *old_value;
 
1195
  /* Placement new was hidden by `new' in ilink (TODO: check): */
 
1196
  static void *operator new(size_t size __attribute__((unused)),
 
1197
                            void *mem)
 
1198
    { return mem; }
 
1199
  static void operator delete(void *ptr __attribute__((unused)),
 
1200
                              size_t size __attribute__((unused)))
 
1201
    {}
 
1202
  static void operator delete(void *ptr __attribute__((unused)),
 
1203
                              void *mem __attribute__((unused)))
 
1204
    { /* never called */ }
 
1205
};
 
1206
 
 
1207
 
 
1208
/*
 
1209
  Register an item tree tree transformation, performed by the query
 
1210
  optimizer. We need a pointer to runtime_memroot because it may be !=
 
1211
  session->mem_root (this may no longer be a true statement)
 
1212
*/
 
1213
 
 
1214
void Session::nocheck_register_item_tree_change(Item **place, Item *old_value,
 
1215
                                            MEM_ROOT *runtime_memroot)
 
1216
{
 
1217
  Item_change_record *change;
 
1218
  /*
 
1219
    Now we use one node per change, which adds some memory overhead,
 
1220
    but still is rather fast as we use alloc_root for allocations.
 
1221
    A list of item tree changes of an average query should be short.
 
1222
  */
 
1223
  void *change_mem= alloc_root(runtime_memroot, sizeof(*change));
 
1224
  if (change_mem == 0)
 
1225
  {
 
1226
    /*
 
1227
      OOM, session->fatal_error() is called by the error handler of the
 
1228
      memroot. Just return.
 
1229
    */
 
1230
    return;
 
1231
  }
 
1232
  change= new (change_mem) Item_change_record;
 
1233
  change->place= place;
 
1234
  change->old_value= old_value;
 
1235
  change_list.append(change);
 
1236
}
 
1237
 
 
1238
 
 
1239
void Session::rollback_item_tree_changes()
 
1240
{
 
1241
  I_List_iterator<Item_change_record> it(change_list);
 
1242
  Item_change_record *change;
 
1243
 
 
1244
  while ((change= it++))
 
1245
    *change->place= change->old_value;
 
1246
  /* We can forget about changes memory: it's allocated in runtime memroot */
 
1247
  change_list.empty();
 
1248
  return;
 
1249
}
 
1250
 
 
1251
 
 
1252
/*****************************************************************************
 
1253
** Functions to provide a interface to select results
 
1254
*****************************************************************************/
 
1255
 
 
1256
select_result::select_result()
 
1257
{
 
1258
  session=current_session;
 
1259
}
 
1260
 
 
1261
void select_result::send_error(uint32_t errcode,const char *err)
945
1262
{
946
1263
  my_message(errcode, err, MYF(0));
947
1264
}
948
1265
 
 
1266
 
 
1267
void select_result::cleanup()
 
1268
{
 
1269
  /* do nothing */
 
1270
}
 
1271
 
 
1272
static String default_line_term("\n",default_charset_info);
 
1273
static String default_escaped("\\",default_charset_info);
 
1274
static String default_field_term("\t",default_charset_info);
 
1275
 
 
1276
sql_exchange::sql_exchange(char *name, bool flag,
 
1277
                           enum enum_filetype filetype_arg)
 
1278
  :file_name(name), opt_enclosed(0), dumpfile(flag), skip_lines(0)
 
1279
{
 
1280
  filetype= filetype_arg;
 
1281
  field_term= &default_field_term;
 
1282
  enclosed=   line_start= &my_empty_string;
 
1283
  line_term=  &default_line_term;
 
1284
  escaped=    &default_escaped;
 
1285
  cs= NULL;
 
1286
}
 
1287
 
 
1288
bool select_send::send_fields(List<Item> &list, uint32_t flags)
 
1289
{
 
1290
  bool res;
 
1291
  if (!(res= session->protocol->send_fields(&list, flags)))
 
1292
    is_result_set_started= 1;
 
1293
  return res;
 
1294
}
 
1295
 
 
1296
void select_send::abort()
 
1297
{
 
1298
  return;
 
1299
}
 
1300
 
 
1301
 
 
1302
/**
 
1303
  Cleanup an instance of this class for re-use
 
1304
  at next execution of a prepared statement/
 
1305
  stored procedure statement.
 
1306
*/
 
1307
 
 
1308
void select_send::cleanup()
 
1309
{
 
1310
  is_result_set_started= false;
 
1311
}
 
1312
 
 
1313
/* Send data to client. Returns 0 if ok */
 
1314
 
 
1315
bool select_send::send_data(List<Item> &items)
 
1316
{
 
1317
  if (unit->offset_limit_cnt)
 
1318
  {                                             // using limit offset,count
 
1319
    unit->offset_limit_cnt--;
 
1320
    return 0;
 
1321
  }
 
1322
 
 
1323
  /*
 
1324
    We may be passing the control from mysqld to the client: release the
 
1325
    InnoDB adaptive hash S-latch to avoid thread deadlocks if it was reserved
 
1326
    by session
 
1327
  */
 
1328
  ha_release_temporary_latches(session);
 
1329
 
 
1330
  List_iterator_fast<Item> li(items);
 
1331
  Protocol *protocol= session->protocol;
 
1332
  char buff[MAX_FIELD_WIDTH];
 
1333
  String buffer(buff, sizeof(buff), &my_charset_bin);
 
1334
 
 
1335
  protocol->prepare_for_resend();
 
1336
  Item *item;
 
1337
  while ((item=li++))
 
1338
  {
 
1339
    if (item->send(protocol, &buffer))
 
1340
    {
 
1341
      protocol->free();                         // Free used buffer
 
1342
      my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
 
1343
      break;
 
1344
    }
 
1345
  }
 
1346
  session->sent_row_count++;
 
1347
  if (session->is_error())
 
1348
  {
 
1349
    protocol->remove_last_row();
 
1350
    return(1);
 
1351
  }
 
1352
  if (session->vio_ok())
 
1353
    return(protocol->write());
 
1354
  return(0);
 
1355
}
 
1356
 
 
1357
bool select_send::send_eof()
 
1358
{
 
1359
  /*
 
1360
    We may be passing the control from mysqld to the client: release the
 
1361
    InnoDB adaptive hash S-latch to avoid thread deadlocks if it was reserved
 
1362
    by session
 
1363
  */
 
1364
  ha_release_temporary_latches(session);
 
1365
 
 
1366
  /* Unlock tables before sending packet to gain some speed */
 
1367
  if (session->lock)
 
1368
  {
 
1369
    mysql_unlock_tables(session, session->lock);
 
1370
    session->lock=0;
 
1371
  }
 
1372
  ::my_eof(session);
 
1373
  is_result_set_started= 0;
 
1374
  return false;
 
1375
}
 
1376
 
 
1377
 
949
1378
/************************************************************************
950
1379
  Handling writing to file
951
1380
************************************************************************/
955
1384
  my_message(errcode, err, MYF(0));
956
1385
  if (file > 0)
957
1386
  {
958
 
    (void) cache->end_io_cache();
959
 
    (void) internal::my_close(file, MYF(0));
960
 
    (void) internal::my_delete(path.file_string().c_str(), MYF(0));             // Delete file on error
 
1387
    (void) end_io_cache(&cache);
 
1388
    (void) my_close(file,MYF(0));
 
1389
    (void) my_delete(path,MYF(0));              // Delete file on error
961
1390
    file= -1;
962
1391
  }
963
1392
}
965
1394
 
966
1395
bool select_to_file::send_eof()
967
1396
{
968
 
  int error= test(cache->end_io_cache());
969
 
  if (internal::my_close(file, MYF(MY_WME)))
 
1397
  int error= test(end_io_cache(&cache));
 
1398
  if (my_close(file,MYF(MY_WME)))
970
1399
    error= 1;
971
1400
  if (!error)
972
1401
  {
975
1404
      function, SELECT INTO has to have an own SQLCOM.
976
1405
      TODO: split from SQLCOM_SELECT
977
1406
    */
978
 
    session->my_ok(row_count);
 
1407
    ::my_ok(session,row_count);
979
1408
  }
980
1409
  file= -1;
981
1410
  return error;
987
1416
  /* In case of error send_eof() may be not called: close the file here. */
988
1417
  if (file >= 0)
989
1418
  {
990
 
    (void) cache->end_io_cache();
991
 
    (void) internal::my_close(file, MYF(0));
 
1419
    (void) end_io_cache(&cache);
 
1420
    (void) my_close(file,MYF(0));
992
1421
    file= -1;
993
1422
  }
994
 
  path= "";
 
1423
  path[0]= '\0';
995
1424
  row_count= 0;
996
1425
}
997
1426
 
998
 
select_to_file::select_to_file(file_exchange *ex)
999
 
  : exchange(ex),
1000
 
    file(-1),
1001
 
    cache(static_cast<internal::IO_CACHE *>(memory::sql_calloc(sizeof(internal::IO_CACHE)))),
1002
 
    row_count(0L)
1003
 
{
1004
 
  path= "";
1005
 
}
1006
1427
 
1007
1428
select_to_file::~select_to_file()
1008
1429
{
1009
 
  cleanup();
 
1430
  if (file >= 0)
 
1431
  {                                     // This only happens in case of error
 
1432
    (void) end_io_cache(&cache);
 
1433
    (void) my_close(file,MYF(0));
 
1434
    file= -1;
 
1435
  }
1010
1436
}
1011
1437
 
1012
1438
/***************************************************************************
1035
1461
*/
1036
1462
 
1037
1463
 
1038
 
static int create_file(Session *session,
1039
 
                       fs::path &target_path,
1040
 
                       file_exchange *exchange,
1041
 
                       internal::IO_CACHE *cache)
 
1464
static File create_file(Session *session, char *path, sql_exchange *exchange,
 
1465
                        IO_CACHE *cache)
1042
1466
{
1043
 
  fs::path to_file(exchange->file_name);
1044
 
  int file;
1045
 
 
1046
 
  if (not to_file.has_root_directory())
 
1467
  File file;
 
1468
  uint32_t option= MY_UNPACK_FILENAME | MY_RELATIVE_PATH;
 
1469
 
 
1470
#ifdef DONT_ALLOW_FULL_LOAD_DATA_PATHS
 
1471
  option|= MY_REPLACE_DIR;                      // Force use of db directory
 
1472
#endif
 
1473
 
 
1474
  if (!dirname_length(exchange->file_name))
1047
1475
  {
1048
 
    target_path= fs::system_complete(getDataHomeCatalog());
1049
 
    util::string::const_shared_ptr schema(session->schema());
1050
 
    if (schema and not schema->empty())
1051
 
    {
1052
 
      int count_elements= 0;
1053
 
      for (fs::path::iterator iter= to_file.begin();
1054
 
           iter != to_file.end();
1055
 
           ++iter, ++count_elements)
1056
 
      { }
1057
 
 
1058
 
      if (count_elements == 1)
1059
 
      {
1060
 
        target_path /= *schema;
1061
 
      }
1062
 
    }
1063
 
    target_path /= to_file;
 
1476
    strcpy(path, drizzle_real_data_home);
 
1477
    if (session->db)
 
1478
      strncat(path, session->db, FN_REFLEN-strlen(drizzle_real_data_home)-1);
 
1479
    (void) fn_format(path, exchange->file_name, path, "", option);
1064
1480
  }
1065
1481
  else
1066
 
  {
1067
 
    target_path = exchange->file_name;
1068
 
  }
1069
 
 
1070
 
  if (not secure_file_priv.string().empty())
1071
 
  {
1072
 
    if (target_path.file_string().substr(0, secure_file_priv.file_string().size()) != secure_file_priv.file_string())
1073
 
    {
1074
 
      /* Write only allowed to dir or subdir specified by secure_file_priv */
1075
 
      my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--secure-file-priv");
1076
 
      return -1;
1077
 
    }
1078
 
  }
1079
 
 
1080
 
  if (!access(target_path.file_string().c_str(), F_OK))
 
1482
    (void) fn_format(path, exchange->file_name, drizzle_real_data_home, "", option);
 
1483
 
 
1484
  if (opt_secure_file_priv &&
 
1485
      strncmp(opt_secure_file_priv, path, strlen(opt_secure_file_priv)))
 
1486
  {
 
1487
    /* Write only allowed to dir or subdir specified by secure_file_priv */
 
1488
    my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--secure-file-priv");
 
1489
    return -1;
 
1490
  }
 
1491
 
 
1492
  if (!access(path, F_OK))
1081
1493
  {
1082
1494
    my_error(ER_FILE_EXISTS_ERROR, MYF(0), exchange->file_name);
1083
1495
    return -1;
1084
1496
  }
1085
1497
  /* Create the file world readable */
1086
 
  if ((file= internal::my_create(target_path.file_string().c_str(), 0666, O_WRONLY|O_EXCL, MYF(MY_WME))) < 0)
 
1498
  if ((file= my_create(path, 0666, O_WRONLY|O_EXCL, MYF(MY_WME))) < 0)
1087
1499
    return file;
 
1500
#ifdef HAVE_FCHMOD
1088
1501
  (void) fchmod(file, 0666);                    // Because of umask()
1089
 
  if (cache->init_io_cache(file, 0L, internal::WRITE_CACHE, 0L, 1, MYF(MY_WME)))
 
1502
#else
 
1503
  (void) chmod(path, 0666);
 
1504
#endif
 
1505
  if (init_io_cache(cache, file, 0L, WRITE_CACHE, 0L, 1, MYF(MY_WME)))
1090
1506
  {
1091
 
    internal::my_close(file, MYF(0));
1092
 
    internal::my_delete(target_path.file_string().c_str(), MYF(0));  // Delete file on error, it was just created
 
1507
    my_close(file, MYF(0));
 
1508
    my_delete(path, MYF(0));  // Delete file on error, it was just created
1093
1509
    return -1;
1094
1510
  }
1095
1511
  return file;
1097
1513
 
1098
1514
 
1099
1515
int
1100
 
select_export::prepare(List<Item> &list, Select_Lex_Unit *u)
 
1516
select_export::prepare(List<Item> &list, SELECT_LEX_UNIT *u)
1101
1517
{
1102
1518
  bool blob_flag=0;
1103
1519
  bool string_results= false, non_string_results= false;
1104
1520
  unit= u;
1105
 
  if ((uint32_t) strlen(exchange->file_name) + NAME_LEN >= FN_REFLEN)
1106
 
  {
1107
 
    path= exchange->file_name;
1108
 
  }
 
1521
  if ((uint) strlen(exchange->file_name) + NAME_LEN >= FN_REFLEN)
 
1522
    strncpy(path,exchange->file_name,FN_REFLEN-1);
1109
1523
 
1110
1524
  /* Check if there is any blobs in data */
1111
1525
  {
1115
1529
    {
1116
1530
      if (item->max_length >= MAX_BLOB_WIDTH)
1117
1531
      {
1118
 
        blob_flag=1;
1119
 
        break;
 
1532
        blob_flag=1;
 
1533
        break;
1120
1534
      }
1121
 
 
1122
1535
      if (item->result_type() == STRING_RESULT)
1123
1536
        string_results= true;
1124
1537
      else
1153
1566
    return 1;
1154
1567
  }
1155
1568
 
1156
 
  if ((file= create_file(session, path, exchange, cache)) < 0)
 
1569
  if ((file= create_file(session, path, exchange, &cache)) < 0)
1157
1570
    return 1;
1158
1571
 
1159
1572
  return 0;
1160
1573
}
1161
1574
 
 
1575
 
 
1576
#define NEED_ESCAPING(x) ((int) (unsigned char) (x) == escape_char    || \
 
1577
                          (enclosed ? (int) (unsigned char) (x) == field_sep_char      \
 
1578
                                    : (int) (unsigned char) (x) == field_term_char) || \
 
1579
                          (int) (unsigned char) (x) == line_sep_char  || \
 
1580
                          !(x))
 
1581
 
1162
1582
bool select_export::send_data(List<Item> &items)
1163
1583
{
1164
1584
  char buff[MAX_FIELD_WIDTH],null_buff[2],space[MAX_FIELD_WIDTH];
1169
1589
  if (unit->offset_limit_cnt)
1170
1590
  {                                             // using limit offset,count
1171
1591
    unit->offset_limit_cnt--;
1172
 
    return false;
 
1592
    return(0);
1173
1593
  }
1174
1594
  row_count++;
1175
1595
  Item *item;
1176
1596
  uint32_t used_length=0,items_left=items.elements;
1177
1597
  List_iterator_fast<Item> li(items);
1178
1598
 
1179
 
  if (my_b_write(cache,(unsigned char*) exchange->line_start->ptr(),
1180
 
                 exchange->line_start->length()))
1181
 
    return true;
1182
 
 
 
1599
  if (my_b_write(&cache,(unsigned char*) exchange->line_start->ptr(),
 
1600
                 exchange->line_start->length()))
 
1601
    goto err;
1183
1602
  while ((item=li++))
1184
1603
  {
1185
1604
    Item_result result_type=item->result_type();
1188
1607
    res=item->str_result(&tmp);
1189
1608
    if (res && enclosed)
1190
1609
    {
1191
 
      if (my_b_write(cache,(unsigned char*) exchange->enclosed->ptr(),
1192
 
                     exchange->enclosed->length()))
1193
 
        return true;
 
1610
      if (my_b_write(&cache,(unsigned char*) exchange->enclosed->ptr(),
 
1611
                     exchange->enclosed->length()))
 
1612
        goto err;
1194
1613
    }
1195
1614
    if (!res)
1196
1615
    {                                           // NULL
1197
1616
      if (!fixed_row_size)
1198
1617
      {
1199
 
        if (escape_char != -1)                  // Use \N syntax
1200
 
        {
1201
 
          null_buff[0]=escape_char;
1202
 
          null_buff[1]='N';
1203
 
          if (my_b_write(cache,(unsigned char*) null_buff,2))
1204
 
            return true;
1205
 
        }
1206
 
        else if (my_b_write(cache,(unsigned char*) "NULL",4))
1207
 
          return true;
 
1618
        if (escape_char != -1)                  // Use \N syntax
 
1619
        {
 
1620
          null_buff[0]=escape_char;
 
1621
          null_buff[1]='N';
 
1622
          if (my_b_write(&cache,(unsigned char*) null_buff,2))
 
1623
            goto err;
 
1624
        }
 
1625
        else if (my_b_write(&cache,(unsigned char*) "NULL",4))
 
1626
          goto err;
1208
1627
      }
1209
1628
      else
1210
1629
      {
1211
 
        used_length=0;                          // Fill with space
 
1630
        used_length=0;                          // Fill with space
1212
1631
      }
1213
1632
    }
1214
1633
    else
1215
1634
    {
1216
1635
      if (fixed_row_size)
1217
 
        used_length= min(res->length(), static_cast<size_t>(item->max_length));
 
1636
        used_length=cmin(res->length(),item->max_length);
1218
1637
      else
1219
 
        used_length= res->length();
1220
 
 
 
1638
        used_length=res->length();
1221
1639
      if ((result_type == STRING_RESULT || is_unsafe_field_sep) &&
1222
 
          escape_char != -1)
 
1640
           escape_char != -1)
1223
1641
      {
1224
1642
        char *pos, *start, *end;
1225
1643
        const CHARSET_INFO * const res_charset= res->charset();
1226
1644
        const CHARSET_INFO * const character_set_client= default_charset_info;
1227
1645
 
1228
1646
        bool check_second_byte= (res_charset == &my_charset_bin) &&
1229
 
          character_set_client->
1230
 
          escape_with_backslash_is_dangerous;
 
1647
                                 character_set_client->
 
1648
                                 escape_with_backslash_is_dangerous;
1231
1649
        assert(character_set_client->mbmaxlen == 2 ||
1232
1650
               !character_set_client->escape_with_backslash_is_dangerous);
1233
 
        for (start=pos=(char*) res->ptr(),end=pos+used_length ;
1234
 
             pos != end ;
1235
 
             pos++)
1236
 
        {
1237
 
          if (use_mb(res_charset))
1238
 
          {
1239
 
            int l;
1240
 
            if ((l=my_ismbchar(res_charset, pos, end)))
1241
 
            {
1242
 
              pos += l-1;
1243
 
              continue;
1244
 
            }
1245
 
          }
 
1651
        for (start=pos=(char*) res->ptr(),end=pos+used_length ;
 
1652
             pos != end ;
 
1653
             pos++)
 
1654
        {
 
1655
#ifdef USE_MB
 
1656
          if (use_mb(res_charset))
 
1657
          {
 
1658
            int l;
 
1659
            if ((l=my_ismbchar(res_charset, pos, end)))
 
1660
            {
 
1661
              pos += l-1;
 
1662
              continue;
 
1663
            }
 
1664
          }
 
1665
#endif
1246
1666
 
1247
1667
          /*
1248
1668
            Special case when dumping BINARY/VARBINARY/BLOB values
1276
1696
            assert before the loop makes that sure.
1277
1697
          */
1278
1698
 
1279
 
          if ((needs_escaping(*pos, enclosed) ||
 
1699
          if ((NEED_ESCAPING(*pos) ||
1280
1700
               (check_second_byte &&
1281
1701
                my_mbcharlen(character_set_client, (unsigned char) *pos) == 2 &&
1282
1702
                pos + 1 < end &&
1283
 
                needs_escaping(pos[1], enclosed))) &&
 
1703
                NEED_ESCAPING(pos[1]))) &&
1284
1704
              /*
1285
 
                Don't escape field_term_char by doubling - doubling is only
1286
 
                valid for ENCLOSED BY characters:
 
1705
               Don't escape field_term_char by doubling - doubling is only
 
1706
               valid for ENCLOSED BY characters:
1287
1707
              */
1288
1708
              (enclosed || !is_ambiguous_field_term ||
1289
1709
               (int) (unsigned char) *pos != field_term_char))
1290
1710
          {
1291
 
            char tmp_buff[2];
 
1711
            char tmp_buff[2];
1292
1712
            tmp_buff[0]= ((int) (unsigned char) *pos == field_sep_char &&
1293
1713
                          is_ambiguous_field_sep) ?
1294
 
              field_sep_char : escape_char;
1295
 
            tmp_buff[1]= *pos ? *pos : '0';
1296
 
            if (my_b_write(cache,(unsigned char*) start,(uint32_t) (pos-start)) ||
1297
 
                my_b_write(cache,(unsigned char*) tmp_buff,2))
1298
 
              return true;
1299
 
            start=pos+1;
1300
 
          }
1301
 
        }
1302
 
        if (my_b_write(cache,(unsigned char*) start,(uint32_t) (pos-start)))
1303
 
          return true;
 
1714
                          field_sep_char : escape_char;
 
1715
            tmp_buff[1]= *pos ? *pos : '0';
 
1716
            if (my_b_write(&cache,(unsigned char*) start,(uint) (pos-start)) ||
 
1717
                my_b_write(&cache,(unsigned char*) tmp_buff,2))
 
1718
              goto err;
 
1719
            start=pos+1;
 
1720
          }
 
1721
        }
 
1722
        if (my_b_write(&cache,(unsigned char*) start,(uint) (pos-start)))
 
1723
          goto err;
1304
1724
      }
1305
 
      else if (my_b_write(cache,(unsigned char*) res->ptr(),used_length))
1306
 
        return true;
 
1725
      else if (my_b_write(&cache,(unsigned char*) res->ptr(),used_length))
 
1726
        goto err;
1307
1727
    }
1308
1728
    if (fixed_row_size)
1309
1729
    {                                           // Fill with space
1310
1730
      if (item->max_length > used_length)
1311
1731
      {
1312
 
        /* QQ:  Fix by adding a my_b_fill() function */
1313
 
        if (!space_inited)
1314
 
        {
1315
 
          space_inited=1;
1316
 
          memset(space, ' ', sizeof(space));
1317
 
        }
1318
 
        uint32_t length=item->max_length-used_length;
1319
 
        for (; length > sizeof(space) ; length-=sizeof(space))
1320
 
        {
1321
 
          if (my_b_write(cache,(unsigned char*) space,sizeof(space)))
1322
 
            return true;
1323
 
        }
1324
 
        if (my_b_write(cache,(unsigned char*) space,length))
1325
 
          return true;
 
1732
        /* QQ:  Fix by adding a my_b_fill() function */
 
1733
        if (!space_inited)
 
1734
        {
 
1735
          space_inited=1;
 
1736
          memset(space, ' ', sizeof(space));
 
1737
        }
 
1738
        uint32_t length=item->max_length-used_length;
 
1739
        for (; length > sizeof(space) ; length-=sizeof(space))
 
1740
        {
 
1741
          if (my_b_write(&cache,(unsigned char*) space,sizeof(space)))
 
1742
            goto err;
 
1743
        }
 
1744
        if (my_b_write(&cache,(unsigned char*) space,length))
 
1745
          goto err;
1326
1746
      }
1327
1747
    }
1328
1748
    if (res && enclosed)
1329
1749
    {
1330
 
      if (my_b_write(cache, (unsigned char*) exchange->enclosed->ptr(),
 
1750
      if (my_b_write(&cache, (unsigned char*) exchange->enclosed->ptr(),
1331
1751
                     exchange->enclosed->length()))
1332
 
        return true;
 
1752
        goto err;
1333
1753
    }
1334
1754
    if (--items_left)
1335
1755
    {
1336
 
      if (my_b_write(cache, (unsigned char*) exchange->field_term->ptr(),
 
1756
      if (my_b_write(&cache, (unsigned char*) exchange->field_term->ptr(),
1337
1757
                     field_term_length))
1338
 
        return true;
 
1758
        goto err;
1339
1759
    }
1340
1760
  }
1341
 
  if (my_b_write(cache,(unsigned char*) exchange->line_term->ptr(),
1342
 
                 exchange->line_term->length()))
1343
 
  {
1344
 
    return true;
1345
 
  }
1346
 
 
1347
 
  return false;
 
1761
  if (my_b_write(&cache,(unsigned char*) exchange->line_term->ptr(),
 
1762
                 exchange->line_term->length()))
 
1763
    goto err;
 
1764
  return(0);
 
1765
err:
 
1766
  return(1);
1348
1767
}
1349
1768
 
1350
1769
 
1354
1773
 
1355
1774
 
1356
1775
int
1357
 
select_dump::prepare(List<Item> &, Select_Lex_Unit *u)
 
1776
select_dump::prepare(List<Item> &list __attribute__((unused)),
 
1777
                     SELECT_LEX_UNIT *u)
1358
1778
{
1359
1779
  unit= u;
1360
 
  return (int) ((file= create_file(session, path, exchange, cache)) < 0);
 
1780
  return (int) ((file= create_file(session, path, exchange, &cache)) < 0);
1361
1781
}
1362
1782
 
1363
1783
 
1377
1797
  if (row_count++ > 1)
1378
1798
  {
1379
1799
    my_message(ER_TOO_MANY_ROWS, ER(ER_TOO_MANY_ROWS), MYF(0));
1380
 
    return 1;
 
1800
    goto err;
1381
1801
  }
1382
1802
  while ((item=li++))
1383
1803
  {
1384
1804
    res=item->str_result(&tmp);
1385
1805
    if (!res)                                   // If NULL
1386
1806
    {
1387
 
      if (my_b_write(cache,(unsigned char*) "",1))
1388
 
        return 1;
 
1807
      if (my_b_write(&cache,(unsigned char*) "",1))
 
1808
        goto err;
1389
1809
    }
1390
 
    else if (my_b_write(cache,(unsigned char*) res->ptr(),res->length()))
 
1810
    else if (my_b_write(&cache,(unsigned char*) res->ptr(),res->length()))
1391
1811
    {
1392
 
      my_error(ER_ERROR_ON_WRITE, MYF(0), path.file_string().c_str(), errno);
1393
 
      return 1;
 
1812
      my_error(ER_ERROR_ON_WRITE, MYF(0), path, my_errno);
 
1813
      goto err;
1394
1814
    }
1395
1815
  }
1396
1816
  return(0);
 
1817
err:
 
1818
  return(1);
1397
1819
}
1398
1820
 
1399
1821
 
1428
1850
void select_max_min_finder_subselect::cleanup()
1429
1851
{
1430
1852
  cache= 0;
 
1853
  return;
1431
1854
}
1432
1855
 
1433
1856
 
1451
1874
      switch (val_item->result_type())
1452
1875
      {
1453
1876
      case REAL_RESULT:
1454
 
        op= &select_max_min_finder_subselect::cmp_real;
1455
 
        break;
 
1877
        op= &select_max_min_finder_subselect::cmp_real;
 
1878
        break;
1456
1879
      case INT_RESULT:
1457
 
        op= &select_max_min_finder_subselect::cmp_int;
1458
 
        break;
 
1880
        op= &select_max_min_finder_subselect::cmp_int;
 
1881
        break;
1459
1882
      case STRING_RESULT:
1460
 
        op= &select_max_min_finder_subselect::cmp_str;
1461
 
        break;
 
1883
        op= &select_max_min_finder_subselect::cmp_str;
 
1884
        break;
1462
1885
      case DECIMAL_RESULT:
1463
1886
        op= &select_max_min_finder_subselect::cmp_decimal;
1464
1887
        break;
1465
1888
      case ROW_RESULT:
1466
1889
        // This case should never be choosen
1467
 
        assert(0);
1468
 
        op= 0;
 
1890
        assert(0);
 
1891
        op= 0;
1469
1892
      }
1470
1893
    }
1471
1894
    cache->store(val_item);
1534
1957
     sortcmp(val1, val2, cache->collation.collation) < 0);
1535
1958
}
1536
1959
 
1537
 
bool select_exists_subselect::send_data(List<Item> &)
 
1960
bool select_exists_subselect::send_data(List<Item> &items __attribute__((unused)))
1538
1961
{
1539
1962
  Item_exists_subselect *it= (Item_exists_subselect *)item;
1540
1963
  if (unit->offset_limit_cnt)
1547
1970
  return(0);
1548
1971
}
1549
1972
 
 
1973
 
 
1974
/***************************************************************************
 
1975
  Dump of select to variables
 
1976
***************************************************************************/
 
1977
 
 
1978
int select_dumpvar::prepare(List<Item> &list, SELECT_LEX_UNIT *u)
 
1979
{
 
1980
  unit= u;
 
1981
 
 
1982
  if (var_list.elements != list.elements)
 
1983
  {
 
1984
    my_message(ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT,
 
1985
               ER(ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT), MYF(0));
 
1986
    return 1;
 
1987
  }
 
1988
  return 0;
 
1989
}
 
1990
 
 
1991
 
 
1992
void select_dumpvar::cleanup()
 
1993
{
 
1994
  row_count= 0;
 
1995
}
 
1996
 
 
1997
 
 
1998
void Query_arena::free_items()
 
1999
{
 
2000
  Item *next;
 
2001
  /* This works because items are allocated with sql_alloc() */
 
2002
  for (; free_list; free_list= next)
 
2003
  {
 
2004
    next= free_list->next;
 
2005
    free_list->delete_self();
 
2006
  }
 
2007
  /* Postcondition: free_list is 0 */
 
2008
  return;
 
2009
}
 
2010
 
 
2011
 
 
2012
/*
 
2013
  Statement functions
 
2014
*/
 
2015
 
 
2016
Statement::Statement(LEX *lex_arg, MEM_ROOT *mem_root_arg, ulong id_arg)
 
2017
  :Query_arena(mem_root_arg),
 
2018
  id(id_arg),
 
2019
  mark_used_columns(MARK_COLUMNS_READ),
 
2020
  lex(lex_arg),
 
2021
  query(0),
 
2022
  query_length(0),
 
2023
  db(NULL),
 
2024
  db_length(0)
 
2025
{
 
2026
}
 
2027
 
 
2028
 
1550
2029
/*
1551
2030
  Don't free mem_root, as mem_root is freed in the end of dispatch_command
1552
2031
  (once for any command).
1554
2033
void Session::end_statement()
1555
2034
{
1556
2035
  /* Cleanup SQL processing state to reuse this statement in next query. */
1557
 
  lex->end();
1558
 
  query_cache_key= ""; // reset the cache key
1559
 
  resetResultsetMessage();
 
2036
  lex_end(lex);
1560
2037
}
1561
2038
 
 
2039
 
1562
2040
bool Session::copy_db_to(char **p_db, size_t *p_db_length)
1563
2041
{
1564
 
  assert(_schema);
1565
 
  if (_schema and _schema->empty())
1566
 
  {
1567
 
    my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
1568
 
    return true;
1569
 
  }
1570
 
  else if (not _schema)
1571
 
  {
1572
 
    my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
1573
 
    return true;
1574
 
  }
1575
 
  assert(_schema);
1576
 
 
1577
 
  *p_db= strmake(_schema->c_str(), _schema->size());
1578
 
  *p_db_length= _schema->size();
1579
 
 
 
2042
  if (db == NULL)
 
2043
  {
 
2044
    my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
 
2045
    return true;
 
2046
  }
 
2047
  *p_db= strmake(db, db_length);
 
2048
  *p_db_length= db_length;
1580
2049
  return false;
1581
2050
}
1582
2051
 
 
2052
 
 
2053
bool select_dumpvar::send_data(List<Item> &items)
 
2054
{
 
2055
  List_iterator_fast<my_var> var_li(var_list);
 
2056
  List_iterator<Item> it(items);
 
2057
  Item *item;
 
2058
  my_var *mv;
 
2059
 
 
2060
  if (unit->offset_limit_cnt)
 
2061
  {                                             // using limit offset,count
 
2062
    unit->offset_limit_cnt--;
 
2063
    return(0);
 
2064
  }
 
2065
  if (row_count++)
 
2066
  {
 
2067
    my_message(ER_TOO_MANY_ROWS, ER(ER_TOO_MANY_ROWS), MYF(0));
 
2068
    return(1);
 
2069
  }
 
2070
  while ((mv= var_li++) && (item= it++))
 
2071
  {
 
2072
    if (mv->local == 0)
 
2073
    {
 
2074
      Item_func_set_user_var *suv= new Item_func_set_user_var(mv->s, item);
 
2075
      suv->fix_fields(session, 0);
 
2076
      suv->check(0);
 
2077
      suv->update();
 
2078
    }
 
2079
  }
 
2080
  return(session->is_error());
 
2081
}
 
2082
 
 
2083
bool select_dumpvar::send_eof()
 
2084
{
 
2085
  if (! row_count)
 
2086
    push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
2087
                 ER_SP_FETCH_NO_DATA, ER(ER_SP_FETCH_NO_DATA));
 
2088
  /*
 
2089
    In order to remember the value of affected rows for ROW_COUNT()
 
2090
    function, SELECT INTO has to have an own SQLCOM.
 
2091
    TODO: split from SQLCOM_SELECT
 
2092
  */
 
2093
  ::my_ok(session,row_count);
 
2094
  return 0;
 
2095
}
 
2096
 
1583
2097
/****************************************************************************
1584
 
  Tmp_Table_Param
 
2098
  TMP_TABLE_PARAM
1585
2099
****************************************************************************/
1586
2100
 
1587
 
void Tmp_Table_Param::init()
 
2101
void TMP_TABLE_PARAM::init()
1588
2102
{
1589
2103
  field_count= sum_func_count= func_count= hidden_field_count= 0;
1590
2104
  group_parts= group_length= group_null_parts= 0;
1591
2105
  quick_group= 1;
1592
2106
  table_charset= 0;
1593
2107
  precomputed_group_by= 0;
 
2108
  bit_fields_as_long= 0;
 
2109
  return;
1594
2110
}
1595
2111
 
1596
 
void Tmp_Table_Param::cleanup(void)
 
2112
void TMP_TABLE_PARAM::cleanup(void)
1597
2113
{
1598
2114
  /* Fix for Intel compiler */
1599
2115
  if (copy_field)
1603
2119
  }
1604
2120
}
1605
2121
 
 
2122
 
 
2123
void session_increment_bytes_sent(ulong length)
 
2124
{
 
2125
  Session *session=current_session;
 
2126
  if (likely(session != 0))
 
2127
  { /* current_session==0 when close_connection() calls net_send_error() */
 
2128
    session->status_var.bytes_sent+= length;
 
2129
  }
 
2130
}
 
2131
 
 
2132
 
 
2133
void session_increment_bytes_received(ulong length)
 
2134
{
 
2135
  current_session->status_var.bytes_received+= length;
 
2136
}
 
2137
 
 
2138
 
 
2139
void session_increment_net_big_packet_count(ulong length)
 
2140
{
 
2141
  current_session->status_var.net_big_packet_count+= length;
 
2142
}
 
2143
 
1606
2144
void Session::send_kill_message() const
1607
2145
{
1608
2146
  int err= killed_errno();
1615
2153
  memset(&status_var, 0, sizeof(status_var));
1616
2154
}
1617
2155
 
1618
 
 
1619
 
void Session::set_db(const std::string &new_db)
 
2156
void Security_context::skip_grants()
 
2157
{
 
2158
  /* privileges for the user are unknown everything is allowed */
 
2159
}
 
2160
 
 
2161
 
 
2162
/****************************************************************************
 
2163
  Handling of open and locked tables states.
 
2164
 
 
2165
  This is used when we want to open/lock (and then close) some tables when
 
2166
  we already have a set of tables open and locked. We use these methods for
 
2167
  access to mysql.proc table to find definitions of stored routines.
 
2168
****************************************************************************/
 
2169
 
 
2170
void Session::reset_n_backup_open_tables_state(Open_tables_state *backup)
 
2171
{
 
2172
  backup->set_open_tables_state(this);
 
2173
  reset_open_tables_state();
 
2174
  state_flags|= Open_tables_state::BACKUPS_AVAIL;
 
2175
  return;
 
2176
}
 
2177
 
 
2178
 
 
2179
void Session::restore_backup_open_tables_state(Open_tables_state *backup)
 
2180
{
 
2181
  /*
 
2182
    Before we will throw away current open tables state we want
 
2183
    to be sure that it was properly cleaned up.
 
2184
  */
 
2185
  assert(open_tables == 0 && temporary_tables == 0 &&
 
2186
              handler_tables == 0 && derived_tables == 0 &&
 
2187
              lock == 0 && locked_tables == 0);
 
2188
  set_open_tables_state(backup);
 
2189
  return;
 
2190
}
 
2191
 
 
2192
 
 
2193
bool Session::set_db(const char *new_db, size_t new_db_len)
1620
2194
{
1621
2195
  /* Do not reallocate memory if current chunk is big enough. */
1622
 
  if (new_db.length())
1623
 
  {
1624
 
    _schema.reset(new std::string(new_db));
1625
 
  }
 
2196
  if (db && new_db && db_length >= new_db_len)
 
2197
    memcpy(db, new_db, new_db_len+1);
1626
2198
  else
1627
2199
  {
1628
 
    _schema.reset(new std::string(""));
 
2200
    if (db)
 
2201
      free(db);
 
2202
    if (new_db)
 
2203
    {
 
2204
      db= (char *)malloc(new_db_len + 1);
 
2205
      if (db != NULL)
 
2206
      {
 
2207
        memcpy(db, new_db, new_db_len);
 
2208
        db[new_db_len]= 0;
 
2209
      }
 
2210
    }
 
2211
    else
 
2212
      db= NULL;
1629
2213
  }
 
2214
  db_length= db ? new_db_len : 0;
 
2215
  return new_db && !db;
 
2216
}
 
2217
 
 
2218
 
 
2219
/**
 
2220
  Check the killed state of a user thread
 
2221
  @param session  user thread
 
2222
  @retval 0 the user thread is active
 
2223
  @retval 1 the user thread has been killed
 
2224
*/
 
2225
extern "C" int session_killed(const Session *session)
 
2226
{
 
2227
  return(session->killed);
 
2228
}
 
2229
 
 
2230
/**
 
2231
  Return the thread id of a user thread
 
2232
  @param session user thread
 
2233
  @return thread id
 
2234
*/
 
2235
extern "C" unsigned long session_get_thread_id(const Session *session)
 
2236
{
 
2237
  return((unsigned long)session->thread_id);
 
2238
}
 
2239
 
 
2240
 
 
2241
extern "C"
 
2242
LEX_STRING *session_make_lex_string(Session *session, LEX_STRING *lex_str,
 
2243
                                const char *str, unsigned int size,
 
2244
                                int allocate_lex_string)
 
2245
{
 
2246
  return session->make_lex_string(lex_str, str, size,
 
2247
                              (bool) allocate_lex_string);
 
2248
}
 
2249
 
 
2250
extern "C" const struct charset_info_st *session_charset(Session *session)
 
2251
{
 
2252
  return(session->charset());
 
2253
}
 
2254
 
 
2255
extern "C" char **session_query(Session *session)
 
2256
{
 
2257
  return(&session->query);
 
2258
}
 
2259
 
 
2260
extern "C" int session_slave_thread(const Session *session)
 
2261
{
 
2262
  return(session->slave_thread);
 
2263
}
 
2264
 
 
2265
extern "C" int session_non_transactional_update(const Session *session)
 
2266
{
 
2267
  return(session->transaction.all.modified_non_trans_table);
 
2268
}
 
2269
 
 
2270
extern "C" void session_mark_transaction_to_rollback(Session *session, bool all)
 
2271
{
 
2272
  mark_transaction_to_rollback(session, all);
1630
2273
}
1631
2274
 
1632
2275
 
1636
2279
  @param  session   Thread handle
1637
2280
  @param  all   true <=> rollback main transaction.
1638
2281
*/
 
2282
 
1639
2283
void mark_transaction_to_rollback(Session *session, bool all)
1640
2284
{
1641
2285
  if (session)
1644
2288
    session->transaction_rollback_request= all;
1645
2289
  }
1646
2290
}
1647
 
 
1648
 
void Session::disconnect(uint32_t errcode, bool should_lock)
1649
 
{
1650
 
  /* Allow any plugins to cleanup their session variables */
1651
 
  plugin_sessionvar_cleanup(this);
1652
 
 
1653
 
  /* If necessary, log any aborted or unauthorized connections */
1654
 
  if (getKilled() || client->wasAborted())
1655
 
  {
1656
 
    status_var.aborted_threads++;
1657
 
  }
1658
 
 
1659
 
  if (client->wasAborted())
1660
 
  {
1661
 
    if (not getKilled() && variables.log_warnings > 1)
1662
 
    {
1663
 
      SecurityContext *sctx= &security_ctx;
1664
 
 
1665
 
      errmsg_printf(ERRMSG_LVL_WARN, ER(ER_NEW_ABORTING_CONNECTION)
1666
 
                  , thread_id
1667
 
                  , (_schema->empty() ? "unconnected" : _schema->c_str())
1668
 
                  , sctx->getUser().empty() == false ? sctx->getUser().c_str() : "unauthenticated"
1669
 
                  , sctx->getIp().c_str()
1670
 
                  , (main_da.is_error() ? main_da.message() : ER(ER_UNKNOWN_ERROR)));
1671
 
    }
1672
 
  }
1673
 
 
1674
 
  /* Close out our connection to the client */
1675
 
  if (should_lock)
1676
 
    session::Cache::singleton().mutex().lock();
1677
 
 
1678
 
  setKilled(Session::KILL_CONNECTION);
1679
 
 
1680
 
  if (client->isConnected())
 
2291
/***************************************************************************
 
2292
  Handling of XA id cacheing
 
2293
***************************************************************************/
 
2294
 
 
2295
pthread_mutex_t LOCK_xid_cache;
 
2296
HASH xid_cache;
 
2297
 
 
2298
extern "C" unsigned char *xid_get_hash_key(const unsigned char *, size_t *, bool);
 
2299
extern "C" void xid_free_hash(void *);
 
2300
 
 
2301
unsigned char *xid_get_hash_key(const unsigned char *ptr, size_t *length,
 
2302
                        bool not_used __attribute__((unused)))
 
2303
{
 
2304
  *length=((XID_STATE*)ptr)->xid.key_length();
 
2305
  return ((XID_STATE*)ptr)->xid.key();
 
2306
}
 
2307
 
 
2308
void xid_free_hash(void *ptr)
 
2309
{
 
2310
  if (!((XID_STATE*)ptr)->in_session)
 
2311
    free((unsigned char*)ptr);
 
2312
}
 
2313
 
 
2314
bool xid_cache_init()
 
2315
{
 
2316
  pthread_mutex_init(&LOCK_xid_cache, MY_MUTEX_INIT_FAST);
 
2317
  return hash_init(&xid_cache, &my_charset_bin, 100, 0, 0,
 
2318
                   xid_get_hash_key, xid_free_hash, 0) != 0;
 
2319
}
 
2320
 
 
2321
void xid_cache_free()
 
2322
{
 
2323
  if (hash_inited(&xid_cache))
 
2324
  {
 
2325
    hash_free(&xid_cache);
 
2326
    pthread_mutex_destroy(&LOCK_xid_cache);
 
2327
  }
 
2328
}
 
2329
 
 
2330
XID_STATE *xid_cache_search(XID *xid)
 
2331
{
 
2332
  pthread_mutex_lock(&LOCK_xid_cache);
 
2333
  XID_STATE *res=(XID_STATE *)hash_search(&xid_cache, xid->key(), xid->key_length());
 
2334
  pthread_mutex_unlock(&LOCK_xid_cache);
 
2335
  return res;
 
2336
}
 
2337
 
 
2338
 
 
2339
bool xid_cache_insert(XID *xid, enum xa_states xa_state)
 
2340
{
 
2341
  XID_STATE *xs;
 
2342
  bool res;
 
2343
  pthread_mutex_lock(&LOCK_xid_cache);
 
2344
  if (hash_search(&xid_cache, xid->key(), xid->key_length()))
 
2345
    res=0;
 
2346
  else if (!(xs=(XID_STATE *)malloc(sizeof(*xs))))
 
2347
    res=1;
 
2348
  else
 
2349
  {
 
2350
    xs->xa_state=xa_state;
 
2351
    xs->xid.set(xid);
 
2352
    xs->in_session=0;
 
2353
    res=my_hash_insert(&xid_cache, (unsigned char*)xs);
 
2354
  }
 
2355
  pthread_mutex_unlock(&LOCK_xid_cache);
 
2356
  return res;
 
2357
}
 
2358
 
 
2359
 
 
2360
bool xid_cache_insert(XID_STATE *xid_state)
 
2361
{
 
2362
  pthread_mutex_lock(&LOCK_xid_cache);
 
2363
  assert(hash_search(&xid_cache, xid_state->xid.key(),
 
2364
                          xid_state->xid.key_length())==0);
 
2365
  bool res=my_hash_insert(&xid_cache, (unsigned char*)xid_state);
 
2366
  pthread_mutex_unlock(&LOCK_xid_cache);
 
2367
  return res;
 
2368
}
 
2369
 
 
2370
 
 
2371
void xid_cache_delete(XID_STATE *xid_state)
 
2372
{
 
2373
  pthread_mutex_lock(&LOCK_xid_cache);
 
2374
  hash_delete(&xid_cache, (unsigned char *)xid_state);
 
2375
  pthread_mutex_unlock(&LOCK_xid_cache);
 
2376
}
 
2377
 
 
2378
namespace {
 
2379
  /**
 
2380
     Class to handle temporary allocation of memory for row data.
 
2381
 
 
2382
     The responsibilities of the class is to provide memory for
 
2383
     packing one or two rows of packed data (depending on what
 
2384
     constructor is called).
 
2385
 
 
2386
     In order to make the allocation more efficient for "simple" rows,
 
2387
     i.e., rows that do not contain any blobs, a pointer to the
 
2388
     allocated memory is of memory is stored in the table structure
 
2389
     for simple rows.  If memory for a table containing a blob field
 
2390
     is requested, only memory for that is allocated, and subsequently
 
2391
     released when the object is destroyed.
 
2392
 
 
2393
   */
 
2394
  class Row_data_memory {
 
2395
  public:
 
2396
    /**
 
2397
      Build an object to keep track of a block-local piece of memory
 
2398
      for storing a row of data.
 
2399
 
 
2400
      @param table
 
2401
      Table where the pre-allocated memory is stored.
 
2402
 
 
2403
      @param length
 
2404
      Length of data that is needed, if the record contain blobs.
 
2405
     */
 
2406
    Row_data_memory(Table *table, size_t const len1)
 
2407
      : m_memory(0)
 
2408
    {
 
2409
      m_alloc_checked= false;
 
2410
      allocate_memory(table, len1);
 
2411
      m_ptr[0]= has_memory() ? m_memory : 0;
 
2412
      m_ptr[1]= 0;
 
2413
    }
 
2414
 
 
2415
    Row_data_memory(Table *table, size_t const len1, size_t const len2)
 
2416
      : m_memory(0)
 
2417
    {
 
2418
      m_alloc_checked= false;
 
2419
      allocate_memory(table, len1 + len2);
 
2420
      m_ptr[0]= has_memory() ? m_memory        : 0;
 
2421
      m_ptr[1]= has_memory() ? m_memory + len1 : 0;
 
2422
    }
 
2423
 
 
2424
    ~Row_data_memory()
 
2425
    {
 
2426
      if (m_memory != 0 && m_release_memory_on_destruction)
 
2427
        free((unsigned char*) m_memory);
 
2428
    }
 
2429
 
 
2430
    /**
 
2431
       Is there memory allocated?
 
2432
 
 
2433
       @retval true There is memory allocated
 
2434
       @retval false Memory allocation failed
 
2435
     */
 
2436
    bool has_memory() const {
 
2437
      m_alloc_checked= true;
 
2438
      return m_memory != 0;
 
2439
    }
 
2440
 
 
2441
    unsigned char *slot(uint32_t s)
 
2442
    {
 
2443
      assert(s < sizeof(m_ptr)/sizeof(*m_ptr));
 
2444
      assert(m_ptr[s] != 0);
 
2445
      assert(m_alloc_checked == true);
 
2446
      return m_ptr[s];
 
2447
    }
 
2448
 
 
2449
  private:
 
2450
    void allocate_memory(Table *const table, size_t const total_length)
 
2451
    {
 
2452
      if (table->s->blob_fields == 0)
 
2453
      {
 
2454
        /*
 
2455
          The maximum length of a packed record is less than this
 
2456
          length. We use this value instead of the supplied length
 
2457
          when allocating memory for records, since we don't know how
 
2458
          the memory will be used in future allocations.
 
2459
 
 
2460
          Since table->s->reclength is for unpacked records, we have
 
2461
          to add two bytes for each field, which can potentially be
 
2462
          added to hold the length of a packed field.
 
2463
        */
 
2464
        size_t const maxlen= table->s->reclength + 2 * table->s->fields;
 
2465
 
 
2466
        /*
 
2467
          Allocate memory for two records if memory hasn't been
 
2468
          allocated. We allocate memory for two records so that it can
 
2469
          be used when processing update rows as well.
 
2470
        */
 
2471
        if (table->write_row_record == 0)
 
2472
          table->write_row_record=
 
2473
            (unsigned char *) alloc_root(&table->mem_root, 2 * maxlen);
 
2474
        m_memory= table->write_row_record;
 
2475
        m_release_memory_on_destruction= false;
 
2476
      }
 
2477
      else
 
2478
      {
 
2479
        m_memory= (unsigned char *) malloc(total_length);
 
2480
        m_release_memory_on_destruction= true;
 
2481
      }
 
2482
    }
 
2483
 
 
2484
    mutable bool m_alloc_checked;
 
2485
    bool m_release_memory_on_destruction;
 
2486
    unsigned char *m_memory;
 
2487
    unsigned char *m_ptr[2];
 
2488
  };
 
2489
}
 
2490
 
 
2491
bool Discrete_intervals_list::append(uint64_t start, uint64_t val,
 
2492
                                 uint64_t incr)
 
2493
{
 
2494
  /* first, see if this can be merged with previous */
 
2495
  if ((head == NULL) || tail->merge_if_contiguous(start, val, incr))
 
2496
  {
 
2497
    /* it cannot, so need to add a new interval */
 
2498
    Discrete_interval *new_interval= new Discrete_interval(start, val, incr);
 
2499
    return(append(new_interval));
 
2500
  }
 
2501
  return(0);
 
2502
}
 
2503
 
 
2504
bool Discrete_intervals_list::append(Discrete_interval *new_interval)
 
2505
{
 
2506
  if (unlikely(new_interval == NULL))
 
2507
    return(1);
 
2508
  if (head == NULL)
 
2509
    head= current= new_interval;
 
2510
  else
 
2511
    tail->next= new_interval;
 
2512
  tail= new_interval;
 
2513
  elements++;
 
2514
  return(0);
 
2515
}
 
2516
 
 
2517
/**
 
2518
  Close a connection.
 
2519
 
 
2520
  @param session                Thread handle
 
2521
  @param errcode        Error code to print to console
 
2522
  @param lock           1 if we have have to lock LOCK_thread_count
 
2523
 
 
2524
  @note
 
2525
    For the connection that is doing shutdown, this is called twice
 
2526
*/
 
2527
void Session::close_connection(uint32_t errcode, bool lock)
 
2528
{
 
2529
  st_vio *vio;
 
2530
  if (lock)
 
2531
    (void) pthread_mutex_lock(&LOCK_thread_count);
 
2532
  killed= Session::KILL_CONNECTION;
 
2533
  if ((vio= net.vio) != 0)
1681
2534
  {
1682
2535
    if (errcode)
1683
 
    {
1684
 
      /*my_error(errcode, ER(errcode));*/
1685
 
      client->sendError(errcode, ER(errcode));
1686
 
    }
1687
 
    client->close();
1688
 
  }
1689
 
 
1690
 
  if (should_lock)
1691
 
  {
1692
 
    session::Cache::singleton().mutex().unlock();
1693
 
  }
 
2536
      net_send_error(this, errcode, ER(errcode)); /* purecov: inspected */
 
2537
    net_close(&net);            /* vio is freed in delete session */
 
2538
  }
 
2539
  if (lock)
 
2540
    (void) pthread_mutex_unlock(&LOCK_thread_count);
1694
2541
}
1695
2542
 
 
2543
 
 
2544
 
 
2545
/**
 
2546
 Reset Session part responsible for command processing state.
 
2547
 
 
2548
   This needs to be called before execution of every statement
 
2549
   (prepared or conventional).
 
2550
   It is not called by substatements of routines.
 
2551
 
 
2552
  @todo
 
2553
   Make it a method of Session and align its name with the rest of
 
2554
   reset/end/start/init methods.
 
2555
  @todo
 
2556
   Call it after we use Session for queries, not before.
 
2557
*/
 
2558
 
1696
2559
void Session::reset_for_next_command()
1697
2560
{
1698
2561
  free_list= 0;
1703
2566
  */
1704
2567
  auto_inc_intervals_in_cur_stmt_for_binlog.empty();
1705
2568
 
1706
 
  is_fatal_error= false;
 
2569
  is_fatal_error= 0;
1707
2570
  server_status&= ~ (SERVER_MORE_RESULTS_EXISTS |
1708
2571
                          SERVER_QUERY_NO_INDEX_USED |
1709
2572
                          SERVER_QUERY_NO_GOOD_INDEX_USED);
 
2573
  /*
 
2574
    If in autocommit mode and not in a transaction, reset
 
2575
    OPTION_STATUS_NO_TRANS_UPDATE | OPTION_KEEP_LOG to not get warnings
 
2576
    in ha_rollback_trans() about some tables couldn't be rolled back.
 
2577
  */
 
2578
  if (!(options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))
 
2579
  {
 
2580
    options&= ~OPTION_KEEP_LOG;
 
2581
    transaction.all.modified_non_trans_table= false;
 
2582
  }
 
2583
  thread_specific_used= false;
1710
2584
 
 
2585
  if (opt_bin_log)
 
2586
  {
 
2587
    reset_dynamic(&user_var_events);
 
2588
    user_var_events_alloc= mem_root;
 
2589
  }
1711
2590
  clear_error();
1712
2591
  main_da.reset_diagnostics_area();
1713
2592
  total_warn_count=0;                   // Warnings for this query
1714
2593
  sent_row_count= examined_row_count= 0;
1715
 
}
1716
 
 
1717
 
/*
1718
 
  Close all temporary tables created by 'CREATE TEMPORARY TABLE' for thread
1719
 
*/
1720
 
 
1721
 
void Open_tables_state::close_temporary_tables()
1722
 
{
1723
 
  Table *table;
1724
 
  Table *tmp_next;
1725
 
 
1726
 
  if (not temporary_tables)
1727
 
    return;
1728
 
 
1729
 
  for (table= temporary_tables; table; table= tmp_next)
1730
 
  {
1731
 
    tmp_next= table->getNext();
1732
 
    nukeTable(table);
1733
 
  }
1734
 
  temporary_tables= NULL;
1735
 
}
1736
 
 
1737
 
/*
1738
 
  unlink from session->temporary tables and close temporary table
1739
 
*/
1740
 
 
1741
 
void Open_tables_state::close_temporary_table(Table *table)
1742
 
{
1743
 
  if (table->getPrev())
1744
 
  {
1745
 
    table->getPrev()->setNext(table->getNext());
1746
 
    if (table->getPrev()->getNext())
1747
 
    {
1748
 
      table->getNext()->setPrev(table->getPrev());
1749
 
    }
1750
 
  }
1751
 
  else
1752
 
  {
1753
 
    /* removing the item from the list */
1754
 
    assert(table == temporary_tables);
1755
 
    /*
1756
 
      slave must reset its temporary list pointer to zero to exclude
1757
 
      passing non-zero value to end_slave via rli->save_temporary_tables
1758
 
      when no temp tables opened, see an invariant below.
1759
 
    */
1760
 
    temporary_tables= table->getNext();
1761
 
    if (temporary_tables)
1762
 
    {
1763
 
      table->getNext()->setPrev(NULL);
1764
 
    }
1765
 
  }
1766
 
  nukeTable(table);
1767
 
}
1768
 
 
1769
 
/*
1770
 
  Close and drop a temporary table
1771
 
 
1772
 
  NOTE
1773
 
  This dosn't unlink table from session->temporary
1774
 
  If this is needed, use close_temporary_table()
1775
 
*/
1776
 
 
1777
 
void Open_tables_state::nukeTable(Table *table)
1778
 
{
1779
 
  plugin::StorageEngine *table_type= table->getShare()->db_type();
1780
 
 
1781
 
  table->free_io_cache();
1782
 
  table->delete_table();
1783
 
 
1784
 
  TableIdentifier identifier(table->getShare()->getSchemaName(), table->getShare()->getTableName(), table->getShare()->getPath());
1785
 
  rm_temporary_table(table_type, identifier);
1786
 
 
1787
 
  delete table->getMutableShare();
1788
 
 
1789
 
  /* This makes me sad, but we're allocating it via malloc */
1790
 
  delete table;
1791
 
}
1792
 
 
1793
 
/** Clear most status variables. */
1794
 
extern time_t flush_status_time;
1795
 
 
1796
 
void Session::refresh_status()
1797
 
{
1798
 
  /* Reset thread's status variables */
1799
 
  memset(&status_var, 0, sizeof(status_var));
1800
 
 
1801
 
  flush_status_time= time((time_t*) 0);
1802
 
  current_global_counters.max_used_connections= 1; /* We set it to one, because we know we exist */
1803
 
  current_global_counters.connections= 0;
1804
 
}
1805
 
 
1806
 
user_var_entry *Session::getVariable(LEX_STRING &name, bool create_if_not_exists)
1807
 
{
1808
 
  return getVariable(std::string(name.str, name.length), create_if_not_exists);
1809
 
}
1810
 
 
1811
 
user_var_entry *Session::getVariable(const std::string  &name, bool create_if_not_exists)
1812
 
{
1813
 
  UserVarsRange ppp= user_vars.equal_range(name);
1814
 
 
1815
 
  for (UserVars::iterator iter= ppp.first;
1816
 
       iter != ppp.second; ++iter)
1817
 
  {
1818
 
    return (*iter).second;
1819
 
  }
1820
 
 
1821
 
  if (not create_if_not_exists)
1822
 
    return NULL;
1823
 
 
1824
 
  user_var_entry *entry= NULL;
1825
 
  entry= new (nothrow) user_var_entry(name.c_str(), query_id);
1826
 
 
1827
 
  if (entry == NULL)
1828
 
    return NULL;
1829
 
 
1830
 
  std::pair<UserVars::iterator, bool> returnable= user_vars.insert(make_pair(name, entry));
1831
 
 
1832
 
  if (not returnable.second)
1833
 
  {
1834
 
    delete entry;
1835
 
  }
1836
 
 
1837
 
  return entry;
1838
 
}
1839
 
 
1840
 
void Session::setVariable(const std::string &name, const std::string &value)
1841
 
{
1842
 
  user_var_entry *updateable_var= getVariable(name.c_str(), true);
1843
 
 
1844
 
  updateable_var->update_hash(false,
1845
 
                              (void*)value.c_str(),
1846
 
                              static_cast<uint32_t>(value.length()), STRING_RESULT,
1847
 
                              &my_charset_bin,
1848
 
                              DERIVATION_IMPLICIT, false);
1849
 
}
1850
 
 
1851
 
void Open_tables_state::mark_temp_tables_as_free_for_reuse()
1852
 
{
1853
 
  for (Table *table= temporary_tables ; table ; table= table->getNext())
1854
 
  {
1855
 
    if (table->query_id == getQueryId())
1856
 
    {
1857
 
      table->query_id= 0;
1858
 
      table->cursor->ha_reset();
1859
 
    }
1860
 
  }
1861
 
}
1862
 
 
1863
 
void Session::mark_used_tables_as_free_for_reuse(Table *table)
1864
 
{
1865
 
  for (; table ; table= table->getNext())
1866
 
  {
1867
 
    if (table->query_id == getQueryId())
1868
 
    {
1869
 
      table->query_id= 0;
1870
 
      table->cursor->ha_reset();
1871
 
    }
1872
 
  }
1873
 
}
1874
 
 
1875
 
/*
1876
 
  Unlocks tables and frees derived tables.
1877
 
  Put all normal tables used by thread in free list.
1878
 
 
1879
 
  It will only close/mark as free for reuse tables opened by this
1880
 
  substatement, it will also check if we are closing tables after
1881
 
  execution of complete query (i.e. we are on upper level) and will
1882
 
  leave prelocked mode if needed.
1883
 
*/
1884
 
void Session::close_thread_tables()
1885
 
{
1886
 
  clearDerivedTables();
1887
 
 
1888
 
  /*
1889
 
    Mark all temporary tables used by this statement as free for reuse.
1890
 
  */
1891
 
  mark_temp_tables_as_free_for_reuse();
1892
 
  /*
1893
 
    Let us commit transaction for statement. Since in 5.0 we only have
1894
 
    one statement transaction and don't allow several nested statement
1895
 
    transactions this call will do nothing if we are inside of stored
1896
 
    function or trigger (i.e. statement transaction is already active and
1897
 
    does not belong to statement for which we do close_thread_tables()).
1898
 
    TODO: This should be fixed in later releases.
1899
 
   */
1900
 
  {
1901
 
    TransactionServices &transaction_services= TransactionServices::singleton();
1902
 
    main_da.can_overwrite_status= true;
1903
 
    transaction_services.autocommitOrRollback(this, is_error());
1904
 
    main_da.can_overwrite_status= false;
1905
 
    transaction.stmt.reset();
1906
 
  }
1907
 
 
1908
 
  if (lock)
1909
 
  {
1910
 
    /*
1911
 
      For RBR we flush the pending event just before we unlock all the
1912
 
      tables.  This means that we are at the end of a topmost
1913
 
      statement, so we ensure that the STMT_END_F flag is set on the
1914
 
      pending event.  For statements that are *inside* stored
1915
 
      functions, the pending event will not be flushed: that will be
1916
 
      handled either before writing a query log event (inside
1917
 
      binlog_query()) or when preparing a pending event.
1918
 
     */
1919
 
    unlockTables(lock);
1920
 
    lock= 0;
1921
 
  }
1922
 
  /*
1923
 
    Note that we need to hold table::Cache::singleton().mutex() while changing the
1924
 
    open_tables list. Another thread may work on it.
1925
 
    (See: table::Cache::singleton().removeTable(), mysql_wait_completed_table())
1926
 
    Closing a MERGE child before the parent would be fatal if the
1927
 
    other thread tries to abort the MERGE lock in between.
1928
 
  */
1929
 
  if (open_tables)
1930
 
    close_open_tables();
1931
 
}
1932
 
 
1933
 
void Session::close_tables_for_reopen(TableList **tables)
1934
 
{
1935
 
  /*
1936
 
    If table list consists only from tables from prelocking set, table list
1937
 
    for new attempt should be empty, so we have to update list's root pointer.
1938
 
  */
1939
 
  if (lex->first_not_own_table() == *tables)
1940
 
    *tables= 0;
1941
 
  lex->chop_off_not_own_tables();
1942
 
  for (TableList *tmp= *tables; tmp; tmp= tmp->next_global)
1943
 
    tmp->table= 0;
1944
 
  close_thread_tables();
1945
 
}
1946
 
 
1947
 
bool Session::openTablesLock(TableList *tables)
1948
 
{
1949
 
  uint32_t counter;
1950
 
  bool need_reopen;
1951
 
 
1952
 
  for ( ; ; )
1953
 
  {
1954
 
    if (open_tables_from_list(&tables, &counter))
1955
 
      return true;
1956
 
 
1957
 
    if (not lock_tables(tables, counter, &need_reopen))
1958
 
      break;
1959
 
    if (not need_reopen)
1960
 
      return true;
1961
 
    close_tables_for_reopen(&tables);
1962
 
  }
1963
 
  if ((mysql_handle_derived(lex, &mysql_derived_prepare) ||
1964
 
       (
1965
 
        mysql_handle_derived(lex, &mysql_derived_filling))))
1966
 
    return true;
1967
 
 
1968
 
  return false;
1969
 
}
1970
 
 
1971
 
/*
1972
 
  @note "best_effort" is used in cases were if a failure occurred on this
1973
 
  operation it would not be surprising because we are only removing because there
1974
 
  might be an issue (lame engines).
1975
 
*/
1976
 
 
1977
 
bool Open_tables_state::rm_temporary_table(const TableIdentifier &identifier, bool best_effort)
1978
 
{
1979
 
  if (plugin::StorageEngine::dropTable(*static_cast<Session *>(this), identifier))
1980
 
  {
1981
 
    if (not best_effort)
1982
 
    {
1983
 
      std::string path;
1984
 
      identifier.getSQLPath(path);
1985
 
      errmsg_printf(ERRMSG_LVL_WARN, _("Could not remove temporary table: '%s', error: %d"),
1986
 
                    path.c_str(), errno);
1987
 
    }
1988
 
 
1989
 
    return true;
1990
 
  }
1991
 
 
1992
 
  return false;
1993
 
}
1994
 
 
1995
 
bool Open_tables_state::rm_temporary_table(plugin::StorageEngine *base, const TableIdentifier &identifier)
1996
 
{
1997
 
  assert(base);
1998
 
 
1999
 
  if (plugin::StorageEngine::dropTable(*static_cast<Session *>(this), *base, identifier))
2000
 
  {
2001
 
    std::string path;
2002
 
    identifier.getSQLPath(path);
2003
 
    errmsg_printf(ERRMSG_LVL_WARN, _("Could not remove temporary table: '%s', error: %d"),
2004
 
                  path.c_str(), errno);
2005
 
 
2006
 
    return true;
2007
 
  }
2008
 
 
2009
 
  return false;
2010
 
}
2011
 
 
2012
 
/**
2013
 
  @note this will be removed, I am looking through Hudson to see if it is finding
2014
 
  any tables that are missed during cleanup.
2015
 
*/
2016
 
void Open_tables_state::dumpTemporaryTableNames(const char *foo)
2017
 
{
2018
 
  Table *table;
2019
 
 
2020
 
  if (not temporary_tables)
2021
 
    return;
2022
 
 
2023
 
  cerr << "Begin Run: " << foo << "\n";
2024
 
  for (table= temporary_tables; table; table= table->getNext())
2025
 
  {
2026
 
    bool have_proto= false;
2027
 
 
2028
 
    message::Table *proto= table->getShare()->getTableProto();
2029
 
    if (table->getShare()->getTableProto())
2030
 
      have_proto= true;
2031
 
 
2032
 
    const char *answer= have_proto ? "true" : "false";
2033
 
 
2034
 
    if (have_proto)
2035
 
    {
2036
 
      cerr << "\tTable Name " << table->getShare()->getSchemaName() << "." << table->getShare()->getTableName() << " : " << answer << "\n";
2037
 
      cerr << "\t\t Proto " << proto->schema() << " " << proto->name() << "\n";
2038
 
    }
2039
 
    else
2040
 
    {
2041
 
      cerr << "\tTabl;e Name " << table->getShare()->getSchemaName() << "." << table->getShare()->getTableName() << " : " << answer << "\n";
2042
 
    }
2043
 
  }
2044
 
}
2045
 
 
2046
 
bool Session::TableMessages::storeTableMessage(const TableIdentifier &identifier, message::Table &table_message)
2047
 
{
2048
 
  table_message_cache.insert(make_pair(identifier.getPath(), table_message));
2049
 
 
2050
 
  return true;
2051
 
}
2052
 
 
2053
 
bool Session::TableMessages::removeTableMessage(const TableIdentifier &identifier)
2054
 
{
2055
 
  TableMessageCache::iterator iter;
2056
 
 
2057
 
  iter= table_message_cache.find(identifier.getPath());
2058
 
 
2059
 
  if (iter == table_message_cache.end())
2060
 
    return false;
2061
 
 
2062
 
  table_message_cache.erase(iter);
2063
 
 
2064
 
  return true;
2065
 
}
2066
 
 
2067
 
bool Session::TableMessages::getTableMessage(const TableIdentifier &identifier, message::Table &table_message)
2068
 
{
2069
 
  TableMessageCache::iterator iter;
2070
 
 
2071
 
  iter= table_message_cache.find(identifier.getPath());
2072
 
 
2073
 
  if (iter == table_message_cache.end())
2074
 
    return false;
2075
 
 
2076
 
  table_message.CopyFrom(((*iter).second));
2077
 
 
2078
 
  return true;
2079
 
}
2080
 
 
2081
 
bool Session::TableMessages::doesTableMessageExist(const TableIdentifier &identifier)
2082
 
{
2083
 
  TableMessageCache::iterator iter;
2084
 
 
2085
 
  iter= table_message_cache.find(identifier.getPath());
2086
 
 
2087
 
  if (iter == table_message_cache.end())
2088
 
  {
2089
 
    return false;
2090
 
  }
2091
 
 
2092
 
  return true;
2093
 
}
2094
 
 
2095
 
bool Session::TableMessages::renameTableMessage(const TableIdentifier &from, const TableIdentifier &to)
2096
 
{
2097
 
  TableMessageCache::iterator iter;
2098
 
 
2099
 
  table_message_cache[to.getPath()]= table_message_cache[from.getPath()];
2100
 
 
2101
 
  iter= table_message_cache.find(to.getPath());
2102
 
 
2103
 
  if (iter == table_message_cache.end())
2104
 
  {
2105
 
    return false;
2106
 
  }
2107
 
 
2108
 
  (*iter).second.set_schema(to.getSchemaName());
2109
 
  (*iter).second.set_name(to.getTableName());
2110
 
 
2111
 
  return true;
2112
 
}
2113
 
 
2114
 
table::Instance *Session::getInstanceTable()
2115
 
{
2116
 
  temporary_shares.push_back(new table::Instance()); // This will not go into the tableshare cache, so no key is used.
2117
 
 
2118
 
  table::Instance *tmp_share= temporary_shares.back();
2119
 
 
2120
 
  assert(tmp_share);
2121
 
 
2122
 
  return tmp_share;
2123
 
}
2124
 
 
2125
 
 
2126
 
/**
2127
 
  Create a reduced Table object with properly set up Field list from a
2128
 
  list of field definitions.
2129
 
 
2130
 
    The created table doesn't have a table Cursor associated with
2131
 
    it, has no keys, no group/distinct, no copy_funcs array.
2132
 
    The sole purpose of this Table object is to use the power of Field
2133
 
    class to read/write data to/from table->getInsertRecord(). Then one can store
2134
 
    the record in any container (RB tree, hash, etc).
2135
 
    The table is created in Session mem_root, so are the table's fields.
2136
 
    Consequently, if you don't BLOB fields, you don't need to free it.
2137
 
 
2138
 
  @param session         connection handle
2139
 
  @param field_list  list of column definitions
2140
 
 
2141
 
  @return
2142
 
    0 if out of memory, Table object in case of success
2143
 
*/
2144
 
table::Instance *Session::getInstanceTable(List<CreateField> &field_list)
2145
 
{
2146
 
  temporary_shares.push_back(new table::Instance(this, field_list)); // This will not go into the tableshare cache, so no key is used.
2147
 
 
2148
 
  table::Instance *tmp_share= temporary_shares.back();
2149
 
 
2150
 
  assert(tmp_share);
2151
 
 
2152
 
  return tmp_share;
2153
 
}
2154
 
 
2155
 
namespace display  {
2156
 
 
2157
 
static const std::string NONE= "NONE";
2158
 
static const std::string GOT_GLOBAL_READ_LOCK= "HAS GLOBAL READ LOCK";
2159
 
static const std::string MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT= "HAS GLOBAL READ LOCK WITH BLOCKING COMMIT";
2160
 
 
2161
 
const std::string &type(drizzled::Session::global_read_lock_t type)
2162
 
{
2163
 
  switch (type) {
2164
 
    default:
2165
 
    case Session::NONE:
2166
 
      return NONE;
2167
 
    case Session::GOT_GLOBAL_READ_LOCK:
2168
 
      return GOT_GLOBAL_READ_LOCK;
2169
 
    case Session::MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT:
2170
 
      return MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT;
2171
 
  }
2172
 
}
2173
 
 
2174
 
size_t max_string_length(drizzled::Session::global_read_lock_t)
2175
 
{
2176
 
  return MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT.size();
2177
 
}
2178
 
 
2179
 
} /* namespace display */
2180
 
 
2181
 
} /* namespace drizzled */
 
2594
 
 
2595
  return;
 
2596
}