~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to sql/sql_class.cc

  • Committer: brian
  • Date: 2008-06-25 05:29:13 UTC
  • Revision ID: brian@localhost.localdomain-20080625052913-6upwo0jsrl4lnapl
clean slate

Show diffs side-by-side

added added

removed removed

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