~drizzle-trunk/drizzle/development

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