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