~ubuntu-branches/ubuntu/precise/mysql-5.1/precise

« back to all changes in this revision

Viewing changes to sql/sql_class.cc

  • Committer: Bazaar Package Importer
  • Author(s): Norbert Tretkowski
  • Date: 2010-03-17 14:56:02 UTC
  • Revision ID: james.westby@ubuntu.com-20100317145602-x7e30l1b2sb5s6w6
Tags: upstream-5.1.45
ImportĀ upstreamĀ versionĀ 5.1.45

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.
 
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_filter.h"
 
31
#include "rpl_record.h"
 
32
#include "slave.h"
 
33
#include <my_bitmap.h>
 
34
#include "log_event.h"
 
35
#include <m_ctype.h>
 
36
#include <sys/stat.h>
 
37
#include <thr_alarm.h>
 
38
#ifdef  __WIN__
 
39
#include <io.h>
 
40
#endif
 
41
#include <mysys_err.h>
 
42
 
 
43
#include "sp_rcontext.h"
 
44
#include "sp_cache.h"
 
45
#include "debug_sync.h"
 
46
 
 
47
/*
 
48
  The following is used to initialise Table_ident with a internal
 
49
  table name
 
50
*/
 
51
char internal_table_name[2]= "*";
 
52
char empty_c_string[1]= {0};    /* used for not defined db */
 
53
 
 
54
const char * const THD::DEFAULT_WHERE= "field list";
 
55
 
 
56
 
 
57
/*****************************************************************************
 
58
** Instansiate templates
 
59
*****************************************************************************/
 
60
 
 
61
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
 
62
/* Used templates */
 
63
template class List<Key>;
 
64
template class List_iterator<Key>;
 
65
template class List<Key_part_spec>;
 
66
template class List_iterator<Key_part_spec>;
 
67
template class List<Alter_drop>;
 
68
template class List_iterator<Alter_drop>;
 
69
template class List<Alter_column>;
 
70
template class List_iterator<Alter_column>;
 
71
#endif
 
72
 
 
73
/****************************************************************************
 
74
** User variables
 
75
****************************************************************************/
 
76
 
 
77
extern "C" uchar *get_var_key(user_var_entry *entry, size_t *length,
 
78
                              my_bool not_used __attribute__((unused)))
 
79
{
 
80
  *length= entry->name.length;
 
81
  return (uchar*) entry->name.str;
 
82
}
 
83
 
 
84
extern "C" void free_user_var(user_var_entry *entry)
 
85
{
 
86
  char *pos= (char*) entry+ALIGN_SIZE(sizeof(*entry));
 
87
  if (entry->value && entry->value != pos)
 
88
    my_free(entry->value, MYF(0));
 
89
  my_free((char*) entry,MYF(0));
 
90
}
 
91
 
 
92
bool Key_part_spec::operator==(const Key_part_spec& other) const
 
93
{
 
94
  return length == other.length && !strcmp(field_name, other.field_name);
 
95
}
 
96
 
 
97
/**
 
98
  Construct an (almost) deep copy of this key. Only those
 
99
  elements that are known to never change are not copied.
 
100
  If out of memory, a partial copy is returned and an error is set
 
101
  in THD.
 
102
*/
 
103
 
 
104
Key::Key(const Key &rhs, MEM_ROOT *mem_root)
 
105
  :type(rhs.type),
 
106
  key_create_info(rhs.key_create_info),
 
107
  columns(rhs.columns, mem_root),
 
108
  name(rhs.name),
 
109
  generated(rhs.generated)
 
110
{
 
111
  list_copy_and_replace_each_value(columns, mem_root);
 
112
}
 
113
 
 
114
/**
 
115
  Construct an (almost) deep copy of this foreign key. Only those
 
116
  elements that are known to never change are not copied.
 
117
  If out of memory, a partial copy is returned and an error is set
 
118
  in THD.
 
119
*/
 
120
 
 
121
Foreign_key::Foreign_key(const Foreign_key &rhs, MEM_ROOT *mem_root)
 
122
  :Key(rhs),
 
123
  ref_table(rhs.ref_table),
 
124
  ref_columns(rhs.ref_columns),
 
125
  delete_opt(rhs.delete_opt),
 
126
  update_opt(rhs.update_opt),
 
127
  match_opt(rhs.match_opt)
 
128
{
 
129
  list_copy_and_replace_each_value(ref_columns, mem_root);
 
130
}
 
131
 
 
132
/*
 
133
  Test if a foreign key (= generated key) is a prefix of the given key
 
134
  (ignoring key name, key type and order of columns)
 
135
 
 
136
  NOTES:
 
137
    This is only used to test if an index for a FOREIGN KEY exists
 
138
 
 
139
  IMPLEMENTATION
 
140
    We only compare field names
 
141
 
 
142
  RETURN
 
143
    0   Generated key is a prefix of other key
 
144
    1   Not equal
 
145
*/
 
146
 
 
147
bool foreign_key_prefix(Key *a, Key *b)
 
148
{
 
149
  /* Ensure that 'a' is the generated key */
 
150
  if (a->generated)
 
151
  {
 
152
    if (b->generated && a->columns.elements > b->columns.elements)
 
153
      swap_variables(Key*, a, b);               // Put shorter key in 'a'
 
154
  }
 
155
  else
 
156
  {
 
157
    if (!b->generated)
 
158
      return TRUE;                              // No foreign key
 
159
    swap_variables(Key*, a, b);                 // Put generated key in 'a'
 
160
  }
 
161
 
 
162
  /* Test if 'a' is a prefix of 'b' */
 
163
  if (a->columns.elements > b->columns.elements)
 
164
    return TRUE;                                // Can't be prefix
 
165
 
 
166
  List_iterator<Key_part_spec> col_it1(a->columns);
 
167
  List_iterator<Key_part_spec> col_it2(b->columns);
 
168
  const Key_part_spec *col1, *col2;
 
169
 
 
170
#ifdef ENABLE_WHEN_INNODB_CAN_HANDLE_SWAPED_FOREIGN_KEY_COLUMNS
 
171
  while ((col1= col_it1++))
 
172
  {
 
173
    bool found= 0;
 
174
    col_it2.rewind();
 
175
    while ((col2= col_it2++))
 
176
    {
 
177
      if (*col1 == *col2)
 
178
      {
 
179
        found= TRUE;
 
180
        break;
 
181
      }
 
182
    }
 
183
    if (!found)
 
184
      return TRUE;                              // Error
 
185
  }
 
186
  return FALSE;                                 // Is prefix
 
187
#else
 
188
  while ((col1= col_it1++))
 
189
  {
 
190
    col2= col_it2++;
 
191
    if (!(*col1 == *col2))
 
192
      return TRUE;
 
193
  }
 
194
  return FALSE;                                 // Is prefix
 
195
#endif
 
196
}
 
197
 
 
198
 
 
199
/****************************************************************************
 
200
** Thread specific functions
 
201
****************************************************************************/
 
202
 
 
203
/** Push an error to the error stack and return TRUE for now. */
 
204
 
 
205
bool
 
206
Reprepare_observer::report_error(THD *thd)
 
207
{
 
208
  my_error(ER_NEED_REPREPARE, MYF(ME_NO_WARNING_FOR_ERROR|ME_NO_SP_HANDLER));
 
209
 
 
210
  m_invalidated= TRUE;
 
211
 
 
212
  return TRUE;
 
213
}
 
214
 
 
215
 
 
216
Open_tables_state::Open_tables_state(ulong version_arg)
 
217
  :version(version_arg), state_flags(0U)
 
218
{
 
219
  reset_open_tables_state();
 
220
}
 
221
 
 
222
/*
 
223
  The following functions form part of the C plugin API
 
224
*/
 
225
 
 
226
extern "C" int mysql_tmpfile(const char *prefix)
 
227
{
 
228
  char filename[FN_REFLEN];
 
229
  File fd = create_temp_file(filename, mysql_tmpdir, prefix,
 
230
#ifdef __WIN__
 
231
                             O_BINARY | O_TRUNC | O_SEQUENTIAL |
 
232
                             O_SHORT_LIVED |
 
233
#endif /* __WIN__ */
 
234
                             O_CREAT | O_EXCL | O_RDWR | O_TEMPORARY,
 
235
                             MYF(MY_WME));
 
236
  if (fd >= 0) {
 
237
#ifndef __WIN__
 
238
    /*
 
239
      This can be removed once the following bug is fixed:
 
240
      Bug #28903  create_temp_file() doesn't honor O_TEMPORARY option
 
241
                  (file not removed) (Unix)
 
242
    */
 
243
    unlink(filename);
 
244
#endif /* !__WIN__ */
 
245
  }
 
246
 
 
247
  return fd;
 
248
}
 
249
 
 
250
 
 
251
extern "C"
 
252
int thd_in_lock_tables(const THD *thd)
 
253
{
 
254
  return test(thd->in_lock_tables);
 
255
}
 
256
 
 
257
 
 
258
extern "C"
 
259
int thd_tablespace_op(const THD *thd)
 
260
{
 
261
  return test(thd->tablespace_op);
 
262
}
 
263
 
 
264
 
 
265
extern "C"
 
266
const char *set_thd_proc_info(THD *thd, const char *info, 
 
267
                              const char *calling_function, 
 
268
                              const char *calling_file, 
 
269
                              const unsigned int calling_line)
 
270
{
 
271
  const char *old_info= thd->proc_info;
 
272
  DBUG_PRINT("proc_info", ("%s:%d  %s", calling_file, calling_line, 
 
273
                           (info != NULL) ? info : "(null)"));
 
274
#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
 
275
  thd->profiling.status_change(info, calling_function, calling_file, calling_line);
 
276
#endif
 
277
  thd->proc_info= info;
 
278
  return old_info;
 
279
}
 
280
 
 
281
extern "C"
 
282
void **thd_ha_data(const THD *thd, const struct handlerton *hton)
 
283
{
 
284
  return (void **) &thd->ha_data[hton->slot].ha_ptr;
 
285
}
 
286
 
 
287
extern "C"
 
288
long long thd_test_options(const THD *thd, long long test_options)
 
289
{
 
290
  return thd->options & test_options;
 
291
}
 
292
 
 
293
extern "C"
 
294
int thd_sql_command(const THD *thd)
 
295
{
 
296
  return (int) thd->lex->sql_command;
 
297
}
 
298
 
 
299
extern "C"
 
300
int thd_tx_isolation(const THD *thd)
 
301
{
 
302
  return (int) thd->variables.tx_isolation;
 
303
}
 
304
 
 
305
extern "C"
 
306
void thd_inc_row_count(THD *thd)
 
307
{
 
308
  thd->row_count++;
 
309
}
 
310
 
 
311
 
 
312
/**
 
313
  Dumps a text description of a thread, its security context
 
314
  (user, host) and the current query.
 
315
 
 
316
  @param thd thread context
 
317
  @param buffer pointer to preferred result buffer
 
318
  @param length length of buffer
 
319
  @param max_query_len how many chars of query to copy (0 for all)
 
320
 
 
321
  @req LOCK_thread_count
 
322
  
 
323
  @note LOCK_thread_count mutex is not necessary when the function is invoked on
 
324
   the currently running thread (current_thd) or if the caller in some other
 
325
   way guarantees that access to thd->query is serialized.
 
326
 
 
327
  @return Pointer to string
 
328
*/
 
329
 
 
330
extern "C"
 
331
char *thd_security_context(THD *thd, char *buffer, unsigned int length,
 
332
                           unsigned int max_query_len)
 
333
{
 
334
  String str(buffer, length, &my_charset_latin1);
 
335
  const Security_context *sctx= &thd->main_security_ctx;
 
336
  char header[64];
 
337
  int len;
 
338
  /*
 
339
    The pointers thd->query and thd->proc_info might change since they are
 
340
    being modified concurrently. This is acceptable for proc_info since its
 
341
    values doesn't have to very accurate and the memory it points to is static,
 
342
    but we need to attempt a snapshot on the pointer values to avoid using NULL
 
343
    values. The pointer to thd->query however, doesn't point to static memory
 
344
    and has to be protected by LOCK_thread_count or risk pointing to
 
345
    uninitialized memory.
 
346
  */
 
347
  const char *proc_info= thd->proc_info;
 
348
 
 
349
  len= my_snprintf(header, sizeof(header),
 
350
                   "MySQL thread id %lu, query id %lu",
 
351
                   thd->thread_id, (ulong) thd->query_id);
 
352
  str.length(0);
 
353
  str.append(header, len);
 
354
 
 
355
  if (sctx->host)
 
356
  {
 
357
    str.append(' ');
 
358
    str.append(sctx->host);
 
359
  }
 
360
 
 
361
  if (sctx->ip)
 
362
  {
 
363
    str.append(' ');
 
364
    str.append(sctx->ip);
 
365
  }
 
366
 
 
367
  if (sctx->user)
 
368
  {
 
369
    str.append(' ');
 
370
    str.append(sctx->user);
 
371
  }
 
372
 
 
373
  if (proc_info)
 
374
  {
 
375
    str.append(' ');
 
376
    str.append(proc_info);
 
377
  }
 
378
 
 
379
  pthread_mutex_lock(&thd->LOCK_thd_data);
 
380
 
 
381
  if (thd->query())
 
382
  {
 
383
    if (max_query_len < 1)
 
384
      len= thd->query_length();
 
385
    else
 
386
      len= min(thd->query_length(), max_query_len);
 
387
    str.append('\n');
 
388
    str.append(thd->query(), len);
 
389
  }
 
390
 
 
391
  pthread_mutex_unlock(&thd->LOCK_thd_data);
 
392
 
 
393
  if (str.c_ptr_safe() == buffer)
 
394
    return buffer;
 
395
 
 
396
  /*
 
397
    We have to copy the new string to the destination buffer because the string
 
398
    was reallocated to a larger buffer to be able to fit.
 
399
  */
 
400
  DBUG_ASSERT(buffer != NULL);
 
401
  length= min(str.length(), length-1);
 
402
  memcpy(buffer, str.c_ptr_quick(), length);
 
403
  /* Make sure that the new string is null terminated */
 
404
  buffer[length]= '\0';
 
405
  return buffer;
 
406
}
 
407
 
 
408
 
 
409
/**
 
410
  Implementation of Drop_table_error_handler::handle_error().
 
411
  The reason in having this implementation is to silence technical low-level
 
412
  warnings during DROP TABLE operation. Currently we don't want to expose
 
413
  the following warnings during DROP TABLE:
 
414
    - Some of table files are missed or invalid (the table is going to be
 
415
      deleted anyway, so why bother that something was missed);
 
416
    - A trigger associated with the table does not have DEFINER (One of the
 
417
      MySQL specifics now is that triggers are loaded for the table being
 
418
      dropped. So, we may have a warning that trigger does not have DEFINER
 
419
      attribute during DROP TABLE operation).
 
420
 
 
421
  @return TRUE if the condition is handled.
 
422
*/
 
423
bool Drop_table_error_handler::handle_error(uint sql_errno,
 
424
                                            const char *message,
 
425
                                            MYSQL_ERROR::enum_warning_level level,
 
426
                                            THD *thd)
 
427
{
 
428
  return ((sql_errno == EE_DELETE && my_errno == ENOENT) ||
 
429
          sql_errno == ER_TRG_NO_DEFINER);
 
430
}
 
431
 
 
432
 
 
433
/**
 
434
  Clear this diagnostics area. 
 
435
 
 
436
  Normally called at the end of a statement.
 
437
*/
 
438
 
 
439
void
 
440
Diagnostics_area::reset_diagnostics_area()
 
441
{
 
442
#ifdef DBUG_OFF
 
443
  can_overwrite_status= FALSE;
 
444
  /** Don't take chances in production */
 
445
  m_message[0]= '\0';
 
446
  m_sql_errno= 0;
 
447
  m_server_status= 0;
 
448
  m_affected_rows= 0;
 
449
  m_last_insert_id= 0;
 
450
  m_total_warn_count= 0;
 
451
#endif
 
452
  is_sent= FALSE;
 
453
  /** Tiny reset in debug mode to see garbage right away */
 
454
  m_status= DA_EMPTY;
 
455
}
 
456
 
 
457
 
 
458
/**
 
459
  Set OK status -- ends commands that do not return a
 
460
  result set, e.g. INSERT/UPDATE/DELETE.
 
461
*/
 
462
 
 
463
void
 
464
Diagnostics_area::set_ok_status(THD *thd, ha_rows affected_rows_arg,
 
465
                                ulonglong last_insert_id_arg,
 
466
                                const char *message_arg)
 
467
{
 
468
  DBUG_ASSERT(! is_set());
 
469
#ifdef DBUG_OFF
 
470
  /*
 
471
    In production, refuse to overwrite an error or a custom response
 
472
    with an OK packet.
 
473
  */
 
474
  if (is_error() || is_disabled())
 
475
    return;
 
476
#endif
 
477
  /** Only allowed to report success if has not yet reported an error */
 
478
 
 
479
  m_server_status= thd->server_status;
 
480
  m_total_warn_count= thd->total_warn_count;
 
481
  m_affected_rows= affected_rows_arg;
 
482
  m_last_insert_id= last_insert_id_arg;
 
483
  if (message_arg)
 
484
    strmake(m_message, message_arg, sizeof(m_message) - 1);
 
485
  else
 
486
    m_message[0]= '\0';
 
487
  m_status= DA_OK;
 
488
}
 
489
 
 
490
 
 
491
/**
 
492
  Set EOF status.
 
493
*/
 
494
 
 
495
void
 
496
Diagnostics_area::set_eof_status(THD *thd)
 
497
{
 
498
  /** Only allowed to report eof if has not yet reported an error */
 
499
 
 
500
  DBUG_ASSERT(! is_set());
 
501
#ifdef DBUG_OFF
 
502
  /*
 
503
    In production, refuse to overwrite an error or a custom response
 
504
    with an EOF packet.
 
505
  */
 
506
  if (is_error() || is_disabled())
 
507
    return;
 
508
#endif
 
509
 
 
510
  m_server_status= thd->server_status;
 
511
  /*
 
512
    If inside a stored procedure, do not return the total
 
513
    number of warnings, since they are not available to the client
 
514
    anyway.
 
515
  */
 
516
  m_total_warn_count= thd->spcont ? 0 : thd->total_warn_count;
 
517
 
 
518
  m_status= DA_EOF;
 
519
}
 
520
 
 
521
/**
 
522
  Set ERROR status.
 
523
*/
 
524
 
 
525
void
 
526
Diagnostics_area::set_error_status(THD *thd, uint sql_errno_arg,
 
527
                                   const char *message_arg)
 
528
{
 
529
  /*
 
530
    Only allowed to report error if has not yet reported a success
 
531
    The only exception is when we flush the message to the client,
 
532
    an error can happen during the flush.
 
533
  */
 
534
  DBUG_ASSERT(! is_set() || can_overwrite_status);
 
535
#ifdef DBUG_OFF
 
536
  /*
 
537
    In production, refuse to overwrite a custom response with an
 
538
    ERROR packet.
 
539
  */
 
540
  if (is_disabled())
 
541
    return;
 
542
#endif
 
543
 
 
544
  m_sql_errno= sql_errno_arg;
 
545
  strmake(m_message, message_arg, sizeof(m_message) - 1);
 
546
 
 
547
  m_status= DA_ERROR;
 
548
}
 
549
 
 
550
 
 
551
/**
 
552
  Mark the diagnostics area as 'DISABLED'.
 
553
 
 
554
  This is used in rare cases when the COM_ command at hand sends a response
 
555
  in a custom format. One example is the query cache, another is
 
556
  COM_STMT_PREPARE.
 
557
*/
 
558
 
 
559
void
 
560
Diagnostics_area::disable_status()
 
561
{
 
562
  DBUG_ASSERT(! is_set());
 
563
  m_status= DA_DISABLED;
 
564
}
 
565
 
 
566
 
 
567
THD::THD()
 
568
   :Statement(&main_lex, &main_mem_root, CONVENTIONAL_EXECUTION,
 
569
              /* statement id */ 0),
 
570
   Open_tables_state(refresh_version), rli_fake(0),
 
571
   lock_id(&main_lock_id),
 
572
   user_time(0), in_sub_stmt(0),
 
573
   sql_log_bin_toplevel(false),
 
574
   binlog_table_maps(0), binlog_flags(0UL),
 
575
   table_map_for_update(0),
 
576
   arg_of_last_insert_id_function(FALSE),
 
577
   first_successful_insert_id_in_prev_stmt(0),
 
578
   first_successful_insert_id_in_prev_stmt_for_binlog(0),
 
579
   first_successful_insert_id_in_cur_stmt(0),
 
580
   stmt_depends_on_first_successful_insert_id_in_prev_stmt(FALSE),
 
581
   examined_row_count(0),
 
582
   global_read_lock(0),
 
583
   is_fatal_error(0),
 
