~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/session.cc

  • Committer: Brian Aker
  • Date: 2010-02-11 22:43:58 UTC
  • Revision ID: brian@gaz-20100211224358-y0gdvnat2ahg4c1e
Disabling support for memcached plugins until we can test for version of
memcached.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (C) 2000-2006 MySQL AB
2
 
 
3
 
   This program is free software; you can redistribute it and/or modify
4
 
   it under the terms of the GNU General Public License as published by
5
 
   the Free Software Foundation; version 2 of the License.
6
 
 
7
 
   This program is distributed in the hope that it will be useful,
8
 
   but WITHOUT ANY WARRANTY; without even the implied warranty of
9
 
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
 
   GNU General Public License for more details.
11
 
 
12
 
   You should have received a copy of the GNU General Public License
13
 
   along with this program; if not, write to the Free Software
14
 
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
 
 
16
 
 
17
 
/*****************************************************************************
18
 
**
19
 
** This file implements classes defined in sql_class.h
20
 
** Especially the classes to handle a result from a select
21
 
**
22
 
*****************************************************************************/
23
 
#include <drizzled/server_includes.h>
24
 
#include "rpl_rli.h"
25
 
#include "rpl_record.h"
26
 
#include "log_event.h"
 
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
 
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
 
3
 *
 
4
 *  Copyright (C) 2008 Sun Microsystems
 
5
 *
 
6
 *  This program is free software; you can redistribute it and/or modify
 
7
 *  it under the terms of the GNU General Public License as published by
 
8
 *  the Free Software Foundation; version 2 of the License.
 
9
 *
 
10
 *  This program is distributed in the hope that it will be useful,
 
11
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
 *  GNU General Public License for more details.
 
14
 *
 
15
 *  You should have received a copy of the GNU General Public License
 
16
 *  along with this program; if not, write to the Free Software
 
17
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
18
 */
 
19
 
 
20
/**
 
21
 * @file Implementation of the Session class and API
 
22
 */
 
23
 
 
24
#include "config.h"
 
25
#include <drizzled/session.h>
 
26
#include "drizzled/session_list.h"
27
27
#include <sys/stat.h>
28
 
#include <mysys/thr_alarm.h>
29
 
#include <mysys/mysys_err.h>
30
 
#include <drizzled/drizzled_error_messages.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/probes.h"
 
43
#include "drizzled/table_proto.h"
 
44
#include "drizzled/db.h"
 
45
#include "drizzled/pthread_globals.h"
 
46
#include "drizzled/transaction_services.h"
 
47
 
 
48
#include "plugin/myisam/myisam.h"
 
49
#include "drizzled/internal/iocache.h"
 
50
 
 
51
#include <fcntl.h>
 
52
#include <algorithm>
 
53
#include <climits>
 
54
 
 
55
using namespace std;
 
56
namespace drizzled
 
57
{
 
58
 
 
59
extern "C"
 
60
{
 
61
  unsigned char *get_var_key(user_var_entry *entry, size_t *length, bool );
 
62
  void free_user_var(user_var_entry *entry);
 
63
}
31
64
 
32
65
/*
33
66
  The following is used to initialise Table_ident with a internal
36
69
char internal_table_name[2]= "*";
37
70
char empty_c_string[1]= {0};    /* used for not defined db */
38
71
 
39
 
const char * const THD::DEFAULT_WHERE= "field list";
40
 
 
41
 
 
42
 
/*****************************************************************************
43
 
** Instansiate templates
44
 
*****************************************************************************/
45
 
 
46
 
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
47
 
/* Used templates */
48
 
template class List<Key>;
49
 
template class List_iterator<Key>;
50
 
template class List<Key_part_spec>;
51
 
template class List_iterator<Key_part_spec>;
52
 
template class List<Alter_drop>;
53
 
template class List_iterator<Alter_drop>;
54
 
template class List<Alter_column>;
55
 
template class List_iterator<Alter_column>;
56
 
#endif
 
72
const char * const Session::DEFAULT_WHERE= "field list";
 
73
extern pthread_key_t THR_Session;
 
74
extern pthread_key_t THR_Mem_root;
 
75
extern uint32_t max_used_connections;
 
76
extern atomic<uint32_t> connection_count;
 
77
 
57
78
 
58
79
/****************************************************************************
59
80
** User variables
60
81
****************************************************************************/
61
 
 
62
 
extern "C" uchar *get_var_key(user_var_entry *entry, size_t *length,
63
 
                              bool not_used __attribute__((unused)))
 
82
unsigned char *get_var_key(user_var_entry *entry, size_t *length, bool )
64
83
{
65
84
  *length= entry->name.length;
66
 
  return (uchar*) entry->name.str;
 
85
  return (unsigned char*) entry->name.str;
67
86
}
68
87
 
69
 
extern "C" void free_user_var(user_var_entry *entry)
 
88
void free_user_var(user_var_entry *entry)
70
89
{
71
 
  char *pos= (char*) entry+ALIGN_SIZE(sizeof(*entry));
72
 
  if (entry->value && entry->value != pos)
73
 
    my_free(entry->value, MYF(0));
74
 
  my_free((char*) entry,MYF(0));
 
90
  delete entry;
75
91
}
76
92
 
77
93
bool Key_part_spec::operator==(const Key_part_spec& other) const
81
97
         !strcmp(field_name.str, other.field_name.str);
82
98
}
83
99
 
84
 
/**
85
 
  Construct an (almost) deep copy of this key. Only those
86
 
  elements that are known to never change are not copied.
87
 
  If out of memory, a partial copy is returned and an error is set
88
 
  in THD.
89
 
*/
90
 
 
91
 
Key::Key(const Key &rhs, MEM_ROOT *mem_root)
92
 
  :type(rhs.type),
93
 
  key_create_info(rhs.key_create_info),
94
 
  columns(rhs.columns, mem_root),
95
 
  name(rhs.name),
96
 
  generated(rhs.generated)
97
 
{
98
 
  list_copy_and_replace_each_value(columns, mem_root);
99
 
}
100
 
 
101
 
/**
102
 
  Construct an (almost) deep copy of this foreign 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 THD.
106
 
*/
107
 
 
108
 
Foreign_key::Foreign_key(const Foreign_key &rhs, MEM_ROOT *mem_root)
109
 
  :Key(rhs),
110
 
  ref_table(rhs.ref_table),
111
 
  ref_columns(rhs.ref_columns),
112
 
  delete_opt(rhs.delete_opt),
113
 
  update_opt(rhs.update_opt),
114
 
  match_opt(rhs.match_opt)
115
 
{
116
 
  list_copy_and_replace_each_value(ref_columns, mem_root);
117
 
}
118
 
 
119
 
/*
120
 
  Test if a foreign key (= generated key) is a prefix of the given key
121
 
  (ignoring key name, key type and order of columns)
122
 
 
123
 
  NOTES:
124
 
    This is only used to test if an index for a FOREIGN KEY exists
125
 
 
126
 
  IMPLEMENTATION
127
 
    We only compare field names
128
 
 
129
 
  RETURN
130
 
    0   Generated key is a prefix of other key
131
 
    1   Not equal
132
 
*/
133
 
 
134
 
bool foreign_key_prefix(Key *a, Key *b)
135
 
{
136
 
  /* Ensure that 'a' is the generated key */
137
 
  if (a->generated)
138
 
  {
139
 
    if (b->generated && a->columns.elements > b->columns.elements)
140
 
      swap_variables(Key*, a, b);               // Put shorter key in 'a'
141
 
  }
142
 
  else
143
 
  {
144
 
    if (!b->generated)
145
 
      return true;                              // No foreign key
146
 
    swap_variables(Key*, a, b);                 // Put generated key in 'a'
147
 
  }
148
 
 
149
 
  /* Test if 'a' is a prefix of 'b' */
150
 
  if (a->columns.elements > b->columns.elements)
151
 
    return true;                                // Can't be prefix
152
 
 
153
 
  List_iterator<Key_part_spec> col_it1(a->columns);
154
 
  List_iterator<Key_part_spec> col_it2(b->columns);
155
 
  const Key_part_spec *col1, *col2;
156
 
 
157
 
#ifdef ENABLE_WHEN_INNODB_CAN_HANDLE_SWAPED_FOREIGN_KEY_COLUMNS
158
 
  while ((col1= col_it1++))
159
 
  {
160
 
    bool found= 0;
161
 
    col_it2.rewind();
162
 
    while ((col2= col_it2++))
163
 
    {
164
 
      if (*col1 == *col2)
165
 
      {
166
 
        found= true;
167
 
        break;
168
 
      }
169
 
    }
170
 
    if (!found)
171
 
      return true;                              // Error
172
 
  }
173
 
  return false;                                 // Is prefix
174
 
#else
175
 
  while ((col1= col_it1++))
176
 
  {
177
 
    col2= col_it2++;
178
 
    if (!(*col1 == *col2))
179
 
      return true;
180
 
  }
181
 
  return false;                                 // Is prefix
182
 
#endif
183
 
}
184
 
 
185
 
 
186
 
/****************************************************************************
187
 
** Thread specific functions
188
 
****************************************************************************/
189
 
 
190
 
Open_tables_state::Open_tables_state(ulong version_arg)
191
 
  :version(version_arg), state_flags(0U)
 
100
Open_tables_state::Open_tables_state(uint64_t version_arg)
 
101
  :version(version_arg), backups_available(false)
192
102
{
193
103
  reset_open_tables_state();
194
104
}
196
106
/*
197
107
  The following functions form part of the C plugin API
198
108
*/
199
 
 
200
109
extern "C" int mysql_tmpfile(const char *prefix)
201
110
{
202
111
  char filename[FN_REFLEN];
203
 
  File fd = create_temp_file(filename, mysql_tmpdir, prefix,
204
 
                             O_CREAT | O_EXCL | O_RDWR | O_TEMPORARY,
205
 
                             MYF(MY_WME));
 
112
  int fd = internal::create_temp_file(filename, drizzle_tmpdir, prefix, MYF(MY_WME));
206
113
  if (fd >= 0) {
207
 
    /*
208
 
      This can be removed once the following bug is fixed:
209
 
      Bug #28903  create_temp_file() doesn't honor O_TEMPORARY option
210
 
                  (file not removed) (Unix)
211
 
    */
212
114
    unlink(filename);
213
115
  }
214
116
 
215
117
  return fd;
216
118
}
217
119
 
218
 
 
219
 
extern "C"
220
 
int thd_in_lock_tables(const THD *thd)
221
 
{
222
 
  return test(thd->in_lock_tables);
223
 
}
224
 
 
225
 
 
226
 
extern "C"
227
 
int thd_tablespace_op(const THD *thd)
228
 
{
229
 
  return test(thd->tablespace_op);
230
 
}
231
 
 
232
 
 
233
 
extern "C"
234
 
const char *set_thd_proc_info(THD *thd, const char *info,
235
 
                              const char *calling_function __attribute__((unused)),
236
 
                              const char *calling_file __attribute__((unused)),
237
 
                              const unsigned int calling_line __attribute__((unused)))
238
 
{
239
 
  const char *old_info= thd->proc_info;
240
 
  thd->proc_info= info;
241
 
  return old_info;
242
 
}
243
 
 
244
 
extern "C"
245
 
void **thd_ha_data(const THD *thd, const struct handlerton *hton)
246
 
{
247
 
  return (void **) &thd->ha_data[hton->slot].ha_ptr;
248
 
}
249
 
 
250
 
extern "C"
251
 
int64_t thd_test_options(const THD *thd, int64_t test_options)
252
 
{
253
 
  return thd->options & test_options;
254
 
}
255
 
 
256
 
extern "C"
257
 
int thd_sql_command(const THD *thd)
258
 
{
259
 
  return (int) thd->lex->sql_command;
260
 
}
261
 
 
262
 
extern "C"
263
 
int thd_tx_isolation(const THD *thd)
264
 
{
265
 
  return (int) thd->variables.tx_isolation;
266
 
}
267
 
 
268
 
extern "C"
269
 
void thd_inc_row_count(THD *thd)
270
 
{
271
 
  thd->row_count++;
272
 
}
273
 
 
274
 
/**
275
 
  Clear this diagnostics area. 
276
 
 
277
 
  Normally called at the end of a statement.
278
 
*/
279
 
 
280
 
void
281
 
Diagnostics_area::reset_diagnostics_area()
282
 
{
283
 
  can_overwrite_status= false;
284
 
  /** Don't take chances in production */
285
 
  m_message[0]= '\0';
286
 
  m_sql_errno= 0;
287
 
  m_server_status= 0;
288
 
  m_affected_rows= 0;
289
 
  m_last_insert_id= 0;
290
 
  m_total_warn_count= 0;
291
 
  is_sent= false;
292
 
  /** Tiny reset in debug mode to see garbage right away */
293
 
  m_status= DA_EMPTY;
294
 
}
295
 
 
296
 
 
297
 
/**
298
 
  Set OK status -- ends commands that do not return a
299
 
  result set, e.g. INSERT/UPDATE/DELETE.
300
 
*/
301
 
 
302
 
void
303
 
Diagnostics_area::set_ok_status(THD *thd, ha_rows affected_rows_arg,
304
 
                                uint64_t last_insert_id_arg,
305
 
                                const char *message_arg)
306
 
{
307
 
  assert(! is_set());
308
 
  /*
309
 
    In production, refuse to overwrite an error or a custom response
310
 
    with an OK packet.
311
 
  */
312
 
  if (is_error() || is_disabled())
313
 
    return;
314
 
  /** Only allowed to report success if has not yet reported an error */
315
 
 
316
 
  m_server_status= thd->server_status;
317
 
  m_total_warn_count= thd->total_warn_count;
318
 
  m_affected_rows= affected_rows_arg;
319
 
  m_last_insert_id= last_insert_id_arg;
320
 
  if (message_arg)
321
 
    strmake(m_message, message_arg, sizeof(m_message) - 1);
322
 
  else
323
 
    m_message[0]= '\0';
324
 
  m_status= DA_OK;
325
 
}
326
 
 
327
 
 
328
 
/**
329
 
  Set EOF status.
330
 
*/
331
 
 
332
 
void
333
 
Diagnostics_area::set_eof_status(THD *thd)
334
 
{
335
 
  /** Only allowed to report eof if has not yet reported an error */
336
 
 
337
 
  assert(! is_set());
338
 
  /*
339
 
    In production, refuse to overwrite an error or a custom response
340
 
    with an EOF packet.
341
 
  */
342
 
  if (is_error() || is_disabled())
343
 
    return;
344
 
 
345
 
  m_server_status= thd->server_status;
346
 
  /*
347
 
    If inside a stored procedure, do not return the total
348
 
    number of warnings, since they are not available to the client
349
 
    anyway.
350
 
  */
351
 
  m_total_warn_count= thd->total_warn_count;
352
 
 
353
 
  m_status= DA_EOF;
354
 
}
355
 
 
356
 
/**
357
 
  Set ERROR status.
358
 
*/
359
 
 
360
 
void
361
 
Diagnostics_area::set_error_status(THD *thd __attribute__((unused)),
362
 
                                   uint sql_errno_arg,
363
 
                                   const char *message_arg)
364
 
{
365
 
  /*
366
 
    Only allowed to report error if has not yet reported a success
367
 
    The only exception is when we flush the message to the client,
368
 
    an error can happen during the flush.
369
 
  */
370
 
  assert(! is_set() || can_overwrite_status);
371
 
  /*
372
 
    In production, refuse to overwrite a custom response with an
373
 
    ERROR packet.
374
 
  */
375
 
  if (is_disabled())
376
 
    return;
377
 
 
378
 
  m_sql_errno= sql_errno_arg;
379
 
  strmake(m_message, message_arg, sizeof(m_message) - 1);
380
 
 
381
 
  m_status= DA_ERROR;
382
 
}
383
 
 
384
 
 
385
 
/**
386
 
  Mark the diagnostics area as 'DISABLED'.
387
 
 
388
 
  This is used in rare cases when the COM_ command at hand sends a response
389
 
  in a custom format. One example is the query cache, another is
390
 
  COM_STMT_PREPARE.
391
 
*/
392
 
 
393
 
void
394
 
Diagnostics_area::disable_status()
395
 
{
396
 
  assert(! is_set());
397
 
  m_status= DA_DISABLED;
398
 
}
399
 
 
400
 
 
401
 
THD::THD()
402
 
   :Statement(&main_lex, &main_mem_root, CONVENTIONAL_EXECUTION,
403
 
              /* statement id */ 0),
404
 
   Open_tables_state(refresh_version), rli_fake(0),
405
 
   lock_id(&main_lock_id),
406
 
   user_time(0), in_sub_stmt(0),
407
 
   binlog_table_maps(0), binlog_flags(0UL),
408
 
   arg_of_last_insert_id_function(false),
409
 
   first_successful_insert_id_in_prev_stmt(0),
410
 
   first_successful_insert_id_in_prev_stmt_for_binlog(0),
411
 
   first_successful_insert_id_in_cur_stmt(0),
412
 
   stmt_depends_on_first_successful_insert_id_in_prev_stmt(false),
413
 
   global_read_lock(0),
414
 
   is_fatal_error(0),
415
 
   transaction_rollback_request(0),
416
 
   is_fatal_sub_stmt_error(0),
417
 
   rand_used(0),
418
 
   time_zone_used(0),
419
 
   in_lock_tables(0),
420
 
   bootstrap(0),
421
 
   derived_tables_processing(false),
422
 
   m_lip(NULL)
423
 
