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