584
   transaction_rollback_request(0),
 
585
   is_fatal_sub_stmt_error(0),
 
586
   rand_used(0),
 
587
   time_zone_used(0),
 
588
   in_lock_tables(0),
 
589
   bootstrap(0),
 
590
   derived_tables_processing(FALSE),
 
591
   spcont(NULL),
 
592
   m_parser_state(NULL)
 
593
#if defined(ENABLED_DEBUG_SYNC)
 
594
   , debug_sync_control(0)
 
595
#endif /* defined(ENABLED_DEBUG_SYNC) */
 
596
{
 
597
  ulong tmp;
 
598
 
 
599
  /*
 
600
    Pass nominal parameters to init_alloc_root only to ensure that
 
601
    the destructor works OK in case of an error. The main_mem_root
 
602
    will be re-initialized in init_for_queries().
 
603
  */
 
604
  init_sql_alloc(&main_mem_root, ALLOC_ROOT_MIN_BLOCK_SIZE, 0);
 
605
  stmt_arena= this;
 
606
  thread_stack= 0;
 
607
  catalog= (char*)"std"; // the only catalog we have for now
 
608
  main_security_ctx.init();
 
609
  security_ctx= &main_security_ctx;
 
610
  locked=some_tables_deleted=no_errors=password= 0;
 
611
  query_start_used= 0;
 
612
  count_cuted_fields= CHECK_FIELD_IGNORE;
 
613
  killed= NOT_KILLED;
 
614
  col_access=0;
 
615
  is_slave_error= thread_specific_used= FALSE;
 
616
  hash_clear(&handler_tables_hash);
 
617
  tmp_table=0;
 
618
  used_tables=0;
 
619
  cuted_fields= sent_row_count= row_count= 0L;
 
620
  limit_found_rows= 0;
 
621
  row_count_func= -1;
 
622
  statement_id_counter= 0UL;
 
623
#ifdef ERROR_INJECT_SUPPORT
 
624
  error_inject_value= 0UL;
 
625
#endif
 
626
  // Must be reset to handle error with THD's created for init of mysqld
 
627
  lex->current_select= 0;
 
628
  start_time=(time_t) 0;
 
629
  start_utime= prior_thr_create_utime= 0L;
 
630
  utime_after_lock= 0L;
 
631
  current_linfo =  0;
 
632
  slave_thread = 0;
 
633
  bzero(&variables, sizeof(variables));
 
634
  thread_id= 0;
 
635
  one_shot_set= 0;
 
636
  file_id = 0;
 
637
  query_id= 0;
 
638
  query_name_consts= 0;
 
639
  warn_id= 0;
 
640
  db_charset= global_system_variables.collation_database;
 
641
  bzero(ha_data, sizeof(ha_data));
 
642
  mysys_var=0;
 
643
  binlog_evt_union.do_union= FALSE;
 
644
  enable_slow_log= 0;
 
645
#ifndef DBUG_OFF
 
646
  dbug_sentry=THD_SENTRY_MAGIC;
 
647
#endif
 
648
#ifndef EMBEDDED_LIBRARY
 
649
  net.vio=0;
 
650
#endif
 
651
  client_capabilities= 0;                       // minimalistic client
 
652
#ifdef HAVE_QUERY_CACHE
 
653
  query_cache_init_query(&net);                 // If error on boot
 
654
#endif
 
655
  ull=0;
 
656
  system_thread= NON_SYSTEM_THREAD;
 
657
  cleanup_done= abort_on_warning= no_warnings_for_error= 0;
 
658
  peer_port= 0;                                 // For SHOW PROCESSLIST
 
659
  transaction.m_pending_rows_event= 0;
 
660
  transaction.on= 1;
 
661
#ifdef SIGNAL_WITH_VIO_CLOSE
 
662
  active_vio = 0;
 
663
#endif
 
664
  pthread_mutex_init(&LOCK_thd_data, MY_MUTEX_INIT_FAST);
 
665
 
 
666
  /* Variables with default values */
 
667
  proc_info="login";
 
668
  where= THD::DEFAULT_WHERE;
 
669
  server_id = ::server_id;
 
670
  slave_net = 0;
 
671
  command=COM_CONNECT;
 
672
  *scramble= '\0';
 
673
 
 
674
  init();
 
675
  /* Initialize sub structures */
 
676
  init_sql_alloc(&warn_root, WARN_ALLOC_BLOCK_SIZE, WARN_ALLOC_PREALLOC_SIZE);
 
677
#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
 
678
  profiling.set_thd(this);
 
679
#endif
 
680
  user_connect=(USER_CONN *)0;
 
681
  hash_init(&user_vars, system_charset_info, USER_VARS_HASH_SIZE, 0, 0,
 
682
            (hash_get_key) get_var_key,
 
683
            (hash_free_key) free_user_var, 0);
 
684
 
 
685
  sp_proc_cache= NULL;
 
686
  sp_func_cache= NULL;
 
687
 
 
688
  /* For user vars replication*/
 
689
  if (opt_bin_log)
 
690
    my_init_dynamic_array(&user_var_events,
 
691
                          sizeof(BINLOG_USER_VAR_EVENT *), 16, 16);
 
692
  else
 
693
    bzero((char*) &user_var_events, sizeof(user_var_events));
 
694
 
 
695
  /* Protocol */
 
696
  protocol= &protocol_text;                     // Default protocol
 
697
  protocol_text.init(this);
 
698
  protocol_binary.init(this);
 
699
 
 
700
  tablespace_op=FALSE;
 
701
  tmp= sql_rnd_with_mutex();
 
702
  randominit(&rand, tmp + (ulong) &rand, tmp + (ulong) ::global_query_id);
 
703
  substitute_null_with_insert_id = FALSE;
 
704
  thr_lock_info_init(&lock_info); /* safety: will be reset after start */
 
705
  thr_lock_owner_init(&main_lock_id, &lock_info);
 
706
 
 
707
  m_internal_handler= NULL;
 
708
}
 
709
 
 
710
 
 
711
void THD::push_internal_handler(Internal_error_handler *handler)
 
712
{
 
713
  if (m_internal_handler)
 
714
  {
 
715
    handler->m_prev_internal_handler= m_internal_handler;
 
716
    m_internal_handler= handler;
 
717
  }
 
718
  else
 
719
  {
 
720
    m_internal_handler= handler;
 
721
  }
 
722
}
 
723
 
 
724
 
 
725
bool THD::handle_error(uint sql_errno, const char *message,
 
726
                       MYSQL_ERROR::enum_warning_level level)
 
727
{
 
728
  for (Internal_error_handler *error_handler= m_internal_handler;
 
729
       error_handler;
 
730
       error_handler= error_handler->m_prev_internal_handler)
 
731
  {
 
732
    if (error_handler->handle_error(sql_errno, message, level, this))
 
733
      return TRUE;
 
734
  }
 
735
 
 
736
  return FALSE;
 
737
}
 
738
 
 
739
 
 
740
Internal_error_handler *THD::pop_internal_handler()
 
741
{
 
742
  DBUG_ASSERT(m_internal_handler != NULL);
 
743
  Internal_error_handler *popped_handler= m_internal_handler;
 
744
  m_internal_handler= m_internal_handler->m_prev_internal_handler;
 
745
  return popped_handler;
 
746
}
 
747
 
 
748
extern "C"
 
749
void *thd_alloc(MYSQL_THD thd, unsigned int size)
 
750
{
 
751
  return thd->alloc(size);
 
752
}
 
753
 
 
754
extern "C"
 
755
void *thd_calloc(MYSQL_THD thd, unsigned int size)
 
756
{
 
757
  return thd->calloc(size);
 
758
}
 
759
 
 
760
extern "C"
 
761
char *thd_strdup(MYSQL_THD thd, const char *str)
 
762
{
 
763
  return thd->strdup(str);
 
764
}
 
765
 
 
766
extern "C"
 
767
char *thd_strmake(MYSQL_THD thd, const char *str, unsigned int size)
 
768
{
 
769
  return thd->strmake(str, size);
 
770
}
 
771
 
 
772
extern "C"
 
773
LEX_STRING *thd_make_lex_string(THD *thd, LEX_STRING *lex_str,
 
774
                                const char *str, unsigned int size,
 
775
                                int allocate_lex_string)
 
776
{
 
777
  return thd->make_lex_string(lex_str, str, size,
 
778
                              (bool) allocate_lex_string);
 
779
}
 
780
 
 
781
extern "C"
 
782
void *thd_memdup(MYSQL_THD thd, const void* str, unsigned int size)
 
783
{
 
784
  return thd->memdup(str, size);
 
785
}
 
786
 
 
787
extern "C"
 
788
void thd_get_xid(const MYSQL_THD thd, MYSQL_XID *xid)
 
789
{
 
790
  *xid = *(MYSQL_XID *) &thd->transaction.xid_state.xid;
 
791
}
 
792
 
 
793
#ifdef _WIN32
 
794
extern "C"   THD *_current_thd_noinline(void)
 
795
{
 
796
  return my_pthread_getspecific_ptr(THD*,THR_THD);
 
797
}
 
798
#endif
 
799
/*
 
800
  Init common variables that has to be reset on start and on change_user
 
801
*/
 
802
 
 
803
void THD::init(void)
 
804
{
 
805
  pthread_mutex_lock(&LOCK_global_system_variables);
 
806
  plugin_thdvar_init(this);
 
807
  variables.time_format= date_time_format_copy((THD*) 0,
 
808
                                               variables.time_format);
 
809
  variables.date_format= date_time_format_copy((THD*) 0,
 
810
                                               variables.date_format);
 
811
  variables.datetime_format= date_time_format_copy((THD*) 0,
 
812
                                                   variables.datetime_format);
 
813
  /*
 
814
    variables= global_system_variables above has reset
 
815
    variables.pseudo_thread_id to 0. We need to correct it here to
 
816
    avoid temporary tables replication failure.
 
817
  */
 
818
  variables.pseudo_thread_id= thread_id;
 
819
  pthread_mutex_unlock(&LOCK_global_system_variables);
 
820
  server_status= SERVER_STATUS_AUTOCOMMIT;
 
821
  if (variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES)
 
822
    server_status|= SERVER_STATUS_NO_BACKSLASH_ESCAPES;
 
823
  options= thd_startup_options;
 
824
 
 
825
  if (variables.max_join_size == HA_POS_ERROR)
 
826
    options |= OPTION_BIG_SELECTS;
 
827
  else
 
828
    options &= ~OPTION_BIG_SELECTS;
 
829
 
 
830
  transaction.all.modified_non_trans_table= transaction.stmt.modified_non_trans_table= FALSE;
 
831
  open_options=ha_open_options;
 
832
  update_lock_default= (variables.low_priority_updates ?
 
833
                        TL_WRITE_LOW_PRIORITY :
 
834
                        TL_WRITE);
 
835
  session_tx_isolation= (enum_tx_isolation) variables.tx_isolation;
 
836
  warn_list.empty();
 
837
  bzero((char*) warn_count, sizeof(warn_count));
 
838
  total_warn_count= 0;
 
839
  update_charset();
 
840
  reset_current_stmt_binlog_row_based();
 
841
  bzero((char *) &status_var, sizeof(status_var));
 
842
  sql_log_bin_toplevel= options & OPTION_BIN_LOG;
 
843
 
 
844
#if defined(ENABLED_DEBUG_SYNC)
 
845
  /* Initialize the Debug Sync Facility. See debug_sync.cc. */
 
846
  debug_sync_init_thread(this);
 
847
#endif /* defined(ENABLED_DEBUG_SYNC) */
 
848
}
 
849
 
 
850
 
 
851
/*
 
852
  Init THD for query processing.
 
853
  This has to be called once before we call mysql_parse.
 
854
  See also comments in sql_class.h.
 
855
*/
 
856
 
 
857
void THD::init_for_queries()
 
858
{
 
859
  set_time(); 
 
860
  ha_enable_transaction(this,TRUE);
 
861
 
 
862
  reset_root_defaults(mem_root, variables.query_alloc_block_size,
 
863
                      variables.query_prealloc_size);
 
864
#ifdef USING_TRANSACTIONS
 
865
  reset_root_defaults(&transaction.mem_root,
 
866
                      variables.trans_alloc_block_size,
 
867
                      variables.trans_prealloc_size);
 
868
#endif
 
869
  transaction.xid_state.xid.null();
 
870
  transaction.xid_state.in_thd=1;
 
871
}
 
872
 
 
873
 
 
874
/*
 
875
  Do what's needed when one invokes change user
 
876
 
 
877
  SYNOPSIS
 
878
    change_user()
 
879
 
 
880
  IMPLEMENTATION
 
881
    Reset all resources that are connection specific
 
882
*/
 
883
 
 
884
 
 
885
void THD::change_user(void)
 
886
{
 
887
  pthread_mutex_lock(&LOCK_status);
 
888
  add_to_status(&global_status_var, &status_var);
 
889
  pthread_mutex_unlock(&LOCK_status);
 
890
 
 
891
  cleanup();
 
892
  killed= NOT_KILLED;
 
893
  cleanup_done= 0;
 
894
  init();
 
895
  stmt_map.reset();
 
896
  hash_init(&user_vars, system_charset_info, USER_VARS_HASH_SIZE, 0, 0,
 
897
            (hash_get_key) get_var_key,
 
898
            (hash_free_key) free_user_var, 0);
 
899
  sp_cache_clear(&sp_proc_cache);
 
900
  sp_cache_clear(&sp_func_cache);
 
901
}
 
902
 
 
903
 
 
904
/* Do operations that may take a long time */
 
905
 
 
906
void THD::cleanup(void)
 
907
{
 
908
  DBUG_ENTER("THD::cleanup");
 
909
  DBUG_ASSERT(cleanup_done == 0);
 
910
 
 
911
  killed= KILL_CONNECTION;
 
912
#ifdef ENABLE_WHEN_BINLOG_WILL_BE_ABLE_TO_PREPARE
 
913
  if (transaction.xid_state.xa_state == XA_PREPARED)
 
914
  {
 
915
#error xid_state in the cache should be replaced by the allocated value
 
916
  }
 
917
#endif
 
918
  {
 
919
    ha_rollback(this);
 
920
    xid_cache_delete(&transaction.xid_state);
 
921
  }
 
922
  if (locked_tables)
 
923
  {
 
924
    lock=locked_tables; locked_tables=0;
 
925
    close_thread_tables(this);
 
926
  }
 
927
 
 
928
#if defined(ENABLED_DEBUG_SYNC)
 
929
  /* End the Debug Sync Facility. See debug_sync.cc. */
 
930
  debug_sync_end_thread(this);
 
931
#endif /* defined(ENABLED_DEBUG_SYNC) */
 
932
 
 
933
  mysql_ha_cleanup(this);
 
934
  delete_dynamic(&user_var_events);
 
935
  hash_free(&user_vars);
 
936
  close_temporary_tables(this);
 
937
  my_free((char*) variables.time_format, MYF(MY_ALLOW_ZERO_PTR));
 
938
  my_free((char*) variables.date_format, MYF(MY_ALLOW_ZERO_PTR));
 
939
  my_free((char*) variables.datetime_format, MYF(MY_ALLOW_ZERO_PTR));
 
940
  
 
941
  sp_cache_clear(&sp_proc_cache);
 
942
  sp_cache_clear(&sp_func_cache);
 
943
 
 
944
  if (global_read_lock)
 
945
    unlock_global_read_lock(this);
 
946
  if (ull)
 
947
  {
 
948
    pthread_mutex_lock(&LOCK_user_locks);
 
949
    item_user_lock_release(ull);
 
950
    pthread_mutex_unlock(&LOCK_user_locks);
 
951
    ull= NULL;
 
952
  }
 
953
 
 
954
  cleanup_done=1;
 
955
  DBUG_VOID_RETURN;
 
956
}
 
957
 
 
958
 
 
959
THD::~THD()
 
960
{
 
961
  THD_CHECK_SENTRY(this);
 
962
  DBUG_ENTER("~THD()");
 
963
  /* Ensure that no one is using THD */
 
964
  pthread_mutex_lock(&LOCK_thd_data);
 
965
  pthread_mutex_unlock(&LOCK_thd_data);
 
966
  add_to_status(&global_status_var, &status_var);
 
967
 
 
968
  /* Close connection */
 
969
#ifndef EMBEDDED_LIBRARY
 
970
  if (net.vio)
 
971
  {
 
972
    vio_delete(net.vio);
 
973
    net_end(&net);
 
974
  }
 
975
#endif
 
976
  stmt_map.reset();                     /* close all prepared statements */
 
977
  DBUG_ASSERT(lock_info.n_cursors == 0);
 
978
  if (!cleanup_done)
 
979
    cleanup();
 
980
 
 
981
  ha_close_connection(this);
 
982
  plugin_thdvar_cleanup(this);
 
983
 
 
984
  DBUG_PRINT("info", ("freeing security context"));
 
985
  main_security_ctx.destroy();
 
986
  safeFree(db);
 
987
  free_root(&warn_root,MYF(0));
 
988
#ifdef USING_TRANSACTIONS
 
989
  free_root(&transaction.mem_root,MYF(0));
 
990
#endif
 
991
  mysys_var=0;                                  // Safety (shouldn't be needed)
 
992
  pthread_mutex_destroy(&LOCK_thd_data);
 
993
#ifndef DBUG_OFF
 
994
  dbug_sentry= THD_SENTRY_GONE;
 
995
#endif  
 
996
#ifndef EMBEDDED_LIBRARY
 
997
  if (rli_fake)
 
998
  {
 
999
    delete rli_fake;
 
1000
    rli_fake= NULL;
 
1001
  }
 
1002
#endif
 
1003
 
 
1004
  free_root(&main_mem_root, MYF(0));
 
1005
  DBUG_VOID_RETURN;
 
1006
}
 
1007
 
 
1008
 
 
1009
/*
 
1010
  Add all status variables to another status variable array
 
1011
 
 
1012
  SYNOPSIS
 
1013
   add_to_status()
 
1014
   to_var       add to this array
 
1015
   from_var     from this array
 
1016
 
 
1017
  NOTES
 
1018
    This function assumes that all variables are long/ulong.
 
1019
    If this assumption will change, then we have to explictely add
 
1020
    the other variables after the while loop
 
1021
*/
 
1022
 
 
1023
void add_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var)
 
1024
{
 
1025
  ulong *end= (ulong*) ((uchar*) to_var +
 
1026
                        offsetof(STATUS_VAR, last_system_status_var) +
 
1027
                        sizeof(ulong));
 
1028
  ulong *to= (ulong*) to_var, *from= (ulong*) from_var;
 
1029
 
 
1030
  while (to != end)
 
1031
    *(to++)+= *(from++);
 
1032
}
 
1033
 
 
1034
/*
 
1035
  Add the difference between two status variable arrays to another one.
 
1036
 
 
1037
  SYNOPSIS
 
1038
    add_diff_to_status
 
1039
    to_var       add to this array
 
1040
    from_var     from this array
 
1041
    dec_var      minus this array
 
1042
  
 
1043
  NOTE
 
1044
    This function assumes that all variables are long/ulong.
 
1045
*/
 
1046
 
 
1047
void add_diff_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var,
 
1048
                        STATUS_VAR *dec_var)
 
1049
{
 
1050
  ulong *end= (ulong*) ((uchar*) to_var + offsetof(STATUS_VAR,
 
1051
                                                  last_system_status_var) +
 
1052
                        sizeof(ulong));
 
1053
  ulong *to= (ulong*) to_var, *from= (ulong*) from_var, *dec= (ulong*) dec_var;
 
1054
 
 
1055
  while (to != end)
 
1056
    *(to++)+= *(from++) - *(dec++);
 
1057
}
 
1058
 
 
1059
 
 
1060
void THD::awake(THD::killed_state state_to_set)
 