{
424
 
  ulong tmp;
 
120
extern "C"
 
121
int session_tablespace_op(const Session *session)
 
122
{
 
123
  return test(session->tablespace_op);
 
124
}
 
125
 
 
126
/**
 
127
   Set the process info field of the Session structure.
 
128
 
 
129
   This function is used by plug-ins. Internally, the
 
130
   Session::set_proc_info() function should be used.
 
131
 
 
132
   @see Session::set_proc_info
 
133
 */
 
134
extern "C" void
 
135
set_session_proc_info(Session *session, const char *info)
 
136
{
 
137
  session->set_proc_info(info);
 
138
}
 
139
 
 
140
extern "C"
 
141
const char *get_session_proc_info(Session *session)
 
142
{
 
143
  return session->get_proc_info();
 
144
}
 
145
 
 
146
void **Session::getEngineData(const plugin::StorageEngine *engine)
 
147
{
 
148
  return static_cast<void **>(&ha_data[engine->slot].ha_ptr);
 
149
}
 
150
 
 
151
Ha_trx_info *Session::getEngineInfo(const plugin::StorageEngine *engine,
 
152
                                    size_t index)
 
153
{
 
154
  return &ha_data[engine->getSlot()].ha_info[index];
 
155
}
 
156
 
 
157
extern "C"
 
158
int64_t session_test_options(const Session *session, int64_t test_options)
 
159
{
 
160
  return session->options & test_options;
 
161
}
 
162
 
 
163
extern "C"
 
164
int session_sql_command(const Session *session)
 
165
{
 
166
  return (int) session->lex->sql_command;
 
167
}
 
168
 
 
169
extern "C"
 
170
int session_tx_isolation(const Session *session)
 
171
{
 
172
  return (int) session->variables.tx_isolation;
 
173
}
 
174
 
 
175
Session::Session(plugin::Client *client_arg)
 
176
  :
 
177
  Open_tables_state(refresh_version),
 
178
  mem_root(&main_mem_root),
 
179
  lex(&main_lex),
 
180
  client(client_arg),
 
181
  scheduler(NULL),
 
182
  scheduler_arg(NULL),
 
183
  lock_id(&main_lock_id),
 
184
  user_time(0),
 
185
  arg_of_last_insert_id_function(false),
 
186
  first_successful_insert_id_in_prev_stmt(0),
 
187
  first_successful_insert_id_in_cur_stmt(0),
 
188
  limit_found_rows(0),
 
189
  global_read_lock(0),
 
190
  some_tables_deleted(false),
 
191
  no_errors(false),
 
192
  password(false),
 
193
  is_fatal_error(false),
 
194
  transaction_rollback_request(false),
 
195
  is_fatal_sub_stmt_error(0),
 
196
  derived_tables_processing(false),
 
197
  tablespace_op(false),
 
198
  m_lip(NULL),
 
199
  cached_table(0),
 
200
  transaction_message(NULL),
 
201
  statement_message(NULL)
 
202
{
 
203
  memset(process_list_info, 0, PROCESS_LIST_WIDTH);
 
204
  client->setSession(this);
425
205
 
426
206
  /*
427
207
    Pass nominal parameters to init_alloc_root only to ensure that
428
208
    the destructor works OK in case of an error. The main_mem_root
429
209
    will be re-initialized in init_for_queries().
430
210
  */
431
 
  init_sql_alloc(&main_mem_root, ALLOC_ROOT_MIN_BLOCK_SIZE, 0);
432
 
  stmt_arena= this;
433
 
  thread_stack= 0;
434
 
  catalog= (char*)"std"; // the only catalog we have for now
435
 
  main_security_ctx.init();
436
 
  security_ctx= &main_security_ctx;
437
 
  some_tables_deleted=no_errors=password= 0;
438
 
  query_start_used= 0;
 
211
  memory::init_sql_alloc(&main_mem_root, memory::ROOT_MIN_BLOCK_SIZE, 0);
 
212
  thread_stack= NULL;
439
213
  count_cuted_fields= CHECK_FIELD_IGNORE;
440
214
  killed= NOT_KILLED;
441
 
  col_access=0;
442
 
  is_slave_error= thread_specific_used= false;
443
 
  hash_clear(&handler_tables_hash);
444
 
  tmp_table=0;
445
 
  used_tables=0;
 
215
  col_access= 0;
 
216
  tmp_table= 0;
 
217
  used_tables= 0;
446
218
  cuted_fields= sent_row_count= row_count= 0L;
447
 
  limit_found_rows= 0;
448
219
  row_count_func= -1;
449
220
  statement_id_counter= 0UL;
450
 
  // Must be reset to handle error with THD's created for init of mysqld
 
221
  // Must be reset to handle error with Session's created for init of mysqld
451
222
  lex->current_select= 0;
452
223
  start_time=(time_t) 0;
453
224
  start_utime= 0L;
454
225
  utime_after_lock= 0L;
455
 
  current_linfo =  0;
456
 
  slave_thread = 0;
457
226
  memset(&variables, 0, sizeof(variables));
458
227
  thread_id= 0;
459
 
  one_shot_set= 0;
460
228
  file_id = 0;
461
229
  query_id= 0;
462
 
  warn_id= 0;
463
 
  db_charset= global_system_variables.collation_database;
 
230
  query= NULL;
 
231
  query_length= 0;
 
232
  warn_query_id= 0;
464
233
  memset(ha_data, 0, sizeof(ha_data));
465
 
  mysys_var=0;
466
 
  binlog_evt_union.do_union= false;
467
 
  enable_slow_log= 0;
468
 
  dbug_sentry=THD_SENTRY_MAGIC;
469
 
  net.vio=0;
470
 
  client_capabilities= 0;                       // minimalistic client
471
 
  system_thread= NON_SYSTEM_THREAD;
472
 
  cleanup_done= abort_on_warning= no_warnings_for_error= 0;
473
 
  peer_port= 0;                                 // For SHOW PROCESSLIST
474
 
  transaction.m_pending_rows_event= 0;
475
 
  transaction.on= 1;
476
 
#ifdef SIGNAL_WITH_VIO_CLOSE
477
 
  active_vio = 0;
478
 
#endif
 
234
  mysys_var= 0;
 
235
  dbug_sentry=Session_SENTRY_MAGIC;
 
236
  cleanup_done= abort_on_warning= no_warnings_for_error= false;
479
237
  pthread_mutex_init(&LOCK_delete, MY_MUTEX_INIT_FAST);
480
238
 
481
239
  /* Variables with default values */
482
240
  proc_info="login";
483
 
  where= THD::DEFAULT_WHERE;
484
 
  server_id = ::server_id;
485
 
  slave_net = 0;
486
 
  command=COM_CONNECT;
487
 
  *scramble= '\0';
488
 
 
489
 
  init();
 
241
  where= Session::DEFAULT_WHERE;
 
242
  command= COM_CONNECT;
 
243
 
 
244
  plugin_sessionvar_init(this);
 
245
  /*
 
246
    variables= global_system_variables above has reset
 
247
    variables.pseudo_thread_id to 0. We need to correct it here to
 
248
    avoid temporary tables replication failure.
 
249
  */
 
250
  variables.pseudo_thread_id= thread_id;
 
251
  server_status= SERVER_STATUS_AUTOCOMMIT;
 
252
  options= session_startup_options;
 
253
 
 
254
  if (variables.max_join_size == HA_POS_ERROR)
 
255
    options |= OPTION_BIG_SELECTS;
 
256
  else
 
257
    options &= ~OPTION_BIG_SELECTS;
 
258
 
 
259
  transaction.all.modified_non_trans_table= transaction.stmt.modified_non_trans_table= false;
 
260
  open_options=ha_open_options;
 
261
  update_lock_default= TL_WRITE;
 
262
  session_tx_isolation= (enum_tx_isolation) variables.tx_isolation;
 
263
  warn_list.empty();
 
264
  memset(warn_count, 0, sizeof(warn_count));
 
265
  total_warn_count= 0;
 
266
  memset(&status_var, 0, sizeof(status_var));
 
267
 
490
268
  /* Initialize sub structures */
491
 
  init_sql_alloc(&warn_root, WARN_ALLOC_BLOCK_SIZE, WARN_ALLOC_PREALLOC_SIZE);
492
 
  user_connect=(USER_CONN *)0;
 
269
  memory::init_sql_alloc(&warn_root, WARN_ALLOC_BLOCK_SIZE, WARN_ALLOC_PREALLOC_SIZE);
493
270
  hash_init(&user_vars, system_charset_info, USER_VARS_HASH_SIZE, 0, 0,
494
271
            (hash_get_key) get_var_key,
495
272
            (hash_free_key) free_user_var, 0);
496
273
 
497
 
  /* For user vars replication*/
498
 
  if (opt_bin_log)
499
 
    my_init_dynamic_array(&user_var_events,
500
 
                          sizeof(BINLOG_USER_VAR_EVENT *), 16, 16);
501
 
  else
502
 
    memset(&user_var_events, 0, sizeof(user_var_events));
503
 
 
504
 
  /* Protocol */
505
 
  protocol= &protocol_text;                     // Default protocol
506
 
  protocol_text.init(this);
507
 
 
508
 
  tablespace_op= false;
509
 
  tmp= sql_rnd();
510
 
  randominit(&rand, tmp + (ulong) &rand, tmp + (ulong) ::global_query_id);
511
274
  substitute_null_with_insert_id = false;
512
275
  thr_lock_info_init(&lock_info); /* safety: will be reset after start */
513
276
  thr_lock_owner_init(&main_lock_id, &lock_info);
515
278
  m_internal_handler= NULL;
516
279
}
517
280
 
 
281
void Session::free_items()
 
282
{
 
283
  Item *next;
 
284
  /* This works because items are allocated with memory::sql_alloc() */
 
285
  for (; free_list; free_list= next)
 
286
  {
 
287
    next= free_list->next;
 
288
    free_list->delete_self();
 
289
  }
 
290
}
518
291
 
519
 
void THD::push_internal_handler(Internal_error_handler *handler)
 
292
void Session::push_internal_handler(Internal_error_handler *handler)
520
293
{
521
294
  /*
522
295
    TODO: The current implementation is limited to 1 handler at a time only.
523
 
    THD and sp_rcontext need to be modified to use a common handler stack.
 
296
    Session and sp_rcontext need to be modified to use a common handler stack.
524
297
  */
525
298
  assert(m_internal_handler == NULL);
526
299
  m_internal_handler= handler;
527
300
}
528
301
 
529
 
 
530
 
bool THD::handle_error(uint sql_errno, const char *message,
 
302
bool Session::handle_error(uint32_t sql_errno, const char *message,
531
303
                       DRIZZLE_ERROR::enum_warning_level level)
532
304
{
533
305
  if (m_internal_handler)
538
310
  return false;                                 // 'false', as per coding style
539
311
}
540
312
 
541
 
 
542
 
void THD::pop_internal_handler()
 
313
void Session::pop_internal_handler()
543
314
{
544
315
  assert(m_internal_handler != NULL);
545
316
  m_internal_handler= NULL;
546
317
}
547
318
 
548
 
extern "C"
549
 
void *thd_alloc(DRIZZLE_THD thd, unsigned int size)
550
 
{
551
 
  return thd->alloc(size);
552
 
}
553
 
 
554
 
extern "C"
555
 
void *thd_calloc(DRIZZLE_THD thd, unsigned int size)
556
 
{
557
 
  return thd->calloc(size);
558
 
}
559
 
 
560
 
extern "C"
561
 
char *thd_strdup(DRIZZLE_THD thd, const char *str)
562
 
{
563
 
  return thd->strdup(str);
564
 
}
565
 
 
566
 
extern "C"
567
 
char *thd_strmake(DRIZZLE_THD thd, const char *str, unsigned int size)
568
 
{
569
 
  return thd->strmake(str, size);
570
 
}
571
 
 
572
 
extern "C"
573
 
LEX_STRING *thd_make_lex_string(THD *thd, LEX_STRING *lex_str,
574
 
                                const char *str, unsigned int size,
575
 
                                int allocate_lex_string)
576
 
{
577
 
  return thd->make_lex_string(lex_str, str, size,
578
 
                              (bool) allocate_lex_string);
579
 
}
580
 
 
581
 
extern "C"
582
 
void *thd_memdup(DRIZZLE_THD thd, const void* str, unsigned int size)
583
 
{
584
 
  return thd->memdup(str, size);
585
 
}
586
 
 
587
 
extern "C"
588
 
void thd_get_xid(const DRIZZLE_THD thd, DRIZZLE_XID *xid)
589
 
{
590
 
  *xid = *(DRIZZLE_XID *) &thd->transaction.xid_state.xid;
591
 
}
592
 
 
593
 
/*
594
 
  Init common variables that has to be reset on start and on change_user
595
 
*/
596
 
 
597
 
void THD::init(void)
598
 
{
599
 
  pthread_mutex_lock(&LOCK_global_system_variables);
600
 
  plugin_thdvar_init(this);
601
 
  variables.time_format= date_time_format_copy((THD*) 0,
602
 
                                               variables.time_format);
603
 
  variables.date_format= date_time_format_copy((THD*) 0,
604
 
                                               variables.date_format);
605
 
  variables.datetime_format= date_time_format_copy((THD*) 0,
606
 
                                                   variables.datetime_format);
607
 
  /*
608
 
    variables= global_system_variables above has reset
609
 
    variables.pseudo_thread_id to 0. We need to correct it here to
610
 
    avoid temporary tables replication failure.
611
 
  */
612
 
  variables.pseudo_thread_id= thread_id;
613
 
  pthread_mutex_unlock(&LOCK_global_system_variables);
614
 
  server_status= SERVER_STATUS_AUTOCOMMIT;
615
 
  options= thd_startup_options;
616
 
 
617
 
  if (variables.max_join_size == HA_POS_ERROR)
618
 
    options |= OPTION_BIG_SELECTS;
619
 
  else
620
 
    options &= ~OPTION_BIG_SELECTS;
621
 
 
622
 
  transaction.all.modified_non_trans_table= transaction.stmt.modified_non_trans_table= false;
623
 
  open_options=ha_open_options;
624
 
  update_lock_default= (variables.low_priority_updates ?
625
 
                        TL_WRITE_LOW_PRIORITY :
626
 
                        TL_WRITE);
627
 
  session_tx_isolation= (enum_tx_isolation) variables.tx_isolation;
628
 
  warn_list.empty();
629
 
  memset(warn_count, 0, sizeof(warn_count));
630
 
  total_warn_count= 0;
631
 
  update_charset();
632
 
  reset_current_stmt_binlog_row_based();
633
 
  memset(&status_var, 0, sizeof(status_var));
634
 
}
635
 
 
636
 
 
637
 
/*
638
 
  Init THD for query processing.
639
 
  This has to be called once before we call mysql_parse.
640
 
  See also comments in sql_class.h.
641
 
*/
642
 
 
643
 
void THD::init_for_queries()
644
 
{
645
 
  set_time(); 
646
 
  ha_enable_transaction(this,true);
647
 
 
648
 
  reset_root_defaults(mem_root, variables.query_alloc_block_size,
649
 
                      variables.query_prealloc_size);
650
 
  reset_root_defaults(&transaction.mem_root,
651
 
                      variables.trans_alloc_block_size,
652
 
                      variables.trans_prealloc_size);
653
 
  transaction.xid_state.xid.null();
654
 
  transaction.xid_state.in_thd=1;
655
 
}
656
 
 
 
319
#if defined(__cplusplus)
 
320
extern "C" {
 
321
#endif
 
322
 
 
323
void *session_alloc(Session *session, unsigned int size)
 
324
{
 
325
  return session->alloc(size);
 
326
}
 
327
 
 
328
void *session_calloc(Session *session, unsigned int size)
 
329
{
 
330
  return session->calloc(size);
 
331
}
 
332
 
 
333
char *session_strdup(Session *session, const char *str)
 
334
{
 
335
  return session->strdup(str);
 
336
}
 
337
 
 
338
char *session_strmake(Session *session, const char *str, unsigned int size)
 
339
{
 
340
  return session->strmake(str, size);
 
341
}
 
342
 
 
343
void *session_memdup(Session *session, const void* str, unsigned int size)
 
344
{
 
345
  return session->memdup(str, size);
 
346
}
 
347
 
 
348
void session_get_xid(const Session *session, DRIZZLE_XID *xid)
 
349
{
 
350
  *xid = *(DRIZZLE_XID *) &session->transaction.xid_state.xid;
 
351
}
 
352
 
 
353
#if defined(__cplusplus)
 
354
}
 
355
#endif
657
356
 
658
357
/* Do operations that may take a long time */
659
358
 
660
 
void THD::cleanup(void)
 
359
void Session::cleanup(void)
661
360
{
662
 
  assert(cleanup_done == 0);
 
361
  assert(cleanup_done == false);
663
362
 
664
363
  killed= KILL_CONNECTION;
665
364
#ifdef ENABLE_WHEN_BINLOG_WILL_BE_ABLE_TO_PREPARE
669
368
  }
670
369
#endif
671
370
  {
672
 
    ha_rollback(this);
 
371
    TransactionServices &transaction_services= TransactionServices::singleton();
 
372
    transaction_services.ha_rollback_trans(this, true);
673
373
    xid_cache_delete(&transaction.xid_state);
674
374
  }
675
 
  if (locked_tables)
676
 
  {
677
 
    lock=locked_tables; locked_tables=0;
678
 
    close_thread_tables(this);
679
 
  }
680
 
  mysql_ha_cleanup(this);
681
 
  delete_dynamic(&user_var_events);
682
375
  hash_free(&user_vars);
683
 
  close_temporary_tables(this);
684
 
  my_free((char*) variables.time_format, MYF(MY_ALLOW_ZERO_PTR));
685
 
  my_free((char*) variables.date_format, MYF(MY_ALLOW_ZERO_PTR));
686
 
  my_free((char*) variables.datetime_format, MYF(MY_ALLOW_ZERO_PTR));
687
 
  
 
376
  close_temporary_tables();
 
377
 
688
378
  if (global_read_lock)
689
379
    unlock_global_read_lock(this);
690
380
 
691
 
  cleanup_done=1;
692
 
  return;
 
381
  cleanup_done= true;
693
382
}
694
383
 
695
 
THD::~THD()
 
384
Session::~Session()
696
385
{
697
 
  THD_CHECK_SENTRY(this);
698
 
  /* Ensure that no one is using THD */
699
 
  pthread_mutex_lock(&LOCK_delete);
700
 
  pthread_mutex_unlock(&LOCK_delete);
 
386
  Session_CHECK_SENTRY(this);
701
387
  add_to_status(&global_status_var, &status_var);
702
388
 
 
389
  if (client->isConnected())
 
390
  {
 
391
    if (global_system_variables.log_warnings)
 
392
        errmsg_printf(ERRMSG_LVL_WARN, ER(ER_FORCING_CLOSE),internal::my_progname,
 
393
                      thread_id,
 
394
                      (getSecurityContext().getUser().c_str() ?
 
395
                       getSecurityContext().getUser().c_str() : ""));
 
396
    disconnect(0, false);
 
397
  }
 
398
 
703
399
  /* Close connection */
704
 
  if (net.vio)
705
 
  {
706
 
    vio_delete(net.vio);
707
 
    net_end(&net);
708
 
  }
709
 
  if (!cleanup_done)
 
400
  client->close();
 
401
  delete client;
 
402
 
 
403
  if (cleanup_done == false)
710
404
    cleanup();
711
405
 
712
 
  ha_close_connection(this);
713
 
  plugin_thdvar_cleanup(this);
 
406
  plugin::StorageEngine::closeConnection(this);
 
407
  plugin_sessionvar_cleanup(this);
714
408
 
715
 
  main_security_ctx.destroy();
716
 
  safeFree(db);
717
409
  free_root(&warn_root,MYF(0));
718
 
  free_root(&transaction.mem_root,MYF(0));
719
410
  mysys_var=0;                                  // Safety (shouldn't be needed)
 
411
  dbug_sentry= Session_SENTRY_GONE;
 
412
 
 
413
  free_root(&main_mem_root, MYF(0));
 
414
  pthread_setspecific(THR_Session,  0);
 
415
 
 
416
 
 
417
  /* Ensure that no one is using Session */
 
418
  pthread_mutex_unlock(&LOCK_delete);
720
419
  pthread_mutex_destroy(&LOCK_delete);
721
 
  dbug_sentry= THD_SENTRY_GONE;
722
 
  if (rli_fake)
723
 
  {
724
 
    delete rli_fake;
725
 
    rli_fake= NULL;
726
 
  }
727
 
  
728
 
  free_root(&main_mem_root, MYF(0));
729
 
  return;
730
420
}
731
421
 
732
 
 
733
422
/*
734
423
  Add all status variables to another status variable array
735
424
 
743
432
    If this assumption will change, then we have to explictely add
744
433
    the other variables after the while loop
745
434
*/
746
 
 
747
435
void add_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var)
748
436
{
749
 
  ulong *end= (ulong*) ((uchar*) to_var +
 
437
  ulong *end= (ulong*) ((unsigned char*) to_var +
750
438
                        offsetof(STATUS_VAR, last_system_status_var) +
751
439
                        sizeof(ulong));
752
440
  ulong *to= (ulong*) to_var, *from= (ulong*) from_var;
763
451
    to_var       add to this array
764
452
    from_var     from this array
765
453
    dec_var      minus this array
766
 
  
 
454
 
767
455
  NOTE
768
456
    This function assumes that all variables are long/ulong.
769
457
*/
770
 
 
771
458
void add_diff_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var,
772
459
                        STATUS_VAR *dec_var)
773
460
{
774
 
  ulong *end= (ulong*) ((uchar*) to_var + offsetof(STATUS_VAR,
 
461
  ulong *end= (ulong*) ((unsigned char*) to_var + offsetof(STATUS_VAR,
775
462
                                                  last_system_status_var) +
776
463
                        sizeof(ulong));
777
464
  ulong *to= (ulong*) to_var, *from= (ulong*) from_var, *dec= (ulong*) dec_var;
780
467
    *(to++)+= *(from++) - *(dec++);
781
468
}
782
469
 
783
 
 
784
 
void THD::awake(THD::killed_state state_to_set)
 
470
void Session::awake(Session::killed_state state_to_set)
785
471
{
786
 
  THD_CHECK_SENTRY(this);
787
 
  safe_mutex_assert_owner(&LOCK_delete); 
 
472
  Session_CHECK_SENTRY(this);
 
473
  safe_mutex_assert_owner(&LOCK_delete);
788
474
 
789
475
  killed= state_to_set;
790
 
  if (state_to_set != THD::KILL_QUERY)
 
476
  if (state_to_set != Session::KILL_QUERY)
791
477
  {
792
 
    thr_alarm_kill(thread_id);
793
 
    if (!slave_thread)
794
 
      thread_scheduler.post_kill_notification(this);
795
 
#ifdef SIGNAL_WITH_VIO_CLOSE
796
 
    if (this != current_thd)
797
 
    {
798
 
      /*
799
 
        In addition to a signal, let's close the socket of the thread that
800
 
        is being killed. This is to make sure it does not block if the
801
 
        signal is lost. This needs to be done only on platforms where
802
 
        signals are not a reliable interruption mechanism.
803
 
 
804
 
        If we're killing ourselves, we know that we're not blocked, so this
805
 
        hack is not used.
806
 
      */
807
 
 
808
 
      close_active_vio();
809
 
    }
810
 
#endif    
 
478
    scheduler->killSession(this);
 
479
    DRIZZLE_CONNECTION_DONE(thread_id);
811
480
  }
812
481
  if (mysys_var)
813
482
  {
814
483
    pthread_mutex_lock(&mysys_var->mutex);
815
 
    if (!system_thread)         // Don't abort locks
816
 
      mysys_var->abort=1;
817
484
    /*
818
485
      This broadcast could be up in the air if the victim thread
819
486
      exits the cond in the time between read and broadcast, but that is
830
497
      current_cond and current_mutex are 0), then the victim will not get
831
498
      a signal and it may wait "forever" on the cond (until
832
499
      we issue a second KILL or the status it's waiting for happens).
833
 
      It's true that we have set its thd->killed but it may not
 
500
      It's true that we have set its session->killed but it may not
834
501
      see it immediately and so may have time to reach the cond_wait().
835
502
    */
836
503
    if (mysys_var->current_cond && mysys_var->current_mutex)
841
508
    }
842
509
    pthread_mutex_unlock(&mysys_var->mutex);
843
510
  }
844
 
  return;
845
511
}
846
512
 
847
513
/*
848
514
  Remember the location of thread info, the structure needed for
849
 
  sql_alloc() and the structure for the net buffer
 
515
  memory::sql_alloc() and the structure for the net buffer
850
516
*/
851
 
 
852
 
bool THD::store_globals()
 
517
bool Session::storeGlobals()
853
518
{
854
519
  /*
855
520
    Assert that thread_stack is initialized: it's necessary to be able
857
522
  */
858
523
  assert(thread_stack);
859
524
 
860
 
  if (my_pthread_setspecific_ptr(THR_THD,  this) ||
861
 
      my_pthread_setspecific_ptr(THR_MALLOC, &mem_root))
862
 
    return 1;
 
525
  if (pthread_setspecific(THR_Session,  this) ||
 
526
      pthread_setspecific(THR_Mem_root, &mem_root))
 
527
    return true;
 
528
 
863
529
  mysys_var=my_thread_var;
 
530
 
864
531
  /*
865
532
    Let mysqld define the thread id (not mysys)
866
 
    This allows us to move THD to different threads if needed.
 
533
    This allows us to move Session to different threads if needed.
867
534
  */
868
535
  mysys_var->id= thread_id;
869
536
  real_id= pthread_self();                      // For debugging
870
537
 
871
538
  /*
872
 
    We have to call thr_lock_info_init() again here as THD may have been
 
539
    We have to call thr_lock_info_init() again here as Session may have been
873
540
    created in another thread
874
541
  */
875
542
  thr_lock_info_init(&lock_info);
876
 
  return 0;
 
543
  return false;
877
544
}
878
545
 
879
 
 
880
546
/*
881
 
  Cleanup after query.
882
 
 
883
 
  SYNOPSIS
884
 
    THD::cleanup_after_query()
885
 
 
886
 
  DESCRIPTION
887
 
    This function is used to reset thread data to its default state.
888
 
 
889
 
  NOTE
890
 
    This function is not suitable for setting thread data to some
891
 
    non-default values, as there is only one replication thread, so
892
 
    different master threads may overwrite data of each other on
893
 
    slave.
 
547
  Init Session for query processing.
 
548
  This has to be called once before we call mysql_parse.
 
549
  See also comments in session.h.
894
550
*/
895
551
 
896
 
void THD::cleanup_after_query()
897
 
{
898
 
  /*
899
 
    Reset rand_used so that detection of calls to rand() will save random 
 
552
void Session::prepareForQueries()
 
553
{
 
554
  if (variables.max_join_size == HA_POS_ERROR)
 
555
    options |= OPTION_BIG_SELECTS;
 
556
 
 
557
  version= refresh_version;
 
558
  set_proc_info(NULL);
 
559
  command= COM_SLEEP;
 
560
  set_time();
 
561
 
 
562
  reset_root_defaults(mem_root, variables.query_alloc_block_size,
 
563
                      variables.query_prealloc_size);
 
564
  transaction.xid_state.xid.null();
 
565
  transaction.xid_state.in_session=1;
 
566
}
 
567
 
 
568
bool Session::initGlobals()
 
569
{
 
570
  if (storeGlobals())
 
571
  {
 
572
    disconnect(ER_OUT_OF_RESOURCES, true);
 
573
    statistic_increment(aborted_connects, &LOCK_status);
 
574
    return true;
 
575
  }
 
576
  return false;
 
577
}
 
578
 
 
579
void Session::run()
 
580
{
 
581
  if (initGlobals() || authenticate())
 
582
  {
 
583
    disconnect(0, true);
 
584
    return;
 
585
  }
 
586
 
 
587
  prepareForQueries();
 
588
 
 
589
  while (! client->haveError() && killed != KILL_CONNECTION)
 
590
  {
 
591
    if (! executeStatement())
 
592
      break;
 
593
  }
 
594
 
 
595
  disconnect(0, true);
 
596
}
 
597
 
 
598
bool Session::schedule()
 
599
{
 
600
  scheduler= plugin::Scheduler::getScheduler();
 
601
  assert(scheduler);
 
602
 
 
603
  connection_count.increment();
 
604
 
 
605
  if (connection_count > max_used_connections)
 
606
    max_used_connections= connection_count;
 
607
 
 
608
  thread_id= variables.pseudo_thread_id= global_thread_id++;
 
609
 
 
610
  pthread_mutex_lock(&LOCK_thread_count);
 
611
  getSessionList().push_back(this);
 
612
  pthread_mutex_unlock(&LOCK_thread_count);
 
613
 
 
614
  if (scheduler->addSession(this))
 
615
  {
 
616
    DRIZZLE_CONNECTION_START(thread_id);
 
617
    char error_message_buff[DRIZZLE_ERRMSG_SIZE];
 
618
 
 
619
    killed= Session::KILL_CONNECTION;
 
620
 
 
621
    statistic_increment(aborted_connects, &LOCK_status);
 
622
 
 
623
    /* Can't use my_error() since store_globals has not been called. */
 
624
    /* TODO replace will better error message */
 
625
    snprintf(error_message_buff, sizeof(error_message_buff),
 
626
             ER(ER_CANT_CREATE_THREAD), 1);
 
627
    client->sendError(ER_CANT_CREATE_THREAD, error_message_buff);
 
628
    return true;
 
629
  }
 
630
 
 
631
  return false;
 
632
}
 
633
 
 
634
 
 
635
const char* Session::enter_cond(pthread_cond_t *cond,
 
636
                                pthread_mutex_t* mutex,
 
637
                                const char* msg)
 
638
{
 
639
  const char* old_msg = get_proc_info();
 
640
  safe_mutex_assert_owner(mutex);
 
641
  mysys_var->current_mutex = mutex;
 
642
  mysys_var->current_cond = cond;
 
643
  this->set_proc_info(msg);
 
644
  return old_msg;
 
645
}
 
646
 
 
647
void Session::exit_cond(const char* old_msg)
 
648
{
 
649
  /*
 
650
    Putting the mutex unlock in exit_cond() ensures that
 
651
    mysys_var->current_mutex is always unlocked _before_ mysys_var->mutex is
 
652
    locked (if that would not be the case, you'll get a deadlock if someone
 
653
    does a Session::awake() on you).
 
654
  */
 
655
  pthread_mutex_unlock(mysys_var->current_mutex);
 
656
  pthread_mutex_lock(&mysys_var->mutex);
 
657
  mysys_var->current_mutex = 0;
 
658
  mysys_var->current_cond = 0;
 
659
  this->set_proc_info(old_msg);
 
660
  pthread_mutex_unlock(&mysys_var->mutex);
 
661
}
 
662
 
 
663
bool Session::authenticate()
 
664
{
 
665
  lex_start(this);
 
666
  if (client->authenticate())
 
667
    return false;
 
668
 
 
669
  statistic_increment(aborted_connects, &LOCK_status);
 
670
  return true;
 
671
}
 
672
 
 
673
bool Session::checkUser(const char *passwd, uint32_t passwd_len, const char *in_db)
 
674
{
 
675
  LEX_STRING db_str= { (char *) in_db, in_db ? strlen(in_db) : 0 };
 
676
  bool is_authenticated;
 
677
 
 
678
  if (passwd_len != 0 && passwd_len != SCRAMBLE_LENGTH)
 
679
  {
 
680
    my_error(ER_HANDSHAKE_ERROR, MYF(0), getSecurityContext().getIp().c_str());
 
681
    return false;
 
682
  }
 
683
 
 
684
  is_authenticated= plugin::Authentication::isAuthenticated(this, passwd);
 
685
 
 
686
  if (is_authenticated != true)
 
687
  {
 
688
    my_error(ER_ACCESS_DENIED_ERROR, MYF(0),
 
689
             getSecurityContext().getUser().c_str(),
 
690
             getSecurityContext().getIp().c_str(),
 
691
             passwd_len ? ER(ER_YES) : ER(ER_NO));
 
692
 
 
693
    return false;
 
694
  }
 
695
 
 
696
  /* Change database if necessary */
 
697
  if (in_db && in_db[0])
 
698
  {
 
699
    if (mysql_change_db(this, &db_str, false))
 
700
    {
 
701
      /* mysql_change_db() has pushed the error message. */
 
702
      return false;
 
703
    }
 
704
  }
 
705
  my_ok();
 
706
  password= test(passwd_len);          // remember for error messages
 
707
 
 
708
  /* Ready to handle queries */
 
709
  return true;
 
710
}
 
711
 
 
712
bool Session::executeStatement()
 
713
{
 
714
  char *l_packet= 0;
 
715
  uint32_t packet_length;
 
716
 
 
717
  enum enum_server_command l_command;
 
718
 
 
719
  /*
 
720
    indicator of uninitialized lex => normal flow of errors handling
 
721
    (see my_message_sql)
 
722
  */
 
723
  lex->current_select= 0;
 
724
  clear_error();
 
725
  main_da.reset_diagnostics_area();
 
726
 
 
727
  if (client->readCommand(&l_packet, &packet_length) == false)
 
728
    return false;
 
729
 
 
730
  if (packet_length == 0)
 
731
    return true;
 
732
 
 
733
  l_command= (enum enum_server_command) (unsigned char) l_packet[0];
 
734
 
 
735
  if (command >= COM_END)
 
736
    command= COM_END;                           // Wrong command
 
737
 
 
738
  assert(packet_length);
 
739
  return ! dispatch_command(l_command, this, l_packet+1, (uint32_t) (packet_length-1));
 
740
}
 
741
 
 
742
bool Session::readAndStoreQuery(const char *in_packet, uint32_t in_packet_length)
 
743
{
 
744
  /* Remove garbage at start and end of query */
 
745
  while (in_packet_length > 0 && my_isspace(charset(), in_packet[0]))
 
746
  {
 
747
    in_packet++;
 
748
    in_packet_length--;
 
749
  }
 
750
  const char *pos= in_packet + in_packet_length; /* Point at end null */
 
751
  while (in_packet_length > 0 &&
 
752
         (pos[-1] == ';' || my_isspace(charset() ,pos[-1])))
 
753
  {
 
754
    pos--;
 
755
    in_packet_length--;
 
756
  }
 
757
 
 
758
  /* We must allocate some extra memory for the cached query string */
 
759
  query_length= 0; /* Extra safety: Avoid races */
 
760
  query= (char*) memdup_w_gap((unsigned char*) in_packet, in_packet_length, db.length() + 1);
 
761
  if (! query)
 
762
    return false;
 
763
 
 
764
  query[in_packet_length]=0;
 
765
  query_length= in_packet_length;
 
766
 
 
767
  return true;
 
768
}
 
769
 
 
770
bool Session::endTransaction(enum enum_mysql_completiontype completion)
 
771
{
 
772
  bool do_release= 0;
 
773
  bool result= true;
 
774
  TransactionServices &transaction_services= TransactionServices::singleton();
 
775
 
 
776
  if (transaction.xid_state.xa_state != XA_NOTR)
 
777
  {
 
778
    my_error(ER_XAER_RMFAIL, MYF(0), xa_state_names[transaction.xid_state.xa_state]);
 
779
    return false;
 
780
  }
 
781
  switch (completion)
 
782
  {
 
783
    case COMMIT:
 
784
      /*
 
785
       * We don't use endActiveTransaction() here to ensure that this works
 
786
       * even if there is a problem with the OPTION_AUTO_COMMIT flag
 
787
       * (Which of course should never happen...)
 
788
       */
 
789
      server_status&= ~SERVER_STATUS_IN_TRANS;
 
790
      if (transaction_services.ha_commit_trans(this, true))
 
791
        result= false;
 
792
      options&= ~(OPTION_BEGIN);
 
793
      transaction.all.modified_non_trans_table= false;
 
794
      break;
 
795
    case COMMIT_RELEASE:
 
796
      do_release= 1; /* fall through */
 
797
    case COMMIT_AND_CHAIN:
 
798
      result= endActiveTransaction();
 
799
      if (result == true && completion == COMMIT_AND_CHAIN)
 
800
        result= startTransaction();
 
801
      break;
 
802
    case ROLLBACK_RELEASE:
 
803
      do_release= 1; /* fall through */
 
804
    case ROLLBACK:
 
805
    case ROLLBACK_AND_CHAIN:
 
806
    {
 
807
      server_status&= ~SERVER_STATUS_IN_TRANS;
 
808
      if (transaction_services.ha_rollback_trans(this, true))
 
809
        result= false;
 
810
      options&= ~(OPTION_BEGIN);
 
811
      transaction.all.modified_non_trans_table= false;
 
812
      if (result == true && (completion == ROLLBACK_AND_CHAIN))
 
813
        result= startTransaction();
 
814
      break;
 
815
    }
 
816
    default:
 
817
      my_error(ER_UNKNOWN_COM_ERROR, MYF(0));
 
818
      return false;
 
819
  }
 
820
 
 
821
  if (result == false)
 
822
    my_error(killed_errno(), MYF(0));
 
823
  else if ((result == true) && do_release)
 
824
    killed= Session::KILL_CONNECTION;
 
825
 
 
826
  return result;
 
827
}
 
828
 
 
829
bool Session::endActiveTransaction()
 
830
{
 
831
  bool result= true;
 
832
  TransactionServices &transaction_services= TransactionServices::singleton();
 
833
 
 
834
  if (transaction.xid_state.xa_state != XA_NOTR)
 
835
  {
 
836
    my_error(ER_XAER_RMFAIL, MYF(0), xa_state_names[transaction.xid_state.xa_state]);
 
837
    return false;
 
838
  }
 
839
  if (options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
 
840
  {
 
841
    server_status&= ~SERVER_STATUS_IN_TRANS;
 
842
    if (transaction_services.ha_commit_trans(this, true))
 
843
      result= false;
 
844
  }
 
845
  options&= ~(OPTION_BEGIN);
 
846
  transaction.all.modified_non_trans_table= false;
 
847
  return result;
 
848
}
 
849
 
 
850
bool Session::startTransaction(start_transaction_option_t opt)
 
851
{
 
852
  bool result= true;
 
853
 
 
854
  if (! endActiveTransaction())
 
855
  {
 
856
    result= false;
 
857
  }
 
858
  else
 
859
  {
 
860
    options|= OPTION_BEGIN;
 
861
    server_status|= SERVER_STATUS_IN_TRANS;
 
862
 
 
863
    if (opt == START_TRANS_OPT_WITH_CONS_SNAPSHOT)
 
864
    {
 
865
      // TODO make this a loop for all engines, not just this one (Inno only
 
866
      // right now)
 
867
      if (plugin::StorageEngine::startConsistentSnapshot(this))
 
868
      {
 
869
        result= false;
 
870
      }
 
871
    }
 
872
  }
 
873
 
 
874
  return result;
 
875
}
 
876
 
 
877
void Session::cleanup_after_query()
 
878
{
 
879
  /*
 
880
    Reset rand_used so that detection of calls to rand() will save random
900
881
    seeds if needed by the slave.
901
 
 
902
 
    Do not reset rand_used if inside a stored function or trigger because 
903
 
    only the call to these operations is logged. Thus only the calling 
904
 
    statement needs to detect rand() calls made by its substatements. These
905
 
    substatements must not set rand_used to 0 because it would remove the
906
 
    detection of rand() by the calling statement. 
907
882
  */
908
 
  if (!in_sub_stmt) /* stored functions and triggers are a special case */
909
883
  {
910
884
    /* Forget those values, for next binlogger: */
911
 
    stmt_depends_on_first_successful_insert_id_in_prev_stmt= 0;
912
885
    auto_inc_intervals_in_cur_stmt_for_binlog.empty();
913
 
    rand_used= 0;
914
886
  }
915
887
  if (first_successful_insert_id_in_cur_stmt > 0)
916
888
  {
917
889
    /* set what LAST_INSERT_ID() will return */
918
 
    first_successful_insert_id_in_prev_stmt= 
919
 
      first_successful_insert_id_in_cur_stmt;
 
890
    first_successful_insert_id_in_prev_stmt= first_successful_insert_id_in_cur_stmt;
920
891
    first_successful_insert_id_in_cur_stmt= 0;
921
892
    substitute_null_with_insert_id= true;
922
893
  }
923
 
  arg_of_last_insert_id_function= 0;
 
894
  arg_of_last_insert_id_function= false;
924
895
  /* Free Items that were created during this execution */
925
896
  free_items();
926
897
  /* Reset where. */
927
 
  where= THD::DEFAULT_WHERE;
 
898
  where= Session::DEFAULT_WHERE;
928
899
}
929
900
 
930
 
 
931
901
/**
932
902
  Create a LEX_STRING in this connection.
933
903
 
938
908
                              instead of using lex_str value
939
909
  @return  NULL on failure, or pointer to the LEX_STRING object
940
910
*/
941
 
LEX_STRING *THD::make_lex_string(LEX_STRING *lex_str,
942
 
                                 const char* str, uint length,
 
911
LEX_STRING *Session::make_lex_string(LEX_STRING *lex_str,
 
912
                                 const char* str, uint32_t length,
943
913
                                 bool allocate_lex_string)
944
914
{
945
915
  if (allocate_lex_string)
951
921
  return lex_str;
952
922
}
953
923
 
954
 
 
955
 
/*
956
 
  Convert a string to another character set
957
 
 
958
 
  SYNOPSIS
959
 
    convert_string()
960
 
    to                          Store new allocated string here
961
 
    to_cs                       New character set for allocated string
962
 
    from                        String to convert
963
 
    from_length                 Length of string to convert
964
 
    from_cs                     Original character set
965
 
 
966
 
  NOTES
967
 
    to will be 0-terminated to make it easy to pass to system funcs
968
 
 
969
 
  RETURN
970
 
    0   ok
971
 
    1   End of memory.
972
 
        In this case to->str will point to 0 and to->length will be 0.
973
 
*/
974
 
 
975
 
bool THD::convert_string(LEX_STRING *to, const CHARSET_INFO * const to_cs,
976
 
                         const char *from, uint from_length,
977
 
                         const CHARSET_INFO * const from_cs)
978
 
{
979
 
  size_t new_length= to_cs->mbmaxlen * from_length;
980
 
  uint dummy_errors;
981
 
  if (!(to->str= (char*) alloc(new_length+1)))
982
 
  {
983
 
    to->length= 0;                              // Safety fix
984
 
    return(1);                          // EOM
985
 
  }
986
 
  to->length= copy_and_convert((char*) to->str, new_length, to_cs,
987
 
                               from, from_length, from_cs, &dummy_errors);
988
 
  to->str[to->length]=0;                        // Safety
989
 
  return(0);
990
 
}
991
 
 
992
 
 
993
 
/*
994
 
  Convert string from source character set to target character set inplace.
995
 
 
996
 
  SYNOPSIS
997
 
    THD::convert_string
998
 
 
999
 
  DESCRIPTION
1000
 
    Convert string using convert_buffer - buffer for character set 
1001
 
    conversion shared between all protocols.
1002
 
 
1003
 
  RETURN
1004
 
    0   ok
1005
 
   !0   out of memory
1006
 
*/
1007
 
 
1008
 
bool THD::convert_string(String *s, const CHARSET_INFO * const from_cs,
1009
 
                         const CHARSET_INFO * const to_cs)
1010
 
{
1011
 
  uint dummy_errors;
1012
 
  if (convert_buffer.copy(s->ptr(), s->length(), from_cs, to_cs, &dummy_errors))
1013
 
    return true;
1014
 
  /* If convert_buffer >> s copying is more efficient long term */
1015
 
  if (convert_buffer.alloced_length() >= convert_buffer.length() * 2 ||
1016
 
      !s->is_alloced())
1017
 
  {
1018
 
    return s->copy(convert_buffer);
1019
 
  }
1020
 
  s->swap(convert_buffer);
1021
 
  return false;
1022
 
}
1023
 
 
1024
 
 
1025
 
/*
1026
 
  Update some cache variables when character set changes
1027
 
*/
1028
 
 
1029
 
void THD::update_charset()
1030
 
{
1031
 
  uint32_t not_used;
1032
 
  charset_is_system_charset= !String::needs_conversion(0,charset(),
1033
 
                                                       system_charset_info,
1034
 
                                                       &not_used);
1035
 
  charset_is_collation_connection= 
1036
 
    !String::needs_conversion(0,charset(),variables.collation_connection,
1037
 
                              &not_used);
1038
 
  charset_is_character_set_filesystem= 
1039
 
    !String::needs_conversion(0, charset(),
1040
 
                              variables.character_set_filesystem, &not_used);
1041
 
}
1042
 
 
1043
 
 
1044
 
/* routings to adding tables to list of changed in transaction tables */
1045
 
 
1046
 
inline static void list_include(CHANGED_TABLE_LIST** prev,
1047
 
                                CHANGED_TABLE_LIST* curr,
1048
 
                                CHANGED_TABLE_LIST* new_table)
1049
 
{
1050
 
  if (new_table)
1051
 
  {
1052
 
    *prev = new_table;
1053
 
    (*prev)->next = curr;
1054
 
  }
1055
 
}
1056
 
 
1057
 
/* add table to list of changed in transaction tables */
1058
 
 
1059
 
void THD::add_changed_table(TABLE *table)
1060
 
{
1061
 
  assert((options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) &&
1062
 
              table->file->has_transactions());
1063
 
  add_changed_table(table->s->table_cache_key.str,
1064
 
                    (long) table->s->table_cache_key.length);
1065
 
  return;
1066
 
}
1067
 
 
1068
 
 
1069
 
void THD::add_changed_table(const char *key, long key_length)
1070
 
{
1071
 
  CHANGED_TABLE_LIST **prev_changed = &transaction.changed_tables;
1072
 
  CHANGED_TABLE_LIST *curr = transaction.changed_tables;
1073
 
 
1074
 
  for (; curr; prev_changed = &(curr->next), curr = curr->next)
1075
 
  {
1076
 
    int cmp =  (long)curr->key_length - (long)key_length;
1077
 
    if (cmp < 0)
1078
 
    {
1079
 
      list_include(prev_changed, curr, changed_table_dup(key, key_length));
1080
 
      return;
1081
 
    }
1082
 
    else if (cmp == 0)
1083
 
    {
1084
 
      cmp = memcmp(curr->key, key, curr->key_length);
1085
 
      if (cmp < 0)
1086
 
      {
1087
 
        list_include(prev_changed, curr, changed_table_dup(key, key_length));
1088
 
        return;
1089
 
      }
1090
 
      else if (cmp == 0)
1091
 
      {
1092
 
        return;
1093
 
      }
1094
 
    }
1095
 
  }
1096
 
  *prev_changed = changed_table_dup(key, key_length);
1097
 
  return;
1098
 
}
1099
 
 
1100
 
 
1101
 
CHANGED_TABLE_LIST* THD::changed_table_dup(const char *key, long key_length)
1102
 
{
1103
 
  CHANGED_TABLE_LIST* new_table = 
1104
 
    (CHANGED_TABLE_LIST*) trans_alloc(ALIGN_SIZE(sizeof(CHANGED_TABLE_LIST))+
1105
 
                                      key_length + 1);
1106
 
  if (!new_table)
1107
 
  {
1108
 
    my_error(EE_OUTOFMEMORY, MYF(ME_BELL),
1109
 
             ALIGN_SIZE(sizeof(TABLE_LIST)) + key_length + 1);
1110
 
    killed= KILL_CONNECTION;
1111
 
    return 0;
1112
 
  }
1113
 
 
1114
 
  new_table->key= ((char*)new_table)+ ALIGN_SIZE(sizeof(CHANGED_TABLE_LIST));
1115
 
  new_table->next = 0;
1116
 
  new_table->key_length = key_length;
1117
 
  ::memcpy(new_table->key, key, key_length);
1118
 
  return new_table;
1119
 
}
1120
 
 
1121
 
 
1122
 
int THD::send_explain_fields(select_result *result)
 
924
int Session::send_explain_fields(select_result *result)
1123
925
{
1124
926
  List<Item> field_list;
1125
927
  Item *item;
1154
956
  }
1155
957
  item->maybe_null= 1;
1156
958
  field_list.push_back(new Item_empty_string("Extra", 255, cs));
1157
 
  return (result->send_fields(field_list,
1158
 
                              Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF));
1159
 
}
1160
 
 
1161
 
#ifdef SIGNAL_WITH_VIO_CLOSE
1162
 
void THD::close_active_vio()
1163
 
{
1164
 
  safe_mutex_assert_owner(&LOCK_delete); 
1165
 
  if (active_vio)
1166
 
  {
1167
 
    vio_close(active_vio);
1168
 
    active_vio = 0;
1169
 
  }
1170
 
  return;
1171
 
}
1172
 
#endif
1173
 
 
1174
 
 
1175
 
struct Item_change_record: public ilink
1176
 
{
1177
 
  Item **place;
1178
 
  Item *old_value;
1179
 
  /* Placement new was hidden by `new' in ilink (TODO: check): */
1180
 
  static void *operator new(size_t size __attribute__((unused)),
1181
 
                            void *mem)
1182
 
    { return mem; }
1183
 
  static void operator delete(void *ptr __attribute__((unused)),
1184
 
                              size_t size __attribute__((unused)))
1185
 
    {}
1186
 
  static void operator delete(void *ptr __attribute__((unused)),
1187
 
                              void *mem __attribute__((unused)))
1188
 
    { /* never called */ }
1189
 
};
1190
 
 
1191
 
 
1192
 
/*
1193
 
  Register an item tree tree transformation, performed by the query
1194
 
  optimizer. We need a pointer to runtime_memroot because it may be !=
1195
 
  thd->mem_root (due to possible set_n_backup_active_arena called for thd).
1196
 
*/
1197
 
 
1198
 
void THD::nocheck_register_item_tree_change(Item **place, Item *old_value,
1199
 
                                            MEM_ROOT *runtime_memroot)
1200
 
{
1201
 
  Item_change_record *change;
1202
 
  /*
1203
 
    Now we use one node per change, which adds some memory overhead,
1204
 
    but still is rather fast as we use alloc_root for allocations.
1205
 
    A list of item tree changes of an average query should be short.
1206
 
  */
1207
 
  void *change_mem= alloc_root(runtime_memroot, sizeof(*change));
1208
 
  if (change_mem == 0)
1209
 
  {
1210
 
    /*
1211
 
      OOM, thd->fatal_error() is called by the error handler of the
1212
 
      memroot. Just return.
1213
 
    */
1214
 
    return;
1215
 
  }
1216
 
  change= new (change_mem) Item_change_record;
1217
 
  change->place= place;
1218
 
  change->old_value= old_value;
1219
 
  change_list.append(change);
1220
 
}
1221
 
 
1222
 
 
1223
 
void THD::rollback_item_tree_changes()
1224
 
{
1225
 
  I_List_iterator<Item_change_record> it(change_list);
1226
 
  Item_change_record *change;
1227
 
 
1228
 
  while ((change= it++))
1229
 
    *change->place= change->old_value;
1230
 
  /* We can forget about changes memory: it's allocated in runtime memroot */
1231
 
  change_list.empty();
1232
 
  return;
1233
 
}
1234
 
 
1235
 
 
1236
 
/**
1237
 
  Check that the endpoint is still available.
1238
 
*/
1239
 
 
1240
 
bool THD::vio_is_connected()
1241
 
{
1242
 
  uint bytes= 0;
1243
 
 
1244
 
  /* End of input is signaled by poll if the socket is aborted. */
1245
 
  if (vio_poll_read(net.vio, 0))
1246
 
    return true;
1247
 
 
1248
 
  /* Socket is aborted if signaled but no data is available. */
1249
 
  if (vio_peek_read(net.vio, &bytes))
1250
 
    return true;
1251
 
 
1252
 
  return bytes ? true : false;
1253
 
}
1254
 
 
1255
 
 
1256
 
/*****************************************************************************
1257
 
** Functions to provide a interface to select results
1258
 
*****************************************************************************/
1259
 
 
1260
 
select_result::select_result()
1261
 
{
1262
 
  thd=current_thd;
1263
 
}
1264
 
 
1265
 
void select_result::send_error(uint errcode,const char *err)
 
959
  return (result->send_fields(field_list));
 
960
}
 
961
 
 
962
void select_result::send_error(uint32_t errcode, const char *err)
1266
963
{
1267
964
  my_message(errcode, err, MYF(0));
1268
965
}
1269
966
 
1270
 
 
1271
 
void select_result::cleanup()
1272
 
{
1273
 
  /* do nothing */
1274
 
}
1275
 
 
1276
 
bool select_result::check_simple_select() const
1277
 
{
1278
 
  my_error(ER_SP_BAD_CURSOR_QUERY, MYF(0));
1279
 
  return true;
1280
 
}
1281
 
 
1282
 
 
1283
 
static String default_line_term("\n",default_charset_info);
1284
 
static String default_escaped("\\",default_charset_info);
1285
 
static String default_field_term("\t",default_charset_info);
1286
 
 
1287
 
sql_exchange::sql_exchange(char *name, bool flag,
1288
 
                           enum enum_filetype filetype_arg)
1289
 
  :file_name(name), opt_enclosed(0), dumpfile(flag), skip_lines(0)
1290
 
{
1291
 
  filetype= filetype_arg;
1292
 
  field_term= &default_field_term;
1293
 
  enclosed=   line_start= &my_empty_string;
1294
 
  line_term=  &default_line_term;
1295
 
  escaped=    &default_escaped;
1296
 
  cs= NULL;
1297
 
}
1298
 
 
1299
 
bool select_send::send_fields(List<Item> &list, uint flags)
1300
 
{
1301
 
  bool res;
1302
 
  if (!(res= thd->protocol->send_fields(&list, flags)))
1303
 
    is_result_set_started= 1;
1304
 
  return res;
1305
 
}
1306
 
 
1307
 
void select_send::abort()
1308
 
{
1309
 
  return;
1310
 
}
1311
 
 
1312
 
 
1313
 
/** 
1314
 
  Cleanup an instance of this class for re-use
1315
 
  at next execution of a prepared statement/
1316
 
  stored procedure statement.
1317
 
*/
1318
 
 
1319
 
void select_send::cleanup()
1320
 
{
1321
 
  is_result_set_started= false;
1322
 
}
1323
 
 
1324
 
/* Send data to client. Returns 0 if ok */
1325
 
 
1326
 
bool select_send::send_data(List<Item> &items)
1327
 
{
1328
 
  if (unit->offset_limit_cnt)
1329
 
  {                                             // using limit offset,count
1330
 
    unit->offset_limit_cnt--;
1331
 
    return 0;
1332
 
  }
1333
 
 
1334
 
  /*
1335
 
    We may be passing the control from mysqld to the client: release the
1336
 
    InnoDB adaptive hash S-latch to avoid thread deadlocks if it was reserved
1337
 
    by thd
1338
 
  */
1339
 
  ha_release_temporary_latches(thd);
1340
 
 
1341
 
  List_iterator_fast<Item> li(items);
1342
 
  Protocol *protocol= thd->protocol;
1343
 
  char buff[MAX_FIELD_WIDTH];
1344
 
  String buffer(buff, sizeof(buff), &my_charset_bin);
1345
 
 
1346
 
  protocol->prepare_for_resend();
1347
 
  Item *item;
1348
 
  while ((item=li++))
1349
 
  {
1350
 
    if (item->send(protocol, &buffer))
1351
 
    {
1352
 
      protocol->free();                         // Free used buffer
1353
 
      my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
1354
 
      break;
1355
 
    }
1356
 
  }
1357
 
  thd->sent_row_count++;
1358
 
  if (thd->is_error())
1359
 
  {
1360
 
    protocol->remove_last_row();
1361
 
    return(1);
1362
 
  }
1363
 
  if (thd->vio_ok())
1364
 
    return(protocol->write());
1365
 
  return(0);
1366
 
}
1367
 
 
1368
 
bool select_send::send_eof()
1369
 
{
1370
 
  /* 
1371
 
    We may be passing the control from mysqld to the client: release the
1372
 
    InnoDB adaptive hash S-latch to avoid thread deadlocks if it was reserved
1373
 
    by thd 
1374
 
  */
1375
 
  ha_release_temporary_latches(thd);
1376
 
 
1377
 
  /* Unlock tables before sending packet to gain some speed */
1378
 
  if (thd->lock)
1379
 
  {
1380
 
    mysql_unlock_tables(thd, thd->lock);
1381
 
    thd->lock=0;
1382
 
  }
1383
 
  ::my_eof(thd);
1384
 
  is_result_set_started= 0;
1385
 
  return false;
1386
 
}
1387
 
 
1388
 
 
1389
967
/************************************************************************
1390
968
  Handling writing to file
1391
969
************************************************************************/
1392
970
 
1393
 
void select_to_file::send_error(uint errcode,const char *err)
 
971
void select_to_file::send_error(uint32_t errcode,const char *err)
1394
972
{
1395
973
  my_message(errcode, err, MYF(0));
1396
974
  if (file > 0)
1397
975
  {
1398
 
    (void) end_io_cache(&cache);
1399
 
    (void) my_close(file,MYF(0));
1400
 
    (void) my_delete(path,MYF(0));              // Delete file on error
 
976
    (void) end_io_cache(cache);
 
977
    (void) internal::my_close(file, MYF(0));
 
978
    (void) internal::my_delete(path, MYF(0));           // Delete file on error
1401
979
    file= -1;
1402
980
  }
1403
981
}
1405
983
 
1406
984
bool select_to_file::send_eof()
1407
985
{
1408
 
  int error= test(end_io_cache(&cache));
1409
 
  if (my_close(file,MYF(MY_WME)))
 
986
  int error= test(end_io_cache(cache));
 
987
  if (internal::my_close(file, MYF(MY_WME)))
1410
988
    error= 1;
1411
989
  if (!error)
1412
990
  {
1415
993
      function, SELECT INTO has to have an own SQLCOM.
1416
994
      TODO: split from SQLCOM_SELECT
1417
995
    */
1418
 
    ::my_ok(thd,row_count);
 
996
    session->my_ok(row_count);
1419
997
  }
1420
998
  file= -1;
1421
999
  return error;
1427
1005
  /* In case of error send_eof() may be not called: close the file here. */
1428
1006
  if (file >= 0)
1429
1007
  {
1430
 
    (void) end_io_cache(&cache);
1431
 
    (void) my_close(file,MYF(0));
 
1008
    (void) end_io_cache(cache);
 
1009
    (void) internal::my_close(file, MYF(0));
1432
1010
    file= -1;
1433
1011
  }
1434
1012
  path[0]= '\0';
1435
1013
  row_count= 0;
1436
1014
}
1437
1015
 
 
1016
select_to_file::select_to_file(file_exchange *ex)
 
1017
  : exchange(ex),
 
1018
    file(-1),
 
1019
    cache(static_cast<internal::IO_CACHE *>(memory::sql_calloc(sizeof(internal::IO_CACHE)))),
 
1020
    row_count(0L)
 
1021
{
 
1022
  path[0]=0;
 
1023
}
1438
1024
 
1439
1025
select_to_file::~select_to_file()
1440
1026
{
1441
 
  if (file >= 0)
1442
 
  {                                     // This only happens in case of error
1443
 
    (void) end_io_cache(&cache);
1444
 
    (void) my_close(file,MYF(0));
1445
 
    file= -1;
1446
 
  }
 
1027
  cleanup();
1447
1028
}
1448
1029
 
1449
1030
/***************************************************************************
1452
1033
 
1453
1034
select_export::~select_export()
1454
1035
{
1455
 
  thd->sent_row_count=row_count;
 
1036
  session->sent_row_count=row_count;
1456
1037
}
1457
1038
 
1458
1039
 
1461
1042
 
1462
1043
  SYNOPSIS
1463
1044
    create_file()
1464
 
    thd                 Thread handle
 
1045
    session                     Thread handle
1465
1046
    path                File name
1466
1047
    exchange            Excange class
1467
1048
    cache               IO cache
1472
1053
*/
1473
1054
 
1474
1055
 
1475
 
static File create_file(THD *thd, char *path, sql_exchange *exchange,
1476
 
                        IO_CACHE *cache)
 
1056
static int create_file(Session *session, char *path, file_exchange *exchange, internal::IO_CACHE *cache)
1477
1057
{
1478
 
  File file;
1479
 
  uint option= MY_UNPACK_FILENAME | MY_RELATIVE_PATH;
 
1058
  int file;
 
1059
  uint32_t option= MY_UNPACK_FILENAME | MY_RELATIVE_PATH;
1480
1060
 
1481
1061
#ifdef DONT_ALLOW_FULL_LOAD_DATA_PATHS
1482
1062
  option|= MY_REPLACE_DIR;                      // Force use of db directory
1483
1063
#endif
1484
1064
 
1485
 
  if (!dirname_length(exchange->file_name))
 
1065
  if (!internal::dirname_length(exchange->file_name))
1486
1066
  {
1487
 
    strxnmov(path, FN_REFLEN-1, mysql_real_data_home, thd->db ? thd->db : "",
1488
 
             NullS);
1489
 
    (void) fn_format(path, exchange->file_name, path, "", option);
 
1067
    strcpy(path, drizzle_real_data_home);
 
1068
    if (! session->db.empty())
 
1069
      strncat(path, session->db.c_str(), FN_REFLEN-strlen(drizzle_real_data_home)-1);
 
1070
    (void) internal::fn_format(path, exchange->file_name, path, "", option);
1490
1071
  }
1491
1072
  else
1492
 
    (void) fn_format(path, exchange->file_name, mysql_real_data_home, "", option);
 
1073
    (void) internal::fn_format(path, exchange->file_name, drizzle_real_data_home, "", option);
1493
1074
 
1494
1075
  if (opt_secure_file_priv &&
1495
1076
      strncmp(opt_secure_file_priv, path, strlen(opt_secure_file_priv)))
1505
1086
    return -1;
1506
1087
  }
1507
1088
  /* Create the file world readable */
1508
 
  if ((file= my_create(path, 0666, O_WRONLY|O_EXCL, MYF(MY_WME))) < 0)
 
1089
  if ((file= internal::my_create(path, 0666, O_WRONLY|O_EXCL, MYF(MY_WME))) < 0)
1509
1090
    return file;
1510
 
#ifdef HAVE_FCHMOD
1511
1091
  (void) fchmod(file, 0666);                    // Because of umask()
1512
 
#else
1513
 
  (void) chmod(path, 0666);
1514
 
#endif
1515
 
  if (init_io_cache(cache, file, 0L, WRITE_CACHE, 0L, 1, MYF(MY_WME)))
 
1092
  if (init_io_cache(cache, file, 0L, internal::WRITE_CACHE, 0L, 1, MYF(MY_WME)))
1516
1093
  {
1517
 
    my_close(file, MYF(0));
1518
 
    my_delete(path, MYF(0));  // Delete file on error, it was just created 
 
1094
    internal::my_close(file, MYF(0));
 
1095
    internal::my_delete(path, MYF(0));  // Delete file on error, it was just created
1519
1096
    return -1;
1520
1097
  }
1521
1098
  return file;
1523
1100
 
1524
1101
 
1525
1102
int
1526
 
select_export::prepare(List<Item> &list, SELECT_LEX_UNIT *u)
 
1103
select_export::prepare(List<Item> &list, Select_Lex_Unit *u)
1527
1104
{
1528
1105
  bool blob_flag=0;
1529
1106
  bool string_results= false, non_string_results= false;
1530
1107
  unit= u;
1531
 
  if ((uint) strlen(exchange->file_name) + NAME_LEN >= FN_REFLEN)
1532
 
    strmake(path,exchange->file_name,FN_REFLEN-1);
 
1108
  if ((uint32_t) strlen(exchange->file_name) + NAME_LEN >= FN_REFLEN)
 
1109
    strncpy(path,exchange->file_name,FN_REFLEN-1);
1533
1110
 
1534
 
  if ((file= create_file(thd, path, exchange, &cache)) < 0)
1535
 
    return 1;
1536
1111
  /* Check if there is any blobs in data */
1537
1112
  {
1538
1113
    List_iterator_fast<Item> li(list);
1552
1127
  }
1553
1128
  field_term_length=exchange->field_term->length();
1554
1129
  field_term_char= field_term_length ?
1555
 
                   (int) (uchar) (*exchange->field_term)[0] : INT_MAX;
 
1130
                   (int) (unsigned char) (*exchange->field_term)[0] : INT_MAX;
1556
1131
  if (!exchange->line_term->length())
1557
1132
    exchange->line_term=exchange->field_term;   // Use this if it exists
1558
1133
  field_sep_char= (exchange->enclosed->length() ?
1559
 
                  (int) (uchar) (*exchange->enclosed)[0] : field_term_char);
 
1134
                  (int) (unsigned char) (*exchange->enclosed)[0] : field_term_char);
1560
1135
  escape_char=  (exchange->escaped->length() ?
1561
 
                (int) (uchar) (*exchange->escaped)[0] : -1);
 
1136
                (int) (unsigned char) (*exchange->escaped)[0] : -1);
