~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_class.cc

  • Committer: Brian Aker
  • Date: 2008-10-06 06:47:29 UTC
  • Revision ID: brian@tangent.org-20081006064729-2i9mhjkzyvow9xsm
RemoveĀ uint.

Show diffs side-by-side

added added

removed removed

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