1061
{
 
1062
  DBUG_ENTER("THD::awake");
 
1063
  DBUG_PRINT("enter", ("this: 0x%lx", (long) this));
 
1064
  THD_CHECK_SENTRY(this);
 
1065
  safe_mutex_assert_owner(&LOCK_thd_data);
 
1066
 
 
1067
  killed= state_to_set;
 
1068
  if (state_to_set != THD::KILL_QUERY)
 
1069
  {
 
1070
    thr_alarm_kill(thread_id);
 
1071
    if (!slave_thread)
 
1072
      thread_scheduler.post_kill_notification(this);
 
1073
#ifdef SIGNAL_WITH_VIO_CLOSE
 
1074
    if (this != current_thd)
 
1075
    {
 
1076
      /*
 
1077
        In addition to a signal, let's close the socket of the thread that
 
1078
        is being killed. This is to make sure it does not block if the
 
1079
        signal is lost. This needs to be done only on platforms where
 
1080
        signals are not a reliable interruption mechanism.
 
1081
 
 
1082
        If we're killing ourselves, we know that we're not blocked, so this
 
1083
        hack is not used.
 
1084
      */
 
1085
 
 
1086
      close_active_vio();
 
1087
    }
 
1088
#endif    
 
1089
  }
 
1090
  if (mysys_var)
 
1091
  {
 
1092
    pthread_mutex_lock(&mysys_var->mutex);
 
1093
    if (!system_thread)         // Don't abort locks
 
1094
      mysys_var->abort=1;
 
1095
    /*
 
1096
      This broadcast could be up in the air if the victim thread
 
1097
      exits the cond in the time between read and broadcast, but that is
 
1098
      ok since all we want to do is to make the victim thread get out
 
1099
      of waiting on current_cond.
 
1100
      If we see a non-zero current_cond: it cannot be an old value (because
 
1101
      then exit_cond() should have run and it can't because we have mutex); so
 
1102
      it is the true value but maybe current_mutex is not yet non-zero (we're
 
1103
      in the middle of enter_cond() and there is a "memory order
 
1104
      inversion"). So we test the mutex too to not lock 0.
 
1105
 
 
1106
      Note that there is a small chance we fail to kill. If victim has locked
 
1107
      current_mutex, but hasn't yet entered enter_cond() (which means that
 
1108
      current_cond and current_mutex are 0), then the victim will not get
 
1109
      a signal and it may wait "forever" on the cond (until
 
1110
      we issue a second KILL or the status it's waiting for happens).
 
1111
      It's true that we have set its thd->killed but it may not
 
1112
      see it immediately and so may have time to reach the cond_wait().
 
1113
    */
 
1114
    if (mysys_var->current_cond && mysys_var->current_mutex)
 
1115
    {
 
1116
      pthread_mutex_lock(mysys_var->current_mutex);
 
1117
      pthread_cond_broadcast(mysys_var->current_cond);
 
1118
      pthread_mutex_unlock(mysys_var->current_mutex);
 
1119
    }
 
1120
    pthread_mutex_unlock(&mysys_var->mutex);
 
1121
  }
 
1122
  DBUG_VOID_RETURN;
 
1123
}
 
1124
 
 
1125
/*
 
1126
  Remember the location of thread info, the structure needed for
 
1127
  sql_alloc() and the structure for the net buffer
 
1128
*/
 
1129
 
 
1130
bool THD::store_globals()
 
1131
{
 
1132
  /*
 
1133
    Assert that thread_stack is initialized: it's necessary to be able
 
1134
    to track stack overrun.
 
1135
  */
 
1136
  DBUG_ASSERT(thread_stack);
 
1137
 
 
1138
  if (my_pthread_setspecific_ptr(THR_THD,  this) ||
 
1139
      my_pthread_setspecific_ptr(THR_MALLOC, &mem_root))
 
1140
    return 1;
 
1141
  mysys_var=my_thread_var;
 
1142
  /*
 
1143
    Let mysqld define the thread id (not mysys)
 
1144
    This allows us to move THD to different threads if needed.
 
1145
  */
 
1146
  mysys_var->id= thread_id;
 
1147
  real_id= pthread_self();                      // For debugging
 
1148
 
 
1149
  /*
 
1150
    We have to call thr_lock_info_init() again here as THD may have been
 
1151
    created in another thread
 
1152
  */
 
1153
  thr_lock_info_init(&lock_info);
 
1154
  return 0;
 
1155
}
 
1156
 
 
1157
 
 
1158
/*
 
1159
  Cleanup after query.
 
1160
 
 
1161
  SYNOPSIS
 
1162
    THD::cleanup_after_query()
 
1163
 
 
1164
  DESCRIPTION
 
1165
    This function is used to reset thread data to its default state.
 
1166
 
 
1167
  NOTE
 
1168
    This function is not suitable for setting thread data to some
 
1169
    non-default values, as there is only one replication thread, so
 
1170
    different master threads may overwrite data of each other on
 
1171
    slave.
 
1172
*/
 
1173
 
 
1174
void THD::cleanup_after_query()
 
1175
{
 
1176
  /*
 
1177
    Reset rand_used so that detection of calls to rand() will save random 
 
1178
    seeds if needed by the slave.
 
1179
 
 
1180
    Do not reset rand_used if inside a stored function or trigger because 
 
1181
    only the call to these operations is logged. Thus only the calling 
 
1182
    statement needs to detect rand() calls made by its substatements. These
 
1183
    substatements must not set rand_used to 0 because it would remove the
 
1184
    detection of rand() by the calling statement. 
 
1185
  */
 
1186
  if (!in_sub_stmt) /* stored functions and triggers are a special case */
 
1187
  {
 
1188
    /* Forget those values, for next binlogger: */
 
1189
    stmt_depends_on_first_successful_insert_id_in_prev_stmt= 0;
 
1190
    auto_inc_intervals_in_cur_stmt_for_binlog.empty();
 
1191
    rand_used= 0;
 
1192
  }
 
1193
  if (first_successful_insert_id_in_cur_stmt > 0)
 
1194
  {
 
1195
    /* set what LAST_INSERT_ID() will return */
 
1196
    first_successful_insert_id_in_prev_stmt= 
 
1197
      first_successful_insert_id_in_cur_stmt;
 
1198
    first_successful_insert_id_in_cur_stmt= 0;
 
1199
    substitute_null_with_insert_id= TRUE;
 
1200
  }
 
1201
  arg_of_last_insert_id_function= 0;
 
1202
  /* Free Items that were created during this execution */
 
1203
  free_items();
 
1204
  /* Reset where. */
 
1205
  where= THD::DEFAULT_WHERE;
 
1206
  /* reset table map for multi-table update */
 
1207
  table_map_for_update= 0;
 
1208
}
 
1209
 
 
1210
 
 
1211
/**
 
1212
  Create a LEX_STRING in this connection.
 
1213
 
 
1214
  @param lex_str  pointer to LEX_STRING object to be initialized
 
1215
  @param str      initializer to be copied into lex_str
 
1216
  @param length   length of str, in bytes
 
1217
  @param allocate_lex_string  if TRUE, allocate new LEX_STRING object,
 
1218
                              instead of using lex_str value
 
1219
  @return  NULL on failure, or pointer to the LEX_STRING object
 
1220
*/
 
1221
LEX_STRING *THD::make_lex_string(LEX_STRING *lex_str,
 
1222
                                 const char* str, uint length,
 
1223
                                 bool allocate_lex_string)
 
1224
{
 
1225
  if (allocate_lex_string)
 
1226
    if (!(lex_str= (LEX_STRING *)alloc(sizeof(LEX_STRING))))
 
1227
      return 0;
 
1228
  if (!(lex_str->str= strmake_root(mem_root, str, length)))
 
1229
    return 0;
 
1230
  lex_str->length= length;
 
1231
  return lex_str;
 
1232
}
 
1233
 
 
1234
 
 
1235
/*
 
1236
  Convert a string to another character set
 
1237
 
 
1238
  SYNOPSIS
 
1239
    convert_string()
 
1240
    to                          Store new allocated string here
 
1241
    to_cs                       New character set for allocated string
 
1242
    from                        String to convert
 
1243
    from_length                 Length of string to convert
 
1244
    from_cs                     Original character set
 
1245
 
 
1246
  NOTES
 
1247
    to will be 0-terminated to make it easy to pass to system funcs
 
1248
 
 
1249
  RETURN
 
1250
    0   ok
 
1251
    1   End of memory.
 
1252
        In this case to->str will point to 0 and to->length will be 0.
 
1253
*/
 
1254
 
 
1255
bool THD::convert_string(LEX_STRING *to, CHARSET_INFO *to_cs,
 
1256
                         const char *from, uint from_length,
 
1257
                         CHARSET_INFO *from_cs)
 
1258
{
 
1259
  DBUG_ENTER("convert_string");
 
1260
  size_t new_length= to_cs->mbmaxlen * from_length;
 
1261
  uint dummy_errors;
 
1262
  if (!(to->str= (char*) alloc(new_length+1)))
 
1263
  {
 
1264
    to->length= 0;                              // Safety fix
 
1265
    DBUG_RETURN(1);                             // EOM
 
1266
  }
 
1267
  to->length= copy_and_convert((char*) to->str, new_length, to_cs,
 
1268
                               from, from_length, from_cs, &dummy_errors);
 
1269
  to->str[to->length]=0;                        // Safety
 
1270
  DBUG_RETURN(0);
 
1271
}
 
1272
 
 
1273
 
 
1274
/*
 
1275
  Convert string from source character set to target character set inplace.
 
1276
 
 
1277
  SYNOPSIS
 
1278
    THD::convert_string
 
1279
 
 
1280
  DESCRIPTION
 
1281
    Convert string using convert_buffer - buffer for character set 
 
1282
    conversion shared between all protocols.
 
1283
 
 
1284
  RETURN
 
1285
    0   ok
 
1286
   !0   out of memory
 
1287
*/
 
1288
 
 
1289
bool THD::convert_string(String *s, CHARSET_INFO *from_cs, CHARSET_INFO *to_cs)
 
1290
{
 
1291
  uint dummy_errors;
 
1292
  if (convert_buffer.copy(s->ptr(), s->length(), from_cs, to_cs, &dummy_errors))
 
1293
    return TRUE;
 
1294
  /* If convert_buffer >> s copying is more efficient long term */
 
1295
  if (convert_buffer.alloced_length() >= convert_buffer.length() * 2 ||
 
1296
      !s->is_alloced())
 
1297
  {
 
1298
    return s->copy(convert_buffer);
 
1299
  }
 
1300
  s->swap(convert_buffer);
 
1301
  return FALSE;
 
1302
}
 
1303
 
 
1304
 
 
1305
/*
 
1306
  Update some cache variables when character set changes
 
1307
*/
 
1308
 
 
1309
void THD::update_charset()
 
1310
{
 
1311
  uint32 not_used;
 
1312
  charset_is_system_charset= !String::needs_conversion(0,charset(),
 
1313
                                                       system_charset_info,
 
1314
                                                       &not_used);
 
1315
  charset_is_collation_connection= 
 
1316
    !String::needs_conversion(0,charset(),variables.collation_connection,
 
1317
                              &not_used);
 
1318
  charset_is_character_set_filesystem= 
 
1319
    !String::needs_conversion(0, charset(),
 
1320
                              variables.character_set_filesystem, &not_used);
 
1321
}
 
1322
 
 
1323
 
 
1324
/* routings to adding tables to list of changed in transaction tables */
 
1325
 
 
1326
inline static void list_include(CHANGED_TABLE_LIST** prev,
 
1327
                                CHANGED_TABLE_LIST* curr,
 
1328
                                CHANGED_TABLE_LIST* new_table)
 
1329
{
 
1330
  if (new_table)
 
1331
  {
 
1332
    *prev = new_table;
 
1333
    (*prev)->next = curr;
 
1334
  }
 
1335
}
 
1336
 
 
1337
/* add table to list of changed in transaction tables */
 
1338
 
 
1339
void THD::add_changed_table(TABLE *table)
 
1340
{
 
1341
  DBUG_ENTER("THD::add_changed_table(table)");
 
1342
 
 
1343
  DBUG_ASSERT((options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) &&
 
1344
              table->file->has_transactions());
 
1345
  add_changed_table(table->s->table_cache_key.str,
 
1346
                    (long) table->s->table_cache_key.length);
 
1347
  DBUG_VOID_RETURN;
 
1348
}
 
1349
 
 
1350
 
 
1351
void THD::add_changed_table(const char *key, long key_length)
 
1352
{
 
1353
  DBUG_ENTER("THD::add_changed_table(key)");
 
1354
  CHANGED_TABLE_LIST **prev_changed = &transaction.changed_tables;
 
1355
  CHANGED_TABLE_LIST *curr = transaction.changed_tables;
 
1356
 
 
1357
  for (; curr; prev_changed = &(curr->next), curr = curr->next)
 
1358
  {
 
1359
    int cmp =  (long)curr->key_length - (long)key_length;
 
1360
    if (cmp < 0)
 
1361
    {
 
1362
      list_include(prev_changed, curr, changed_table_dup(key, key_length));
 
1363
      DBUG_PRINT("info", 
 
1364
                 ("key_length: %ld  %u", key_length,
 
1365
                  (*prev_changed)->key_length));
 
1366
      DBUG_VOID_RETURN;
 
1367
    }
 
1368
    else if (cmp == 0)
 
1369
    {
 
1370
      cmp = memcmp(curr->key, key, curr->key_length);
 
1371
      if (cmp < 0)
 
1372
      {
 
1373
        list_include(prev_changed, curr, changed_table_dup(key, key_length));
 
1374
        DBUG_PRINT("info", 
 
1375
                   ("key_length:  %ld  %u", key_length,
 
1376
                    (*prev_changed)->key_length));
 
1377
        DBUG_VOID_RETURN;
 
1378
      }
 
1379
      else if (cmp == 0)
 
1380
      {
 
1381
        DBUG_PRINT("info", ("already in list"));
 
1382
        DBUG_VOID_RETURN;
 
1383
      }
 
1384
    }
 
1385
  }
 
1386
  *prev_changed = changed_table_dup(key, key_length);
 
1387
  DBUG_PRINT("info", ("key_length: %ld  %u", key_length,
 
1388
                      (*prev_changed)->key_length));
 
1389
  DBUG_VOID_RETURN;
 
1390
}
 
1391
 
 
1392
 
 
1393
CHANGED_TABLE_LIST* THD::changed_table_dup(const char *key, long key_length)
 
1394
{
 
1395
  CHANGED_TABLE_LIST* new_table = 
 
1396
    (CHANGED_TABLE_LIST*) trans_alloc(ALIGN_SIZE(sizeof(CHANGED_TABLE_LIST))+
 
1397
                                      key_length + 1);
 
1398
  if (!new_table)
 
1399
  {
 
1400
    my_error(EE_OUTOFMEMORY, MYF(ME_BELL),
 
1401
             ALIGN_SIZE(sizeof(TABLE_LIST)) + key_length + 1);
 
1402
    killed= KILL_CONNECTION;
 
1403
    return 0;
 
1404
  }
 
1405
 
 
1406
  new_table->key= ((char*)new_table)+ ALIGN_SIZE(sizeof(CHANGED_TABLE_LIST));
 
1407
  new_table->next = 0;
 
1408
  new_table->key_length = key_length;
 
1409
  ::memcpy(new_table->key, key, key_length);
 
1410
  return new_table;
 
1411
}
 
1412
 
 
1413
 
 
1414
int THD::send_explain_fields(select_result *result)
 
1415
{
 
1416
  List<Item> field_list;
 
1417
  Item *item;
 
1418
  CHARSET_INFO *cs= system_charset_info;
 
1419
  field_list.push_back(new Item_return_int("id",3, MYSQL_TYPE_LONGLONG));
 
1420
  field_list.push_back(new Item_empty_string("select_type", 19, cs));
 
1421
  field_list.push_back(item= new Item_empty_string("table", NAME_CHAR_LEN, cs));
 
1422
  item->maybe_null= 1;
 
1423
  if (lex->describe & DESCRIBE_PARTITIONS)
 
1424
  {
 
1425
    /* Maximum length of string that make_used_partitions_str() can produce */
 
1426
    item= new Item_empty_string("partitions", MAX_PARTITIONS * (1 + FN_LEN),
 
1427
                                cs);
 
1428
    field_list.push_back(item);
 
1429
    item->maybe_null= 1;
 
1430
  }
 
1431
  field_list.push_back(item= new Item_empty_string("type", 10, cs));
 
1432
  item->maybe_null= 1;
 
1433
  field_list.push_back(item=new Item_empty_string("possible_keys",
 
1434
                                                  NAME_CHAR_LEN*MAX_KEY, cs));
 
1435
  item->maybe_null=1;
 
1436
  field_list.push_back(item=new Item_empty_string("key", NAME_CHAR_LEN, cs));
 
1437
  item->maybe_null=1;
 
1438
  field_list.push_back(item=new Item_empty_string("key_len",
 
1439
                                                  NAME_CHAR_LEN*MAX_KEY));
 
1440
  item->maybe_null=1;
 
1441
  field_list.push_back(item=new Item_empty_string("ref",
 
1442
                                                  NAME_CHAR_LEN*MAX_REF_PARTS,
 
1443
                                                  cs));
 
1444
  item->maybe_null=1;
 
1445
  field_list.push_back(item= new Item_return_int("rows", 10,
 
1446
                                                 MYSQL_TYPE_LONGLONG));
 
1447
  if (lex->describe & DESCRIBE_EXTENDED)
 
1448
  {
 
1449
    field_list.push_back(item= new Item_float("filtered", 0.1234, 2, 4));
 
1450
    item->maybe_null=1;
 
1451
  }
 
1452
  item->maybe_null= 1;
 
1453
  field_list.push_back(new Item_empty_string("Extra", 255, cs));
 
1454
  return (result->send_fields(field_list,
 
1455
                              Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF));
 
1456
}
 
1457
 
 
1458
#ifdef SIGNAL_WITH_VIO_CLOSE
 
1459
void THD::close_active_vio()
 
1460
{
 
1461
  DBUG_ENTER("close_active_vio");
 
1462
  safe_mutex_assert_owner(&LOCK_thd_data);
 
1463
#ifndef EMBEDDED_LIBRARY
 
1464
  if (active_vio)
 
1465
  {
 
1466
    vio_close(active_vio);
 
1467
    active_vio = 0;
 
1468
  }
 
1469
#endif
 
1470
  DBUG_VOID_RETURN;
 
1471
}
 
1472
#endif
 
1473
 
 
1474
 
 
1475
struct Item_change_record: public ilink
 
1476
{
 
1477
  Item **place;
 
1478
  Item *old_value;
 
1479
  /* Placement new was hidden by `new' in ilink (TODO: check): */
 
1480
  static void *operator new(size_t size, void *mem) { return mem; }
 
1481
  static void operator delete(void *ptr, size_t size) {}
 
1482
  static void operator delete(void *ptr, void *mem) { /* never called */ }
 
1483
};
 
1484
 
 
1485
 
 
1486
/*
 
1487
  Register an item tree tree transformation, performed by the query
 
1488
  optimizer. We need a pointer to runtime_memroot because it may be !=
 
1489
  thd->mem_root (due to possible set_n_backup_active_arena called for thd).
 
1490
*/
 
1491
 
 
1492
void THD::nocheck_register_item_tree_change(Item **place, Item *old_value,
 
1493
                                            MEM_ROOT *runtime_memroot)
 
1494
{
 
1495
  Item_change_record *change;
 
1496
  /*
 
1497
    Now we use one node per change, which adds some memory overhead,
 
1498
    but still is rather fast as we use alloc_root for allocations.
 
1499
    A list of item tree changes of an average query should be short.
 
1500
  */
 
1501
  void *change_mem= alloc_root(runtime_memroot, sizeof(*change));
 
1502
  if (change_mem == 0)
 
1503
  {
 
1504
    /*
 
1505
      OOM, thd->fatal_error() is called by the error handler of the
 
1506
      memroot. Just return.
 
1507
    */
 
1508
    return;
 
1509
  }
 
1510
  change= new (change_mem) Item_change_record;
 
1511
  change->place= place;
 
1512
  change->old_value= old_value;
 
1513
  change_list.append(change);
 
1514
}
 
1515
 
 
1516
 
 
1517
void THD::rollback_item_tree_changes()
 
1518
{
 
1519
  I_List_iterator<Item_change_record> it(change_list);
 
1520
  Item_change_record *change;
 
1521
  DBUG_ENTER("rollback_item_tree_changes");
 
1522
 
 
1523
  while ((change= it++))
 
1524
    *change->place= change->old_value;
 
1525
  /* We can forget about changes memory: it's allocated in runtime memroot */
 
1526
  change_list.empty();
 
1527
  DBUG_VOID_RETURN;
 
1528
}
 
1529
 
 
1530
 
 
1531
/*****************************************************************************
 
1532
** Functions to provide a interface to select results
 
1533
*****************************************************************************/
 
1534
 
 
1535
select_result::select_result()
 
1536
{
 
1537
  thd=current_thd;
 
1538
  nest_level= -1;
 
1539
}
 
1540
 
 
1541
void select_result::send_error(uint errcode,const char *err)
 
1542
{
 
1543
  my_message(errcode, err, MYF(0));
 
1544
}
 
1545
 
 
1546
 
 
1547
void select_result::cleanup()
 
1548
{
 
1549
  /* do nothing */
 
1550
}
 
1551
 
 
1552
bool select_result::check_simple_select() const
 
1553
{
 
1554
  my_error(ER_SP_BAD_CURSOR_QUERY, MYF(0));
 
1555
  return TRUE;
 
1556
}
 
1557
 
 
1558
 
 
1559
static String default_line_term("\n",default_charset_info);
 
1560
static String default_escaped("\\",default_charset_info);
 
1561
static String default_field_term("\t",default_charset_info);
 