1562
1137
  is_ambiguous_field_sep= test(strchr(ESCAPE_CHARS, field_sep_char));
1563
1138
  is_unsafe_field_sep= test(strchr(NUMERIC_CHARS, field_sep_char));
1564
1139
  line_sep_char= (exchange->line_term->length() ?
1565
 
                 (int) (uchar) (*exchange->line_term)[0] : INT_MAX);
 
1140
                 (int) (unsigned char) (*exchange->line_term)[0] : INT_MAX);
1566
1141
  if (!field_term_length)
1567
1142
    exchange->opt_enclosed=0;
1568
1143
  if (!exchange->enclosed->length())
1574
1149
      (exchange->opt_enclosed && non_string_results &&
1575
1150
       field_term_length && strchr(NUMERIC_CHARS, field_term_char)))
1576
1151
  {
1577
 
    push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
1578
 
                 ER_AMBIGUOUS_FIELD_TERM, ER(ER_AMBIGUOUS_FIELD_TERM));
1579
 
    is_ambiguous_field_term= true;
 
1152
    my_error(ER_AMBIGUOUS_FIELD_TERM, MYF(0));
 
1153
    return 1;
1580
1154
  }
1581
 
  else
1582
 
    is_ambiguous_field_term= false;
 
1155
 
 
1156
  if ((file= create_file(session, path, exchange, cache)) < 0)
 
