~drizzle-trunk/drizzle/development

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