1562
 
 
1563
sql_exchange::sql_exchange(char *name,bool flag)
 
1564
  :file_name(name), opt_enclosed(0), dumpfile(flag), skip_lines(0)
 
1565
{
 
1566
  field_term= &default_field_term;
 
1567
  enclosed=   line_start= &my_empty_string;
 
1568
  line_term=  &default_line_term;
 
1569
  escaped=    &default_escaped;
 
1570
  cs= NULL;
 
1571
}
 
1572
 
 
1573
bool sql_exchange::escaped_given(void)
 
1574
{
 
1575
  return escaped != &default_escaped;
 
1576
}
 
1577
 
 
1578
 
 
1579
bool select_send::send_fields(List<Item> &list, uint flags)
 
1580
{
 
1581
  bool res;
 
1582
  if (!(res= thd->protocol->send_fields(&list, flags)))
 
1583
    is_result_set_started= 1;
 
1584
  return res;
 
1585
}
 
1586
 
 
1587
void select_send::abort()
 
1588
{
 
1589
  DBUG_ENTER("select_send::abort");
 
1590
  if (is_result_set_started && thd->spcont &&
 
1591
      thd->spcont->find_handler(thd, thd->main_da.sql_errno(),
 
1592
                                MYSQL_ERROR::WARN_LEVEL_ERROR))
 
1593
  {
 
1594
    /*
 
1595
      We're executing a stored procedure, have an open result
 
1596
      set, an SQL exception condition and a handler for it.
 
1597
      In this situation we must abort the current statement,
 
1598
      silence the error and start executing the continue/exit
 
1599
      handler.
 
1600
      Before aborting the statement, let's end the open result set, as
 
1601
      otherwise the client will hang due to the violation of the
 
1602
      client/server protocol.
 
1603
    */
 
1604
    thd->protocol->end_partial_result_set(thd);
 
1605
  }
 
1606
  DBUG_VOID_RETURN;
 
1607
}
 
1608
 
 
1609
 
 
1610
/** 
 
1611
  Cleanup an instance of this class for re-use
 
1612
  at next execution of a prepared statement/
 
1613
  stored procedure statement.
 
1614
*/
 
1615
 
 
1616
void select_send::cleanup()
 
1617
{
 
1618
  is_result_set_started= FALSE;
 
1619
}
 
1620
 
 
1621
/* Send data to client. Returns 0 if ok */
 
1622
 
 
1623
bool select_send::send_data(List<Item> &items)
 
1624
{
 
1625
  if (unit->offset_limit_cnt)
 
1626
  {                                             // using limit offset,count
 
1627
    unit->offset_limit_cnt--;
 
1628
    return 0;
 
1629
  }
 
1630
 
 
1631
  /*
 
1632
    We may be passing the control from mysqld to the client: release the
 
1633
    InnoDB adaptive hash S-latch to avoid thread deadlocks if it was reserved
 
1634
    by thd
 
1635
  */
 
1636
  ha_release_temporary_latches(thd);
 
1637
 
 
1638
  List_iterator_fast<Item> li(items);
 
1639
  Protocol *protocol= thd->protocol;
 
1640
  char buff[MAX_FIELD_WIDTH];
 
1641
  String buffer(buff, sizeof(buff), &my_charset_bin);
 
1642
  DBUG_ENTER("select_send::send_data");
 
1643
 
 
1644
  protocol->prepare_for_resend();
 
1645
  Item *item;
 
1646
  while ((item=li++))
 
1647
  {
 
1648
    if (item->send(protocol, &buffer))
 
1649
    {
 
1650
      protocol->free();                         // Free used buffer
 
1651
      my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
 
1652
      break;
 
1653
    }
 
1654
    /*
 
1655
      Reset buffer to its original state, as it may have been altered in
 
1656
      Item::send().
 
1657
    */
 
1658
    buffer.set(buff, sizeof(buff), &my_charset_bin);
 
1659
  }
 
1660
  thd->sent_row_count++;
 
1661
  if (thd->is_error())
 
1662
  {
 
1663
    protocol->remove_last_row();
 
1664
    DBUG_RETURN(1);
 
1665
  }
 
1666
  if (thd->vio_ok())
 
1667
    DBUG_RETURN(protocol->write());
 
1668
  DBUG_RETURN(0);
 
1669
}
 
1670
 
 
1671
bool select_send::send_eof()
 
1672
{
 
1673
  /* 
 
1674
    We may be passing the control from mysqld to the client: release the
 
1675
    InnoDB adaptive hash S-latch to avoid thread deadlocks if it was reserved
 
1676
    by thd 
 
1677
  */
 
1678
  ha_release_temporary_latches(thd);
 
1679
 
 
1680
  /* Unlock tables before sending packet to gain some speed */
 
1681
  if (thd->lock)
 
1682
  {
 
1683
    mysql_unlock_tables(thd, thd->lock);
 
1684
    thd->lock=0;
 
1685
  }
 
1686
  /* 
 
1687
    Don't send EOF if we're in error condition (which implies we've already
 
1688
    sent or are sending an error)
 
1689
  */
 
1690
  if (thd->is_error())
 
1691
    return TRUE;
 
1692
  ::my_eof(thd);
 
1693
  is_result_set_started= 0;
 
1694
  return FALSE;
 
1695
}
 
1696
 
 
1697
 
 
1698
/************************************************************************
 
1699
  Handling writing to file
 
1700
************************************************************************/
 
1701
 
 
1702
void select_to_file::send_error(uint errcode,const char *err)
 
1703
{
 
1704
  my_message(errcode, err, MYF(0));
 
1705
  if (file > 0)
 
1706
  {
 
1707
    (void) end_io_cache(&cache);
 
1708
    (void) my_close(file,MYF(0));
 
1709
    (void) my_delete(path,MYF(0));              // Delete file on error
 
1710
    file= -1;
 
1711
  }
 
1712
}
 
1713
 
 
1714
 
 
1715
bool select_to_file::send_eof()
 
1716
{
 
1717
  int error= test(end_io_cache(&cache));
 
1718
  if (my_close(file,MYF(MY_WME)))
 
1719
    error= 1;
 
1720
  if (!error)
 
1721
  {
 
1722
    /*
 
1723
      In order to remember the value of affected rows for ROW_COUNT()
 
1724
      function, SELECT INTO has to have an own SQLCOM.
 
1725
      TODO: split from SQLCOM_SELECT
 
1726
    */
 
1727
    ::my_ok(thd,row_count);
 
1728
  }
 
1729
  file= -1;
 
1730
  return error;
 
1731
}
 
1732
 
 
1733
 
 
1734
void select_to_file::cleanup()
 
1735
{
 
1736
  /* In case of error send_eof() may be not called: close the file here. */
 
1737
  if (file >= 0)
 
1738
  {
 
1739
    (void) end_io_cache(&cache);
 
1740
    (void) my_close(file,MYF(0));
 
1741
    file= -1;
 
1742
  }
 
1743
  path[0]= '\0';
 
1744
  row_count= 0;
 
1745
}
 
1746
 
 
1747
 
 
1748
select_to_file::~select_to_file()
 
1749
{
 
1750
  if (file >= 0)
 
1751
  {                                     // This only happens in case of error
 
1752
    (void) end_io_cache(&cache);
 
1753
    (void) my_close(file,MYF(0));
 
1754
    file= -1;
 
1755
  }
 
1756
}
 
1757
 
 
1758
/***************************************************************************
 
1759
** Export of select to textfile
 
1760
***************************************************************************/
 
1761
 
 
1762
select_export::~select_export()
 
1763
{
 
1764
  thd->sent_row_count=row_count;
 
1765
}
 
1766
 
 
1767
 
 
1768
/*
 
1769
  Create file with IO cache
 
1770
 
 
1771
  SYNOPSIS
 
1772
    create_file()
 
1773
    thd                 Thread handle
 
1774
    path                File name
 
1775
    exchange            Excange class
 
1776
    cache               IO cache
 
1777
 
 
1778
  RETURN
 
1779
    >= 0        File handle
 
1780
   -1           Error
 
1781
*/
 
1782
 
 
1783
 
 
1784
static File create_file(THD *thd, char *path, sql_exchange *exchange,
 
1785
                        IO_CACHE *cache)
 
1786
{
 
1787
  File file;
 
1788
  uint option= MY_UNPACK_FILENAME | MY_RELATIVE_PATH;
 
1789
 
 
1790
#ifdef DONT_ALLOW_FULL_LOAD_DATA_PATHS
 
1791
  option|= MY_REPLACE_DIR;                      // Force use of db directory
 
1792
#endif
 
1793
 
 
1794
  if (!dirname_length(exchange->file_name))
 
1795
  {
 
1796
    strxnmov(path, FN_REFLEN-1, mysql_real_data_home, thd->db ? thd->db : "",
 
1797
             NullS);
 
1798
    (void) fn_format(path, exchange->file_name, path, "", option);
 
1799
  }
 
1800
  else
 
1801
    (void) fn_format(path, exchange->file_name, mysql_real_data_home, "", option);
 
1802
 
 
1803
  if (opt_secure_file_priv &&
 
1804
      strncmp(opt_secure_file_priv, path, strlen(opt_secure_file_priv)))
 
1805
  {
 
1806
    /* Write only allowed to dir or subdir specified by secure_file_priv */
 
1807
    my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--secure-file-priv");
 
1808
    return -1;
 
1809
  }
 
1810
 
 
1811
  if (!access(path, F_OK))
 
1812
  {
 
1813
    my_error(ER_FILE_EXISTS_ERROR, MYF(0), exchange->file_name);
 
1814
    return -1;
 
1815
  }
 
1816
  /* Create the file world readable */
 
1817
  if ((file= my_create(path, 0666, O_WRONLY|O_EXCL, MYF(MY_WME))) < 0)
 
1818
    return file;
 
1819
#ifdef HAVE_FCHMOD
 
1820
  (void) fchmod(file, 0666);                    // Because of umask()
 
1821
#else
 
1822
  (void) chmod(path, 0666);
 
1823
#endif
 
1824
  if (init_io_cache(cache, file, 0L, WRITE_CACHE, 0L, 1, MYF(MY_WME)))
 
1825
  {
 
1826
    my_close(file, MYF(0));
 
1827
    my_delete(path, MYF(0));  // Delete file on error, it was just created 
 
1828
    return -1;
 
1829
  }
 
1830
  return file;
 
1831
}
 
1832
 
 
1833
 
 
1834
int
 
1835
select_export::prepare(List<Item> &list, SELECT_LEX_UNIT *u)
 
1836
{
 
1837
  bool blob_flag=0;
 
1838
  bool string_results= FALSE, non_string_results= FALSE;
 
1839
  unit= u;
 
1840
  if ((uint) strlen(exchange->file_name) + NAME_LEN >= FN_REFLEN)
 
1841
    strmake(path,exchange->file_name,FN_REFLEN-1);
 
1842
 
 
1843
  write_cs= exchange->cs ? exchange->cs : &my_charset_bin;
 
1844
 
 
1845
  if ((file= create_file(thd, path, exchange, &cache)) < 0)
 
1846
    return 1;
 
1847
  /* Check if there is any blobs in data */
 
1848
  {
 
1849
    List_iterator_fast<Item> li(list);
 
1850
    Item *item;
 
1851
    while ((item=li++))
 
1852
    {
 
1853
      if (item->max_length >= MAX_BLOB_WIDTH)
 
1854
      {
 
1855
        blob_flag=1;
 
1856
        break;
 
1857
      }
 
1858
      if (item->result_type() == STRING_RESULT)
 
1859
        string_results= TRUE;
 
1860
      else
 
1861
        non_string_results= TRUE;
 
1862
    }
 
1863
  }
 
1864
  if (exchange->escaped->numchars() > 1 || exchange->enclosed->numchars() > 1)
 
1865
  {
 
1866
    my_error(ER_WRONG_FIELD_TERMINATORS, MYF(0));
 
1867
    return TRUE;
 
1868
  }
 
1869
  if (exchange->escaped->length() > 1 || exchange->enclosed->length() > 1 ||
 
1870
      !my_isascii(exchange->escaped->ptr()[0]) ||
 
1871
      !my_isascii(exchange->enclosed->ptr()[0]) ||
 
1872
      !exchange->field_term->is_ascii() || !exchange->line_term->is_ascii() ||
 
1873
      !exchange->line_start->is_ascii())
 
1874
  {
 
1875
    /*
 
1876
      Current LOAD DATA INFILE recognizes field/line separators "as is" without
 
1877
      converting from client charset to data file charset. So, it is supposed,
 
1878
      that input file of LOAD DATA INFILE consists of data in one charset and
 
1879
      separators in other charset. For the compatibility with that [buggy]
 
1880
      behaviour SELECT INTO OUTFILE implementation has been saved "as is" too,
 
1881
      but the new warning message has been added:
 
1882
 
 
1883
        Non-ASCII separator arguments are not fully supported
 
1884
    */
 
1885
    push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
 
1886
                 WARN_NON_ASCII_SEPARATOR_NOT_IMPLEMENTED,
 
1887
                 ER(WARN_NON_ASCII_SEPARATOR_NOT_IMPLEMENTED));
 
1888
  }
 
1889
  field_term_length=exchange->field_term->length();
 
1890
  field_term_char= field_term_length ?
 
1891
                   (int) (uchar) (*exchange->field_term)[0] : INT_MAX;
 
1892
  if (!exchange->line_term->length())
 
1893
    exchange->line_term=exchange->field_term;   // Use this if it exists
 
1894
  field_sep_char= (exchange->enclosed->length() ?
 
1895
                  (int) (uchar) (*exchange->enclosed)[0] : field_term_char);
 
1896
  if (exchange->escaped->length() && (exchange->escaped_given() ||
 
1897
      !(thd->variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES)))
 
1898
    escape_char= (int) (uchar) (*exchange->escaped)[0];
 
1899
  else
 
1900
    escape_char= -1;
 
1901
  is_ambiguous_field_sep= test(strchr(ESCAPE_CHARS, field_sep_char));
 
1902
  is_unsafe_field_sep= test(strchr(NUMERIC_CHARS, field_sep_char));
 
1903
  line_sep_char= (exchange->line_term->length() ?
 
1904
                 (int) (uchar) (*exchange->line_term)[0] : INT_MAX);
 
1905
  if (!field_term_length)
 
1906
    exchange->opt_enclosed=0;
 
1907
  if (!exchange->enclosed->length())
 
1908
    exchange->opt_enclosed=1;                   // A little quicker loop
 
1909
  fixed_row_size= (!field_term_length && !exchange->enclosed->length() &&
 
1910
                   !blob_flag);
 
1911
  if ((is_ambiguous_field_sep && exchange->enclosed->is_empty() &&
 
1912
       (string_results || is_unsafe_field_sep)) ||
 
1913
      (exchange->opt_enclosed && non_string_results &&
 
1914
       field_term_length && strchr(NUMERIC_CHARS, field_term_char)))
 
1915
  {
 
1916
    push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
 
1917
                 ER_AMBIGUOUS_FIELD_TERM, ER(ER_AMBIGUOUS_FIELD_TERM));
 
1918
    is_ambiguous_field_term= TRUE;
 
1919
  }
 
1920
  else
 
1921
    is_ambiguous_field_term= FALSE;
 
1922
 
 
1923
  return 0;
 
1924
}
 
1925
 
 
1926
 
 
1927
#define NEED_ESCAPING(x) ((int) (uchar) (x) == escape_char    || \
 
1928
                          (enclosed ? (int) (uchar) (x) == field_sep_char      \
 
1929
                                    : (int) (uchar) (x) == field_term_char) || \
 
1930
                          (int) (uchar) (x) == line_sep_char  || \
 
1931
                          !(x))
 
1932
 
 
1933
bool select_export::send_data(List<Item> &items)
 
1934
{
 
1935
 
 
1936
  DBUG_ENTER("select_export::send_data");
 
1937
  char buff[MAX_FIELD_WIDTH],null_buff[2],space[MAX_FIELD_WIDTH];
 
1938
  char cvt_buff[MAX_FIELD_WIDTH];
 
1939
  String cvt_str(cvt_buff, sizeof(cvt_buff), write_cs);
 
1940
  bool space_inited=0;
 
1941
  String tmp(buff,sizeof(buff),&my_charset_bin),*res;
 
1942
  tmp.length(0);
 
1943
 
 
1944
  if (unit->offset_limit_cnt)
 
1945
  {                                             // using limit offset,count
 
1946
    unit->offset_limit_cnt--;
 
1947
    DBUG_RETURN(0);
 
1948
  }
 
1949
  row_count++;
 
1950
  Item *item;
 
1951
  uint used_length=0,items_left=items.elements;
 
1952
  List_iterator_fast<Item> li(items);
 
1953
 
 
1954
  if (my_b_write(&cache,(uchar*) exchange->line_start->ptr(),
 
1955
                 exchange->line_start->length()))
 
1956
    goto err;
 
1957
  while ((item=li++))
 
1958
  {
 
1959
    Item_result result_type=item->result_type();
 
1960
    bool enclosed = (exchange->enclosed->length() &&
 
1961
                     (!exchange->opt_enclosed || result_type == STRING_RESULT));
 
1962
    res=item->str_result(&tmp);
 
1963
    if (res && !my_charset_same(write_cs, res->charset()) &&
 
1964
        !my_charset_same(write_cs, &my_charset_bin))
 
1965
    {
 
1966
      const char *well_formed_error_pos;
 
1967
      const char *cannot_convert_error_pos;
 
1968
      const char *from_end_pos;
 
1969
      const char *error_pos;
 
1970
      uint32 bytes;
 
1971
      bytes= well_formed_copy_nchars(write_cs, cvt_buff, sizeof(cvt_buff),
 
1972
                                     res->charset(), res->ptr(), res->length(),
 
1973
                                     sizeof(cvt_buff),
 
1974
                                     &well_formed_error_pos,
 
1975
                                     &cannot_convert_error_pos,
 
1976
                                     &from_end_pos);
 
1977
      error_pos= well_formed_error_pos ? well_formed_error_pos
 
1978
                                       : cannot_convert_error_pos;
 
1979
      if (error_pos)
 
1980
      {
 
1981
        char printable_buff[32];
 
1982
        convert_to_printable(printable_buff, sizeof(printable_buff),
 
1983
                             error_pos, res->ptr() + res->length() - error_pos,
 
1984
                             res->charset(), 6);
 
1985
        push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
 
1986
                            ER_TRUNCATED_WRONG_VALUE_FOR_FIELD,
 
1987
                            ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD),
 
1988
                            "string", printable_buff,
 
1989
                            item->name, row_count);
 
1990
      }
 
1991
      cvt_str.length(bytes);
 
1992
      res= &cvt_str;
 
1993
    }
 
1994
    if (res && enclosed)
 
1995
    {
 
1996
      if (my_b_write(&cache,(uchar*) exchange->enclosed->ptr(),
 
1997
                     exchange->enclosed->length()))
 
1998
        goto err;
 
1999
    }
 
2000
    if (!res)
 
2001
    {                                           // NULL
 
2002
      if (!fixed_row_size)
 
2003
      {
 
2004
        if (escape_char != -1)                  // Use \N syntax
 
2005
        {
 
2006
          null_buff[0]=escape_char;
 
2007
          null_buff[1]='N';
 
2008
          if (my_b_write(&cache,(uchar*) null_buff,2))
 
2009
            goto err;
 
2010
        }
 
2011
        else if (my_b_write(&cache,(uchar*) "NULL",4))
 
2012
          goto err;
 
2013
      }
 
2014
      else
 
2015
      {
 
2016
        used_length=0;                          // Fill with space
 
2017
      }
 
2018
    }
 
2019
    else
 