1157
    return 1;
1583
1158
 
1584
1159
  return 0;
1585
1160
}
1586
1161
 
1587
1162
 
1588
 
#define NEED_ESCAPING(x) ((int) (uchar) (x) == escape_char    || \
1589
 
                          (enclosed ? (int) (uchar) (x) == field_sep_char      \
1590
 
                                    : (int) (uchar) (x) == field_term_char) || \
1591
 
                          (int) (uchar) (x) == line_sep_char  || \
 
1163
#define NEED_ESCAPING(x) ((int) (unsigned char) (x) == escape_char    || \
 
1164
                          (enclosed ? (int) (unsigned char) (x) == field_sep_char      \
 
1165
                                    : (int) (unsigned char) (x) == field_term_char) || \
 
1166
                          (int) (unsigned char) (x) == line_sep_char  || \
1592
1167
                          !(x))
1593
1168
 
1594
1169
bool select_export::send_data(List<Item> &items)
1605
1180
  }
1606
1181
  row_count++;
1607
1182
  Item *item;
1608
 
  uint used_length=0,items_left=items.elements;
 
1183
  uint32_t used_length=0,items_left=items.elements;
1609
1184
  List_iterator_fast<Item> li(items);
1610
1185
 
1611
 
  if (my_b_write(&cache,(uchar*) exchange->line_start->ptr(),
1612
 
                 exchange->line_start->length()))
 
1186
  if (my_b_write(cache,(unsigned char*) exchange->line_start->ptr(),
 
1187
                 exchange->line_start->length()))
1613
1188
    goto err;
1614
1189
  while ((item=li++))
1615
1190
  {
1619
1194
    res=item->str_result(&tmp);
1620
1195
    if (res && enclosed)
1621
1196
    {
1622
 
      if (my_b_write(&cache,(uchar*) exchange->enclosed->ptr(),
1623
 
                     exchange->enclosed->length()))
1624
 
        goto err;
 
1197
      if (my_b_write(cache,(unsigned char*) exchange->enclosed->ptr(),
 
1198
                     exchange->enclosed->length()))
 
1199
        goto err;
1625
1200
    }
1626
1201
    if (!res)
1627
1202
    {                                           // NULL
1628
1203
      if (!fixed_row_size)
1629
1204
      {
1630
 
        if (escape_char != -1)                  // Use \N syntax
1631
 
        {
1632
 
          null_buff[0]=escape_char;
1633
 
          null_buff[1]='N';
1634
 
          if (my_b_write(&cache,(uchar*) null_buff,2))
1635
 
            goto err;
1636
 
        }
1637
 
        else if (my_b_write(&cache,(uchar*) "NULL",4))
1638
 
          goto err;
 
1205
        if (escape_char != -1)                  // Use \N syntax
 
1206
        {
 
1207
          null_buff[0]=escape_char;
 
1208
          null_buff[1]='N';
 
1209
          if (my_b_write(cache,(unsigned char*) null_buff,2))
 
1210
            goto err;
 
1211
        }
 
1212
        else if (my_b_write(cache,(unsigned char*) "NULL",4))
 
1213
          goto err;
1639
1214
      }
1640
1215
      else
1641
1216
      {
1642
 
        used_length=0;                          // Fill with space
 
1217
        used_length=0;                          // Fill with space
1643
1218
      }
1644
1219
    }
1645
1220
    else
1646
1221
    {
1647
1222
      if (fixed_row_size)
1648
 
        used_length=min(res->length(),item->max_length);
 
1223
        used_length= min(res->length(),item->max_length);
1649
1224
      else
1650
 
        used_length=res->length();
 
1225
        used_length= res->length();
 
1226
 
1651
1227
      if ((result_type == STRING_RESULT || is_unsafe_field_sep) &&
1652
 
           escape_char != -1)
 
1228
          escape_char != -1)
1653
1229
      {
1654
1230
        char *pos, *start, *end;
1655
1231
        const CHARSET_INFO * const res_charset= res->charset();
1656
 
        const CHARSET_INFO * const character_set_client= thd->variables.
1657
 
                                                            character_set_client;
 
1232
        const CHARSET_INFO * const character_set_client= default_charset_info;
 
1233
 
1658
1234
        bool check_second_byte= (res_charset == &my_charset_bin) &&
1659
 
                                 character_set_client->
1660
 
                                 escape_with_backslash_is_dangerous;
 
1235
          character_set_client->
 
1236
          escape_with_backslash_is_dangerous;
1661
1237
        assert(character_set_client->mbmaxlen == 2 ||
1662
 
                    !character_set_client->escape_with_backslash_is_dangerous);
1663
 
        for (start=pos=(char*) res->ptr(),end=pos+used_length ;
1664
 
             pos != end ;
1665
 
             pos++)
1666
 
        {
1667
 
#ifdef USE_MB
1668
 
          if (use_mb(res_charset))
1669
 
          {
1670
 
            int l;
1671
 
            if ((l=my_ismbchar(res_charset, pos, end)))
1672
 
            {
1673
 
              pos += l-1;
1674
 
              continue;
1675
 
            }
1676
 
          }
1677
 
#endif
 
1238
               !character_set_client->escape_with_backslash_is_dangerous);
 
1239
        for (start=pos=(char*) res->ptr(),end=pos+used_length ;
 
1240
             pos != end ;
 
1241
             pos++)
 
1242
        {
 
1243
          if (use_mb(res_charset))
 
1244
          {
 
1245
            int l;
 
1246
            if ((l=my_ismbchar(res_charset, pos, end)))
 
1247
            {
 
1248
              pos += l-1;
 
1249
              continue;
 
1250
            }
 
1251
          }
1678
1252
 
1679
1253
          /*
1680
1254
            Special case when dumping BINARY/VARBINARY/BLOB values
1681
1255
            for the clients with character sets big5, cp932, gbk and sjis,
1682
1256
            which can have the escape character (0x5C "\" by default)
1683
1257
            as the second byte of a multi-byte sequence.
1684
 
            
 
1258
 
1685
1259
            If
1686
1260
            - pos[0] is a valid multi-byte head (e.g 0xEE) and
1687
1261
            - pos[1] is 0x00, which will be escaped as "\0",
1688
 
            
 
1262
 
1689
1263
            then we'll get "0xEE + 0x5C + 0x30" in the output file.
1690
 
            
 
1264
 
1691
1265
            If this file is later loaded using this sequence of commands:
1692
 
            
 
1266
 
1693
1267
            mysql> create table t1 (a varchar(128)) character set big5;
1694
 
            mysql> LOAD DATA INFILE 'dump.txt' INTO TABLE t1;
1695
 
            
 
1268
            mysql> LOAD DATA INFILE 'dump.txt' INTO Table t1;
 
1269
 
1696
1270
            then 0x5C will be misinterpreted as the second byte
1697
1271
            of a multi-byte character "0xEE + 0x5C", instead of
1698
1272
            escape character for 0x00.
1699
 
            
 
1273
 
1700
1274
            To avoid this confusion, we'll escape the multi-byte
1701
1275
            head character too, so the sequence "0xEE + 0x00" will be
1702
1276
            dumped as "0x5C + 0xEE + 0x5C + 0x30".
1703
 
            
 
1277
 
1704
1278
            Note, in the condition below we only check if
1705
1279
            mbcharlen is equal to 2, because there are no
1706
1280
            character sets with mbmaxlen longer than 2
1710
1284
 
1711
1285
          if ((NEED_ESCAPING(*pos) ||
1712
1286
               (check_second_byte &&
1713
 
                my_mbcharlen(character_set_client, (uchar) *pos) == 2 &&
 
1287
                my_mbcharlen(character_set_client, (unsigned char) *pos) == 2 &&
1714
1288
                pos + 1 < end &&
1715
1289
                NEED_ESCAPING(pos[1]))) &&
1716
1290
              /*
1717
 
               Don't escape field_term_char by doubling - doubling is only
1718
 
               valid for ENCLOSED BY characters:
 
1291
                Don't escape field_term_char by doubling - doubling is only
 
1292
                valid for ENCLOSED BY characters:
1719
1293
              */
1720
1294
              (enclosed || !is_ambiguous_field_term ||
1721
 
               (int) (uchar) *pos != field_term_char))
 
1295
               (int) (unsigned char) *pos != field_term_char))
1722
1296
          {
1723
 
            char tmp_buff[2];
1724
 
            tmp_buff[0]= ((int) (uchar) *pos == field_sep_char &&
 
1297
            char tmp_buff[2];
 
1298
            tmp_buff[0]= ((int) (unsigned char) *pos == field_sep_char &&
1725
1299
                          is_ambiguous_field_sep) ?
1726
 
                          field_sep_char : escape_char;
1727
 
            tmp_buff[1]= *pos ? *pos : '0';
1728
 
            if (my_b_write(&cache,(uchar*) start,(uint) (pos-start)) ||
1729
 
                my_b_write(&cache,(uchar*) tmp_buff,2))
1730
 
              goto err;
1731
 
            start=pos+1;
1732
 
          }
1733
 
        }
1734
 
        if (my_b_write(&cache,(uchar*) start,(uint) (pos-start)))
1735
 
          goto err;
 
1300
              field_sep_char : escape_char;
 
1301
            tmp_buff[1]= *pos ? *pos : '0';
 
1302
            if (my_b_write(cache,(unsigned char*) start,(uint32_t) (pos-start)) ||
 
1303
                my_b_write(cache,(unsigned char*) tmp_buff,2))
 
1304
              goto err;
 
1305
            start=pos+1;
 
1306
          }
 
1307
        }
 
1308
        if (my_b_write(cache,(unsigned char*) start,(uint32_t) (pos-start)))
 
1309
          goto err;
1736
1310
      }
1737
 
      else if (my_b_write(&cache,(uchar*) res->ptr(),used_length))
1738
 
        goto err;
 
1311
      else if (my_b_write(cache,(unsigned char*) res->ptr(),used_length))
 
1312
        goto err;
1739
1313
    }
1740
1314
    if (fixed_row_size)
1741
1315
    {                                           // Fill with space
1742
1316
      if (item->max_length > used_length)
1743
1317
      {
1744
 
        /* QQ:  Fix by adding a my_b_fill() function */
1745
 
        if (!space_inited)
1746
 
        {
1747
 
          space_inited=1;
1748
 
          memset(space, ' ', sizeof(space));
1749
 
        }
1750
 
        uint length=item->max_length-used_length;
1751
 
        for (; length > sizeof(space) ; length-=sizeof(space))
1752
 
        {
1753
 
          if (my_b_write(&cache,(uchar*) space,sizeof(space)))
1754
 
            goto err;
1755
 
        }
1756
 
        if (my_b_write(&cache,(uchar*) space,length))
1757
 
          goto err;
 
1318
        /* QQ:  Fix by adding a my_b_fill() function */
 
1319
        if (!space_inited)
 
1320
        {
 
1321
          space_inited=1;
 
1322
          memset(space, ' ', sizeof(space));
 
1323
        }
 
1324
        uint32_t length=item->max_length-used_length;
 
1325
        for (; length > sizeof(space) ; length-=sizeof(space))
 
1326
        {
 
1327
          if (my_b_write(cache,(unsigned char*) space,sizeof(space)))
 
1328
            goto err;
 
1329
        }
 
1330
        if (my_b_write(cache,(unsigned char*) space,length))
 
1331
          goto err;
1758
1332
      }
1759
1333
    }
1760
1334
    if (res && enclosed)