2020
    {
 
2021
      if (fixed_row_size)
 
2022
        used_length=min(res->length(),item->max_length);
 
2023
      else
 
2024
        used_length=res->length();
 
2025
      if ((result_type == STRING_RESULT || is_unsafe_field_sep) &&
 
2026
           escape_char != -1)
 
2027
      {
 
2028
        char *pos, *start, *end;
 
2029
        CHARSET_INFO *res_charset= res->charset();
 
2030
        CHARSET_INFO *character_set_client= thd->variables.
 
2031
                                            character_set_client;
 
2032
        bool check_second_byte= (res_charset == &my_charset_bin) &&
 
2033
                                 character_set_client->
 
2034
                                 escape_with_backslash_is_dangerous;
 
2035
        DBUG_ASSERT(character_set_client->mbmaxlen == 2 ||
 
2036
                    !character_set_client->escape_with_backslash_is_dangerous);
 
2037
        for (start=pos=(char*) res->ptr(),end=pos+used_length ;
 
2038
             pos != end ;
 
2039
             pos++)
 
2040
        {
 
2041
#ifdef USE_MB
 
2042
          if (use_mb(res_charset))
 
2043
          {
 
2044
            int l;
 
2045
            if ((l=my_ismbchar(res_charset, pos, end)))
 
2046
            {
 
2047
              pos += l-1;
 
2048
              continue;
 
2049
            }
 
2050
          }
 
2051
#endif
 
2052
 
 
2053
          /*
 
2054
            Special case when dumping BINARY/VARBINARY/BLOB values
 
2055
            for the clients with character sets big5, cp932, gbk and sjis,
 
2056
            which can have the escape character (0x5C "\" by default)
 
2057
            as the second byte of a multi-byte sequence.
 
2058
            
 
2059
            If
 
2060
            - pos[0] is a valid multi-byte head (e.g 0xEE) and
 
2061
            - pos[1] is 0x00, which will be escaped as "\0",
 
2062
            
 
2063
            then we'll get "0xEE + 0x5C + 0x30" in the output file.
 
2064
            
 
2065
            If this file is later loaded using this sequence of commands:
 
2066
            
 
2067
            mysql> create table t1 (a varchar(128)) character set big5;
 
2068
            mysql> LOAD DATA INFILE 'dump.txt' INTO TABLE t1;
 
2069
            
 
2070
            then 0x5C will be misinterpreted as the second byte
 
2071
            of a multi-byte character "0xEE + 0x5C", instead of
 
2072
            escape character for 0x00.
 
2073
            
 
2074
            To avoid this confusion, we'll escape the multi-byte
 
2075
            head character too, so the sequence "0xEE + 0x00" will be
 
2076
            dumped as "0x5C + 0xEE + 0x5C + 0x30".
 
2077
            
 
2078
            Note, in the condition below we only check if
 
2079
            mbcharlen is equal to 2, because there are no
 
2080
            character sets with mbmaxlen longer than 2
 
2081
            and with escape_with_backslash_is_dangerous set.
 
2082
            DBUG_ASSERT before the loop makes that sure.
 
2083
          */
 
2084
 
 
2085
          if ((NEED_ESCAPING(*pos) ||
 
2086
               (check_second_byte &&
 
2087
                my_mbcharlen(character_set_client, (uchar) *pos) == 2 &&
 
2088
                pos + 1 < end &&
 
2089
                NEED_ESCAPING(pos[1]))) &&
 
2090
              /*
 
2091
               Don't escape field_term_char by doubling - doubling is only
 
2092
               valid for ENCLOSED BY characters:
 
2093
              */
 
2094
              (enclosed || !is_ambiguous_field_term ||
 
2095
               (int) (uchar) *pos != field_term_char))
 
2096
          {
 
2097
            char tmp_buff[2];
 
2098
            tmp_buff[0]= ((int) (uchar) *pos == field_sep_char &&
 
2099
                          is_ambiguous_field_sep) ?
 
2100
                          field_sep_char : escape_char;
 
2101
            tmp_buff[1]= *pos ? *pos : '0';
 
2102
            if (my_b_write(&cache,(uchar*) start,(uint) (pos-start)) ||
 
2103
                my_b_write(&cache,(uchar*) tmp_buff,2))
 
2104
              goto err;
 
2105
            start=pos+1;
 
2106
          }
 
2107
        }
 
2108
        if (my_b_write(&cache,(uchar*) start,(uint) (pos-start)))
 
2109
          goto err;
 
2110
      }
 
2111
      else if (my_b_write(&cache,(uchar*) res->ptr(),used_length))
 
2112
        goto err;
 
2113
    }
 
2114
    if (fixed_row_size)
 
2115
    {                                           // Fill with space
 
2116
      if (item->max_length > used_length)
 
2117
      {
 
2118
        /* QQ:  Fix by adding a my_b_fill() function */
 
2119
        if (!space_inited)
 
2120
        {
 
2121
          space_inited=1;
 
2122
          bfill(space,sizeof(space),' ');
 
2123
        }
 
2124
        uint length=item->max_length-used_length;
 
2125
        for (; length > sizeof(space) ; length-=sizeof(space))
 
2126
        {
 
2127
          if (my_b_write(&cache,(uchar*) space,sizeof(space)))
 
2128
            goto err;
 
2129
        }
 
2130
        if (my_b_write(&cache,(uchar*) space,length))
 
2131
          goto err;
 
2132
      }
 
2133
    }
 
2134
    if (res && enclosed)
 
2135
    {
 
2136
      if (my_b_write(&cache, (uchar*) exchange->enclosed->ptr(),
 
2137
                     exchange->enclosed->length()))
 
2138
        goto err;
 
2139
    }
 
2140
    if (--items_left)
 
2141
    {
 
2142
      if (my_b_write(&cache, (uchar*) exchange->field_term->ptr(),
 
2143
                     field_term_length))
 
2144
        goto err;
 
2145
    }
 
2146
  }
 
2147
  if (my_b_write(&cache,(uchar*) exchange->line_term->ptr(),
 
2148
                 exchange->line_term->length()))
 
2149
    goto err;
 
2150
  DBUG_RETURN(0);
 
2151
err:
 
2152
  DBUG_RETURN(1);
 
2153
}
 
2154
 
 
2155
 
 
2156
/***************************************************************************
 
2157
** Dump  of select to a binary file
 
2158
***************************************************************************/
 
2159
 
 
2160
 
 
2161
int
 
2162
select_dump::prepare(List<Item> &list __attribute__((unused)),
 
2163
                     SELECT_LEX_UNIT *u)
 
2164
{
 
2165
  unit= u;
 
2166
  return (int) ((file= create_file(thd, path, exchange, &cache)) < 0);
 
2167
}
 
2168
 
 
2169
 
 
2170
bool select_dump::send_data(List<Item> &items)
 
2171
{
 
2172
  List_iterator_fast<Item> li(items);
 
2173
  char buff[MAX_FIELD_WIDTH];
 
2174
  String tmp(buff,sizeof(buff),&my_charset_bin),*res;
 
2175
  tmp.length(0);
 
2176
  Item *item;
 
2177
  DBUG_ENTER("select_dump::send_data");
 
2178
 
 
2179
  if (unit->offset_limit_cnt)
 
2180
  {                                             // using limit offset,count
 
2181
    unit->offset_limit_cnt--;
 
2182
    DBUG_RETURN(0);
 
2183
  }
 
2184
  if (row_count++ > 1) 
 
2185
  {
 
2186
    my_message(ER_TOO_MANY_ROWS, ER(ER_TOO_MANY_ROWS), MYF(0));
 
2187
    goto err;
 
2188
  }
 
2189
  while ((item=li++))
 
2190
  {
 
2191
    res=item->str_result(&tmp);
 
2192
    if (!res)                                   // If NULL
 
2193
    {
 
2194
      if (my_b_write(&cache,(uchar*) "",1))
 
2195
        goto err;
 
2196
    }
 
2197
    else if (my_b_write(&cache,(uchar*) res->ptr(),res->length()))
 
2198
    {
 
2199
      my_error(ER_ERROR_ON_WRITE, MYF(0), path, my_errno);
 
2200
      goto err;
 
2201
    }
 
2202
  }
 
2203
  DBUG_RETURN(0);
 
2204
err:
 
2205
  DBUG_RETURN(1);
 
2206
}
 
2207
 
 
2208
 
 
2209
select_subselect::select_subselect(Item_subselect *item_arg)
 
2210
{
 
2211
  item= item_arg;
 
2212
}
 
2213
 
 
2214
 
 
2215
bool select_singlerow_subselect::send_data(List<Item> &items)
 
2216
{
 
2217
  DBUG_ENTER("select_singlerow_subselect::send_data");
 
2218
  Item_singlerow_subselect *it= (Item_singlerow_subselect *)item;
 
2219
  if (it->assigned())
 
2220
  {
 
2221
    my_message(ER_SUBQUERY_NO_1_ROW, ER(ER_SUBQUERY_NO_1_ROW), MYF(0));
 
2222
    DBUG_RETURN(1);
 
2223
  }
 
2224
  if (unit->offset_limit_cnt)
 
2225
  {                                       // Using limit offset,count
 
2226
    unit->offset_limit_cnt--;
 
2227
    DBUG_RETURN(0);
 
2228
  }
 
2229
  List_iterator_fast<Item> li(items);
 
2230
  Item *val_item;
 
2231
  for (uint i= 0; (val_item= li++); i++)
 
2232
    it->store(i, val_item);
 
2233
  it->assigned(1);
 
2234
  DBUG_RETURN(0);
 
2235
}
 
2236
 
 
2237
 
 
2238
void select_max_min_finder_subselect::cleanup()
 
2239
{
 
2240
  DBUG_ENTER("select_max_min_finder_subselect::cleanup");
 
2241
  cache= 0;
 
2242
  DBUG_VOID_RETURN;
 
2243
}
 
2244
 
 
2245
 
 
2246
bool select_max_min_finder_subselect::send_data(List<Item> &items)
 
2247
{
 
2248
  DBUG_ENTER("select_max_min_finder_subselect::send_data");
 
2249
  Item_maxmin_subselect *it= (Item_maxmin_subselect *)item;
 
2250
  List_iterator_fast<Item> li(items);
 
2251
  Item *val_item= li++;
 
2252
  it->register_value();
 
2253
  if (it->assigned())
 
2254
  {
 
2255
    cache->store(val_item);
 
2256
    if ((this->*op)())
 
2257
      it->store(0, cache);
 
2258
  }
 
2259
  else
 
2260
  {
 
2261
    if (!cache)
 
2262
    {
 
2263
      cache= Item_cache::get_cache(val_item);
 
2264
      switch (val_item->result_type())
 
2265
      {
 
2266
      case REAL_RESULT:
 
2267
        op= &select_max_min_finder_subselect::cmp_real;
 
2268
        break;
 
2269
      case INT_RESULT:
 
2270
        op= &select_max_min_finder_subselect::cmp_int;
 
2271
        break;
 
2272
      case STRING_RESULT:
 
2273
        op= &select_max_min_finder_subselect::cmp_str;
 
2274
        break;
 
2275
      case DECIMAL_RESULT:
 
2276
        op= &select_max_min_finder_subselect::cmp_decimal;
 
2277
        break;
 
2278
      case ROW_RESULT:
 
2279
        // This case should never be choosen
 
2280
        DBUG_ASSERT(0);
 
2281
        op= 0;
 
2282
      }
 
2283
    }
 
2284
    cache->store(val_item);
 
2285
    it->store(0, cache);
 
2286
  }
 
2287
  it->assigned(1);
 
2288
  DBUG_RETURN(0);
 
2289
}
 
2290
 
 
2291
bool select_max_min_finder_subselect::cmp_real()
 
2292
{
 
2293
  Item *maxmin= ((Item_singlerow_subselect *)item)->element_index(0);
 
2294
  double val1= cache->val_real(), val2= maxmin->val_real();
 
2295
  if (fmax)
 
2296
    return (cache->null_value && !maxmin->null_value) ||
 
2297
      (!cache->null_value && !maxmin->null_value &&
 
2298
       val1 > val2);
 
2299
  return (maxmin->null_value && !cache->null_value) ||
 
2300
    (!cache->null_value && !maxmin->null_value &&
 
2301
     val1 < val2);
 
2302
}
 
2303
 
 
2304
bool select_max_min_finder_subselect::cmp_int()
 
2305
{
 
2306
  Item *maxmin= ((Item_singlerow_subselect *)item)->element_index(0);
 
2307
  longlong val1= cache->val_int(), val2= maxmin->val_int();
 
2308
  if (fmax)
 
2309
    return (cache->null_value && !maxmin->null_value) ||
 
2310
      (!cache->null_value && !maxmin->null_value &&
 
2311
       val1 > val2);
 
2312
  return (maxmin->null_value && !cache->null_value) ||
 
2313
    (!cache->null_value && !maxmin->null_value &&
 
2314
     val1 < val2);
 
2315
}
 
2316
 
 
2317
bool select_max_min_finder_subselect::cmp_decimal()
 
2318
{
 
2319
  Item *maxmin= ((Item_singlerow_subselect *)item)->element_index(0);
 
2320
  my_decimal cval, *cvalue= cache->val_decimal(&cval);
 
2321
  my_decimal mval, *mvalue= maxmin->val_decimal(&mval);
 
2322
  if (fmax)
 
2323
    return (cache->null_value && !maxmin->null_value) ||
 
2324
      (!cache->null_value && !maxmin->null_value &&
 
2325
       my_decimal_cmp(cvalue, mvalue) > 0) ;
 
2326
  return (maxmin->null_value && !cache->null_value) ||
 
2327
    (!cache->null_value && !maxmin->null_value &&
 
2328
     my_decimal_cmp(cvalue,mvalue) < 0);
 
2329
}
 
2330
 
 
2331
bool select_max_min_finder_subselect::cmp_str()
 
2332
{
 
2333
  String *val1, *val2, buf1, buf2;
 
2334
  Item *maxmin= ((Item_singlerow_subselect *)item)->element_index(0);
 
2335
  /*
 
2336
    as far as both operand is Item_cache buf1 & buf2 will not be used,
 
2337
    but added for safety
 
2338
  */
 
2339
  val1= cache->val_str(&buf1);
 
2340
  val2= maxmin->val_str(&buf1);
 
2341
  if (fmax)
 
2342
    return (cache->null_value && !maxmin->null_value) ||
 
2343
      (!cache->null_value && !maxmin->null_value &&
 
2344
       sortcmp(val1, val2, cache->collation.collation) > 0) ;
 
2345
  return (maxmin->null_value && !cache->null_value) ||
 
2346
    (!cache->null_value && !maxmin->null_value &&
 
2347
     sortcmp(val1, val2, cache->collation.collation) < 0);
 
2348
}
 
2349
 
 
2350
bool select_exists_subselect::send_data(List<Item> &items)
 
2351
{
 
2352
  DBUG_ENTER("select_exists_subselect::send_data");
 
2353
  Item_exists_subselect *it= (Item_exists_subselect *)item;
 
2354
  if (unit->offset_limit_cnt)
 
2355
  {                                       // Using limit offset,count
 
2356
    unit->offset_limit_cnt--;
 
2357
    DBUG_RETURN(0);
 
2358
  }
 
2359
  it->value= 1;
 
2360
  it->assigned(1);
 
2361
  DBUG_RETURN(0);
 
2362
}
 
2363
 
 
2364
 
 
2365
/***************************************************************************
 
2366
  Dump of select to variables
 
2367
***************************************************************************/
 
2368
 
 
2369
int select_dumpvar::prepare(List<Item> &list, SELECT_LEX_UNIT *u)
 
2370
{
 
2371
  unit= u;
 
2372
  
 
2373
  if (var_list.elements != list.elements)
 
2374
  {
 
2375
    my_message(ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT,
 
2376
               ER(ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT), MYF(0));
 
2377
    return 1;
 
2378
  }               
 
2379
  return 0;
 
2380
}
 
2381
 
 
2382
 
 
2383
bool select_dumpvar::check_simple_select() const
 
2384
{
 
2385
  my_error(ER_SP_BAD_CURSOR_SELECT, MYF(0));
 
2386
  return TRUE;
 
2387
}
 
2388
 
 
2389
 
 
2390
void select_dumpvar::cleanup()
 
2391
{
 
2392
  row_count= 0;
 
2393
}
 
2394
 
 
2395
 
 
2396
Query_arena::Type Query_arena::type() const
 
2397
{
 
2398
  DBUG_ASSERT(0); /* Should never be called */
 
2399
  return STATEMENT;
 
2400
}
 
2401
 
 
2402
 
 
2403
void Query_arena::free_items()
 
2404
{
 
2405
  Item *next;
 
2406
  DBUG_ENTER("Query_arena::free_items");
 
2407
  /* This works because items are allocated with sql_alloc() */
 
2408
  for (; free_list; free_list= next)
 
2409
  {
 
2410
    next= free_list->next;
 
2411
    free_list->delete_self();
 
2412
  }
 
2413
  /* Postcondition: free_list is 0 */
 
2414
  DBUG_VOID_RETURN;
 
2415
}
 
2416
 
 
2417
 
 
2418
void Query_arena::set_query_arena(Query_arena *set)
 
2419
{
 
2420
  mem_root=  set->mem_root;
 
2421
  free_list= set->free_list;
 
2422
  state= set->state;
 
2423
}
 
2424
 
 
2425
 
 
2426
void Query_arena::cleanup_stmt()
 
2427
{
 
2428
  DBUG_ASSERT(! "Query_arena::cleanup_stmt() not implemented");
 
2429
}
 
2430
 
 
2431
/*
 
2432
  Statement functions
 
2433
*/
 
2434
 
 
2435
Statement::Statement(LEX *lex_arg, MEM_ROOT *mem_root_arg,
 
2436
                     enum enum_state state_arg, ulong id_arg)
 
2437
  :Query_arena(mem_root_arg, state_arg),
 
2438
  id(id_arg),
 
2439
  mark_used_columns(MARK_COLUMNS_READ),
 
2440
  lex(lex_arg),
 
2441
  cursor(0),
 
2442
  db(NULL),
 
2443
  db_length(0)
 
2444
{
 
2445
  query_string.length= 0;
 
2446
  query_string.str= NULL;
 
2447
  name.str= NULL;
 
2448
}
 
2449
 
 
2450
 
 
2451
Query_arena::Type Statement::type() const
 
2452
{
 
2453
  return STATEMENT;
 
2454
}
 
2455
 
 
2456
 
 
2457
void Statement::set_statement(Statement *stmt)
 
2458
{
 
2459
  id=             stmt->id;
 
2460
  mark_used_columns=   stmt->mark_used_columns;
 
2461
  lex=            stmt->lex;
 
2462
  query_string=   stmt->query_string;
 
2463
  cursor=         stmt->cursor;
 
2464
}
 
2465
 
 
2466
 
 
2467
void
 
2468
Statement::set_n_backup_statement(Statement *stmt, Statement *backup)
 
2469
{
 
2470
  DBUG_ENTER("Statement::set_n_backup_statement");
 
2471
  backup->set_statement(this);
 
2472
  set_statement(stmt);
 
2473
  DBUG_VOID_RETURN;
 
2474
}
 
2475
 
 
2476
 
 
2477
void Statement::restore_backup_statement(Statement *stmt, Statement *backup)
 
2478
{
 
2479
  DBUG_ENTER("Statement::restore_backup_statement");
 
2480
  stmt->set_statement(this);
 
2481
  set_statement(backup);
 
2482
  DBUG_VOID_RETURN;
 
2483
}
 
2484
 
 
2485
 
 
2486
/** Assign a new value to thd->query.  */
 
2487
 
 
2488
void Statement::set_query_inner(char *query_arg, uint32 query_length_arg)
 
2489
{
 
2490
  query_string.str= query_arg;
 
2491
  query_string.length= query_length_arg;
 
2492
}
 
2493
 
 
2494
 
 
2495
void THD::end_statement()
 
2496
{
 
2497
  /* Cleanup SQL processing state to reuse this statement in next query. */
 
2498
  lex_end(lex);
 
2499
  delete lex->result;
 
2500
  lex->result= 0;
 
2501
  /* Note that free_list is freed in cleanup_after_query() */
 
2502
 
 
2503
  /*
 
2504
    Don't free mem_root, as mem_root is freed in the end of dispatch_command
 
2505
    (once for any command).
 
2506
  */
 
2507
}
 
2508
 
 
2509
 
 
2510
void THD::set_n_backup_active_arena(Query_arena *set, Query_arena *backup)
 
2511
{
 
2512
  DBUG_ENTER("THD::set_n_backup_active_arena");
 
2513
  DBUG_ASSERT(backup->is_backup_arena == FALSE);
 
2514
 
 
2515
  backup->set_query_arena(this);
 
2516
  set_query_arena(set);
 
2517
#ifndef DBUG_OFF
 
2518
  backup->is_backup_arena= TRUE;
 
2519
#endif
 
2520
  DBUG_VOID_RETURN;
 
2521
}
 
2522
 
 
2523
 
 
2524
void THD::restore_active_arena(Query_arena *set, Query_arena *backup)
 
2525
{
 
2526
  DBUG_ENTER("THD::restore_active_arena");
 
2527
  DBUG_ASSERT(backup->is_backup_arena);
 
2528
  set->set_query_arena(this);
 
2529
  set_query_arena(backup);
 
2530
#ifndef DBUG_OFF
 
2531
  backup->is_backup_arena= FALSE;
 
2532
#endif
 
2533
  DBUG_VOID_RETURN;
 
2534
}
 
2535
 
 
2536
Statement::~Statement()
 
2537
{
 
2538
}
 
2539
 
 
2540
C_MODE_START
 
2541
 
 
2542
static uchar *
 
2543
get_statement_id_as_hash_key(const uchar *record, size_t *key_length,
 
2544
                             my_bool not_used __attribute__((unused)))
 
2545
{
 
2546
  const Statement *statement= (const Statement *) record; 
 
2547
  *key_length= sizeof(statement->id);
 
2548
  return (uchar *) &((const Statement *) statement)->id;
 
2549
}
 