1761
1335
    {
1762
 
      if (my_b_write(&cache, (uchar*) exchange->enclosed->ptr(),
 
1336
      if (my_b_write(cache, (unsigned char*) exchange->enclosed->ptr(),
1763
1337
                     exchange->enclosed->length()))
1764
1338
        goto err;
1765
1339
    }
1766
1340
    if (--items_left)
1767
1341
    {
1768
 
      if (my_b_write(&cache, (uchar*) exchange->field_term->ptr(),
 
1342
      if (my_b_write(cache, (unsigned char*) exchange->field_term->ptr(),
1769
1343
                     field_term_length))
1770
1344
        goto err;
1771
1345
    }
1772
1346
  }
1773
 
  if (my_b_write(&cache,(uchar*) exchange->line_term->ptr(),
1774
 
                 exchange->line_term->length()))
 
1347
  if (my_b_write(cache,(unsigned char*) exchange->line_term->ptr(),
 
1348
                 exchange->line_term->length()))
1775
1349
    goto err;
1776
1350
  return(0);
1777
1351
err:
1785
1359
 
1786
1360
 
1787
1361
int
1788
 
select_dump::prepare(List<Item> &list __attribute__((unused)),
1789
 
                     SELECT_LEX_UNIT *u)
 
1362
select_dump::prepare(List<Item> &, Select_Lex_Unit *u)
1790
1363
{
1791
1364
  unit= u;
1792
 
  return (int) ((file= create_file(thd, path, exchange, &cache)) < 0);
 
1365
  return (int) ((file= create_file(session, path, exchange, cache)) < 0);
1793
1366
}
1794
1367
 
1795
1368
 
1806
1379
    unit->offset_limit_cnt--;
1807
1380
    return(0);
1808
1381
  }
1809
 
  if (row_count++ > 1) 
 
1382
  if (row_count++ > 1)
1810
1383
  {
1811
1384
    my_message(ER_TOO_MANY_ROWS, ER(ER_TOO_MANY_ROWS), MYF(0));
1812
1385
    goto err;
1816
1389
    res=item->str_result(&tmp);
1817
1390
    if (!res)                                   // If NULL
1818
1391
    {
1819
 
      if (my_b_write(&cache,(uchar*) "",1))
 
1392
      if (my_b_write(cache,(unsigned char*) "",1))
1820
1393
        goto err;
1821
1394
    }
1822
 
    else if (my_b_write(&cache,(uchar*) res->ptr(),res->length()))
 
1395
    else if (my_b_write(cache,(unsigned char*) res->ptr(),res->length()))
1823
1396
    {
1824
 
      my_error(ER_ERROR_ON_WRITE, MYF(0), path, my_errno);
 
1397
      my_error(ER_ERROR_ON_WRITE, MYF(0), path, errno);
1825
1398
      goto err;
1826
1399
    }
1827
1400
  }
1852
1425
  }
1853
1426
  List_iterator_fast<Item> li(items);
1854
1427
  Item *val_item;
1855
 
  for (uint i= 0; (val_item= li++); i++)
 
1428
  for (uint32_t i= 0; (val_item= li++); i++)
1856
1429
    it->store(i, val_item);
1857
1430
  it->assigned(1);
1858
1431
  return(0);
1862
1435
void select_max_min_finder_subselect::cleanup()
1863
1436
{
1864
1437
  cache= 0;
1865
 
  return;
1866
1438
}
1867
1439
 
1868
1440
 
1969
1541
     sortcmp(val1, val2, cache->collation.collation) < 0);
1970
1542
}
1971
1543
 
1972
 
bool select_exists_subselect::send_data(List<Item> &items __attribute__((unused)))
 
1544
bool select_exists_subselect::send_data(List<Item> &)
1973
1545
{
1974
1546
  Item_exists_subselect *it= (Item_exists_subselect *)item;
1975
1547
  if (unit->offset_limit_cnt)
1982
1554
  return(0);
1983
1555
}
1984
1556
 
1985
 
 
1986
 
/***************************************************************************
1987
 
  Dump of select to variables
1988
 
***************************************************************************/
1989
 
 
1990
 
int select_dumpvar::prepare(List<Item> &list, SELECT_LEX_UNIT *u)
1991
 
{
1992
 
  unit= u;
1993
 
  
1994
 
  if (var_list.elements != list.elements)
1995
 
  {
1996
 
    my_message(ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT,
1997
 
               ER(ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT), MYF(0));
1998
 
    return 1;
1999
 
  }               
2000
 
  return 0;
2001
 
}
2002
 
 
2003
 
 
2004
 
bool select_dumpvar::check_simple_select() const
2005
 
{
2006
 
  my_error(ER_SP_BAD_CURSOR_SELECT, MYF(0));
2007
 
  return true;
2008
 
}
2009
 
 
2010
 
 
2011
 
void select_dumpvar::cleanup()
2012
 
{
2013
 
  row_count= 0;
2014
 
}
2015
 
 
2016
 
 
2017
 
void Query_arena::free_items()
2018
 
{
2019
 
  Item *next;
2020
 
  /* This works because items are allocated with sql_alloc() */
2021
 
  for (; free_list; free_list= next)
2022
 
  {
2023
 
    next= free_list->next;
2024
 
    free_list->delete_self();
2025
 
  }
2026
 
  /* Postcondition: free_list is 0 */
2027
 
  return;
2028
 
}
2029
 
 
2030
 
 
2031
 
void Query_arena::set_query_arena(Query_arena *set)
2032
 
{
2033
 
  mem_root= set->mem_root;
2034
 
  free_list= set->free_list;
2035
 
  state= set->state;
2036
 
}
2037
 
 
2038
 
 
2039
 
void Query_arena::cleanup_stmt()
2040
 
{
2041
 
  assert("not implemented");
2042
 
}
2043
 
 
2044
1557
/*
2045
 
  Statement functions
 
1558
  Don't free mem_root, as mem_root is freed in the end of dispatch_command
 
1559
  (once for any command).
2046
1560
*/
2047
 
 
2048
 
Statement::Statement(LEX *lex_arg, MEM_ROOT *mem_root_arg,
2049
 
                     enum enum_state state_arg, ulong id_arg)
2050
 
  :Query_arena(mem_root_arg, state_arg),
2051
 
  id(id_arg),
2052
 
  mark_used_columns(MARK_COLUMNS_READ),
2053
 
  lex(lex_arg),
2054
 
  query(0),
2055
 
  query_length(0),
2056
 
  db(NULL),
2057
 
  db_length(0)
2058
 
{
2059
 
  name.str= NULL;
2060
 
}
2061
 
 
2062
 
 
2063
 
void Statement::set_statement(Statement *stmt)
2064
 
{
2065
 
  id=             stmt->id;
2066
 
  mark_used_columns=   stmt->mark_used_columns;
2067
 
  lex=            stmt->lex;
2068
 
  query=          stmt->query;
2069
 
  query_length=   stmt->query_length;
2070
 
}
2071
 
 
2072
 
 
2073
 
void
2074
 
Statement::set_n_backup_statement(Statement *stmt, Statement *backup)
2075
 
{
2076
 
  backup->set_statement(this);
2077
 
  set_statement(stmt);
2078
 
  return;
2079
 
}
2080
 
 
2081
 
 
2082
 
void Statement::restore_backup_statement(Statement *stmt, Statement *backup)
2083
 
{
2084
 
  stmt->set_statement(this);
2085
 
  set_statement(backup);
2086
 
  return;
2087
 
}
2088
 
 
2089
 
 
2090
 
void THD::end_statement()
 
1561
void Session::end_statement()
2091
1562
{
2092
1563
  /* Cleanup SQL processing state to reuse this statement in next query. */
2093
1564
  lex_end(lex);
2094
 
  delete lex->result;
2095
 
  lex->result= 0;
2096
 
  /* Note that free_list is freed in cleanup_after_query() */
2097
 
 
2098
 
  /*
2099
 
    Don't free mem_root, as mem_root is freed in the end of dispatch_command
2100
 
    (once for any command).
2101
 
  */
2102
 
}
2103
 
 
2104
 
 
2105
 
void THD::set_n_backup_active_arena(Query_arena *set, Query_arena *backup)
2106
 
{
2107
 
  assert(backup->is_backup_arena == false);
2108
 
 
2109
 
  backup->set_query_arena(this);
2110
 
  set_query_arena(set);
2111
 
  backup->is_backup_arena= true;
2112
 
  return;
2113
 
}
2114
 
 
2115
 
 
2116
 
void THD::restore_active_arena(Query_arena *set, Query_arena *backup)
2117
 
{
2118
 
  assert(backup->is_backup_arena);
2119
 
  set->set_query_arena(this);
2120
 
  set_query_arena(backup);
2121
 
  backup->is_backup_arena= false;
2122
 
  return;
2123
 
}
2124
 
 
2125
 
 
2126
 
bool THD::copy_db_to(char **p_db, size_t *p_db_length)
2127
 
{
2128
 
  if (db == NULL)
 
1565
}
 
1566
 
 
1567
bool Session::copy_db_to(char **p_db, size_t *p_db_length)
 
1568
{
 
1569
  if (db.empty())
2129
1570
  {
2130
1571
    my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
2131
1572
    return true;
2132
1573
  }
2133
 
  *p_db= strmake(db, db_length);
2134
 
  *p_db_length= db_length;
 
1574
  *p_db= strmake(db.c_str(), db.length());
 
1575
  *p_db_length= db.length();
2135
1576
  return false;
2136
1577
}
2137
1578
 
2138
 
 
2139
 
bool select_dumpvar::send_data(List<Item> &items)
2140
 
{
2141
 
  List_iterator_fast<my_var> var_li(var_list);
2142
 
  List_iterator<Item> it(items);
2143
 
  Item *item;
2144
 
  my_var *mv;
2145
 
 
2146
 
  if (unit->offset_limit_cnt)
2147
 
  {                                             // using limit offset,count
2148
 
    unit->offset_limit_cnt--;
2149
 
    return(0);
2150
 
  }
2151
 
  if (row_count++) 
2152
 
  {
2153
 
    my_message(ER_TOO_MANY_ROWS, ER(ER_TOO_MANY_ROWS), MYF(0));
2154
 
    return(1);
2155
 
  }
2156
 
  while ((mv= var_li++) && (item= it++))
2157
 
  {
2158
 
    if (mv->local == 0)
2159
 
    {
2160
 
      Item_func_set_user_var *suv= new Item_func_set_user_var(mv->s, item);
2161
 
      suv->fix_fields(thd, 0);
2162
 
      suv->check(0);
2163
 
      suv->update();
2164
 
    }
2165
 
  }
2166
 
  return(thd->is_error());
2167
 
}
2168
 
 
2169
 
bool select_dumpvar::send_eof()
2170
 
{
2171
 
  if (! row_count)
2172
 
    push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
2173
 
                 ER_SP_FETCH_NO_DATA, ER(ER_SP_FETCH_NO_DATA));
2174
 
  /*
2175
 
    In order to remember the value of affected rows for ROW_COUNT()
2176
 
    function, SELECT INTO has to have an own SQLCOM.
2177
 
    TODO: split from SQLCOM_SELECT
2178
 
  */
2179
 
  ::my_ok(thd,row_count);
2180
 
  return 0;
2181
 
}
2182
 
 
2183
1579
/****************************************************************************
2184
 
  TMP_TABLE_PARAM
 
1580
  Tmp_Table_Param
2185
1581
****************************************************************************/
2186
1582
 
2187
 
void TMP_TABLE_PARAM::init()
 
1583
void Tmp_Table_Param::init()
2188
1584
{
2189
1585
  field_count= sum_func_count= func_count= hidden_field_count= 0;
2190
1586
  group_parts= group_length= group_null_parts= 0;
2191
1587
  quick_group= 1;
2192
1588
  table_charset= 0;
2193
1589
  precomputed_group_by= 0;
2194
 
  bit_fields_as_long= 0;
2195
 
  return;
2196
1590
}
2197
1591
 
2198
 
 
2199
 
void thd_increment_bytes_sent(ulong length)
 
1592
void Tmp_Table_Param::cleanup(void)
2200
1593
{
2201
 
  THD *thd=current_thd;
2202
 
  if (likely(thd != 0))
2203
 
  { /* current_thd==0 when close_connection() calls net_send_error() */
2204
 
    thd->status_var.bytes_sent+= length;
 
1594
  /* Fix for Intel compiler */
 
1595
  if (copy_field)
 
1596
  {
 
1597
    delete [] copy_field;
 
1598
    save_copy_field= copy_field= 0;
2205
1599
  }
2206
1600
}
2207
1601
 
2208
 
 
2209
 
void thd_increment_bytes_received(ulong length)
2210
 
{
2211
 
  current_thd->status_var.bytes_received+= length;
2212
 
}
2213
 
 
2214
 
 
2215
 
void thd_increment_net_big_packet_count(ulong length)
2216
 
{
2217
 
  current_thd->status_var.net_big_packet_count+= length;
2218
 
}
2219
 
 
2220
 
void THD::send_kill_message() const
 
1602
void Session::send_kill_message() const
2221
1603
{
2222
1604
  int err= killed_errno();
2223
1605
  if (err)
2224
1606
    my_message(err, ER(err), MYF(0));
2225
1607
}
2226
1608
 
2227
 
void THD::set_status_var_init()
 
1609
void Session::set_status_var_init()
2228
1610
{
2229
1611
  memset(&status_var, 0, sizeof(status_var));
2230
1612
}
2231
1613
 
2232
1614
 
2233
 
void Security_context::init()
2234
 
{
2235
 
  user= ip= 0;
2236
 
}
2237
 
 
2238
 
 
2239
 
void Security_context::destroy()
2240
 
{
2241
 
  // If not pointer to constant
2242
 
  safeFree(user);
2243
 
  safeFree(ip);
2244
 
}
2245
 
 
2246
 
 
2247
 
void Security_context::skip_grants()
2248
 
{
2249
 
  /* privileges for the user are unknown everything is allowed */
2250
 
}
2251
 
 
2252
 
 
2253
1615
/****************************************************************************
2254
1616
  Handling of open and locked tables states.
2255
1617
 
2258
1620
  access to mysql.proc table to find definitions of stored routines.
2259
1621
****************************************************************************/
2260
1622
 
2261
 
void THD::reset_n_backup_open_tables_state(Open_tables_state *backup)
 
1623
void Session::reset_n_backup_open_tables_state(Open_tables_state *backup)
2262
1624
{
2263
1625
  backup->set_open_tables_state(this);
2264
1626
  reset_open_tables_state();
2265
 
  state_flags|= Open_tables_state::BACKUPS_AVAIL;
2266
 
  return;
 
1627
  backups_available= false;
2267
1628
}
2268
1629
 
2269
1630
 
2270
 
void THD::restore_backup_open_tables_state(Open_tables_state *backup)
 
1631
void Session::restore_backup_open_tables_state(Open_tables_state *backup)
2271
1632
{
2272
1633
  /*
2273
1634
    Before we will throw away current open tables state we want
2274
1635
    to be sure that it was properly cleaned up.
2275
1636
  */
2276
1637
  assert(open_tables == 0 && temporary_tables == 0 &&
2277
 
              handler_tables == 0 && derived_tables == 0 &&
2278
 
              lock == 0 && locked_tables == 0);
 
1638
              derived_tables == 0 &&
 
1639
              lock == 0);
2279
1640
  set_open_tables_state(backup);
2280
 
  return;
2281
 
}
 
1641
}
 
1642
 
 
1643
bool Session::set_db(const char *new_db, size_t length)
 
1644
{
 
1645
  /* Do not reallocate memory if current chunk is big enough. */
 
1646
  if (length)
 
1647
    db= new_db;
 
1648
  else
 
1649
    db.clear();
 
1650
 
 
1651
  return false;
 
1652
}
 
1653
 
 
1654
 
 
1655
 
2282
1656
 
2283
1657
/**
2284
1658
  Check the killed state of a user thread
2285
 
  @param thd  user thread
 
1659
  @param session  user thread
2286
1660
  @retval 0 the user thread is active
2287
1661
  @retval 1 the user thread has been killed
2288
1662
*/
2289
 
extern "C" int thd_killed(const DRIZZLE_THD thd)
 
1663
extern "C" int session_killed(const Session *session)
2290
1664
{
2291
 
  return(thd->killed);
 
1665
  return(session->killed);
2292
1666
}
2293
1667
 
2294
1668
/**
2295
 
  Return the thread id of a user thread
2296
 
  @param thd user thread
2297
 
  @return thread id
 
1669
  Return the session id of a user session
 
1670
  @param pointer to Session object
 
1671
  @return session's id
2298
1672
*/
2299
 
extern "C" unsigned long thd_get_thread_id(const DRIZZLE_THD thd)
2300
 
{
2301
 
  return((unsigned long)thd->thread_id);
2302
 
}
2303
 
 
2304
 
 
2305
 
#ifdef INNODB_COMPATIBILITY_HOOKS
2306
 
extern "C" const struct charset_info_st *thd_charset(DRIZZLE_THD thd)
2307
 
{
2308
 
  return(thd->charset());
2309
 
}
2310
 
 
2311
 
extern "C" char **thd_query(DRIZZLE_THD thd)
2312
 
{
2313
 
  return(&thd->query);
2314
 
}
2315
 
 
2316
 
extern "C" int thd_slave_thread(const DRIZZLE_THD thd)
2317
 
{
2318
 
  return(thd->slave_thread);
2319
 
}
2320
 
 
2321
 
extern "C" int thd_non_transactional_update(const DRIZZLE_THD thd)
2322
 
{
2323
 
  return(thd->transaction.all.modified_non_trans_table);
2324
 
}
2325
 
 
2326
 
extern "C" int thd_binlog_format(const DRIZZLE_THD thd)
2327
 
{
2328
 
  return (int) thd->variables.binlog_format;
2329
 
}
2330
 
 
2331
 
extern "C" void thd_mark_transaction_to_rollback(DRIZZLE_THD thd, bool all)
2332
 
{
2333
 
  mark_transaction_to_rollback(thd, all);
2334
 
}
2335
 
#endif // INNODB_COMPATIBILITY_HOOKS */
2336
 
 
 
1673
extern "C" unsigned long session_get_thread_id(const Session *session)
 
1674
{
 
1675
  return (unsigned long) session->getSessionId();
 
1676
}
 
1677
 
 
1678
 
 
1679
const struct charset_info_st *session_charset(Session *session)
 
1680
{
 
1681
  return(session->charset());
 
1682
}
 
1683
 
 
1684
char **session_query(Session *session)
 
1685
{
 
1686
  return(&session->query);
 
1687
}
 
1688
 
 
1689
int session_non_transactional_update(const Session *session)
 
1690
{
 
1691
  return(session->transaction.all.modified_non_trans_table);
 
1692
}
 
1693
 
 
1694
void session_mark_transaction_to_rollback(Session *session, bool all)
 
1695
{
 
1696
  mark_transaction_to_rollback(session, all);
 
1697
}
2337
1698
 
2338
1699
/**
2339
1700
  Mark transaction to rollback and mark error as fatal to a sub-statement.
2340
1701
 
2341
 
  @param  thd   Thread handle
 
1702
  @param  session   Thread handle
2342
1703
  @param  all   true <=> rollback main transaction.
2343
1704
*/
2344
 
 
2345
 
void mark_transaction_to_rollback(THD *thd, bool all)
2346
 
{
2347
 
  if (thd)
2348
 
  {
2349
 
    thd->is_fatal_sub_stmt_error= true;
2350
 
    thd->transaction_rollback_request= all;
2351
 
  }
2352
 
}
2353
 
/***************************************************************************
2354
 
  Handling of XA id cacheing
2355
 
***************************************************************************/
2356
 
 
2357
 
pthread_mutex_t LOCK_xid_cache;
2358
 
HASH xid_cache;
2359
 
 
2360
 
extern "C" uchar *xid_get_hash_key(const uchar *, size_t *, bool);
2361
 
extern "C" void xid_free_hash(void *);
2362
 
 
2363
 
uchar *xid_get_hash_key(const uchar *ptr, size_t *length,
2364
 
                        bool not_used __attribute__((unused)))
2365
 
{
2366
 
  *length=((XID_STATE*)ptr)->xid.key_length();
2367
 
  return ((XID_STATE*)ptr)->xid.key();
2368
 
}
2369
 
 
2370
 
void xid_free_hash(void *ptr)
2371
 
{
2372
 
  if (!((XID_STATE*)ptr)->in_thd)
2373
 
    my_free((uchar*)ptr, MYF(0));
2374
 
}
2375
 
 
2376
 
bool xid_cache_init()
2377
 
{
2378
 
  pthread_mutex_init(&LOCK_xid_cache, MY_MUTEX_INIT_FAST);
2379
 
  return hash_init(&xid_cache, &my_charset_bin, 100, 0, 0,
2380
 
                   xid_get_hash_key, xid_free_hash, 0) != 0;
2381
 
}
2382
 
 
2383
 