2550
 
 
2551
static void delete_statement_as_hash_key(void *key)
 
2552
{
 
2553
  delete (Statement *) key;
 
2554
}
 
2555
 
 
2556
static uchar *get_stmt_name_hash_key(Statement *entry, size_t *length,
 
2557
                                    my_bool not_used __attribute__((unused)))
 
2558
{
 
2559
  *length= entry->name.length;
 
2560
  return (uchar*) entry->name.str;
 
2561
}
 
2562
 
 
2563
C_MODE_END
 
2564
 
 
2565
Statement_map::Statement_map() :
 
2566
  last_found_statement(0)
 
2567
{
 
2568
  enum
 
2569
  {
 
2570
    START_STMT_HASH_SIZE = 16,
 
2571
    START_NAME_HASH_SIZE = 16
 
2572
  };
 
2573
  hash_init(&st_hash, &my_charset_bin, START_STMT_HASH_SIZE, 0, 0,
 
2574
            get_statement_id_as_hash_key,
 
2575
            delete_statement_as_hash_key, MYF(0));
 
2576
  hash_init(&names_hash, system_charset_info, START_NAME_HASH_SIZE, 0, 0,
 
2577
            (hash_get_key) get_stmt_name_hash_key,
 
2578
            NULL,MYF(0));
 
2579
}
 
2580
 
 
2581
 
 
2582
/*
 
2583
  Insert a new statement to the thread-local statement map.
 
2584
 
 
2585
  DESCRIPTION
 
2586
    If there was an old statement with the same name, replace it with the
 
2587
    new one. Otherwise, check if max_prepared_stmt_count is not reached yet,
 
2588
    increase prepared_stmt_count, and insert the new statement. It's okay
 
2589
    to delete an old statement and fail to insert the new one.
 
2590
 
 
2591
  POSTCONDITIONS
 
2592
    All named prepared statements are also present in names_hash.
 
2593
    Statement names in names_hash are unique.
 
2594
    The statement is added only if prepared_stmt_count < max_prepard_stmt_count
 
2595
    last_found_statement always points to a valid statement or is 0
 
2596
 
 
2597
  RETURN VALUE
 
2598
    0  success
 
2599
    1  error: out of resources or max_prepared_stmt_count limit has been
 
2600
       reached. An error is sent to the client, the statement is deleted.
 
2601
*/
 
2602
 
 
2603
int Statement_map::insert(THD *thd, Statement *statement)
 
2604
{
 
2605
  if (my_hash_insert(&st_hash, (uchar*) statement))
 
2606
  {
 
2607
    /*
 
2608
      Delete is needed only in case of an insert failure. In all other
 
2609
      cases hash_delete will also delete the statement.
 
2610
    */
 
2611
    delete statement;
 
2612
    my_error(ER_OUT_OF_RESOURCES, MYF(0));
 
2613
    goto err_st_hash;
 
2614
  }
 
2615
  if (statement->name.str && my_hash_insert(&names_hash, (uchar*) statement))
 
2616
  {
 
2617
    my_error(ER_OUT_OF_RESOURCES, MYF(0));
 
2618
    goto err_names_hash;
 
2619
  }
 
2620
  pthread_mutex_lock(&LOCK_prepared_stmt_count);
 
2621
  /*
 
2622
    We don't check that prepared_stmt_count is <= max_prepared_stmt_count
 
2623
    because we would like to allow to lower the total limit
 
2624
    of prepared statements below the current count. In that case
 
2625
    no new statements can be added until prepared_stmt_count drops below
 
2626
    the limit.
 
2627
  */
 
2628
  if (prepared_stmt_count >= max_prepared_stmt_count)
 
2629
  {
 
2630
    pthread_mutex_unlock(&LOCK_prepared_stmt_count);
 
2631
    my_error(ER_MAX_PREPARED_STMT_COUNT_REACHED, MYF(0),
 
2632
             max_prepared_stmt_count);
 
2633
    goto err_max;
 
2634
  }
 
2635
  prepared_stmt_count++;
 
2636
  pthread_mutex_unlock(&LOCK_prepared_stmt_count);
 
2637
 
 
2638
  last_found_statement= statement;
 
2639
  return 0;
 
2640
 
 
2641
err_max:
 
2642
  if (statement->name.str)
 
2643
    hash_delete(&names_hash, (uchar*) statement);
 
2644
err_names_hash:
 
2645
  hash_delete(&st_hash, (uchar*) statement);
 
2646
err_st_hash:
 
2647
  return 1;
 
2648
}
 
2649
 
 
2650
 
 
2651
void Statement_map::close_transient_cursors()
 
2652
{
 
2653
#ifdef TO_BE_IMPLEMENTED
 
2654
  Statement *stmt;
 
2655
  while ((stmt= transient_cursor_list.head()))
 
2656
    stmt->close_cursor();                 /* deletes itself from the list */
 
2657
#endif
 
2658
}
 
2659
 
 
2660
 
 
2661
void Statement_map::erase(Statement *statement)
 
2662
{
 
2663
  if (statement == last_found_statement)
 
2664
    last_found_statement= 0;
 
2665
  if (statement->name.str)
 
2666
    hash_delete(&names_hash, (uchar *) statement);
 
2667
 
 
2668
  hash_delete(&st_hash, (uchar *) statement);
 
2669
  pthread_mutex_lock(&LOCK_prepared_stmt_count);
 
2670
  DBUG_ASSERT(prepared_stmt_count > 0);
 
2671
  prepared_stmt_count--;
 
2672
  pthread_mutex_unlock(&LOCK_prepared_stmt_count);
 
2673
}
 
2674
 
 
2675
 
 
2676
void Statement_map::reset()
 
2677
{
 
2678
  /* Must be first, hash_free will reset st_hash.records */
 
2679
  pthread_mutex_lock(&LOCK_prepared_stmt_count);
 
2680
  DBUG_ASSERT(prepared_stmt_count >= st_hash.records);
 
2681
  prepared_stmt_count-= st_hash.records;
 
2682
  pthread_mutex_unlock(&LOCK_prepared_stmt_count);
 
2683
 
 
2684
  my_hash_reset(&names_hash);
 
2685
  my_hash_reset(&st_hash);
 
2686
  last_found_statement= 0;
 
2687
}
 
2688
 
 
2689
 
 
2690
Statement_map::~Statement_map()
 
2691
{
 
2692
  /* Must go first, hash_free will reset st_hash.records */
 
2693
  pthread_mutex_lock(&LOCK_prepared_stmt_count);
 
2694
  DBUG_ASSERT(prepared_stmt_count >= st_hash.records);
 
2695
  prepared_stmt_count-= st_hash.records;
 
2696
  pthread_mutex_unlock(&LOCK_prepared_stmt_count);
 
2697
 
 
2698
  hash_free(&names_hash);
 
2699
  hash_free(&st_hash);
 
2700
}
 
2701
 
 
2702
bool select_dumpvar::send_data(List<Item> &items)
 
2703
{
 
2704
  List_iterator_fast<my_var> var_li(var_list);
 
2705
  List_iterator<Item> it(items);
 
2706
  Item *item;
 
2707
  my_var *mv;
 
2708
  DBUG_ENTER("select_dumpvar::send_data");
 
2709
 
 
2710
  if (unit->offset_limit_cnt)
 
2711
  {                                             // using limit offset,count
 
2712
    unit->offset_limit_cnt--;
 
2713
    DBUG_RETURN(0);
 
2714
  }
 
2715
  if (row_count++) 
 
2716
  {
 
2717
    my_message(ER_TOO_MANY_ROWS, ER(ER_TOO_MANY_ROWS), MYF(0));
 
2718
    DBUG_RETURN(1);
 
2719
  }
 
2720
  while ((mv= var_li++) && (item= it++))
 
2721
  {
 
2722
    if (mv->local)
 
2723
    {
 
2724
      if (thd->spcont->set_variable(thd, mv->offset, &item))
 
2725
            DBUG_RETURN(1);
 
2726
    }
 
2727
    else
 
2728
    {
 
2729
      Item_func_set_user_var *suv= new Item_func_set_user_var(mv->s, item);
 
2730
      if (suv->fix_fields(thd, 0))
 
2731
        DBUG_RETURN (1);
 
2732
      suv->save_item_result(item);
 
2733
      if (suv->update())
 
2734
        DBUG_RETURN (1);
 
2735
    }
 
2736
  }
 
2737
  DBUG_RETURN(thd->is_error());
 
2738
}
 
2739
 
 
2740
bool select_dumpvar::send_eof()
 
2741
{
 
2742
  if (! row_count)
 
2743
    push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
 
2744
                 ER_SP_FETCH_NO_DATA, ER(ER_SP_FETCH_NO_DATA));
 
2745
  /*
 
2746
    In order to remember the value of affected rows for ROW_COUNT()
 
2747
    function, SELECT INTO has to have an own SQLCOM.
 
2748
    TODO: split from SQLCOM_SELECT
 
2749
  */
 
2750
  ::my_ok(thd,row_count);
 
2751
  return 0;
 
2752
}
 
2753
 
 
2754
/****************************************************************************
 
2755
  TMP_TABLE_PARAM
 
2756
****************************************************************************/
 
2757
 
 
2758
void TMP_TABLE_PARAM::init()
 
2759
{
 
2760
  DBUG_ENTER("TMP_TABLE_PARAM::init");
 
2761
  DBUG_PRINT("enter", ("this: 0x%lx", (ulong)this));
 
2762
  field_count= sum_func_count= func_count= hidden_field_count= 0;
 
2763
  group_parts= group_length= group_null_parts= 0;
 
2764
  quick_group= 1;
 
2765
  table_charset= 0;
 
2766
  precomputed_group_by= 0;
 
2767
  DBUG_VOID_RETURN;
 
2768
}
 
2769
 
 
2770
 
 
2771
void thd_increment_bytes_sent(ulong length)
 
2772
{
 
2773
  THD *thd=current_thd;
 
2774
  if (likely(thd != 0))
 
2775
  { /* current_thd==0 when close_connection() calls net_send_error() */
 
2776
    thd->status_var.bytes_sent+= length;
 
2777
  }
 
2778
}
 
2779
 
 
2780
 
 
2781
void thd_increment_bytes_received(ulong length)
 
2782
{
 
2783
  current_thd->status_var.bytes_received+= length;
 
2784
}
 
2785
 
 
2786
 
 
2787
void thd_increment_net_big_packet_count(ulong length)
 
2788
{
 
2789
  current_thd->status_var.net_big_packet_count+= length;
 
2790
}
 
2791
 
 
2792
 
 
2793
void THD::set_status_var_init()
 
2794
{
 
2795
  bzero((char*) &status_var, sizeof(status_var));
 
2796
}
 
2797
 
 
2798
 
 
2799
void Security_context::init()
 
2800
{
 
2801
  host= user= priv_user= ip= 0;
 
2802
  host_or_ip= "connecting host";
 
2803
  priv_host[0]= '\0';
 
2804
  master_access= 0;
 
2805
#ifndef NO_EMBEDDED_ACCESS_CHECKS
 
2806
  db_access= NO_ACCESS;
 
2807
#endif
 
2808
}
 
2809
 
 
2810
 
 
2811
void Security_context::destroy()
 
2812
{
 
2813
  // If not pointer to constant
 
2814
  if (host != my_localhost)
 
2815
    safeFree(host);
 
2816
  if (user != delayed_user)
 
2817
    safeFree(user);
 
2818
  safeFree(ip);
 
2819
}
 
2820
 
 
2821
 
 
2822
void Security_context::skip_grants()
 
2823
{
 
2824
  /* privileges for the user are unknown everything is allowed */
 
2825
  host_or_ip= (char *)"";
 
2826
  master_access= ~NO_ACCESS;
 
2827
  priv_user= (char *)"";
 
2828
  *priv_host= '\0';
 
2829
}
 
2830
 
 
2831
 
 
2832
bool Security_context::set_user(char *user_arg)
 
2833
{
 
2834
  safeFree(user);
 
2835
  user= my_strdup(user_arg, MYF(0));
 
2836
  return user == 0;
 
2837
}
 
2838
 
 
2839
#ifndef NO_EMBEDDED_ACCESS_CHECKS
 
2840
/**
 
2841
  Initialize this security context from the passed in credentials
 
2842
  and activate it in the current thread.
 
2843
 
 
2844
  @param       thd
 
2845
  @param       definer_user
 
2846
  @param       definer_host
 
2847
  @param       db
 
2848
  @param[out]  backup  Save a pointer to the current security context
 
2849
                       in the thread. In case of success it points to the
 
2850
                       saved old context, otherwise it points to NULL.
 
2851
 
 
2852
 
 
2853
  During execution of a statement, multiple security contexts may
 
2854
  be needed:
 
2855
  - the security context of the authenticated user, used as the
 
2856
    default security context for all top-level statements
 
2857
  - in case of a view or a stored program, possibly the security
 
2858
    context of the definer of the routine, if the object is
 
2859
    defined with SQL SECURITY DEFINER option.
 
2860
 
 
2861
  The currently "active" security context is parameterized in THD
 
2862
  member security_ctx. By default, after a connection is
 
2863
  established, this member points at the "main" security context
 
2864
  - the credentials of the authenticated user.
 
2865
 
 
2866
  Later, if we would like to execute some sub-statement or a part
 
2867
  of a statement under credentials of a different user, e.g.
 
2868
  definer of a procedure, we authenticate this user in a local
 
2869
  instance of Security_context by means of this method (and
 
2870
  ultimately by means of acl_getroot_no_password), and make the
 
2871
  local instance active in the thread by re-setting
 
2872
  thd->security_ctx pointer.
 
2873
 
 
2874
  Note, that the life cycle and memory management of the "main" and
 
2875
  temporary security contexts are different.
 
2876
  For the main security context, the memory for user/host/ip is
 
2877
  allocated on system heap, and the THD class frees this memory in
 
2878
  its destructor. The only case when contents of the main security
 
2879
  context may change during its life time is when someone issued
 
2880
  CHANGE USER command.
 
2881
  Memory management of a "temporary" security context is
 
2882
  responsibility of the module that creates it.
 
2883
 
 
2884
  @retval TRUE  there is no user with the given credentials. The erro
 
2885
                is reported in the thread.
 
2886
  @retval FALSE success
 
2887
*/
 
2888
 
 
2889
bool
 
2890
Security_context::
 
2891
change_security_context(THD *thd,
 
2892
                        LEX_STRING *definer_user,
 
2893
                        LEX_STRING *definer_host,
 
2894
                        LEX_STRING *db,
 
2895
                        Security_context **backup)
 
2896
{
 
2897
  bool needs_change;
 
2898
 
 
2899
  DBUG_ENTER("Security_context::change_security_context");
 
2900
 
 
2901
  DBUG_ASSERT(definer_user->str && definer_host->str);
 
2902
 
 
2903
  *backup= NULL;
 
2904
  /*
 
2905
    The current security context may have NULL members
 
2906
    if we have just started the thread and not authenticated
 
2907
    any user. This use case is currently in events worker thread.
 
2908
  */
 
2909
  needs_change= (thd->security_ctx->priv_user == NULL ||
 
2910
                 strcmp(definer_user->str, thd->security_ctx->priv_user) ||
 
2911
                 thd->security_ctx->priv_host == NULL ||
 
2912
                 my_strcasecmp(system_charset_info, definer_host->str,
 
2913
                               thd->security_ctx->priv_host));
 
2914
  if (needs_change)
 
2915
  {
 
2916
    if (acl_getroot_no_password(this, definer_user->str, definer_host->str,
 
2917
                                definer_host->str, db->str))
 
2918
    {
 
2919
      my_error(ER_NO_SUCH_USER, MYF(0), definer_user->str,
 
2920
               definer_host->str);
 
2921
      DBUG_RETURN(TRUE);
 
2922
    }
 
2923
    *backup= thd->security_ctx;
 
2924
    thd->security_ctx= this;
 
2925
  }
 
2926
 
 
2927
  DBUG_RETURN(FALSE);
 
2928
}
 
2929
 
 
2930
 
 
2931
void
 
2932
Security_context::restore_security_context(THD *thd,
 
2933
                                           Security_context *backup)
 
2934
{
 
2935
  if (backup)
 
2936
    thd->security_ctx= backup;
 
2937
}
 
2938
#endif
 
2939
 
 
2940
 
 
2941
bool Security_context::user_matches(Security_context *them)
 
2942
{
 
2943
  return ((user != NULL) && (them->user != NULL) &&
 
2944
          !strcmp(user, them->user));
 
2945
}
 
2946
 
 
2947
 
 
2948
/****************************************************************************
 
2949
  Handling of open and locked tables states.
 
2950
 
 
2951
  This is used when we want to open/lock (and then close) some tables when
 
2952
  we already have a set of tables open and locked. We use these methods for
 
2953
  access to mysql.proc table to find definitions of stored routines.
 
2954
****************************************************************************/
 
2955
 
 
2956
void THD::reset_n_backup_open_tables_state(Open_tables_state *backup)
 
2957
{
 
2958
  DBUG_ENTER("reset_n_backup_open_tables_state");
 
2959
  backup->set_open_tables_state(this);
 
2960
  reset_open_tables_state();
 
2961
  state_flags|= Open_tables_state::BACKUPS_AVAIL;
 
2962
  DBUG_VOID_RETURN;
 
2963
}
 
2964
 
 
2965
 
 
2966
void THD::restore_backup_open_tables_state(Open_tables_state *backup)
 
2967
{
 
2968
  DBUG_ENTER("restore_backup_open_tables_state");
 
2969
  /*
 
2970
    Before we will throw away current open tables state we want
 
2971
    to be sure that it was properly cleaned up.
 
2972
  */
 
2973
  DBUG_ASSERT(open_tables == 0 && temporary_tables == 0 &&
 
2974
              handler_tables == 0 && derived_tables == 0 &&
 
2975
              lock == 0 && locked_tables == 0 &&
 
2976
              prelocked_mode == NON_PRELOCKED &&
 
2977
              m_reprepare_observer == NULL);
 
2978
  set_open_tables_state(backup);
 
2979
  DBUG_VOID_RETURN;
 
2980
}
 
2981
 
 
2982
/**
 
2983
  Check the killed state of a user thread
 
2984
  @param thd  user thread
 
2985
  @retval 0 the user thread is active
 
2986
  @retval 1 the user thread has been killed
 
2987
*/
 
2988
extern "C" int thd_killed(const MYSQL_THD thd)
 
2989
{
 
2990
  return(thd->killed);
 
2991
}
 
2992
 
 
2993
/**
 
2994
  Return the thread id of a user thread
 
2995
  @param thd user thread
 
2996
  @return thread id
 
2997
*/
 
2998
extern "C" unsigned long thd_get_thread_id(const MYSQL_THD thd)
 
2999
{
 
3000
  return((unsigned long)thd->thread_id);
 
3001
}
 
3002
 
 
3003
 
 
3004
#ifdef INNODB_COMPATIBILITY_HOOKS
 
3005
extern "C" struct charset_info_st *thd_charset(MYSQL_THD thd)
 
3006
{
 
3007
  return(thd->charset());
 
3008
}
 
3009
 
 
3010
/**
 
3011
  OBSOLETE : there's no way to ensure the string is null terminated.
 
3012
  Use thd_query_string instead()
 
3013
*/
 
3014
extern "C" char **thd_query(MYSQL_THD thd)
 
3015
{
 
3016
  return(&thd->query_string.str);
 
3017
}
 
3018
 
 
3019
/**
 
3020
  Get the current query string for the thread.
 
3021
 
 
3022
  @param The MySQL internal thread pointer
 
3023
  @return query string and length. May be non-null-terminated.
 
3024
*/
 
3025
extern "C" LEX_STRING * thd_query_string (MYSQL_THD thd)
 
3026
{
 
3027
  return(&thd->query_string);
 
3028
}
 
3029
 
 
3030
extern "C" int thd_slave_thread(const MYSQL_THD thd)
 
3031
{
 
3032
  return(thd->slave_thread);
 
3033
}
 
3034
 
 
3035
extern "C" int thd_non_transactional_update(const MYSQL_THD thd)
 
3036
{
 
3037
  return(thd->transaction.all.modified_non_trans_table);
 
3038
}
 
3039
 
 
3040
extern "C" int thd_binlog_format(const MYSQL_THD thd)
 
3041
{
 
3042
  if (mysql_bin_log.is_open() && (thd->options & OPTION_BIN_LOG))
 
3043
    return (int) thd->variables.binlog_format;
 
3044
  else
 
3045
    return BINLOG_FORMAT_UNSPEC;
 
3046
}
 
3047
 
 
3048
extern "C" void thd_mark_transaction_to_rollback(MYSQL_THD thd, bool all)
 
3049
{
 
3050
  mark_transaction_to_rollback(thd, all);
 
3051
}
 
3052
 
 
3053
extern "C" bool thd_binlog_filter_ok(const MYSQL_THD thd)
 
3054
{
 
3055
  return binlog_filter->db_ok(thd->db);
 
3056
}
 
3057
#endif // INNODB_COMPATIBILITY_HOOKS */
 
3058
 
 
3059
/****************************************************************************
 
3060
  Handling of statement states in functions and triggers.
 
3061
 
 
3062
  This is used to ensure that the function/trigger gets a clean state
 
3063
  to work with and does not cause any side effects of the calling statement.
 
3064
 
 
3065
  It also allows most stored functions and triggers to replicate even
 
3066
  if they are used items that would normally be stored in the binary
 
3067
  replication (like last_insert_id() etc...)
 
3068
 
 
3069
  The following things is done
 
3070
  - Disable binary logging for the duration of the statement
 
3071
  - Disable multi-result-sets for the duration of the statement
 
3072
  - Value of last_insert_id() is saved and restored
 
3073
  - Value set by 'SET INSERT_ID=#' is reset and restored
 
3074
  - Value for found_rows() is reset and restored
 
3075
  - examined_row_count is added to the total
 
3076
  - cuted_fields is added to the total
 
3077
  - new savepoint level is created and destroyed
 
3078
 
 
3079
  NOTES:
 
3080
    Seed for random() is saved for the first! usage of RAND()
 
3081
    We reset examined_row_count and cuted_fields and add these to the
 
3082
    result to ensure that if we have a bug that would reset these within
 
3083
    a function, we are not loosing any rows from the main statement.
 
3084
 
 
3085
    We do not reset value of last_insert_id().
 
3086
****************************************************************************/
 
3087
 
 
3088
void THD::reset_sub_statement_state(Sub_statement_state *backup,
 
3089
                                    uint new_state)
 
3090
{
 
3091
#ifndef EMBEDDED_LIBRARY
 
3092
  /* BUG#33029, if we are replicating from a buggy master, reset
 
3093
     auto_inc_intervals_forced to prevent substatement
 
3094
     (triggers/functions) from using erroneous INSERT_ID value
 
3095
   */
 
3096
  if (rpl_master_erroneous_autoinc(this))
 
3097
  {
 
3098
    DBUG_ASSERT(backup->auto_inc_intervals_forced.nb_elements() == 0);
 
3099
    auto_inc_intervals_forced.swap(&backup->auto_inc_intervals_forced);
 
3100
  }
 
3101
#endif
 
3102
  
 
3103
  backup->options=         options;
 
3104
  backup->in_sub_stmt=     in_sub_stmt;
 
3105
  backup->enable_slow_log= enable_slow_log;
 
3106
  backup->limit_found_rows= limit_found_rows;
 
3107
  backup->examined_row_count= examined_row_count;
 
3108
  backup->sent_row_count=   sent_row_count;
 
3109
  backup->cuted_fields=     cuted_fields;
 
3110
  backup->client_capabilities= client_capabilities;
 
3111
  backup->savepoints= transaction.savepoints;
 
3112
  backup->first_successful_insert_id_in_prev_stmt= 
 
3113
    first_successful_insert_id_in_prev_stmt;
 
3114
  backup->first_successful_insert_id_in_cur_stmt= 
 
3115
    first_successful_insert_id_in_cur_stmt;
 
3116
 
 
3117
  if ((!lex->requires_prelocking() || is_update_query(lex->sql_command)) &&
 
3118
      !current_stmt_binlog_row_based)
 
3119
  {
 
3120
    options&= ~OPTION_BIN_LOG;
 
3121
  }
 
3122
 
 
3123
  if ((backup->options & OPTION_BIN_LOG) && is_update_query(lex->sql_command)&&
 
3124
      !current_stmt_binlog_row_based)
 
3125
    mysql_bin_log.start_union_events(this, this->query_id);
 
3126
 
 
3127
  /* Disable result sets */
 
3128
  client_capabilities &= ~CLIENT_MULTI_RESULTS;
 
3129
  in_sub_stmt|= new_state;
 
3130
  examined_row_count= 0;
 
3131
  sent_row_count= 0;
 
3132
  cuted_fields= 0;
 
3133
  transaction.savepoints= 0;
 
3134
  first_successful_insert_id_in_cur_stmt= 0;
 
3135
}
 
3136
 
 
3137
 
 
3138
void THD::restore_sub_statement_state(Sub_statement_state *backup)
 
3139
{
 
3140
#ifndef EMBEDDED_LIBRARY
 
3141
  /* BUG#33029, if we are replicating from a buggy master, restore
 
3142
     auto_inc_intervals_forced so that the top statement can use the
 
3143
     INSERT_ID value set before this statement.
 
3144
   */
 
3145
  if (rpl_master_erroneous_autoinc(this))
 
3146
  {
 
3147
    backup->auto_inc_intervals_forced.swap(&auto_inc_intervals_forced);
 
3148
    DBUG_ASSERT(backup->auto_inc_intervals_forced.nb_elements() == 0);
 
3149
  }
 
3150
#endif
 
3151
 
 
3152
  /*
 
3153
    To save resources we want to release savepoints which were created
 
3154
    during execution of function or trigger before leaving their savepoint
 
3155
    level. It is enough to release first savepoint set on this level since
 
3156
    all later savepoints will be released automatically.
 
3157
  */
 
3158
  if (transaction.savepoints)
 
3159
  {
 
3160
    SAVEPOINT *sv;
 
3161
    for (sv= transaction.savepoints; sv->prev; sv= sv->prev)
 
3162
    {}
 
3163
    /* ha_release_savepoint() never returns error. */
 
3164
    (void)ha_release_savepoint(this, sv);
 
3165
  }
 
3166
  transaction.savepoints= backup->savepoints;
 
3167
  options=          backup->options;
 
3168
  in_sub_stmt=      backup->in_sub_stmt;
 
3169
  enable_slow_log=  backup->enable_slow_log;
 
3170
  first_successful_insert_id_in_prev_stmt= 
 
3171
    backup->first_successful_insert_id_in_prev_stmt;
 
3172
  first_successful_insert_id_in_cur_stmt= 
 
3173
    backup->first_successful_insert_id_in_cur_stmt;
 
3174
  limit_found_rows= backup->limit_found_rows;
 
3175
  sent_row_count=   backup->sent_row_count;
 
3176
  client_capabilities= backup->client_capabilities;
 
3177
  /*
 
3178
    If we've left sub-statement mode, reset the fatal error flag.
 
3179
    Otherwise keep the current value, to propagate it up the sub-statement
 
3180
    stack.
 
3181
  */
 
3182
  if (!in_sub_stmt)
 
3183
    is_fatal_sub_stmt_error= FALSE;
 
3184
 
 
3185
  if ((options & OPTION_BIN_LOG) && is_update_query(lex->sql_command) &&
 
3186
    !current_stmt_binlog_row_based)
 
3187
    mysql_bin_log.stop_union_events(this);
 
3188
 
 
3189
  /*
 
3190
    The following is added to the old values as we are interested in the
 
3191
    total complexity of the query
 
3192
  */
 
3193
  examined_row_count+= backup->examined_row_count;
 
3194
  cuted_fields+=       backup->cuted_fields;
 
3195
}
 
3196
 
 
3197
 
 
3198
void THD::set_statement(Statement *stmt)
 
3199
{
 
3200
  pthread_mutex_lock(&LOCK_thd_data);
 
3201
  Statement::set_statement(stmt);
 
3202
  pthread_mutex_unlock(&LOCK_thd_data);
 
3203
}
 
3204
 
 
3205
 
 
3206
/** Assign a new value to thd->query.  */
 
3207
 
 
3208
void THD::set_query(char *query_arg, uint32 query_length_arg)
 
3209
{
 
3210
  pthread_mutex_lock(&LOCK_thd_data);
 
3211
  set_query_inner(query_arg, query_length_arg);
 
3212
  pthread_mutex_unlock(&LOCK_thd_data);
 
3213
}
 
3214
 
 
3215
 
 
3216
/**
 
3217
  Mark transaction to rollback and mark error as fatal to a sub-statement.
 
3218
 
 
3219
  @param  thd   Thread handle
 
3220
  @param  all   TRUE <=> rollback main transaction.
 
3221
*/
 
3222
 
 
3223
void mark_transaction_to_rollback(THD *thd, bool all)
 
3224
{
 
3225
  if (thd)
 
3226
  {
 
3227
    thd->is_fatal_sub_stmt_error= TRUE;
 
3228
    thd->transaction_rollback_request= all;
 
3229
    /*
 
3230
      Aborted transactions can not be IGNOREd.
 
3231
      Switch off the IGNORE flag for the current
 
3232
      SELECT_LEX. This should allow my_error()
 
3233
      to report the error and abort the execution
 
3234
      flow, even in presence
 
3235
      of IGNORE clause.
 
3236
    */
 
3237
    if (thd->lex->current_select)
 
3238
      thd->lex->current_select->no_error= FALSE;
 
3239
  }
 
3240
}
 
3241
/***************************************************************************
 
3242
  Handling of XA id cacheing
 
3243
***************************************************************************/
 
3244
 
 
3245
pthread_mutex_t LOCK_xid_cache;
 
3246
HASH xid_cache;
 
3247
 
 
3248
extern "C" uchar *xid_get_hash_key(const uchar *, size_t *, my_bool);
 
3249
extern "C" void xid_free_hash(void *);
 
3250
 
 
3251
uchar *xid_get_hash_key(const uchar *ptr, size_t *length,
 
3252
                                  my_bool not_used __attribute__((unused)))
 
3253
{
 
3254
  *length=((XID_STATE*)ptr)->xid.key_length();
 
3255
  return ((XID_STATE*)ptr)->xid.key();
 
3256
}
 
3257
 
 
3258
void xid_free_hash(void *ptr)
 
3259
{
 
3260
  if (!((XID_STATE*)ptr)->in_thd)
 
3261
    my_free((uchar*)ptr, MYF(0));
 
3262
}
 
3263
 
 
3264
bool xid_cache_init()
 
3265
{
 
3266
  pthread_mutex_init(&LOCK_xid_cache, MY_MUTEX_INIT_FAST);
 
3267
  return hash_init(&xid_cache, &my_charset_bin, 100, 0, 0,
 
3268
                   xid_get_hash_key, xid_free_hash, 0) != 0;
 
3269
}
 
3270
 
 
3271
void xid_cache_free()
 
3272
{
 
3273
  if (hash_inited(&xid_cache))
 
3274
  {
 
3275
    hash_free(&xid_cache);
 
3276
    pthread_mutex_destroy(&LOCK_xid_cache);
 
3277
  }
 
3278
}
 
3279
 
 
3280
XID_STATE *xid_cache_search(XID *xid)
 
3281
{
 
3282
  pthread_mutex_lock(&LOCK_xid_cache);
 
3283
  XID_STATE *res=(XID_STATE *)hash_search(&xid_cache, xid->key(), xid->key_length());
 
3284
  pthread_mutex_unlock(&LOCK_xid_cache);
 
3285
  return res;
 
3286
}
 
3287
 
 
3288
 
 
3289
bool xid_cache_insert(XID *xid, enum xa_states xa_state)
 
3290
{
 
3291
  XID_STATE *xs;
 
3292
  my_bool res;
 
3293
  pthread_mutex_lock(&LOCK_xid_cache);
 
3294
  if (hash_search(&xid_cache, xid->key(), xid->key_length()))
 
3295
    res=0;
 
3296
  else if (!(xs=(XID_STATE *)my_malloc(sizeof(*xs), MYF(MY_WME))))
 
3297
    res=1;
 
3298
  else
 
3299
  {
 
3300
    xs->xa_state=xa_state;
 
3301
    xs->xid.set(xid);
 
3302
    xs->in_thd=0;
 
3303
    res=my_hash_insert(&xid_cache, (uchar*)xs);
 
3304
  }
 
3305
  pthread_mutex_unlock(&LOCK_xid_cache);
 
3306
  return res;
 
3307
}
 
3308
 
 
3309
 
 
3310
bool xid_cache_insert(XID_STATE *xid_state)
 
3311
{
 
3312
  pthread_mutex_lock(&LOCK_xid_cache);
 
3313
  DBUG_ASSERT(hash_search(&xid_cache, xid_state->xid.key(),
 
3314
                          xid_state->xid.key_length())==0);
 
3315
  my_bool res=my_hash_insert(&xid_cache, (uchar*)xid_state);
 
3316
  pthread_mutex_unlock(&LOCK_xid_cache);
 
3317
  return res;
 
3318
}
 
3319
 
 
3320
 
 
3321
void xid_cache_delete(XID_STATE *xid_state)
 
3322
{
 
3323
  pthread_mutex_lock(&LOCK_xid_cache);
 
3324
  hash_delete(&xid_cache, (uchar *)xid_state);
 
3325
  pthread_mutex_unlock(&LOCK_xid_cache);
 
3326
}
 
3327
 
 
3328
/*
 
3329
  Implementation of interface to write rows to the binary log through the
 
3330
  thread.  The thread is responsible for writing the rows it has
 
3331
  inserted/updated/deleted.
 
3332
*/
 
3333
 
 
3334
#ifndef MYSQL_CLIENT
 
3335
 
 
3336
/*
 
3337
  Template member function for ensuring that there is an rows log
 
3338
  event of the apropriate type before proceeding.
 
3339
 
 
3340
  PRE CONDITION:
 
3341
    - Events of type 'RowEventT' have the type code 'type_code'.
 
3342
    
 
3343
  POST CONDITION:
 
3344
    If a non-NULL pointer is returned, the pending event for thread 'thd' will
 
3345
    be an event of type 'RowEventT' (which have the type code 'type_code')
 
3346
    will either empty or have enough space to hold 'needed' bytes.  In
 
3347
    addition, the columns bitmap will be correct for the row, meaning that
 
3348
    the pending event will be flushed if the columns in the event differ from
 
3349
    the columns suppled to the function.
 
3350
 
 
3351
  RETURNS
 
3352
    If no error, a non-NULL pending event (either one which already existed or
 
3353
    the newly created one).
 
3354
    If error, NULL.
 
3355
 */
 
3356
 
 
3357
template <class RowsEventT> Rows_log_event* 
 
3358
THD::binlog_prepare_pending_rows_event(TABLE* table, uint32 serv_id,
 
3359
                                       MY_BITMAP const* cols,
 
3360
                                       size_t colcnt,
 
3361
                                       size_t needed,
 
3362
                                       bool is_transactional,
 
3363
                                       RowsEventT *hint __attribute__((unused)))
 
3364
{
 
3365
  DBUG_ENTER("binlog_prepare_pending_rows_event");
 
3366
  /* Pre-conditions */
 
3367
  DBUG_ASSERT(table->s->table_map_id != ~0UL);
 
3368
 
 
3369
  /* Fetch the type code for the RowsEventT template parameter */
 
3370
  int const type_code= RowsEventT::TYPE_CODE;
 
3371
 
 
3372
  /*
 
3373
    There is no good place to set up the transactional data, so we
 
3374
    have to do it here.
 
3375
  */
 
3376
  if (binlog_setup_trx_data())
 
3377
    DBUG_RETURN(NULL);
 
3378
 
 
3379
  Rows_log_event* pending= binlog_get_pending_rows_event();
 
3380
 
 
3381
  if (unlikely(pending && !pending->is_valid()))
 
3382
    DBUG_RETURN(NULL);
 
3383
 
 
3384
  /*
 
3385
    Check if the current event is non-NULL and a write-rows
 
3386
    event. Also check if the table provided is mapped: if it is not,
 
3387
    then we have switched to writing to a new table.
 
3388
    If there is no pending event, we need to create one. If there is a pending
 
3389
    event, but it's not about the same table id, or not of the same type
 
3390
    (between Write, Update and Delete), or not the same affected columns, or
 
3391
    going to be too big, flush this event to disk and create a new pending
 
3392
    event.
 
3393
  */
 
3394
  if (!pending ||
 
3395
      pending->server_id != serv_id || 
 
3396
      pending->get_table_id() != table->s->table_map_id ||
 
3397
      pending->get_type_code() != type_code || 
 
3398
      pending->get_data_size() + needed > opt_binlog_rows_event_max_size || 
 
3399
      pending->get_width() != colcnt ||
 
3400
      !bitmap_cmp(pending->get_cols(), cols)) 
 
3401
  {
 
3402
    /* Create a new RowsEventT... */
 
3403
    Rows_log_event* const
 
3404
        ev= new RowsEventT(this, table, table->s->table_map_id, cols,
 
3405
                           is_transactional);
 
3406
    if (unlikely(!ev))
 
3407
      DBUG_RETURN(NULL);
 
3408
    ev->server_id= serv_id; // I don't like this, it's too easy to forget.
 
3409
    /*
 
3410
      flush the pending event and replace it with the newly created
 
3411
      event...
 
3412
    */
 
3413
    if (unlikely(mysql_bin_log.flush_and_set_pending_rows_event(this, ev)))
 
3414
    {
 
3415
      delete ev;
 
3416
      DBUG_RETURN(NULL);
 
3417
    }
 
3418
 
 
3419
    DBUG_RETURN(ev);               /* This is the new pending event */
 
3420
  }
 
3421
  DBUG_RETURN(pending);        /* This is the current pending event */
 
3422
}
 
3423
 
 
3424
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
 
3425
/*
 
3426
  Instantiate the versions we need, we have -fno-implicit-template as
 
3427
  compiling option.
 
3428
*/
 
3429
template Rows_log_event*
 
3430
THD::binlog_prepare_pending_rows_event(TABLE*, uint32, MY_BITMAP const*,
 
3431
                                       size_t, size_t, bool,
 
3432
                                       Write_rows_log_event*);
 
3433
 
 
3434
template Rows_log_event*
 
3435
THD::binlog_prepare_pending_rows_event(TABLE*, uint32, MY_BITMAP const*,
 
3436
                                       size_t colcnt, size_t, bool,
 
3437
                                       Delete_rows_log_event *);
 
3438
 
 
3439
template Rows_log_event* 
 
3440
THD::binlog_prepare_pending_rows_event(TABLE*, uint32, MY_BITMAP const*,
 
3441
                                       size_t colcnt, size_t, bool,
 
3442
                                       Update_rows_log_event *);
 
3443
#endif
 
3444
 
 
3445
#ifdef NOT_USED
 
3446
static char const* 
 
3447
field_type_name(enum_field_types type) 
 
3448
{
 
3449
  switch (type) {
 
3450
  case MYSQL_TYPE_DECIMAL:
 
3451
    return "MYSQL_TYPE_DECIMAL";
 
3452
  case MYSQL_TYPE_TINY:
 
3453
    return "MYSQL_TYPE_TINY";
 
3454
  case MYSQL_TYPE_SHORT:
 
3455
    return "MYSQL_TYPE_SHORT";
 
3456
  case MYSQL_TYPE_LONG:
 
3457
    return "MYSQL_TYPE_LONG";
 
3458
  case MYSQL_TYPE_FLOAT:
 
3459
    return "MYSQL_TYPE_FLOAT";
 
3460
  case MYSQL_TYPE_DOUBLE:
 
3461
    return "MYSQL_TYPE_DOUBLE";
 
3462
  case MYSQL_TYPE_NULL:
 
3463
    return "MYSQL_TYPE_NULL";
 
3464
  case MYSQL_TYPE_TIMESTAMP:
 
3465
    return "MYSQL_TYPE_TIMESTAMP";
 
3466
  case MYSQL_TYPE_LONGLONG:
 
3467
    return "MYSQL_TYPE_LONGLONG";
 
3468
  case MYSQL_TYPE_INT24:
 
3469
    return "MYSQL_TYPE_INT24";
 
3470
  case MYSQL_TYPE_DATE:
 
3471
    return "MYSQL_TYPE_DATE";
 
3472
  case MYSQL_TYPE_TIME:
 
3473
    return "MYSQL_TYPE_TIME";
 
3474
  case MYSQL_TYPE_DATETIME:
 
3475
    return "MYSQL_TYPE_DATETIME";
 
3476
  case MYSQL_TYPE_YEAR:
 
3477
    return "MYSQL_TYPE_YEAR";
 
3478
  case MYSQL_TYPE_NEWDATE:
 
3479
    return "MYSQL_TYPE_NEWDATE";
 
3480
  case MYSQL_TYPE_VARCHAR:
 
3481
    return "MYSQL_TYPE_VARCHAR";
 
3482
  case MYSQL_TYPE_BIT:
 
3483
    return "MYSQL_TYPE_BIT";
 
3484
  case MYSQL_TYPE_NEWDECIMAL:
 
3485
    return "MYSQL_TYPE_NEWDECIMAL";
 
3486
  case MYSQL_TYPE_ENUM:
 
3487
    return "MYSQL_TYPE_ENUM";
 
3488
  case MYSQL_TYPE_SET:
 
3489
    return "MYSQL_TYPE_SET";
 
3490
  case MYSQL_TYPE_TINY_BLOB:
 
3491
    return "MYSQL_TYPE_TINY_BLOB";
 
3492
  case MYSQL_TYPE_MEDIUM_BLOB:
 
3493
    return "MYSQL_TYPE_MEDIUM_BLOB";
 
3494
  case MYSQL_TYPE_LONG_BLOB:
 
3495
    return "MYSQL_TYPE_LONG_BLOB";
 
3496
  case MYSQL_TYPE_BLOB:
 
3497
    return "MYSQL_TYPE_BLOB";
 
3498
  case MYSQL_TYPE_VAR_STRING:
 
3499
    return "MYSQL_TYPE_VAR_STRING";
 
3500
  case MYSQL_TYPE_STRING:
 
3501
    return "MYSQL_TYPE_STRING";
 
3502
  case MYSQL_TYPE_GEOMETRY:
 
3503
    return "MYSQL_TYPE_GEOMETRY";
 
3504
  }
 
3505
  return "Unknown";
 
3506
}
 