void xid_cache_free()
2384
 
{
2385
 
  if (hash_inited(&xid_cache))
2386
 
  {
2387
 
    hash_free(&xid_cache);
2388
 
    pthread_mutex_destroy(&LOCK_xid_cache);
2389
 
  }
2390
 
}
2391
 
 
2392
 
XID_STATE *xid_cache_search(XID *xid)
2393
 
{
2394
 
  pthread_mutex_lock(&LOCK_xid_cache);
2395
 
  XID_STATE *res=(XID_STATE *)hash_search(&xid_cache, xid->key(), xid->key_length());
2396
 
  pthread_mutex_unlock(&LOCK_xid_cache);
2397
 
  return res;
2398
 
}
2399
 
 
2400
 
 
2401
 
bool xid_cache_insert(XID *xid, enum xa_states xa_state)
2402
 
{
2403
 
  XID_STATE *xs;
2404
 
  bool res;
2405
 
  pthread_mutex_lock(&LOCK_xid_cache);
2406
 
  if (hash_search(&xid_cache, xid->key(), xid->key_length()))
2407
 
    res=0;
2408
 
  else if (!(xs=(XID_STATE *)my_malloc(sizeof(*xs), MYF(MY_WME))))
2409
 
    res=1;
2410
 
  else
2411
 
  {
2412
 
    xs->xa_state=xa_state;
2413
 
    xs->xid.set(xid);
2414
 
    xs->in_thd=0;
2415
 
    res=my_hash_insert(&xid_cache, (uchar*)xs);
2416
 
  }
2417
 
  pthread_mutex_unlock(&LOCK_xid_cache);
2418
 
  return res;
2419
 
}
2420
 
 
2421
 
 
2422
 
bool xid_cache_insert(XID_STATE *xid_state)
2423
 
{
2424
 
  pthread_mutex_lock(&LOCK_xid_cache);
2425
 
  assert(hash_search(&xid_cache, xid_state->xid.key(),
2426
 
                          xid_state->xid.key_length())==0);
2427
 
  bool res=my_hash_insert(&xid_cache, (uchar*)xid_state);
2428
 
  pthread_mutex_unlock(&LOCK_xid_cache);
2429
 
  return res;
2430
 
}
2431
 
 
2432
 
 
2433
 
void xid_cache_delete(XID_STATE *xid_state)
2434
 
{
2435
 
  pthread_mutex_lock(&LOCK_xid_cache);
2436
 
  hash_delete(&xid_cache, (uchar *)xid_state);
2437
 
  pthread_mutex_unlock(&LOCK_xid_cache);
2438
 
}
2439
 
 
2440
 
/*
2441
 
  Implementation of interface to write rows to the binary log through the
2442
 
  thread.  The thread is responsible for writing the rows it has
2443
 
  inserted/updated/deleted.
2444
 
*/
2445
 
 
2446
 
#ifndef DRIZZLE_CLIENT
2447
 
 
2448
 
/*
2449
 
  Template member function for ensuring that there is an rows log
2450
 
  event of the apropriate type before proceeding.
2451
 
 
2452
 
  PRE CONDITION:
2453
 
    - Events of type 'RowEventT' have the type code 'type_code'.
2454
 
    
2455
 
  POST CONDITION:
2456
 
    If a non-NULL pointer is returned, the pending event for thread 'thd' will
2457
 
    be an event of type 'RowEventT' (which have the type code 'type_code')
2458
 
    will either empty or have enough space to hold 'needed' bytes.  In
2459
 
    addition, the columns bitmap will be correct for the row, meaning that
2460
 
    the pending event will be flushed if the columns in the event differ from
2461
 
    the columns suppled to the function.
2462
 
 
2463
 
  RETURNS
2464
 
    If no error, a non-NULL pending event (either one which already existed or
2465
 
    the newly created one).
2466
 
    If error, NULL.
2467
 
 */
2468
 
 
2469
 
template <class RowsEventT> Rows_log_event* 
2470
 
THD::binlog_prepare_pending_rows_event(TABLE* table, uint32_t serv_id,
2471
 
                                       size_t needed,
2472
 
                                       bool is_transactional,
2473
 
                                       RowsEventT *hint __attribute__((unused)))
2474
 
{
2475
 
  /* Pre-conditions */
2476
 
  assert(table->s->table_map_id != ~0UL);
2477
 
 
2478
 
  /* Fetch the type code for the RowsEventT template parameter */
2479
 
  int const type_code= RowsEventT::TYPE_CODE;
2480
 
 
2481
 
  /*
2482
 
    There is no good place to set up the transactional data, so we
2483
 
    have to do it here.
2484
 
  */
2485
 
  if (binlog_setup_trx_data())
2486
 
    return(NULL);
2487
 
 
2488
 
  Rows_log_event* pending= binlog_get_pending_rows_event();
2489
 
 
2490
 
  if (unlikely(pending && !pending->is_valid()))
2491
 
    return(NULL);
2492
 
 
2493
 
  /*
2494
 
    Check if the current event is non-NULL and a write-rows
2495
 
    event. Also check if the table provided is mapped: if it is not,
2496
 
    then we have switched to writing to a new table.
2497
 
    If there is no pending event, we need to create one. If there is a pending
2498
 
    event, but it's not about the same table id, or not of the same type
2499
 
    (between Write, Update and Delete), or not the same affected columns, or
2500
 
    going to be too big, flush this event to disk and create a new pending
2501
 
    event.
2502
 
 
2503
 
    The last test is necessary for the Cluster injector to work
2504
 
    correctly. The reason is that the Cluster can inject two write
2505
 
    rows with different column bitmaps if there is an insert followed
2506
 
    by an update in the same transaction, and these are grouped into a
2507
 
    single epoch/transaction when fed to the injector.
2508
 
 
2509
 
    TODO: Fix the code so that the last test can be removed.
2510
 
  */
2511
 
  if (!pending ||
2512
 
      pending->server_id != serv_id || 
2513
 
      pending->get_table_id() != table->s->table_map_id ||
2514
 
      pending->get_type_code() != type_code || 
2515
 
      pending->get_data_size() + needed > opt_binlog_rows_event_max_size ||
2516
 
      !bitmap_cmp(pending->get_cols(), table->write_set))
2517
 
    {
2518
 
    /* Create a new RowsEventT... */
2519
 
    Rows_log_event* const
2520
 
        ev= new RowsEventT(this, table, table->s->table_map_id,
2521
 
                           is_transactional);
2522
 
    if (unlikely(!ev))
2523
 
      return(NULL);
2524
 
    ev->server_id= serv_id; // I don't like this, it's too easy to forget.
2525
 
    /*
2526
 
      flush the pending event and replace it with the newly created
2527
 
      event...
2528
 
    */
2529
 
    if (unlikely(mysql_bin_log.flush_and_set_pending_rows_event(this, ev)))
2530
 
    {
2531
 
      delete ev;
2532
 
      return(NULL);
2533
 
    }
2534
 
 
2535
 
    return(ev);               /* This is the new pending event */
2536
 
  }
2537
 
  return(pending);        /* This is the current pending event */
2538
 
}
2539
 
 
2540
 
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
2541
 
/*
2542
 
  Instantiate the versions we need, we have -fno-implicit-template as
2543
 
  compiling option.
2544
 
*/
2545
 
template Rows_log_event*
2546
 
THD::binlog_prepare_pending_rows_event(TABLE*, uint32_t, size_t, bool,
2547
 
                                       Write_rows_log_event*);
2548
 
 
2549
 
template Rows_log_event*
2550
 
THD::binlog_prepare_pending_rows_event(TABLE*, uint32_t, size_t, bool,
2551
 
                                       Delete_rows_log_event *);
2552
 
 
2553
 
template Rows_log_event* 
2554
 
THD::binlog_prepare_pending_rows_event(TABLE*, uint32_t, size_t, bool,
2555
 
                                       Update_rows_log_event *);
2556
 
#endif
2557
 
 
2558
 
namespace {
2559
 
  /**
2560
 
     Class to handle temporary allocation of memory for row data.
2561
 
 
2562
 
     The responsibilities of the class is to provide memory for
2563
 
     packing one or two rows of packed data (depending on what
2564
 
     constructor is called).
2565
 
 
2566
 
     In order to make the allocation more efficient for "simple" rows,
2567
 
     i.e., rows that do not contain any blobs, a pointer to the
2568
 
     allocated memory is of memory is stored in the table structure
2569
 
     for simple rows.  If memory for a table containing a blob field
2570
 
     is requested, only memory for that is allocated, and subsequently
2571
 
     released when the object is destroyed.
2572
 
 
2573
 
   */
2574
 
  class Row_data_memory {
2575
 
  public:
2576
 
    /**
2577
 
      Build an object to keep track of a block-local piece of memory
2578
 
      for storing a row of data.
2579
 
 
2580
 
      @param table
2581
 
      Table where the pre-allocated memory is stored.
2582
 
 
2583
 
      @param length
2584
 
      Length of data that is needed, if the record contain blobs.
2585
 
     */
2586
 
    Row_data_memory(TABLE *table, size_t const len1)
2587
 
      : m_memory(0)
2588
 
    {
2589
 
      m_alloc_checked= false;
2590
 
      allocate_memory(table, len1);
2591
 
      m_ptr[0]= has_memory() ? m_memory : 0;
2592
 
      m_ptr[1]= 0;
2593
 
    }
2594
 
 
2595
 
    Row_data_memory(TABLE *table, size_t const len1, size_t const len2)
2596
 
      : m_memory(0)
2597
 
    {
2598
 
      m_alloc_checked= false;
2599
 
      allocate_memory(table, len1 + len2);
2600
 
      m_ptr[0]= has_memory() ? m_memory        : 0;
2601
 
      m_ptr[1]= has_memory() ? m_memory + len1 : 0;
2602
 
    }
2603
 
 
2604
 
    ~Row_data_memory()
2605
 
    {
2606
 
      if (m_memory != 0 && m_release_memory_on_destruction)
2607
 
        my_free((uchar*) m_memory, MYF(MY_WME));
2608
 
    }
2609
 
 
2610
 
    /**
2611
 
       Is there memory allocated?
2612
 
 
2613
 
       @retval true There is memory allocated
2614
 
       @retval false Memory allocation failed
2615
 
     */
2616
 
    bool has_memory() const {
2617
 
      m_alloc_checked= true;
2618
 
      return m_memory != 0;
2619
 
    }
2620
 
 
2621
 
    uchar *slot(uint s)
2622
 
    {
2623
 
      assert(s < sizeof(m_ptr)/sizeof(*m_ptr));
2624
 
      assert(m_ptr[s] != 0);
2625
 
      assert(m_alloc_checked == true);
2626
 
      return m_ptr[s];
2627
 
    }
2628
 
 
2629
 
  private:
2630
 
    void allocate_memory(TABLE *const table, size_t const total_length)
2631
 
    {
2632
 
      if (table->s->blob_fields == 0)
2633
 
      {
2634
 
        /*
2635
 
          The maximum length of a packed record is less than this
2636
 
          length. We use this value instead of the supplied length
2637
 
          when allocating memory for records, since we don't know how
2638
 
          the memory will be used in future allocations.
2639
 
 
2640
 
          Since table->s->reclength is for unpacked records, we have
2641
 
          to add two bytes for each field, which can potentially be
2642
 
          added to hold the length of a packed field.
2643
 
        */
2644
 
        size_t const maxlen= table->s->reclength + 2 * table->s->fields;
2645
 
 
2646
 
        /*
2647
 
          Allocate memory for two records if memory hasn't been
2648
 
          allocated. We allocate memory for two records so that it can
2649
 
          be used when processing update rows as well.
2650
 
        */
2651
 
        if (table->write_row_record == 0)
2652
 
          table->write_row_record=
2653
 
            (uchar *) alloc_root(&table->mem_root, 2 * maxlen);
2654
 
        m_memory= table->write_row_record;
2655
 
        m_release_memory_on_destruction= false;
2656
 
      }
2657
 
      else
2658
 
      {
2659
 
        m_memory= (uchar *) my_malloc(total_length, MYF(MY_WME));
2660
 
        m_release_memory_on_destruction= true;
2661
 
      }
2662
 
    }
2663
 
 
2664
 
    mutable bool m_alloc_checked;
2665
 
    bool m_release_memory_on_destruction;
2666
 
    uchar *m_memory;
2667
 
    uchar *m_ptr[2];
2668
 
  };
2669
 
}
2670
 
 
2671
 
 
2672
 
int THD::binlog_write_row(TABLE* table, bool is_trans, 
2673
 
                          uchar const *record) 
2674
 
2675
 
  assert(current_stmt_binlog_row_based && mysql_bin_log.is_open());
2676
 
 
2677
 
  /*
2678
 
    Pack records into format for transfer. We are allocating more
2679
 
    memory than needed, but that doesn't matter.
2680
 
  */
2681
 
  Row_data_memory memory(table, max_row_length(table, record));
2682
 
  if (!memory.has_memory())
2683
 
    return HA_ERR_OUT_OF_MEM;
2684
 
 
2685
 
  uchar *row_data= memory.slot(0);
2686
 
 
2687
 
  size_t const len= pack_row(table, table->write_set, row_data, record);
2688
 
 
2689
 
  Rows_log_event* const ev=
2690
 
    binlog_prepare_pending_rows_event(table, server_id, len, is_trans,
2691
 
                                      static_cast<Write_rows_log_event*>(0));
2692
 
 
2693
 
  if (unlikely(ev == 0))
2694
 
    return HA_ERR_OUT_OF_MEM;
2695
 
 
2696
 
  return ev->add_row_data(row_data, len);
2697
 
}
2698
 
 
2699
 
int THD::binlog_update_row(TABLE* table, bool is_trans,
2700
 
                           const uchar *before_record,
2701
 
                           const uchar *after_record)
2702
 
2703
 
  assert(current_stmt_binlog_row_based && mysql_bin_log.is_open());
2704
 
 
2705
 
  size_t const before_maxlen = max_row_length(table, before_record);
2706
 
  size_t const after_maxlen  = max_row_length(table, after_record);
2707
 
 
2708
 
  Row_data_memory row_data(table, before_maxlen, after_maxlen);
2709
 
  if (!row_data.has_memory())
2710
 
    return HA_ERR_OUT_OF_MEM;
2711
 
 
2712
 
  uchar *before_row= row_data.slot(0);
2713
 
  uchar *after_row= row_data.slot(1);
2714
 
 
2715
 
  size_t const before_size= pack_row(table, table->read_set, before_row,
2716
 
                                        before_record);
2717
 
  size_t const after_size= pack_row(table, table->write_set, after_row,
2718
 
                                       after_record);
2719
 
 
2720
 
  Rows_log_event* const ev=
2721
 
    binlog_prepare_pending_rows_event(table, server_id,
2722
 
                                      before_size + after_size, is_trans,
2723
 
                                      static_cast<Update_rows_log_event*>(0));
2724
 
 
2725
 
  if (unlikely(ev == 0))
2726
 
    return HA_ERR_OUT_OF_MEM;
2727
 
 
2728
 
  return
2729
 
    ev->add_row_data(before_row, before_size) ||
2730
 
    ev->add_row_data(after_row, after_size);
2731
 
}
2732
 
 
2733
 
int THD::binlog_delete_row(TABLE* table, bool is_trans, 
2734
 
                           uchar const *record)
2735
 
2736
 
  assert(current_stmt_binlog_row_based && mysql_bin_log.is_open());
2737
 
 
2738
 
  /* 
2739
 
     Pack records into format for transfer. We are allocating more
2740
 
     memory than needed, but that doesn't matter.
2741
 
  */
2742
 
  Row_data_memory memory(table, max_row_length(table, record));
2743
 
  if (unlikely(!memory.has_memory()))
2744
 
    return HA_ERR_OUT_OF_MEM;
2745
 
 
2746
 
  uchar *row_data= memory.slot(0);
2747
 
 
2748
 
  size_t const len= pack_row(table, table->read_set, row_data, record);
2749
 
 
2750
 
  Rows_log_event* const ev=
2751
 
    binlog_prepare_pending_rows_event(table, server_id, len, is_trans,
2752
 
                                      static_cast<Delete_rows_log_event*>(0));
2753
 
 
2754
 
  if (unlikely(ev == 0))
2755
 
    return HA_ERR_OUT_OF_MEM;
2756
 
 
2757
 
  return ev->add_row_data(row_data, len);
2758
 
}
2759
 
 
2760
 
 
2761
 
int THD::binlog_flush_pending_rows_event(bool stmt_end)
2762
 
{
2763
 
  /*
2764
 
    We shall flush the pending event even if we are not in row-based
2765
 
    mode: it might be the case that we left row-based mode before
2766
 
    flushing anything (e.g., if we have explicitly locked tables).
2767
 
   */
2768
 
  if (!mysql_bin_log.is_open())
2769
 
    return(0);
2770
 
 
2771
 
  /*
2772
 
    Mark the event as the last event of a statement if the stmt_end
2773
 
    flag is set.
2774
 
  */
2775
 
  int error= 0;
2776
 
  if (Rows_log_event *pending= binlog_get_pending_rows_event())
2777
 
  {
2778
 
    if (stmt_end)
2779
 
    {
2780
 
      pending->set_flags(Rows_log_event::STMT_END_F);
2781
 
      pending->flags|= LOG_EVENT_UPDATE_TABLE_MAP_VERSION_F;
2782
 
      binlog_table_maps= 0;
2783
 
    }
2784
 
 
2785
 
    error= mysql_bin_log.flush_and_set_pending_rows_event(this, 0);
2786
 
  }
2787
 
 
2788
 
  return(error);
2789
 
}
2790
 
 
2791
 
 
2792
 
/*
2793
 
  Member function that will log query, either row-based or
2794
 
  statement-based depending on the value of the 'current_stmt_binlog_row_based'
2795
 
  the value of the 'qtype' flag.
2796
 
 
2797
 
  This function should be called after the all calls to ha_*_row()
2798
 
  functions have been issued, but before tables are unlocked and
2799
 
  closed.
2800
 
 
2801
 
  OBSERVE
2802
 
    There shall be no writes to any system table after calling
2803
 
    binlog_query(), so these writes has to be moved to before the call
2804
 
    of binlog_query() for correct functioning.
2805
 
 
2806
 
    This is necessesary not only for RBR, but the master might crash
2807
 
    after binlogging the query but before changing the system tables.
2808
 
    This means that the slave and the master are not in the same state
2809
 
    (after the master has restarted), so therefore we have to
2810
 
    eliminate this problem.
2811
 
 
2812
 
  RETURN VALUE
2813
 
    Error code, or 0 if no error.
2814
 
*/
2815
 
int THD::binlog_query(THD::enum_binlog_query_type qtype, char const *query_arg,
2816
 
                      ulong query_len, bool is_trans, bool suppress_use,
2817
 
                      THD::killed_state killed_status_arg)
2818
 