3507
#endif
 
3508
 
 
3509
 
 
3510
namespace {
 
3511
  /**
 
3512
     Class to handle temporary allocation of memory for row data.
 
3513
 
 
3514
     The responsibilities of the class is to provide memory for
 
3515
     packing one or two rows of packed data (depending on what
 
3516
     constructor is called).
 
3517
 
 
3518
     In order to make the allocation more efficient for "simple" rows,
 
3519
     i.e., rows that do not contain any blobs, a pointer to the
 
3520
     allocated memory is of memory is stored in the table structure
 
3521
     for simple rows.  If memory for a table containing a blob field
 
3522
     is requested, only memory for that is allocated, and subsequently
 
3523
     released when the object is destroyed.
 
3524
 
 
3525
   */
 
3526
  class Row_data_memory {
 
3527
  public:
 
3528
    /**
 
3529
      Build an object to keep track of a block-local piece of memory
 
3530
      for storing a row of data.
 
3531
 
 
3532
      @param table
 
3533
      Table where the pre-allocated memory is stored.
 
3534
 
 
3535
      @param length
 
3536
      Length of data that is needed, if the record contain blobs.
 
3537
     */
 
3538
    Row_data_memory(TABLE *table, size_t const len1)
 
3539
      : m_memory(0)
 
3540
    {
 
3541
#ifndef DBUG_OFF
 
3542
      m_alloc_checked= FALSE;
 
3543
#endif
 
3544
      allocate_memory(table, len1);
 
3545
      m_ptr[0]= has_memory() ? m_memory : 0;
 
3546
      m_ptr[1]= 0;
 
3547
    }
 
3548
 
 
3549
    Row_data_memory(TABLE *table, size_t const len1, size_t const len2)
 
3550
      : m_memory(0)
 
3551
    {
 
3552
#ifndef DBUG_OFF
 
3553
      m_alloc_checked= FALSE;
 
3554
#endif
 
3555
      allocate_memory(table, len1 + len2);
 
3556
      m_ptr[0]= has_memory() ? m_memory        : 0;
 
3557
      m_ptr[1]= has_memory() ? m_memory + len1 : 0;
 
3558
    }
 
3559
 
 
3560
    ~Row_data_memory()
 
3561
    {
 
3562
      if (m_memory != 0 && m_release_memory_on_destruction)
 
3563
        my_free((uchar*) m_memory, MYF(MY_WME));
 
3564
    }
 
3565
 
 
3566
    /**
 
3567
       Is there memory allocated?
 
3568
 
 
3569
       @retval true There is memory allocated
 
3570
       @retval false Memory allocation failed
 
3571
     */
 
3572
    bool has_memory() const {
 
3573
#ifndef DBUG_OFF
 
3574
      m_alloc_checked= TRUE;
 
3575
#endif
 
3576
      return m_memory != 0;
 
3577
    }
 
3578
 
 
3579
    uchar *slot(uint s)
 
3580
    {
 
3581
      DBUG_ASSERT(s < sizeof(m_ptr)/sizeof(*m_ptr));
 
3582
      DBUG_ASSERT(m_ptr[s] != 0);
 
3583
      DBUG_ASSERT(m_alloc_checked == TRUE);
 
3584
      return m_ptr[s];
 
3585
    }
 
3586
 
 
3587
  private:
 
3588
    void allocate_memory(TABLE *const table, size_t const total_length)
 
3589
    {
 
3590
      if (table->s->blob_fields == 0)
 
3591
      {
 
3592
        /*
 
3593
          The maximum length of a packed record is less than this
 
3594
          length. We use this value instead of the supplied length
 
3595
          when allocating memory for records, since we don't know how
 
3596
          the memory will be used in future allocations.
 
3597
 
 
3598
          Since table->s->reclength is for unpacked records, we have
 
3599
          to add two bytes for each field, which can potentially be
 
3600
          added to hold the length of a packed field.
 
3601
        */
 
3602
        size_t const maxlen= table->s->reclength + 2 * table->s->fields;
 
3603
 
 
3604
        /*
 
3605
          Allocate memory for two records if memory hasn't been
 
3606
          allocated. We allocate memory for two records so that it can
 
3607
          be used when processing update rows as well.
 
3608
        */
 
3609
        if (table->write_row_record == 0)
 
3610
          table->write_row_record=
 
3611
            (uchar *) alloc_root(&table->mem_root, 2 * maxlen);
 
3612
        m_memory= table->write_row_record;
 
3613
        m_release_memory_on_destruction= FALSE;
 
3614
      }
 
3615
      else
 
3616
      {
 
3617
        m_memory= (uchar *) my_malloc(total_length, MYF(MY_WME));
 
3618
        m_release_memory_on_destruction= TRUE;
 
3619
      }
 
3620
    }
 
3621
 
 
3622
#ifndef DBUG_OFF
 
3623
    mutable bool m_alloc_checked;
 
3624
#endif
 
3625
    bool m_release_memory_on_destruction;
 
3626
    uchar *m_memory;
 
3627
    uchar *m_ptr[2];
 
3628
  };
 
3629
}
 
3630
 
 
3631
 
 
3632
int THD::binlog_write_row(TABLE* table, bool is_trans, 
 
3633
                          MY_BITMAP const* cols, size_t colcnt, 
 
3634
                          uchar const *record) 
 
3635
 
3636
  DBUG_ASSERT(current_stmt_binlog_row_based && mysql_bin_log.is_open());
 
3637
 
 
3638
  /*
 
3639
    Pack records into format for transfer. We are allocating more
 
3640
    memory than needed, but that doesn't matter.
 
3641
  */
 
3642
  Row_data_memory memory(table, max_row_length(table, record));
 
3643
  if (!memory.has_memory())
 
3644
    return HA_ERR_OUT_OF_MEM;
 
3645
 
 
3646
  uchar *row_data= memory.slot(0);
 
3647
 
 
3648
  size_t const len= pack_row(table, cols, row_data, record);
 
3649
 
 
3650
  Rows_log_event* const ev=
 
3651
    binlog_prepare_pending_rows_event(table, server_id, cols, colcnt,
 
3652
                                      len, is_trans,
 
3653
                                      static_cast<Write_rows_log_event*>(0));
 
3654
 
 
3655
  if (unlikely(ev == 0))
 
3656
    return HA_ERR_OUT_OF_MEM;
 
3657
 
 
3658
  return ev->add_row_data(row_data, len);
 
3659
}
 
3660
 
 
3661
int THD::binlog_update_row(TABLE* table, bool is_trans,
 
3662
                           MY_BITMAP const* cols, size_t colcnt,
 
3663
                           const uchar *before_record,
 
3664
                           const uchar *after_record)
 
3665
 
3666
  DBUG_ASSERT(current_stmt_binlog_row_based && mysql_bin_log.is_open());
 
3667
 
 
3668
  size_t const before_maxlen = max_row_length(table, before_record);
 
3669
  size_t const after_maxlen  = max_row_length(table, after_record);
 
3670
 
 
3671
  Row_data_memory row_data(table, before_maxlen, after_maxlen);
 
3672
  if (!row_data.has_memory())
 
3673
    return HA_ERR_OUT_OF_MEM;
 
3674
 
 
3675
  uchar *before_row= row_data.slot(0);
 
3676
  uchar *after_row= row_data.slot(1);
 
3677
 
 
3678
  size_t const before_size= pack_row(table, cols, before_row,
 
3679
                                        before_record);
 
3680
  size_t const after_size= pack_row(table, cols, after_row,
 
3681
                                       after_record);
 
3682
 
 
3683
  /*
 
3684
    Don't print debug messages when running valgrind since they can
 
3685
    trigger false warnings.
 
3686
   */
 
3687
#ifndef HAVE_purify
 
3688
  DBUG_DUMP("before_record", before_record, table->s->reclength);
 
3689
  DBUG_DUMP("after_record",  after_record, table->s->reclength);
 
3690
  DBUG_DUMP("before_row",    before_row, before_size);
 
3691
  DBUG_DUMP("after_row",     after_row, after_size);
 
3692
#endif
 
3693
 
 
3694
  Rows_log_event* const ev=
 
3695
    binlog_prepare_pending_rows_event(table, server_id, cols, colcnt,
 
3696
                                      before_size + after_size, is_trans,
 
3697
                                      static_cast<Update_rows_log_event*>(0));
 
3698
 
 
3699
  if (unlikely(ev == 0))
 
3700
    return HA_ERR_OUT_OF_MEM;
 
3701
 
 
3702
  return
 
3703
    ev->add_row_data(before_row, before_size) ||
 
3704
    ev->add_row_data(after_row, after_size);
 
3705
}
 
3706
 
 
3707
int THD::binlog_delete_row(TABLE* table, bool is_trans, 
 
3708
                           MY_BITMAP const* cols, size_t colcnt,
 
3709
                           uchar const *record)
 
3710
 
3711
  DBUG_ASSERT(current_stmt_binlog_row_based && mysql_bin_log.is_open());
 
3712
 
 
3713
  /* 
 
3714
     Pack records into format for transfer. We are allocating more
 
3715
     memory than needed, but that doesn't matter.
 
3716
  */
 
3717
  Row_data_memory memory(table, max_row_length(table, record));
 
3718
  if (unlikely(!memory.has_memory()))
 
3719
    return HA_ERR_OUT_OF_MEM;
 
3720
 
 
3721
  uchar *row_data= memory.slot(0);
 
3722
 
 
3723
  size_t const len= pack_row(table, cols, row_data, record);
 
3724
 
 
3725
  Rows_log_event* const ev=
 
3726
    binlog_prepare_pending_rows_event(table, server_id, cols, colcnt,
 
3727
                                      len, is_trans,
 
3728
                                      static_cast<Delete_rows_log_event*>(0));
 
3729
 
 
3730
  if (unlikely(ev == 0))
 
3731
    return HA_ERR_OUT_OF_MEM;
 
3732
 
 
3733
  return ev->add_row_data(row_data, len);
 
3734
}
 
3735
 
 
3736
 
 
3737
int THD::binlog_remove_pending_rows_event(bool clear_maps)
 
3738
{
 
3739
  DBUG_ENTER("THD::binlog_remove_pending_rows_event");
 
3740
 
 
3741
  if (!mysql_bin_log.is_open())
 
3742
    DBUG_RETURN(0);
 
3743
 
 
3744
  mysql_bin_log.remove_pending_rows_event(this);
 
3745
 
 
3746
  if (clear_maps)
 
3747
    binlog_table_maps= 0;
 
3748
 
 
3749
  DBUG_RETURN(0);
 
3750
}
 
3751
 
 
3752
int THD::binlog_flush_pending_rows_event(bool stmt_end)
 
3753
{
 
3754
  DBUG_ENTER("THD::binlog_flush_pending_rows_event");
 
3755
  /*
 
3756
    We shall flush the pending event even if we are not in row-based
 
3757
    mode: it might be the case that we left row-based mode before
 
3758
    flushing anything (e.g., if we have explicitly locked tables).
 
3759
   */
 
3760
  if (!mysql_bin_log.is_open())
 
3761
    DBUG_RETURN(0);
 
3762
 
 
3763
  /*
 
3764
    Mark the event as the last event of a statement if the stmt_end
 
3765
    flag is set.
 
3766
  */
 
3767
  int error= 0;
 
3768
  if (Rows_log_event *pending= binlog_get_pending_rows_event())
 
3769
  {
 
3770
    if (stmt_end)
 
3771
    {
 
3772
      pending->set_flags(Rows_log_event::STMT_END_F);
 
3773
      pending->flags|= LOG_EVENT_UPDATE_TABLE_MAP_VERSION_F;
 
3774
      binlog_table_maps= 0;
 
3775
    }
 
3776
 
 
3777
    error= mysql_bin_log.flush_and_set_pending_rows_event(this, 0);
 
3778
  }
 
3779
 
 
3780
  DBUG_RETURN(error);
 
3781
}
 
3782
 
 
3783
 
 
3784
#if !defined(DBUG_OFF) && !defined(_lint)
 
3785
static const char *
 
3786
show_query_type(THD::enum_binlog_query_type qtype)
 
3787
{
 
3788
  switch (qtype) {
 
3789
  case THD::ROW_QUERY_TYPE:
 
3790
    return "ROW";
 
3791
  case THD::STMT_QUERY_TYPE:
 
3792
    return "STMT";
 
3793
  case THD::MYSQL_QUERY_TYPE:
 
3794
    return "MYSQL";
 
3795
  case THD::QUERY_TYPE_COUNT:
 
3796
  default:
 
3797
    DBUG_ASSERT(0 <= qtype && qtype < THD::QUERY_TYPE_COUNT);
 
3798
  }
 
3799
  static char buf[64];
 
3800
  sprintf(buf, "UNKNOWN#%d", qtype);
 
3801
  return buf;
 
3802
}
 
3803
#endif
 
3804
 
 
3805
 
 
3806
/*
 
3807
  Member function that will log query, either row-based or
 
3808
  statement-based depending on the value of the 'current_stmt_binlog_row_based'
 
3809
  the value of the 'qtype' flag.
 
3810
 
 
3811
  This function should be called after the all calls to ha_*_row()
 
3812
  functions have been issued, but before tables are unlocked and
 
3813
  closed.
 
3814
 
 
3815
  OBSERVE
 
3816
    There shall be no writes to any system table after calling
 
3817
    binlog_query(), so these writes has to be moved to before the call
 
3818
    of binlog_query() for correct functioning.
 
3819
 
 
3820
    This is necessesary not only for RBR, but the master might crash
 
3821
    after binlogging the query but before changing the system tables.
 
3822
    This means that the slave and the master are not in the same state
 
3823
    (after the master has restarted), so therefore we have to
 
3824
    eliminate this problem.
 
3825
 
 
3826
  RETURN VALUE
 
3827
    Error code, or 0 if no error.
 
3828
*/
 
3829
int THD::binlog_query(THD::enum_binlog_query_type qtype, char const *query_arg,
 
3830
                      ulong query_len, bool is_trans, bool suppress_use,
 
3831
                      int errcode)
 
3832
{
 
3833
  DBUG_ENTER("THD::binlog_query");
 
3834
  DBUG_PRINT("enter", ("qtype: %s  query: '%s'",
 
3835
                       show_query_type(qtype), query_arg));
 
3836
  DBUG_ASSERT(query_arg && mysql_bin_log.is_open());
 
3837
 
 
3838
  /*
 
3839
    If we are not in prelocked mode, mysql_unlock_tables() will be
 
3840
    called after this binlog_query(), so we have to flush the pending
 
3841
    rows event with the STMT_END_F set to unlock all tables at the
 
3842
    slave side as well.
 
3843
 
 
3844
    If we are in prelocked mode, the flushing will be done inside the
 
3845
    top-most close_thread_tables().
 
3846
  */
 
3847
  if (this->prelocked_mode == NON_PRELOCKED)
 
3848
    if (int error= binlog_flush_pending_rows_event(TRUE))
 
3849
      DBUG_RETURN(error);
 
3850
 
 
3851
  /*
 
3852
    If we are in statement mode and trying to log an unsafe statement,
 
3853
    we should print a warning.
 
3854
  */
 
3855
  if (sql_log_bin_toplevel && lex->is_stmt_unsafe() &&
 
3856
      variables.binlog_format == BINLOG_FORMAT_STMT && 
 
3857
      binlog_filter->db_ok(this->db))
 
3858
  {
 
3859
   /*
 
3860
     A warning can be elevated a error when STRICT sql mode.
 
3861
     But we don't want to elevate binlog warning to error here.
 
3862
   */
 
3863
    push_warning(this, MYSQL_ERROR::WARN_LEVEL_NOTE,
 
3864
                 ER_BINLOG_UNSAFE_STATEMENT,
 
3865
                 ER(ER_BINLOG_UNSAFE_STATEMENT));
 
3866
    if (global_system_variables.log_warnings &&
 
3867
        !(binlog_flags & BINLOG_FLAG_UNSAFE_STMT_PRINTED))
 
3868
    {
 
3869
      sql_print_warning("%s Statement: %.*s",
 
3870
                        ER(ER_BINLOG_UNSAFE_STATEMENT),
 
3871
                        MYSQL_ERRMSG_SIZE, query_arg);
 
3872
      binlog_flags|= BINLOG_FLAG_UNSAFE_STMT_PRINTED;
 
3873
    }
 
3874
  }
 
3875
 
 
3876
  switch (qtype) {
 
3877
  case THD::ROW_QUERY_TYPE:
 
3878
    DBUG_PRINT("debug",
 
3879
               ("current_stmt_binlog_row_based: %d",
 
3880
                current_stmt_binlog_row_based));
 
3881
    if (current_stmt_binlog_row_based)
 
3882
      DBUG_RETURN(0);
 
3883
    /* Otherwise, we fall through */
 
3884
  case THD::MYSQL_QUERY_TYPE:
 
3885
    /*
 
3886
      Using this query type is a conveniece hack, since we have been
 
3887
      moving back and forth between using RBR for replication of
 
3888
      system tables and not using it.
 
3889
 
 
3890
      Make sure to change in check_table_binlog_row_based() according
 
3891
      to how you treat this.
 
3892
    */
 
3893
  case THD::STMT_QUERY_TYPE:
 
3894
    /*
 
3895
      The MYSQL_LOG::write() function will set the STMT_END_F flag and
 
3896
      flush the pending rows event if necessary.
 
3897
     */
 
3898
    {
 
3899
      Query_log_event qinfo(this, query_arg, query_len, is_trans, suppress_use,
 
3900
                            errcode);
 
3901
      qinfo.flags|= LOG_EVENT_UPDATE_TABLE_MAP_VERSION_F;
 
3902
      /*
 
3903
        Binlog table maps will be irrelevant after a Query_log_event
 
3904
        (they are just removed on the slave side) so after the query
 
3905
        log event is written to the binary log, we pretend that no
 
3906
        table maps were written.
 
3907
       */
 
3908
      int error= mysql_bin_log.write(&qinfo);
 
3909
      binlog_table_maps= 0;
 
3910
      DBUG_RETURN(error);
 
3911
    }
 
3912
    break;
 
3913
 
 
3914
  case THD::QUERY_TYPE_COUNT:
 
3915
  default:
 
3916
    DBUG_ASSERT(0 <= qtype && qtype < QUERY_TYPE_COUNT);
 
3917
  }
 
3918
  DBUG_RETURN(0);
 
3919
}
 
3920
 
 
3921
bool Discrete_intervals_list::append(ulonglong start, ulonglong val,
 
3922
                                 ulonglong incr)
 
3923
{
 
3924
  DBUG_ENTER("Discrete_intervals_list::append");
 
3925
  /* first, see if this can be merged with previous */
 
3926
  if ((head == NULL) || tail->merge_if_contiguous(start, val, incr))
 
3927
  {
 
3928
    /* it cannot, so need to add a new interval */
 
3929
    Discrete_interval *new_interval= new Discrete_interval(start, val, incr);
 
3930
    DBUG_RETURN(append(new_interval));
 
3931
  }
 
3932
  DBUG_RETURN(0);
 
3933
}
 
3934
 
 
3935
bool Discrete_intervals_list::append(Discrete_interval *new_interval)
 
3936
{
 
3937
  DBUG_ENTER("Discrete_intervals_list::append");
 
3938
  if (unlikely(new_interval == NULL))
 
3939
    DBUG_RETURN(1);
 
3940
  DBUG_PRINT("info",("adding new auto_increment interval"));
 
3941
  if (head == NULL)
 
3942
    head= current= new_interval;
 
3943
  else
 
3944
    tail->next= new_interval;
 
3945
  tail= new_interval;
 
3946
  elements++;
 
3947
  DBUG_RETURN(0);
 
3948
}
 
3949
 
 
3950
#endif /* !defined(MYSQL_CLIENT) */