{
2819
 
  assert(query_arg && mysql_bin_log.is_open());
2820
 
 
2821
 
  if (int error= binlog_flush_pending_rows_event(true))
2822
 
    return(error);
2823
 
 
2824
 
  /*
2825
 
    If we are in statement mode and trying to log an unsafe statement,
2826
 
    we should print a warning.
2827
 
  */
2828
 
  if (lex->is_stmt_unsafe() &&
2829
 
      variables.binlog_format == BINLOG_FORMAT_STMT)
2830
 
  {
2831
 
    assert(this->query != NULL);
2832
 
    push_warning(this, DRIZZLE_ERROR::WARN_LEVEL_WARN,
2833
 
                 ER_BINLOG_UNSAFE_STATEMENT,
2834
 
                 ER(ER_BINLOG_UNSAFE_STATEMENT));
2835
 
    if (!(binlog_flags & BINLOG_FLAG_UNSAFE_STMT_PRINTED))
2836
 
    {
2837
 
      char warn_buf[DRIZZLE_ERRMSG_SIZE];
2838
 
      snprintf(warn_buf, DRIZZLE_ERRMSG_SIZE, "%s Statement: %s",
2839
 
               ER(ER_BINLOG_UNSAFE_STATEMENT), this->query);
2840
 
      sql_print_warning(warn_buf);
2841
 
      binlog_flags|= BINLOG_FLAG_UNSAFE_STMT_PRINTED;
2842
 
    }
2843
 
  }
2844
 
 
2845
 
  switch (qtype) {
2846
 
  case THD::ROW_QUERY_TYPE:
2847
 
    if (current_stmt_binlog_row_based)
2848
 
      return(0);
2849
 
    /* Otherwise, we fall through */
2850
 
  case THD::DRIZZLE_QUERY_TYPE:
2851
 
    /*
2852
 
      Using this query type is a conveniece hack, since we have been
2853
 
      moving back and forth between using RBR for replication of
2854
 
      system tables and not using it.
2855
 
 
2856
 
      Make sure to change in check_table_binlog_row_based() according
2857
 
      to how you treat this.
2858
 
    */
2859
 
  case THD::STMT_QUERY_TYPE:
2860
 
    /*
2861
 
      The DRIZZLE_LOG::write() function will set the STMT_END_F flag and
2862
 
      flush the pending rows event if necessary.
2863
 
     */
2864
 
    {
2865
 
      Query_log_event qinfo(this, query_arg, query_len, is_trans, suppress_use,
2866
 
                            killed_status_arg);
2867
 
      qinfo.flags|= LOG_EVENT_UPDATE_TABLE_MAP_VERSION_F;
2868
 
      /*
2869
 
        Binlog table maps will be irrelevant after a Query_log_event
2870
 
        (they are just removed on the slave side) so after the query
2871
 
        log event is written to the binary log, we pretend that no
2872
 
        table maps were written.
2873
 
       */
2874
 
      int error= mysql_bin_log.write(&qinfo);
2875
 
      binlog_table_maps= 0;
2876
 
      return(error);
2877
 
    }
2878
 
    break;
2879
 
 
2880
 
  case THD::QUERY_TYPE_COUNT:
2881
 
  default:
2882
 
    assert(0 <= qtype && qtype < QUERY_TYPE_COUNT);
2883
 
  }
2884
 
  return(0);
2885
 
}
2886
 
 
2887
 
bool Discrete_intervals_list::append(uint64_t start, uint64_t val,
2888
 
                                 uint64_t incr)
2889
 
{
2890
 
  /* first, see if this can be merged with previous */
2891
 
  if ((head == NULL) || tail->merge_if_contiguous(start, val, incr))
2892
 
  {
2893
 
    /* it cannot, so need to add a new interval */
2894
 
    Discrete_interval *new_interval= new Discrete_interval(start, val, incr);
2895
 
    return(append(new_interval));
2896
 
  }
2897
 
  return(0);
2898
 
}
2899
 
 
2900
 
bool Discrete_intervals_list::append(Discrete_interval *new_interval)
2901
 
{
2902
 
  if (unlikely(new_interval == NULL))
2903
 
    return(1);
2904
 
  if (head == NULL)
2905
 
    head= current= new_interval;
2906
 
  else
2907
 
    tail->next= new_interval;
2908
 
  tail= new_interval;
2909
 
  elements++;
2910
 
  return(0);
2911
 
}
2912
 
 
2913
 
#endif /* !defined(DRIZZLE_CLIENT) */
 
1705
void mark_transaction_to_rollback(Session *session, bool all)
 
1706
{
 
1707
  if (session)
 
1708
  {
 
1709
    session->is_fatal_sub_stmt_error= true;
 
1710
    session->transaction_rollback_request= all;
 
1711
  }
 
1712
}
 
1713
 
 
1714
void Session::disconnect(uint32_t errcode, bool should_lock)
 
1715
{
 
1716
  /* Allow any plugins to cleanup their session variables */
 
1717
  plugin_sessionvar_cleanup(this);
 
1718
 
 
1719
  /* If necessary, log any aborted or unauthorized connections */
 
1720
  if (killed || client->wasAborted())
 
1721
    statistic_increment(aborted_threads, &LOCK_status);
 
1722
 
 
1723
  if (client->wasAborted())
 
1724
  {
 
1725
    if (! killed && variables.log_warnings > 1)
 
1726
    {
 
1727
      SecurityContext *sctx= &security_ctx;
 
1728
 
 
1729
      errmsg_printf(ERRMSG_LVL_WARN, ER(ER_NEW_ABORTING_CONNECTION)
 
1730
                  , thread_id
 
1731
                  , (db.empty() ? "unconnected" : db.c_str())
 
1732
                  , sctx->getUser().empty() == false ? sctx->getUser().c_str() : "unauthenticated"
 
1733
                  , sctx->getIp().c_str()
 
1734
                  , (main_da.is_error() ? main_da.message() : ER(ER_UNKNOWN_ERROR)));
 
1735
    }
 
1736
  }
 
1737
 
 
1738
  /* Close out our connection to the client */
 
1739
  if (should_lock)
 
1740
    (void) pthread_mutex_lock(&LOCK_thread_count);
 
1741
  killed= Session::KILL_CONNECTION;
 
1742
  if (client->isConnected())
 
1743
  {
 
1744
    if (errcode)
 
1745
    {
 
1746
      /*my_error(errcode, ER(errcode));*/
 
1747
      client->sendError(errcode, ER(errcode));
 
1748
    }
 
1749
    client->close();
 
1750
  }
 
1751
  if (should_lock)
 
1752
    (void) pthread_mutex_unlock(&LOCK_thread_count);
 
1753
}
 
1754
 
 
1755
void Session::reset_for_next_command()
 
1756
{
 
1757
  free_list= 0;
 
1758
  select_number= 1;
 
1759
  /*
 
1760
    Those two lines below are theoretically unneeded as
 
1761
    Session::cleanup_after_query() should take care of this already.
 
1762
  */
 
1763
  auto_inc_intervals_in_cur_stmt_for_binlog.empty();
 
1764
 
 
1765
  is_fatal_error= false;
 
1766
  server_status&= ~ (SERVER_MORE_RESULTS_EXISTS |
 
1767
                          SERVER_QUERY_NO_INDEX_USED |
 
1768
                          SERVER_QUERY_NO_GOOD_INDEX_USED);
 
1769
  /*
 
1770
    If in autocommit mode and not in a transaction, reset
 
1771
    OPTION_STATUS_NO_TRANS_UPDATE to not get warnings
 
1772
    in ha_rollback_trans() about some tables couldn't be rolled back.
 
1773
  */
 
1774
  if (!(options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))
 
1775
  {
 
1776
    transaction.all.modified_non_trans_table= false;
 
1777
  }
 
1778
 
 
1779
  clear_error();
 
1780
  main_da.reset_diagnostics_area();
 
1781
  total_warn_count=0;                   // Warnings for this query
 
1782
  sent_row_count= examined_row_count= 0;
 
1783
}
 
1784
 
 
1785
/*
 
1786
  Close all temporary tables created by 'CREATE TEMPORARY TABLE' for thread
 
1787
*/
 
1788
 
 
1789
void Session::close_temporary_tables()
 
1790
{
 
1791
  Table *table;
 
1792
  Table *tmp_next;
 
1793
 
 
1794
  if (!temporary_tables)
 
1795
    return;
 
1796
 
 
1797
  for (table= temporary_tables; table; table= tmp_next)
 
1798
  {
 
1799
    tmp_next= table->next;
 
1800
    close_temporary(table);
 
1801
  }
 
1802
  temporary_tables= NULL;
 
1803
}
 
1804
 
 
1805
/*
 
1806
  unlink from session->temporary tables and close temporary table
 
1807
*/
 
1808
 
 
1809
void Session::close_temporary_table(Table *table)
 
1810
{
 
1811
  if (table->prev)
 
1812
  {
 
1813
    table->prev->next= table->next;
 
1814
    if (table->prev->next)
 
1815
      table->next->prev= table->prev;
 
1816
  }
 
1817
  else
 
1818
  {
 
1819
    /* removing the item from the list */
 
1820
    assert(table == temporary_tables);
 
1821
    /*
 
1822
      slave must reset its temporary list pointer to zero to exclude
 
1823
      passing non-zero value to end_slave via rli->save_temporary_tables
 
1824
      when no temp tables opened, see an invariant below.
 
1825
    */
 
1826
    temporary_tables= table->next;
 
1827
    if (temporary_tables)
 
1828
      table->next->prev= NULL;
 
1829
  }
 
1830
  close_temporary(table);
 
1831
}
 
1832
 
 
1833
/*
 
1834
  Close and delete a temporary table
 
1835
 
 
1836
  NOTE
 
1837
  This dosn't unlink table from session->temporary
 
1838
  If this is needed, use close_temporary_table()
 
1839
*/
 
1840
 
 
1841
void Session::close_temporary(Table *table)
 
1842
{
 
1843
  plugin::StorageEngine *table_type= table->s->db_type();
 
1844
 
 
1845
  table->free_io_cache();
 
1846
  table->closefrm(false);
 
1847
 
 
1848
  rm_temporary_table(table_type, table->s->path.str);
 
1849
 
 
1850
  table->s->free_table_share();
 
1851
 
 
1852
  /* This makes me sad, but we're allocating it via malloc */
 
1853
  free(table);
 
1854
}
 
1855
 
 
1856
/** Clear most status variables. */
 
1857
extern time_t flush_status_time;
 
1858
extern uint32_t max_used_connections;
 
1859
 
 
1860
void Session::refresh_status()
 
1861
{
 
1862
  pthread_mutex_lock(&LOCK_status);
 
1863
 
 
1864
  /* Add thread's status variabes to global status */
 
1865
  add_to_status(&global_status_var, &status_var);
 
1866
 
 
1867
  /* Reset thread's status variables */
 
1868
  memset(&status_var, 0, sizeof(status_var));
 
1869
 
 
1870
  /* Reset some global variables */
 
1871
  reset_status_vars();
 
1872
 
 
1873
  /* Reset the counters of all key caches (default and named). */
 
1874
  reset_key_cache_counters();
 
1875
  flush_status_time= time((time_t*) 0);
 
1876
  max_used_connections= 1; /* We set it to one, because we know we exist */
 
1877
  pthread_mutex_unlock(&LOCK_status);
 
1878
}
 
1879
 
 
1880
user_var_entry *Session::getVariable(LEX_STRING &name, bool create_if_not_exists)
 
1881
{
 
1882
  user_var_entry *entry= NULL;
 
1883
 
 
1884
  entry= (user_var_entry*) hash_search(&user_vars, (unsigned char*) name.str, name.length);
 
1885
 
 
1886
  if ((entry == NULL) && create_if_not_exists)
 
1887
  {
 
1888
    if (!hash_inited(&user_vars))
 
1889
      return NULL;
 
1890
    entry= new (nothrow) user_var_entry(name.str, query_id);
 
1891
 
 
1892
    if (entry == NULL)
 
1893
      return NULL;
 
1894
 
 
1895
    if (my_hash_insert(&user_vars, (unsigned char*) entry))
 
1896
    {
 
1897
      assert(1);
 
1898
      free((char*) entry);
 
1899
      return 0;
 
1900
    }
 
1901
 
 
1902
  }
 
1903
 
 
1904
  return entry;
 
1905
}
 
1906
 
 
1907
void Session::mark_temp_tables_as_free_for_reuse()
 
1908
{
 
1909
  for (Table *table= temporary_tables ; table ; table= table->next)
 
1910
  {
 
1911
    if (table->query_id == query_id)
 
1912
    {
 
1913
      table->query_id= 0;
 
1914
      table->cursor->ha_reset();
 
1915
    }
 
1916
  }
 
1917
}
 
1918
 
 
1919
void Session::mark_used_tables_as_free_for_reuse(Table *table)
 
1920
{
 
1921
  for (; table ; table= table->next)
 
1922
  {
 
1923
    if (table->query_id == query_id)
 
1924
    {
 
1925
      table->query_id= 0;
 
1926
      table->cursor->ha_reset();
 
1927
    }
 
1928
  }
 
1929
}
 
1930
 
 
1931
/*
 
1932
  Unlocks tables and frees derived tables.
 
1933
  Put all normal tables used by thread in free list.
 
1934
 
 
1935
  It will only close/mark as free for reuse tables opened by this
 
1936
  substatement, it will also check if we are closing tables after
 
1937
  execution of complete query (i.e. we are on upper level) and will
 
1938
  leave prelocked mode if needed.
 
1939
*/
 
1940
void Session::close_thread_tables()
 
1941
{
 
1942
  Table *table;
 
1943
 
 
1944
  /*
 
1945
    We are assuming here that session->derived_tables contains ONLY derived
 
1946
    tables for this substatement. i.e. instead of approach which uses
 
1947
    query_id matching for determining which of the derived tables belong
 
1948
    to this substatement we rely on the ability of substatements to
 
1949
    save/restore session->derived_tables during their execution.
 
1950
 
 
1951
    TODO: Probably even better approach is to simply associate list of
 
1952
          derived tables with (sub-)statement instead of thread and destroy
 
1953
          them at the end of its execution.
 
1954
  */
 
1955
  if (derived_tables)
 
1956
  {
 
1957
    Table *next;
 
1958
    /*
 
1959
      Close all derived tables generated in queries like
 
1960
      SELECT * FROM (SELECT * FROM t1)
 
1961
    */
 
1962
    for (table= derived_tables ; table ; table= next)
 
1963
    {
 
1964
      next= table->next;
 
1965
      table->free_tmp_table(this);
 
1966
    }
 
1967
    derived_tables= 0;
 
1968
  }
 
1969
 
 
1970
  /*
 
1971
    Mark all temporary tables used by this statement as free for reuse.
 
1972
  */
 
1973
  mark_temp_tables_as_free_for_reuse();
 
1974
  /*
 
1975
    Let us commit transaction for statement. Since in 5.0 we only have
 
1976
    one statement transaction and don't allow several nested statement
 
1977
    transactions this call will do nothing if we are inside of stored
 
1978
    function or trigger (i.e. statement transaction is already active and
 
1979
    does not belong to statement for which we do close_thread_tables()).
 
1980
    TODO: This should be fixed in later releases.
 
1981
   */
 
1982
  if (backups_available == false)
 
1983
  {
 
1984
    TransactionServices &transaction_services= TransactionServices::singleton();
 
1985
    main_da.can_overwrite_status= true;
 
1986
    transaction_services.ha_autocommit_or_rollback(this, is_error());
 
1987
    main_da.can_overwrite_status= false;
 
1988
    transaction.stmt.reset();
 
1989
  }
 
1990
 
 
1991
  if (lock)
 
1992
  {
 
1993
    /*
 
1994
      For RBR we flush the pending event just before we unlock all the
 
1995
      tables.  This means that we are at the end of a topmost
 
1996
      statement, so we ensure that the STMT_END_F flag is set on the
 
1997
      pending event.  For statements that are *inside* stored
 
1998
      functions, the pending event will not be flushed: that will be
 
1999
      handled either before writing a query log event (inside
 
2000
      binlog_query()) or when preparing a pending event.
 
2001
     */
 
2002
    mysql_unlock_tables(this, lock);
 
2003
    lock= 0;
 
2004
  }
 
2005
  /*
 
2006
    Note that we need to hold LOCK_open while changing the
 
2007
    open_tables list. Another thread may work on it.
 
2008
    (See: remove_table_from_cache(), mysql_wait_completed_table())
 
2009
    Closing a MERGE child before the parent would be fatal if the
 
2010
    other thread tries to abort the MERGE lock in between.
 
2011
  */
 
2012
  if (open_tables)
 
2013
    close_open_tables();
 
2014
}
 
2015
 
 
2016
void Session::close_tables_for_reopen(TableList **tables)
 
2017
{
 
2018
  /*
 
2019
    If table list consists only from tables from prelocking set, table list
 
2020
    for new attempt should be empty, so we have to update list's root pointer.
 
2021
  */
 
2022
  if (lex->first_not_own_table() == *tables)
 
2023
    *tables= 0;
 
2024
  lex->chop_off_not_own_tables();
 
2025
  for (TableList *tmp= *tables; tmp; tmp= tmp->next_global)
 
2026
    tmp->table= 0;
 
2027
  close_thread_tables();
 
2028
}
 
2029
 
 
2030
bool Session::openTablesLock(TableList *tables)
 
2031
{
 
2032
  uint32_t counter;
 
2033
  bool need_reopen;
 
2034
 
 
2035
  for ( ; ; )
 
2036
  {
 
2037
    if (open_tables_from_list(&tables, &counter))
 
2038
      return true;
 
2039
 
 
2040
    if (!lock_tables(tables, counter, &need_reopen))
 
2041
      break;
 
2042
    if (!need_reopen)
 
2043
      return true;
 
2044
    close_tables_for_reopen(&tables);
 
2045
  }
 
2046
  if ((mysql_handle_derived(lex, &mysql_derived_prepare) ||
 
2047
       (fill_derived_tables() &&
 
2048
        mysql_handle_derived(lex, &mysql_derived_filling))))
 
2049
    return true;
 
2050
 
 
2051
  return false;
 
2052
}
 
2053
 
 
2054
bool Session::openTables(TableList *tables, uint32_t flags)
 
2055
{
 
2056
  uint32_t counter;
 
2057
  bool ret= fill_derived_tables();
 
2058
  assert(ret == false);
 
2059
  if (open_tables_from_list(&tables, &counter, flags) ||
 
2060
      mysql_handle_derived(lex, &mysql_derived_prepare))
 
2061
    return true;
 
2062
  return false;
 
2063
}
 
2064
 
 
2065
bool Session::rm_temporary_table(plugin::StorageEngine *base, TableIdentifier &identifier)
 
2066
{
 
2067
  bool error= false;
 
2068
 
 
2069
  assert(base);
 
2070
 
 
2071
  if (plugin::StorageEngine::deleteDefinitionFromPath(identifier))
 
2072
    error= true;
 
2073
 
 
2074
  if (base->doDropTable(*this, identifier.getPath()))
 
2075
  {
 
2076
    error= true;
 
2077
    errmsg_printf(ERRMSG_LVL_WARN, _("Could not remove temporary table: '%s', error: %d"),
 
2078
                  identifier.getPath(), errno);
 
2079
  }
 
2080
  return error;
 
2081
}
 
2082
 
 
2083
bool Session::rm_temporary_table(plugin::StorageEngine *base, const char *path)
 
2084
{
 
2085
  bool error= false;
 
2086
 
 
2087
  assert(base);
 
2088
 
 
2089
  if (delete_table_proto_file(path))
 
2090
    error= true;
 
2091
 
 
2092
  if (base->doDropTable(*this, path))
 
2093
  {
 
2094
    error= true;
 
2095
    errmsg_printf(ERRMSG_LVL_WARN, _("Could not remove temporary table: '%s', error: %d"),
 
2096
                  path, errno);
 
2097
  }
 
2098
  return error;
 
2099
}
 
2100
 
 
2101
} /* namespace drizzled */