~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
1055.2.13 by Jay Pipes
Documentation and style fixes in Session class. Doxygen should finally pick up the Statement and Session classes now. Removes the silly Query_arena class, as it's not needed anymore.
20
/**
21
 * @file Implementation of the Session class and API
22
 */
23
243.1.17 by Jay Pipes
FINAL PHASE removal of mysql_priv.h (Bye, bye my friend.)
24
#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.
25
#include <drizzled/session.h>
1 by brian
clean slate
26
#include <sys/stat.h>
212.5.13 by Monty Taylor
Moved my_sys/my_pthread/my_nosys and mysys_err to mysys.
27
#include <mysys/mysys_err.h>
549 by Monty Taylor
Took gettext.h out of header files.
28
#include <drizzled/error.h>
561.1.3 by Monty Taylor
Split some more things out of common_includes.h.
29
#include <drizzled/query_id.h>
520.6.7 by Monty Taylor
Moved a bunch of crap out of common_includes.
30
#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.
31
#include <drizzled/sql_base.h>
670.2.4 by Monty Taylor
Removed more stuff from the headers.
32
#include <drizzled/lock.h>
675 by Brian Aker
Cleanup around item includes.
33
#include <drizzled/item/cache.h>
676 by Brian Aker
Merge of Monty's work.
34
#include <drizzled/item/float.h>
642.1.17 by Lee
header file clean up
35
#include <drizzled/item/return_int.h>
675 by Brian Aker
Cleanup around item includes.
36
#include <drizzled/item/empty_string.h>
793 by Brian Aker
Pass through on refactoring functions to clases.
37
#include <drizzled/show.h>
960.1.1 by Monty Taylor
First pass at scheduler plugin.
38
#include <drizzled/scheduling.h>
1 by brian
clean slate
39
1067.4.1 by Nathan Williams
First few changes at converting cmin to std::min.
40
#include <algorithm>
41
42
using namespace std;
43
1085.1.2 by Monty Taylor
Fixed -Wmissing-declarations
44
extern "C"
45
{
46
  unsigned char *get_var_key(user_var_entry *entry, size_t *length, bool );
47
  void free_user_var(user_var_entry *entry);
48
}
1067.4.1 by Nathan Williams
First few changes at converting cmin to std::min.
49
1 by brian
clean slate
50
/*
51
  The following is used to initialise Table_ident with a internal
52
  table name
53
*/
54
char internal_table_name[2]= "*";
55
char empty_c_string[1]= {0};    /* used for not defined db */
56
520.1.21 by Brian Aker
THD -> Session rename
57
const char * const Session::DEFAULT_WHERE= "field list";
670.2.1 by Monty Taylor
Moved pthread keys
58
extern pthread_key_t THR_Session;
59
extern pthread_key_t THR_Mem_root;
1 by brian
clean slate
60
61
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
62
/* Used templates */
63
template class List<Key>;
64
template class List_iterator<Key>;
65
template class List<Key_part_spec>;
66
template class List_iterator<Key_part_spec>;
67
template class List<Alter_drop>;
68
template class List_iterator<Alter_drop>;
69
template class List<Alter_column>;
70
template class List_iterator<Alter_column>;
71
#endif
72
73
/****************************************************************************
74
** User variables
75
****************************************************************************/
1085.1.2 by Monty Taylor
Fixed -Wmissing-declarations
76
unsigned char *get_var_key(user_var_entry *entry, size_t *length, bool )
1 by brian
clean slate
77
{
78
  *length= entry->name.length;
481 by Brian Aker
Remove all of uchar.
79
  return (unsigned char*) entry->name.str;
1 by brian
clean slate
80
}
81
1085.1.2 by Monty Taylor
Fixed -Wmissing-declarations
82
void free_user_var(user_var_entry *entry)
1 by brian
clean slate
83
{
1089.1.5 by Brian Aker
Cleanup of user_var
84
  delete entry;
1 by brian
clean slate
85
}
86
87
bool Key_part_spec::operator==(const Key_part_spec& other) const
88
{
89
  return length == other.length &&
90
         field_name.length == other.field_name.length &&
91
         !strcmp(field_name.str, other.field_name.str);
92
}
93
94
Open_tables_state::Open_tables_state(ulong version_arg)
1089.1.6 by Brian Aker
Removed dead flag code, style cleanup in FK. Removed dead structs.
95
  :version(version_arg), backups_available(false)
1 by brian
clean slate
96
{
97
  reset_open_tables_state();
98
}
99
100
/*
101
  The following functions form part of the C plugin API
102
*/
103
extern "C" int mysql_tmpfile(const char *prefix)
104
{
105
  char filename[FN_REFLEN];
1034.1.8 by Brian Aker
Remove locks around my_open(). Open file counts are now "best effort" (not
106
  File fd = create_temp_file(filename, drizzle_tmpdir, prefix, MYF(MY_WME));
1 by brian
clean slate
107
  if (fd >= 0) {
108
    unlink(filename);
109
  }
110
111
  return fd;
112
}
113
114
extern "C"
520.1.22 by Brian Aker
Second pass of thd cleanup
115
int session_tablespace_op(const Session *session)
1 by brian
clean slate
116
{
520.1.22 by Brian Aker
Second pass of thd cleanup
117
  return test(session->tablespace_op);
1 by brian
clean slate
118
}
119
322.2.5 by Mats Kindahl
Replaced use of thd_proc_info() macro with calls to
120
/**
520.1.21 by Brian Aker
THD -> Session rename
121
   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
122
123
   This function is used by plug-ins. Internally, the
520.1.21 by Brian Aker
THD -> Session rename
124
   Session::set_proc_info() function should be used.
322.2.5 by Mats Kindahl
Replaced use of thd_proc_info() macro with calls to
125
520.1.21 by Brian Aker
THD -> Session rename
126
   @see Session::set_proc_info
322.2.5 by Mats Kindahl
Replaced use of thd_proc_info() macro with calls to
127
 */
128
extern "C" void
520.1.22 by Brian Aker
Second pass of thd cleanup
129
set_session_proc_info(Session *session, const char *info)
130
{
131
  session->set_proc_info(info);
132
}
133
134
extern "C"
135
const char *get_session_proc_info(Session *session)
136
{
137
  return session->get_proc_info();
138
}
139
140
extern "C"
960.2.26 by Monty Taylor
Rename hton to engine.
141
void **session_ha_data(const Session *session, const struct StorageEngine *engine)
520.1.22 by Brian Aker
Second pass of thd cleanup
142
{
960.2.26 by Monty Taylor
Rename hton to engine.
143
  return (void **) &session->ha_data[engine->slot].ha_ptr;
520.1.22 by Brian Aker
Second pass of thd cleanup
144
}
145
146
extern "C"
147
int64_t session_test_options(const Session *session, int64_t test_options)
148
{
149
  return session->options & test_options;
150
}
151
152
extern "C"
153
int session_sql_command(const Session *session)
154
{
155
  return (int) session->lex->sql_command;
156
}
157
158
extern "C"
159
int session_tx_isolation(const Session *session)
160
{
161
  return (int) session->variables.tx_isolation;
162
}
163
164
extern "C"
165
void session_inc_row_count(Session *session)
166
{
167
  session->row_count++;
1 by brian
clean slate
168
}
169
971.3.12 by Eric Day
Started abstracting Protocol, removed init_connect, init_file.
170
Session::Session(Protocol *protocol_arg)
1055.2.16 by Jay Pipes
Removes dead Session::catalog member variable
171
  :
172
  Statement(&main_lex, &main_mem_root, /* statement id */ 0),
173
  Open_tables_state(refresh_version),
174
  lock_id(&main_lock_id),
175
  user_time(0),
176
  arg_of_last_insert_id_function(false),
177
  first_successful_insert_id_in_prev_stmt(0),
178
  first_successful_insert_id_in_cur_stmt(0),
1055.2.17 by Jay Pipes
More style cleanups in Session
179
  limit_found_rows(0),
1055.2.16 by Jay Pipes
Removes dead Session::catalog member variable
180
  global_read_lock(0),
1055.2.17 by Jay Pipes
More style cleanups in Session
181
  some_tables_deleted(false),
182
  no_errors(false),
183
  password(false),
184
  is_fatal_error(false),
185
  transaction_rollback_request(false),
1055.2.16 by Jay Pipes
Removes dead Session::catalog member variable
186
  is_fatal_sub_stmt_error(0),
187
  derived_tables_processing(false),
1055.2.17 by Jay Pipes
More style cleanups in Session
188
  tablespace_op(false),
1055.2.16 by Jay Pipes
Removes dead Session::catalog member variable
189
  m_lip(NULL),
190
  scheduler(0),
1055.2.17 by Jay Pipes
More style cleanups in Session
191
  cached_table(0)
1 by brian
clean slate
192
{
892.2.3 by Monty Taylor
Fixed fixes.
193
  uint64_t tmp;
1 by brian
clean slate
194
1014 by Brian Aker
Fix for processlist (Eric found).
195
  memset(process_list_info, 0, PROCESS_LIST_WIDTH);
961.1.3 by Brian Aker
Remove additional lock for proceslist.
196
1 by brian
clean slate
197
  /*
198
    Pass nominal parameters to init_alloc_root only to ensure that
199
    the destructor works OK in case of an error. The main_mem_root
200
    will be re-initialized in init_for_queries().
201
  */
202
  init_sql_alloc(&main_mem_root, ALLOC_ROOT_MIN_BLOCK_SIZE, 0);
1055.2.17 by Jay Pipes
More style cleanups in Session
203
  thread_stack= NULL;
1 by brian
clean slate
204
  count_cuted_fields= CHECK_FIELD_IGNORE;
205
  killed= NOT_KILLED;
1055.2.17 by Jay Pipes
More style cleanups in Session
206
  col_access= 0;
207
  tmp_table= 0;
208
  used_tables= 0;
1 by brian
clean slate
209
  cuted_fields= sent_row_count= row_count= 0L;
210
  row_count_func= -1;
211
  statement_id_counter= 0UL;
520.1.21 by Brian Aker
THD -> Session rename
212
  // Must be reset to handle error with Session's created for init of mysqld
1 by brian
clean slate
213
  lex->current_select= 0;
214
  start_time=(time_t) 0;
215
  start_utime= 0L;
216
  utime_after_lock= 0L;
212.6.1 by Mats Kindahl
Replacing all bzero() calls with memset() calls and removing the bzero.c file.
217
  memset(&variables, 0, sizeof(variables));
1 by brian
clean slate
218
  thread_id= 0;
219
  file_id = 0;
220
  query_id= 0;
221
  warn_id= 0;
212.6.1 by Mats Kindahl
Replacing all bzero() calls with memset() calls and removing the bzero.c file.
222
  memset(ha_data, 0, sizeof(ha_data));
661 by Brian Aker
First major pass through new replication.
223
  replication_data= 0;
1055.2.17 by Jay Pipes
More style cleanups in Session
224
  mysys_var= 0;
520.1.21 by Brian Aker
THD -> Session rename
225
  dbug_sentry=Session_SENTRY_MAGIC;
1 by brian
clean slate
226
  client_capabilities= 0;                       // minimalistic client
947 by Brian Aker
Merge fix
227
  cleanup_done= abort_on_warning= no_warnings_for_error= false;
1 by brian
clean slate
228
  peer_port= 0;					// For SHOW PROCESSLIST
229
  transaction.on= 1;
230
  pthread_mutex_init(&LOCK_delete, MY_MUTEX_INIT_FAST);
231
232
  /* Variables with default values */
233
  proc_info="login";
520.1.21 by Brian Aker
THD -> Session rename
234
  where= Session::DEFAULT_WHERE;
1055.2.17 by Jay Pipes
More style cleanups in Session
235
  command= COM_CONNECT;
1 by brian
clean slate
236
1039.1.13 by Brian Aker
Removed dead bit in Session.
237
  plugin_sessionvar_init(this);
238
  /*
239
    variables= global_system_variables above has reset
240
    variables.pseudo_thread_id to 0. We need to correct it here to
241
    avoid temporary tables replication failure.
242
  */
243
  variables.pseudo_thread_id= thread_id;
244
  server_status= SERVER_STATUS_AUTOCOMMIT;
245
  options= session_startup_options;
246
247
  if (variables.max_join_size == HA_POS_ERROR)
248
    options |= OPTION_BIG_SELECTS;
249
  else
250
    options &= ~OPTION_BIG_SELECTS;
251
252
  transaction.all.modified_non_trans_table= transaction.stmt.modified_non_trans_table= false;
253
  open_options=ha_open_options;
254
  update_lock_default= TL_WRITE;
255
  session_tx_isolation= (enum_tx_isolation) variables.tx_isolation;
256
  warn_list.empty();
257
  memset(warn_count, 0, sizeof(warn_count));
258
  total_warn_count= 0;
259
  memset(&status_var, 0, sizeof(status_var));
260
1 by brian
clean slate
261
  /* Initialize sub structures */
262
  init_sql_alloc(&warn_root, WARN_ALLOC_BLOCK_SIZE, WARN_ALLOC_PREALLOC_SIZE);
263
  hash_init(&user_vars, system_charset_info, USER_VARS_HASH_SIZE, 0, 0,
264
	    (hash_get_key) get_var_key,
265
	    (hash_free_key) free_user_var, 0);
266
267
  /* Protocol */
971.3.12 by Eric Day
Started abstracting Protocol, removed init_connect, init_file.
268
  protocol= protocol_arg;
269
  protocol->setSession(this);
1 by brian
clean slate
270
779.3.10 by Monty Taylor
Turned on -Wshadow.
271
  const Query_id& local_query_id= Query_id::get_query_id();
251 by Brian Aker
Cleanup around rand.
272
  tmp= sql_rnd();
971.3.19 by Eric Day
Finished first pass at Protocol cleanup, still some things to remove but they are a bit more involved.
273
  protocol->setRandom(tmp + (uint64_t) &protocol,
274
                      tmp + (uint64_t)local_query_id.value());
51.1.50 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
275
  substitute_null_with_insert_id = false;
1 by brian
clean slate
276
  thr_lock_info_init(&lock_info); /* safety: will be reset after start */
277
  thr_lock_owner_init(&main_lock_id, &lock_info);
278
279
  m_internal_handler= NULL;
280
}
281
1055.2.13 by Jay Pipes
Documentation and style fixes in Session class. Doxygen should finally pick up the Statement and Session classes now. Removes the silly Query_arena class, as it's not needed anymore.
282
void Statement::free_items()
283
{
284
  Item *next;
285
  /* This works because items are allocated with sql_alloc() */
286
  for (; free_list; free_list= next)
287
  {
288
    next= free_list->next;
289
    free_list->delete_self();
290
  }
291
}
1 by brian
clean slate
292
520.1.21 by Brian Aker
THD -> Session rename
293
void Session::push_internal_handler(Internal_error_handler *handler)
1 by brian
clean slate
294
{
295
  /*
296
    TODO: The current implementation is limited to 1 handler at a time only.
520.1.21 by Brian Aker
THD -> Session rename
297
    Session and sp_rcontext need to be modified to use a common handler stack.
1 by brian
clean slate
298
  */
51.1.50 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
299
  assert(m_internal_handler == NULL);
1 by brian
clean slate
300
  m_internal_handler= handler;
301
}
302
520.1.21 by Brian Aker
THD -> Session rename
303
bool Session::handle_error(uint32_t sql_errno, const char *message,
261.4.1 by Felipe
- Renamed MYSQL_ERROR to DRIZZLE_ERROR.
304
                       DRIZZLE_ERROR::enum_warning_level level)
1 by brian
clean slate
305
{
306
  if (m_internal_handler)
307
  {
308
    return m_internal_handler->handle_error(sql_errno, message, level, this);
309
  }
310
51.1.50 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
311
  return false;                                 // 'false', as per coding style
1 by brian
clean slate
312
}
313
520.1.21 by Brian Aker
THD -> Session rename
314
void Session::pop_internal_handler()
1 by brian
clean slate
315
{
51.1.50 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
316
  assert(m_internal_handler != NULL);
1 by brian
clean slate
317
  m_internal_handler= NULL;
318
}
319
520.6.7 by Monty Taylor
Moved a bunch of crap out of common_includes.
320
#if defined(__cplusplus)
321
extern "C" {
322
#endif
323
520.1.22 by Brian Aker
Second pass of thd cleanup
324
void *session_alloc(Session *session, unsigned int size)
325
{
326
  return session->alloc(size);
327
}
328
329
void *session_calloc(Session *session, unsigned int size)
330
{
331
  return session->calloc(size);
332
}
333
334
char *session_strdup(Session *session, const char *str)
335
{
336
  return session->strdup(str);
337
}
338
339
char *session_strmake(Session *session, const char *str, unsigned int size)
340
{
341
  return session->strmake(str, size);
342
}
343
344
void *session_memdup(Session *session, const void* str, unsigned int size)
1 by brian
clean slate
345
{
520.1.22 by Brian Aker
Second pass of thd cleanup
346
  return session->memdup(str, size);
1 by brian
clean slate
347
}
348
520.1.22 by Brian Aker
Second pass of thd cleanup
349
void session_get_xid(const Session *session, DRIZZLE_XID *xid)
1 by brian
clean slate
350
{
520.1.22 by Brian Aker
Second pass of thd cleanup
351
  *xid = *(DRIZZLE_XID *) &session->transaction.xid_state.xid;
1 by brian
clean slate
352
}
353
520.6.7 by Monty Taylor
Moved a bunch of crap out of common_includes.
354
#if defined(__cplusplus)
355
}
356
#endif
357
1 by brian
clean slate
358
/*
520.1.21 by Brian Aker
THD -> Session rename
359
  Init Session for query processing.
1 by brian
clean slate
360
  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.
361
  See also comments in session.h.
1 by brian
clean slate
362
*/
363
520.1.21 by Brian Aker
THD -> Session rename
364
void Session::init_for_queries()
1 by brian
clean slate
365
{
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
366
  set_time();
51.1.50 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
367
  ha_enable_transaction(this,true);
1 by brian
clean slate
368
369
  reset_root_defaults(mem_root, variables.query_alloc_block_size,
370
                      variables.query_prealloc_size);
371
  reset_root_defaults(&transaction.mem_root,
372
                      variables.trans_alloc_block_size,
373
                      variables.trans_prealloc_size);
374
  transaction.xid_state.xid.null();
520.1.22 by Brian Aker
Second pass of thd cleanup
375
  transaction.xid_state.in_session=1;
1 by brian
clean slate
376
}
377
378
379
/* Do operations that may take a long time */
380
520.1.21 by Brian Aker
THD -> Session rename
381
void Session::cleanup(void)
1 by brian
clean slate
382
{
947 by Brian Aker
Merge fix
383
  assert(cleanup_done == false);
1 by brian
clean slate
384
385
  killed= KILL_CONNECTION;
386
#ifdef ENABLE_WHEN_BINLOG_WILL_BE_ABLE_TO_PREPARE
387
  if (transaction.xid_state.xa_state == XA_PREPARED)
388
  {
389
#error xid_state in the cache should be replaced by the allocated value
390
  }
391
#endif
392
  {
393
    ha_rollback(this);
394
    xid_cache_delete(&transaction.xid_state);
395
  }
396
  hash_free(&user_vars);
793 by Brian Aker
Pass through on refactoring functions to clases.
397
  close_temporary_tables();
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
398
1 by brian
clean slate
399
  if (global_read_lock)
400
    unlock_global_read_lock(this);
401
947 by Brian Aker
Merge fix
402
  cleanup_done= true;
51.1.50 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
403
}
1 by brian
clean slate
404
520.1.21 by Brian Aker
THD -> Session rename
405
Session::~Session()
1 by brian
clean slate
406
{
520.1.21 by Brian Aker
THD -> Session rename
407
  Session_CHECK_SENTRY(this);
1 by brian
clean slate
408
  add_to_status(&global_status_var, &status_var);
409
971.3.12 by Eric Day
Started abstracting Protocol, removed init_connect, init_file.
410
  if (protocol->isConnected())
942.1.2 by Monty Taylor
Started trying to sort out session lifecycle.
411
  {
412
    if (global_system_variables.log_warnings)
413
        errmsg_printf(ERRMSG_LVL_WARN, ER(ER_FORCING_CLOSE),my_progname,
414
                      thread_id,
415
                      (security_ctx.user.c_str() ?
416
                       security_ctx.user.c_str() : ""));
417
    disconnect(0, false);
418
  }
419
1 by brian
clean slate
420
  /* Close connection */
971.3.6 by Eric Day
Moved the last of the libdrizzleclient calls into Protocol.
421
  protocol->close();
971.3.12 by Eric Day
Started abstracting Protocol, removed init_connect, init_file.
422
  delete protocol;
971.3.6 by Eric Day
Moved the last of the libdrizzleclient calls into Protocol.
423
947 by Brian Aker
Merge fix
424
  if (cleanup_done == false)
1 by brian
clean slate
425
    cleanup();
426
427
  ha_close_connection(this);
520.1.22 by Brian Aker
Second pass of thd cleanup
428
  plugin_sessionvar_cleanup(this);
1 by brian
clean slate
429
462 by Monty Taylor
Removed safeFree.
430
  if (db)
431
  {
432
    free(db);
433
    db= NULL;
434
  }
1 by brian
clean slate
435
  free_root(&warn_root,MYF(0));
436
  free_root(&transaction.mem_root,MYF(0));
437
  mysys_var=0;					// Safety (shouldn't be needed)
520.1.21 by Brian Aker
THD -> Session rename
438
  dbug_sentry= Session_SENTRY_GONE;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
439
1 by brian
clean slate
440
  free_root(&main_mem_root, MYF(0));
670.2.1 by Monty Taylor
Moved pthread keys
441
  pthread_setspecific(THR_Session,  0);
942.1.2 by Monty Taylor
Started trying to sort out session lifecycle.
442
948 by Brian Aker
Restoring code Monty deleted.
443
444
  /* Ensure that no one is using Session */
445
  pthread_mutex_unlock(&LOCK_delete);
942.1.2 by Monty Taylor
Started trying to sort out session lifecycle.
446
  pthread_mutex_destroy(&LOCK_delete);
1 by brian
clean slate
447
}
448
449
/*
450
  Add all status variables to another status variable array
451
452
  SYNOPSIS
453
   add_to_status()
454
   to_var       add to this array
455
   from_var     from this array
456
457
  NOTES
458
    This function assumes that all variables are long/ulong.
459
    If this assumption will change, then we have to explictely add
460
    the other variables after the while loop
461
*/
462
void add_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var)
463
{
481 by Brian Aker
Remove all of uchar.
464
  ulong *end= (ulong*) ((unsigned char*) to_var +
1 by brian
clean slate
465
                        offsetof(STATUS_VAR, last_system_status_var) +
466
			sizeof(ulong));
467
  ulong *to= (ulong*) to_var, *from= (ulong*) from_var;
468
469
  while (to != end)
470
    *(to++)+= *(from++);
471
}
472
473
/*
474
  Add the difference between two status variable arrays to another one.
475
476
  SYNOPSIS
477
    add_diff_to_status
478
    to_var       add to this array
479
    from_var     from this array
480
    dec_var      minus this array
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
481
1 by brian
clean slate
482
  NOTE
483
    This function assumes that all variables are long/ulong.
484
*/
485
void add_diff_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var,
486
                        STATUS_VAR *dec_var)
487
{
481 by Brian Aker
Remove all of uchar.
488
  ulong *end= (ulong*) ((unsigned char*) to_var + offsetof(STATUS_VAR,
1 by brian
clean slate
489
						  last_system_status_var) +
490
			sizeof(ulong));
491
  ulong *to= (ulong*) to_var, *from= (ulong*) from_var, *dec= (ulong*) dec_var;
492
493
  while (to != end)
494
    *(to++)+= *(from++) - *(dec++);
495
}
496
520.1.21 by Brian Aker
THD -> Session rename
497
void Session::awake(Session::killed_state state_to_set)
1 by brian
clean slate
498
{
520.1.21 by Brian Aker
THD -> Session rename
499
  Session_CHECK_SENTRY(this);
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
500
  safe_mutex_assert_owner(&LOCK_delete);
960.1.4 by Monty Taylor
Changed get_thread_scheduler to returning a reference.
501
  Scheduler &thread_scheduler= get_thread_scheduler();
1 by brian
clean slate
502
503
  killed= state_to_set;
520.1.21 by Brian Aker
THD -> Session rename
504
  if (state_to_set != Session::KILL_QUERY)
1 by brian
clean slate
505
  {
960.1.4 by Monty Taylor
Changed get_thread_scheduler to returning a reference.
506
    thread_scheduler.post_kill_notification(this);
1 by brian
clean slate
507
  }
508
  if (mysys_var)
509
  {
510
    pthread_mutex_lock(&mysys_var->mutex);
511
    /*
512
      This broadcast could be up in the air if the victim thread
513
      exits the cond in the time between read and broadcast, but that is
514
      ok since all we want to do is to make the victim thread get out
515
      of waiting on current_cond.
516
      If we see a non-zero current_cond: it cannot be an old value (because
517
      then exit_cond() should have run and it can't because we have mutex); so
518
      it is the true value but maybe current_mutex is not yet non-zero (we're
519
      in the middle of enter_cond() and there is a "memory order
520
      inversion"). So we test the mutex too to not lock 0.
521
522
      Note that there is a small chance we fail to kill. If victim has locked
523
      current_mutex, but hasn't yet entered enter_cond() (which means that
524
      current_cond and current_mutex are 0), then the victim will not get
525
      a signal and it may wait "forever" on the cond (until
526
      we issue a second KILL or the status it's waiting for happens).
520.1.22 by Brian Aker
Second pass of thd cleanup
527
      It's true that we have set its session->killed but it may not
1 by brian
clean slate
528
      see it immediately and so may have time to reach the cond_wait().
529
    */
530
    if (mysys_var->current_cond && mysys_var->current_mutex)
531
    {
532
      pthread_mutex_lock(mysys_var->current_mutex);
533
      pthread_cond_broadcast(mysys_var->current_cond);
534
      pthread_mutex_unlock(mysys_var->current_mutex);
535
    }
536
    pthread_mutex_unlock(&mysys_var->mutex);
537
  }
538
}
539
540
/*
541
  Remember the location of thread info, the structure needed for
542
  sql_alloc() and the structure for the net buffer
543
*/
520.1.21 by Brian Aker
THD -> Session rename
544
bool Session::store_globals()
1 by brian
clean slate
545
{
546
  /*
547
    Assert that thread_stack is initialized: it's necessary to be able
548
    to track stack overrun.
549
  */
51.1.50 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
550
  assert(thread_stack);
1 by brian
clean slate
551
520.1.21 by Brian Aker
THD -> Session rename
552
  if (pthread_setspecific(THR_Session,  this) ||
670.2.1 by Monty Taylor
Moved pthread keys
553
      pthread_setspecific(THR_Mem_root, &mem_root))
1 by brian
clean slate
554
    return 1;
555
  mysys_var=my_thread_var;
960.1.1 by Monty Taylor
First pass at scheduler plugin.
556
1 by brian
clean slate
557
  /*
558
    Let mysqld define the thread id (not mysys)
520.1.21 by Brian Aker
THD -> Session rename
559
    This allows us to move Session to different threads if needed.
1 by brian
clean slate
560
  */
561
  mysys_var->id= thread_id;
562
  real_id= pthread_self();                      // For debugging
563
564
  /*
520.1.21 by Brian Aker
THD -> Session rename
565
    We have to call thr_lock_info_init() again here as Session may have been
1 by brian
clean slate
566
    created in another thread
567
  */
568
  thr_lock_info_init(&lock_info);
569
  return 0;
570
}
571
934.2.6 by Jay Pipes
This changeset removes a few more C functions from sql_connect.cc/connect.h
572
void Session::prepareForQueries()
573
{
574
  if (variables.max_join_size == HA_POS_ERROR)
575
    options |= OPTION_BIG_SELECTS;
576
  if (client_capabilities & CLIENT_COMPRESS)
971.3.8 by Eric Day
Moved NET to Protocol. libdrizzleclient is now completely isolated, need to start reworking Protocol now.
577
  {
971.3.19 by Eric Day
Finished first pass at Protocol cleanup, still some things to remove but they are a bit more involved.
578
    protocol->enableCompression();
971.3.8 by Eric Day
Moved NET to Protocol. libdrizzleclient is now completely isolated, need to start reworking Protocol now.
579
  }
934.2.6 by Jay Pipes
This changeset removes a few more C functions from sql_connect.cc/connect.h
580
581
  version= refresh_version;
961.1.4 by Brian Aker
Remove another lock for processlist.
582
  set_proc_info(NULL);
934.2.6 by Jay Pipes
This changeset removes a few more C functions from sql_connect.cc/connect.h
583
  command= COM_SLEEP;
584
  set_time();
585
  init_for_queries();
586
}
587
588
bool Session::initGlobals()
589
{
590
  if (store_globals())
591
  {
592
    disconnect(ER_OUT_OF_RESOURCES, true);
593
    statistic_increment(aborted_connects, &LOCK_status);
960.1.4 by Monty Taylor
Changed get_thread_scheduler to returning a reference.
594
    Scheduler &thread_scheduler= get_thread_scheduler();
595
    thread_scheduler.end_thread(this, 0);
934.2.6 by Jay Pipes
This changeset removes a few more C functions from sql_connect.cc/connect.h
596
    return false;
597
  }
598
  return true;
599
}
600
934.2.4 by Jay Pipes
This changeset pulls check_user(), check_connection(), and login_connection() out of sql_connect.cc and makes them member methods of Session, where they belong. Also, made sure that functions that return a bool return true when it succeeds, and not false...
601
bool Session::authenticate()
602
{
603
  lex_start(this);
971.3.6 by Eric Day
Moved the last of the libdrizzleclient calls into Protocol.
604
  if (protocol->authenticate())
605
    return true;
606
607
  statistic_increment(aborted_connects, &LOCK_status);
608
  return false;
934.2.4 by Jay Pipes
This changeset pulls check_user(), check_connection(), and login_connection() out of sql_connect.cc and makes them member methods of Session, where they belong. Also, made sure that functions that return a bool return true when it succeeds, and not false...
609
}
610
965 by Brian Aker
Merge with Jay
611
bool Session::checkUser(const char *passwd, uint32_t passwd_len, const char *in_db)
934.2.4 by Jay Pipes
This changeset pulls check_user(), check_connection(), and login_connection() out of sql_connect.cc and makes them member methods of Session, where they belong. Also, made sure that functions that return a bool return true when it succeeds, and not false...
612
{
613
  LEX_STRING db_str= { (char *) in_db, in_db ? strlen(in_db) : 0 };
614
  bool is_authenticated;
615
616
  /*
617
    Clear session->db as it points to something, that will be freed when
618
    connection is closed. We don't want to accidentally free a wrong
619
    pointer if connect failed. Also in case of 'CHANGE USER' failure,
620
    current database will be switched to 'no database selected'.
621
  */
622
  reset_db(NULL, 0);
623
624
  if (passwd_len != 0 && passwd_len != SCRAMBLE_LENGTH)
625
  {
626
    my_error(ER_HANDSHAKE_ERROR, MYF(0), security_ctx.ip.c_str());
627
    return false;
628
  }
629
630
  is_authenticated= authenticate_user(this, passwd);
631
632
  if (is_authenticated != true)
633
  {
634
    my_error(ER_ACCESS_DENIED_ERROR, MYF(0),
635
             security_ctx.user.c_str(),
636
             security_ctx.ip.c_str(),
637
             passwd_len ? ER(ER_YES) : ER(ER_NO));
638
639
    return false;
640
  }
641
642
  security_ctx.skip_grants();
643
644
  /* Change database if necessary */
645
  if (in_db && in_db[0])
646
  {
647
    if (mysql_change_db(this, &db_str, false))
648
    {
649
      /* mysql_change_db() has pushed the error message. */
650
      return false;
651
    }
652
  }
653
  my_ok();
654
  password= test(passwd_len);          // remember for error messages
655
656
  /* Ready to handle queries */
657
  return true;
658
}
1 by brian
clean slate
659
934.2.8 by Jay Pipes
Refactors the do_command() function out of the sql_parse.cc stuff and implements it as a member method, executeStatement() on the Session object.
660
bool Session::executeStatement()
661
{
662
  char *l_packet= 0;
663
  uint32_t packet_length;
664
665
  enum enum_server_command l_command;
666
667
  /*
668
    indicator of uninitialized lex => normal flow of errors handling
669
    (see my_message_sql)
670
  */
671
  lex->current_select= 0;
672
971.3.19 by Eric Day
Finished first pass at Protocol cleanup, still some things to remove but they are a bit more involved.
673
  if (protocol->readCommand(&l_packet, &packet_length) == false)
971.3.6 by Eric Day
Moved the last of the libdrizzleclient calls into Protocol.
674
    return false;
675
676
  if (packet_length == 0)
677
    return true;
934.2.8 by Jay Pipes
Refactors the do_command() function out of the sql_parse.cc stuff and implements it as a member method, executeStatement() on the Session object.
678
679
  l_command= (enum enum_server_command) (unsigned char) l_packet[0];
680
681
  if (command >= COM_END)
682
    command= COM_END;                           // Wrong command
683
684
  assert(packet_length);
971.3.6 by Eric Day
Moved the last of the libdrizzleclient calls into Protocol.
685
  return ! dispatch_command(l_command, this, l_packet+1, (uint32_t) (packet_length-1));
934.2.8 by Jay Pipes
Refactors the do_command() function out of the sql_parse.cc stuff and implements it as a member method, executeStatement() on the Session object.
686
}
934.2.9 by Jay Pipes
Pulls alloc_query() C function out of sql_parse.cc and adds readAndStoreQuery() member method of Session class.
687
688
bool Session::readAndStoreQuery(const char *in_packet, uint32_t in_packet_length)
689
{
690
  /* Remove garbage at start and end of query */
691
  while (in_packet_length > 0 && my_isspace(charset(), in_packet[0]))
692
  {
693
    in_packet++;
694
    in_packet_length--;
695
  }
696
  const char *pos= in_packet + in_packet_length; /* Point at end null */
697
  while (in_packet_length > 0 &&
698
	 (pos[-1] == ';' || my_isspace(charset() ,pos[-1])))
699
  {
700
    pos--;
701
    in_packet_length--;
702
  }
703
704
  /* We must allocate some extra memory for the cached query string */
705
  query_length= 0; /* Extra safety: Avoid races */
706
  query= (char*) memdup_w_gap((unsigned char*) in_packet, in_packet_length, db_length + 1);
707
  if (! query)
708
    return false;
709
710
  query[in_packet_length]=0;
711
  query_length= in_packet_length;
712
713
  /* Reclaim some memory */
714
  packet.shrink(variables.net_buffer_length);
715
  convert_buffer.shrink(variables.net_buffer_length);
716
717
  return true;
718
}
719
934.2.11 by Jay Pipes
Moves end_trans(), begin_trans(), end_active_trans() out of the parser module and adds startTransaction(), endTransaction(), and endActiveTransaction() member methods of Session object.
720
bool Session::endTransaction(enum enum_mysql_completiontype completion)
721
{
722
  bool do_release= 0;
723
  bool result= true;
724
725
  if (transaction.xid_state.xa_state != XA_NOTR)
726
  {
727
    my_error(ER_XAER_RMFAIL, MYF(0), xa_state_names[transaction.xid_state.xa_state]);
728
    return false;
729
  }
730
  switch (completion) 
731
  {
732
    case COMMIT:
733
      /*
734
       * We don't use endActiveTransaction() here to ensure that this works
735
       * even if there is a problem with the OPTION_AUTO_COMMIT flag
736
       * (Which of course should never happen...)
737
       */
738
      server_status&= ~SERVER_STATUS_IN_TRANS;
739
      if (ha_commit(this))
740
        result= false;
741
      options&= ~(OPTION_BEGIN | OPTION_KEEP_LOG);
742
      transaction.all.modified_non_trans_table= false;
743
      break;
744
    case COMMIT_RELEASE:
745
      do_release= 1; /* fall through */
746
    case COMMIT_AND_CHAIN:
747
      result= endActiveTransaction();
748
      if (result == true && completion == COMMIT_AND_CHAIN)
749
        result= startTransaction();
750
      break;
751
    case ROLLBACK_RELEASE:
752
      do_release= 1; /* fall through */
753
    case ROLLBACK:
754
    case ROLLBACK_AND_CHAIN:
755
    {
756
      server_status&= ~SERVER_STATUS_IN_TRANS;
757
      if (ha_rollback(this))
758
        result= false;
759
      options&= ~(OPTION_BEGIN | OPTION_KEEP_LOG);
760
      transaction.all.modified_non_trans_table= false;
761
      if (result == true && (completion == ROLLBACK_AND_CHAIN))
762
        result= startTransaction();
763
      break;
764
    }
765
    default:
766
      my_error(ER_UNKNOWN_COM_ERROR, MYF(0));
767
      return false;
768
  }
769
770
  if (result == false)
771
    my_error(killed_errno(), MYF(0));
772
  else if ((result == true) && do_release)
773
    killed= Session::KILL_CONNECTION;
774
775
  return result;
776
}
777
778
bool Session::endActiveTransaction()
779
{
780
  bool result= true;
781
782
  if (transaction.xid_state.xa_state != XA_NOTR)
783
  {
784
    my_error(ER_XAER_RMFAIL, MYF(0), xa_state_names[transaction.xid_state.xa_state]);
785
    return false;
786
  }
1054.1.8 by Brian Aker
Remove lock_tables list from session.
787
  if (options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
934.2.11 by Jay Pipes
Moves end_trans(), begin_trans(), end_active_trans() out of the parser module and adds startTransaction(), endTransaction(), and endActiveTransaction() member methods of Session object.
788
  {
789
    server_status&= ~SERVER_STATUS_IN_TRANS;
790
    if (ha_commit(this))
791
      result= false;
792
  }
793
  options&= ~(OPTION_BEGIN | OPTION_KEEP_LOG);
794
  transaction.all.modified_non_trans_table= false;
795
  return result;
796
}
797
798
bool Session::startTransaction()
799
{
800
  bool result= true;
801
802
  if (! endActiveTransaction())
803
    result= false;
804
  else
805
  {
806
    options|= OPTION_BEGIN;
807
    server_status|= SERVER_STATUS_IN_TRANS;
808
    if (lex->start_transaction_opt & DRIZZLE_START_TRANS_OPT_WITH_CONS_SNAPSHOT)
809
      if (ha_start_consistent_snapshot(this))
810
        result= false;
811
  }
812
  return result;
813
}
814
520.1.21 by Brian Aker
THD -> Session rename
815
void Session::cleanup_after_query()
1 by brian
clean slate
816
{
817
  /*
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
818
    Reset rand_used so that detection of calls to rand() will save random
1 by brian
clean slate
819
    seeds if needed by the slave.
820
  */
821
  {
822
    /* Forget those values, for next binlogger: */
823
    auto_inc_intervals_in_cur_stmt_for_binlog.empty();
824
  }
825
  if (first_successful_insert_id_in_cur_stmt > 0)
826
  {
827
    /* set what LAST_INSERT_ID() will return */
1055.2.17 by Jay Pipes
More style cleanups in Session
828
    first_successful_insert_id_in_prev_stmt= first_successful_insert_id_in_cur_stmt;
1 by brian
clean slate
829
    first_successful_insert_id_in_cur_stmt= 0;
51.1.50 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
830
    substitute_null_with_insert_id= true;
1 by brian
clean slate
831
  }
1055.2.17 by Jay Pipes
More style cleanups in Session
832
  arg_of_last_insert_id_function= false;
1 by brian
clean slate
833
  /* Free Items that were created during this execution */
834
  free_items();
835
  /* Reset where. */
520.1.21 by Brian Aker
THD -> Session rename
836
  where= Session::DEFAULT_WHERE;
1 by brian
clean slate
837
}
838
839
/**
840
  Create a LEX_STRING in this connection.
841
842
  @param lex_str  pointer to LEX_STRING object to be initialized
843
  @param str      initializer to be copied into lex_str
844
  @param length   length of str, in bytes
51.1.50 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
845
  @param allocate_lex_string  if true, allocate new LEX_STRING object,
1 by brian
clean slate
846
                              instead of using lex_str value
847
  @return  NULL on failure, or pointer to the LEX_STRING object
848
*/
520.1.21 by Brian Aker
THD -> Session rename
849
LEX_STRING *Session::make_lex_string(LEX_STRING *lex_str,
482 by Brian Aker
Remove uint.
850
                                 const char* str, uint32_t length,
1 by brian
clean slate
851
                                 bool allocate_lex_string)
852
{
853
  if (allocate_lex_string)
854
    if (!(lex_str= (LEX_STRING *)alloc(sizeof(LEX_STRING))))
855
      return 0;
856
  if (!(lex_str->str= strmake_root(mem_root, str, length)))
857
    return 0;
858
  lex_str->length= length;
859
  return lex_str;
860
}
861
862
/* routings to adding tables to list of changed in transaction tables */
327.2.4 by Brian Aker
Refactoring table.h
863
inline static void list_include(CHANGED_TableList** prev,
864
				CHANGED_TableList* curr,
865
				CHANGED_TableList* new_table)
1 by brian
clean slate
866
{
867
  if (new_table)
868
  {
869
    *prev = new_table;
870
    (*prev)->next = curr;
871
  }
872
}
873
874
/* add table to list of changed in transaction tables */
875
520.1.21 by Brian Aker
THD -> Session rename
876
void Session::add_changed_table(Table *table)
1 by brian
clean slate
877
{
51.1.50 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
878
  assert((options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) &&
1 by brian
clean slate
879
	      table->file->has_transactions());
880
  add_changed_table(table->s->table_cache_key.str,
881
                    (long) table->s->table_cache_key.length);
882
}
883
884
520.1.21 by Brian Aker
THD -> Session rename
885
void Session::add_changed_table(const char *key, long key_length)
1 by brian
clean slate
886
{
327.2.4 by Brian Aker
Refactoring table.h
887
  CHANGED_TableList **prev_changed = &transaction.changed_tables;
888
  CHANGED_TableList *curr = transaction.changed_tables;
1 by brian
clean slate
889
890
  for (; curr; prev_changed = &(curr->next), curr = curr->next)
891
  {
892
    int cmp =  (long)curr->key_length - (long)key_length;
893
    if (cmp < 0)
894
    {
895
      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
896
      return;
1 by brian
clean slate
897
    }
898
    else if (cmp == 0)
899
    {
900
      cmp = memcmp(curr->key, key, curr->key_length);
901
      if (cmp < 0)
902
      {
1046.1.6 by Brian Aker
Formatting/style cleanup.
903
        list_include(prev_changed, curr, changed_table_dup(key, key_length));
904
        return;
1 by brian
clean slate
905
      }
906
      else if (cmp == 0)
907
      {
1046.1.6 by Brian Aker
Formatting/style cleanup.
908
        return;
1 by brian
clean slate
909
      }
910
    }
911
  }
912
  *prev_changed = changed_table_dup(key, key_length);
913
}
914
915
520.1.21 by Brian Aker
THD -> Session rename
916
CHANGED_TableList* Session::changed_table_dup(const char *key, long key_length)
1 by brian
clean slate
917
{
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
918
  CHANGED_TableList* new_table =
327.2.4 by Brian Aker
Refactoring table.h
919
    (CHANGED_TableList*) trans_alloc(ALIGN_SIZE(sizeof(CHANGED_TableList))+
1 by brian
clean slate
920
				      key_length + 1);
921
  if (!new_table)
922
  {
923
    my_error(EE_OUTOFMEMORY, MYF(ME_BELL),
327.2.4 by Brian Aker
Refactoring table.h
924
             ALIGN_SIZE(sizeof(TableList)) + key_length + 1);
1 by brian
clean slate
925
    killed= KILL_CONNECTION;
926
    return 0;
927
  }
928
327.2.4 by Brian Aker
Refactoring table.h
929
  new_table->key= ((char*)new_table)+ ALIGN_SIZE(sizeof(CHANGED_TableList));
1 by brian
clean slate
930
  new_table->next = 0;
931
  new_table->key_length = key_length;
932
  ::memcpy(new_table->key, key, key_length);
933
  return new_table;
934
}
935
936
520.1.21 by Brian Aker
THD -> Session rename
937
int Session::send_explain_fields(select_result *result)
1 by brian
clean slate
938
{
939
  List<Item> field_list;
940
  Item *item;
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
941
  const CHARSET_INFO * const cs= system_charset_info;
212.2.2 by Patrick Galbraith
Renamed FIELD_TYPE to DRIZZLE_TYPE
942
  field_list.push_back(new Item_return_int("id",3, DRIZZLE_TYPE_LONGLONG));
1 by brian
clean slate
943
  field_list.push_back(new Item_empty_string("select_type", 19, cs));
944
  field_list.push_back(item= new Item_empty_string("table", NAME_CHAR_LEN, cs));
945
  item->maybe_null= 1;
946
  field_list.push_back(item= new Item_empty_string("type", 10, cs));
947
  item->maybe_null= 1;
948
  field_list.push_back(item=new Item_empty_string("possible_keys",
949
						  NAME_CHAR_LEN*MAX_KEY, cs));
950
  item->maybe_null=1;
951
  field_list.push_back(item=new Item_empty_string("key", NAME_CHAR_LEN, cs));
952
  item->maybe_null=1;
953
  field_list.push_back(item=
954
    new Item_empty_string("key_len",
955
                          MAX_KEY *
956
                          (MAX_KEY_LENGTH_DECIMAL_WIDTH + 1 /* for comma */),
957
                          cs));
958
  item->maybe_null=1;
959
  field_list.push_back(item=new Item_empty_string("ref",
960
                                                  NAME_CHAR_LEN*MAX_REF_PARTS,
961
                                                  cs));
962
  item->maybe_null=1;
963
  field_list.push_back(item= new Item_return_int("rows", 10,
212.2.2 by Patrick Galbraith
Renamed FIELD_TYPE to DRIZZLE_TYPE
964
                                                 DRIZZLE_TYPE_LONGLONG));
1 by brian
clean slate
965
  if (lex->describe & DESCRIBE_EXTENDED)
966
  {
967
    field_list.push_back(item= new Item_float("filtered", 0.1234, 2, 4));
968
    item->maybe_null=1;
969
  }
970
  item->maybe_null= 1;
971
  field_list.push_back(new Item_empty_string("Extra", 255, cs));
972
  return (result->send_fields(field_list,
973
                              Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF));
974
}
975
976
/************************************************************************
977
  Handling writing to file
978
************************************************************************/
979
482 by Brian Aker
Remove uint.
980
void select_to_file::send_error(uint32_t errcode,const char *err)
1 by brian
clean slate
981
{
982
  my_message(errcode, err, MYF(0));
983
  if (file > 0)
984
  {
985
    (void) end_io_cache(&cache);
986
    (void) my_close(file,MYF(0));
987
    (void) my_delete(path,MYF(0));		// Delete file on error
988
    file= -1;
989
  }
990
}
991
992
993
bool select_to_file::send_eof()
994
{
995
  int error= test(end_io_cache(&cache));
996
  if (my_close(file,MYF(MY_WME)))
997
    error= 1;
998
  if (!error)
999
  {
1000
    /*
1001
      In order to remember the value of affected rows for ROW_COUNT()
1002
      function, SELECT INTO has to have an own SQLCOM.
1003
      TODO: split from SQLCOM_SELECT
1004
    */
836 by Brian Aker
Fixed session call from function to method.
1005
    session->my_ok(row_count);
1 by brian
clean slate
1006
  }
1007
  file= -1;
1008
  return error;
1009
}
1010
1011
1012
void select_to_file::cleanup()
1013
{
1014
  /* In case of error send_eof() may be not called: close the file here. */
1015
  if (file >= 0)
1016
  {
1017
    (void) end_io_cache(&cache);
1018
    (void) my_close(file,MYF(0));
1019
    file= -1;
1020
  }
1021
  path[0]= '\0';
1022
  row_count= 0;
1023
}
1024
1025
1026
select_to_file::~select_to_file()
1027
{
1028
  if (file >= 0)
1029
  {					// This only happens in case of error
1030
    (void) end_io_cache(&cache);
1031
    (void) my_close(file,MYF(0));
1032
    file= -1;
1033
  }
1034
}
1035
1036
/***************************************************************************
1037
** Export of select to textfile
1038
***************************************************************************/
1039
1040
select_export::~select_export()
1041
{
520.1.22 by Brian Aker
Second pass of thd cleanup
1042
  session->sent_row_count=row_count;
1 by brian
clean slate
1043
}
1044
1045
1046
/*
1047
  Create file with IO cache
1048
1049
  SYNOPSIS
1050
    create_file()
520.1.22 by Brian Aker
Second pass of thd cleanup
1051
    session			Thread handle
1 by brian
clean slate
1052
    path		File name
1053
    exchange		Excange class
1054
    cache		IO cache
1055
1056
  RETURN
1057
    >= 0 	File handle
1058
   -1		Error
1059
*/
1060
1061
845 by Brian Aker
Small formatting changes.
1062
static File create_file(Session *session, char *path, file_exchange *exchange, IO_CACHE *cache)
1 by brian
clean slate
1063
{
1064
  File file;
482 by Brian Aker
Remove uint.
1065
  uint32_t option= MY_UNPACK_FILENAME | MY_RELATIVE_PATH;
1 by brian
clean slate
1066
1067
#ifdef DONT_ALLOW_FULL_LOAD_DATA_PATHS
1068
  option|= MY_REPLACE_DIR;			// Force use of db directory
1069
#endif
1070
1071
  if (!dirname_length(exchange->file_name))
1072
  {
575.4.1 by ysano
Rename mysql to drizzle.
1073
    strcpy(path, drizzle_real_data_home);
534 by Monty Taylor
Removed stxnmov. Also deleted strstr which had already been removed.
1074
    if (session->db)
575.4.1 by ysano
Rename mysql to drizzle.
1075
      strncat(path, session->db, FN_REFLEN-strlen(drizzle_real_data_home)-1);
1 by brian
clean slate
1076
    (void) fn_format(path, exchange->file_name, path, "", option);
1077
  }
1078
  else
575.4.1 by ysano
Rename mysql to drizzle.
1079
    (void) fn_format(path, exchange->file_name, drizzle_real_data_home, "", option);
1 by brian
clean slate
1080
1081
  if (opt_secure_file_priv &&
1082
      strncmp(opt_secure_file_priv, path, strlen(opt_secure_file_priv)))
1083
  {
1084
    /* Write only allowed to dir or subdir specified by secure_file_priv */
1085
    my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--secure-file-priv");
1086
    return -1;
1087
  }
1088
1089
  if (!access(path, F_OK))
1090
  {
1091
    my_error(ER_FILE_EXISTS_ERROR, MYF(0), exchange->file_name);
1092
    return -1;
1093
  }
1094
  /* Create the file world readable */
1095
  if ((file= my_create(path, 0666, O_WRONLY|O_EXCL, MYF(MY_WME))) < 0)
1096
    return file;
1097
#ifdef HAVE_FCHMOD
1098
  (void) fchmod(file, 0666);			// Because of umask()
1099
#else
1100
  (void) chmod(path, 0666);
1101
#endif
1102
  if (init_io_cache(cache, file, 0L, WRITE_CACHE, 0L, 1, MYF(MY_WME)))
1103
  {
1104
    my_close(file, MYF(0));
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1105
    my_delete(path, MYF(0));  // Delete file on error, it was just created
1 by brian
clean slate
1106
    return -1;
1107
  }
1108
  return file;
1109
}
1110
1111
1112
int
848 by Brian Aker
typdef class removal (just... use the name of the class).
1113
select_export::prepare(List<Item> &list, Select_Lex_Unit *u)
1 by brian
clean slate
1114
{
1115
  bool blob_flag=0;
51.1.50 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
1116
  bool string_results= false, non_string_results= false;
1 by brian
clean slate
1117
  unit= u;
895 by Brian Aker
Completion (?) of uint conversion.
1118
  if ((uint32_t) strlen(exchange->file_name) + NAME_LEN >= FN_REFLEN)
629.5.4 by Toru Maesaka
Fourth pass of replacing MySQL's strmake() with libc calls
1119
    strncpy(path,exchange->file_name,FN_REFLEN-1);
1 by brian
clean slate
1120
1121
  /* Check if there is any blobs in data */
1122
  {
1123
    List_iterator_fast<Item> li(list);
1124
    Item *item;
1125
    while ((item=li++))
1126
    {
1127
      if (item->max_length >= MAX_BLOB_WIDTH)
1128
      {
1129
	blob_flag=1;
1130
	break;
1131
      }
1132
      if (item->result_type() == STRING_RESULT)
51.1.50 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
1133
        string_results= true;
1 by brian
clean slate
1134
      else
51.1.50 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
1135
        non_string_results= true;
1 by brian
clean slate
1136
    }
1137
  }
1138
  field_term_length=exchange->field_term->length();
1139
  field_term_char= field_term_length ?
481 by Brian Aker
Remove all of uchar.
1140
                   (int) (unsigned char) (*exchange->field_term)[0] : INT_MAX;
1 by brian
clean slate
1141
  if (!exchange->line_term->length())
1142
    exchange->line_term=exchange->field_term;	// Use this if it exists
1143
  field_sep_char= (exchange->enclosed->length() ?
481 by Brian Aker
Remove all of uchar.
1144
                  (int) (unsigned char) (*exchange->enclosed)[0] : field_term_char);
1 by brian
clean slate
1145
  escape_char=	(exchange->escaped->length() ?
481 by Brian Aker
Remove all of uchar.
1146
                (int) (unsigned char) (*exchange->escaped)[0] : -1);
1 by brian
clean slate
1147
  is_ambiguous_field_sep= test(strchr(ESCAPE_CHARS, field_sep_char));
1148
  is_unsafe_field_sep= test(strchr(NUMERIC_CHARS, field_sep_char));
1149
  line_sep_char= (exchange->line_term->length() ?
481 by Brian Aker
Remove all of uchar.
1150
                 (int) (unsigned char) (*exchange->line_term)[0] : INT_MAX);
1 by brian
clean slate
1151
  if (!field_term_length)
1152
    exchange->opt_enclosed=0;
1153
  if (!exchange->enclosed->length())
1154
    exchange->opt_enclosed=1;			// A little quicker loop
1155
  fixed_row_size= (!field_term_length && !exchange->enclosed->length() &&
1156
		   !blob_flag);
1157
  if ((is_ambiguous_field_sep && exchange->enclosed->is_empty() &&
1158
       (string_results || is_unsafe_field_sep)) ||
1159
      (exchange->opt_enclosed && non_string_results &&
1160
       field_term_length && strchr(NUMERIC_CHARS, field_term_char)))
1161
  {
673.3.8 by Stewart Smith
fix outfile_loaddata test for drizzle.
1162
    my_error(ER_AMBIGUOUS_FIELD_TERM, MYF(0));
1163
    return 1;
1 by brian
clean slate
1164
  }
673.3.8 by Stewart Smith
fix outfile_loaddata test for drizzle.
1165
1166
  if ((file= create_file(session, path, exchange, &cache)) < 0)
1167
    return 1;
1 by brian
clean slate
1168
1169
  return 0;
1170
}
1171
1172
481 by Brian Aker
Remove all of uchar.
1173
#define NEED_ESCAPING(x) ((int) (unsigned char) (x) == escape_char    || \
1174
                          (enclosed ? (int) (unsigned char) (x) == field_sep_char      \
1175
                                    : (int) (unsigned char) (x) == field_term_char) || \
1176
                          (int) (unsigned char) (x) == line_sep_char  || \
1 by brian
clean slate
1177
                          !(x))
1178
1179
bool select_export::send_data(List<Item> &items)
1180
{
1181
  char buff[MAX_FIELD_WIDTH],null_buff[2],space[MAX_FIELD_WIDTH];
1182
  bool space_inited=0;
1183
  String tmp(buff,sizeof(buff),&my_charset_bin),*res;
1184
  tmp.length(0);
1185
1186
  if (unit->offset_limit_cnt)
1187
  {						// using limit offset,count
1188
    unit->offset_limit_cnt--;
51.1.50 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
1189
    return(0);
1 by brian
clean slate
1190
  }
1191
  row_count++;
1192
  Item *item;
482 by Brian Aker
Remove uint.
1193
  uint32_t used_length=0,items_left=items.elements;
1 by brian
clean slate
1194
  List_iterator_fast<Item> li(items);
1195
481 by Brian Aker
Remove all of uchar.
1196
  if (my_b_write(&cache,(unsigned char*) exchange->line_start->ptr(),
1 by brian
clean slate
1197
		 exchange->line_start->length()))
1198
    goto err;
1199
  while ((item=li++))
1200
  {
1201
    Item_result result_type=item->result_type();
1202
    bool enclosed = (exchange->enclosed->length() &&
1203
                     (!exchange->opt_enclosed || result_type == STRING_RESULT));
1204
    res=item->str_result(&tmp);
1205
    if (res && enclosed)
1206
    {
481 by Brian Aker
Remove all of uchar.
1207
      if (my_b_write(&cache,(unsigned char*) exchange->enclosed->ptr(),
1 by brian
clean slate
1208
		     exchange->enclosed->length()))
1209
	goto err;
1210
    }
1211
    if (!res)
1212
    {						// NULL
1213
      if (!fixed_row_size)
1214
      {
1215
	if (escape_char != -1)			// Use \N syntax
1216
	{
1217
	  null_buff[0]=escape_char;
1218
	  null_buff[1]='N';
481 by Brian Aker
Remove all of uchar.
1219
	  if (my_b_write(&cache,(unsigned char*) null_buff,2))
1 by brian
clean slate
1220
	    goto err;
1221
	}
481 by Brian Aker
Remove all of uchar.
1222
	else if (my_b_write(&cache,(unsigned char*) "NULL",4))
1 by brian
clean slate
1223
	  goto err;
1224
      }
1225
      else
1226
      {
1227
	used_length=0;				// Fill with space
1228
      }
1229
    }
1230
    else
1231
    {
1232
      if (fixed_row_size)
1067.4.1 by Nathan Williams
First few changes at converting cmin to std::min.
1233
        used_length= min(res->length(),item->max_length);
1 by brian
clean slate
1234
      else
1067.4.1 by Nathan Williams
First few changes at converting cmin to std::min.
1235
        used_length= res->length();
1236
1 by brian
clean slate
1237
      if ((result_type == STRING_RESULT || is_unsafe_field_sep) &&
1238
           escape_char != -1)
1239
      {
1240
        char *pos, *start, *end;
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
1241
        const CHARSET_INFO * const res_charset= res->charset();
748 by Brian Aker
Removal of client side collation.
1242
        const CHARSET_INFO * const character_set_client= default_charset_info;
1243
1 by brian
clean slate
1244
        bool check_second_byte= (res_charset == &my_charset_bin) &&
1245
                                 character_set_client->
1246
                                 escape_with_backslash_is_dangerous;
51.1.50 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
1247
        assert(character_set_client->mbmaxlen == 2 ||
748 by Brian Aker
Removal of client side collation.
1248
               !character_set_client->escape_with_backslash_is_dangerous);
1 by brian
clean slate
1249
	for (start=pos=(char*) res->ptr(),end=pos+used_length ;
1250
	     pos != end ;
1251
	     pos++)
1252
	{
1253
#ifdef USE_MB
1254
	  if (use_mb(res_charset))
1255
	  {
1256
	    int l;
1257
	    if ((l=my_ismbchar(res_charset, pos, end)))
1258
	    {
1259
	      pos += l-1;
1260
	      continue;
1261
	    }
1262
	  }
1263
#endif
1264
1265
          /*
1266
            Special case when dumping BINARY/VARBINARY/BLOB values
1267
            for the clients with character sets big5, cp932, gbk and sjis,
1268
            which can have the escape character (0x5C "\" by default)
1269
            as the second byte of a multi-byte sequence.
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1270
1 by brian
clean slate
1271
            If
1272
            - pos[0] is a valid multi-byte head (e.g 0xEE) and
1273
            - pos[1] is 0x00, which will be escaped as "\0",
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1274
1 by brian
clean slate
1275
            then we'll get "0xEE + 0x5C + 0x30" in the output file.
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1276
1 by brian
clean slate
1277
            If this file is later loaded using this sequence of commands:
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1278
1 by brian
clean slate
1279
            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
1280
            mysql> LOAD DATA INFILE 'dump.txt' INTO Table t1;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1281
1 by brian
clean slate
1282
            then 0x5C will be misinterpreted as the second byte
1283
            of a multi-byte character "0xEE + 0x5C", instead of
1284
            escape character for 0x00.
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1285
1 by brian
clean slate
1286
            To avoid this confusion, we'll escape the multi-byte
1287
            head character too, so the sequence "0xEE + 0x00" will be
1288
            dumped as "0x5C + 0xEE + 0x5C + 0x30".
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1289
1 by brian
clean slate
1290
            Note, in the condition below we only check if
1291
            mbcharlen is equal to 2, because there are no
1292
            character sets with mbmaxlen longer than 2
1293
            and with escape_with_backslash_is_dangerous set.
51.1.50 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
1294
            assert before the loop makes that sure.
1 by brian
clean slate
1295
          */
1296
1297
          if ((NEED_ESCAPING(*pos) ||
1298
               (check_second_byte &&
481 by Brian Aker
Remove all of uchar.
1299
                my_mbcharlen(character_set_client, (unsigned char) *pos) == 2 &&
1 by brian
clean slate
1300
                pos + 1 < end &&
1301
                NEED_ESCAPING(pos[1]))) &&
1302
              /*
1303
               Don't escape field_term_char by doubling - doubling is only
1304
               valid for ENCLOSED BY characters:
1305
              */
1306
              (enclosed || !is_ambiguous_field_term ||
481 by Brian Aker
Remove all of uchar.
1307
               (int) (unsigned char) *pos != field_term_char))
1 by brian
clean slate
1308
          {
1309
	    char tmp_buff[2];
481 by Brian Aker
Remove all of uchar.
1310
            tmp_buff[0]= ((int) (unsigned char) *pos == field_sep_char &&
1 by brian
clean slate
1311
                          is_ambiguous_field_sep) ?
1312
                          field_sep_char : escape_char;
1313
	    tmp_buff[1]= *pos ? *pos : '0';
895 by Brian Aker
Completion (?) of uint conversion.
1314
	    if (my_b_write(&cache,(unsigned char*) start,(uint32_t) (pos-start)) ||
481 by Brian Aker
Remove all of uchar.
1315
		my_b_write(&cache,(unsigned char*) tmp_buff,2))
1 by brian
clean slate
1316
	      goto err;
1317
	    start=pos+1;
1318
	  }
1319
	}
895 by Brian Aker
Completion (?) of uint conversion.
1320
	if (my_b_write(&cache,(unsigned char*) start,(uint32_t) (pos-start)))
1 by brian
clean slate
1321
	  goto err;
1322
      }
481 by Brian Aker
Remove all of uchar.
1323
      else if (my_b_write(&cache,(unsigned char*) res->ptr(),used_length))
1 by brian
clean slate
1324
	goto err;
1325
    }
1326
    if (fixed_row_size)
1327
    {						// Fill with space
1328
      if (item->max_length > used_length)
1329
      {
1330
	/* QQ:  Fix by adding a my_b_fill() function */
1331
	if (!space_inited)
1332
	{
1333
	  space_inited=1;
212.6.3 by Mats Kindahl
Removing deprecated functions from code and replacing them with C99 equivalents:
1334
	  memset(space, ' ', sizeof(space));
1 by brian
clean slate
1335
	}
482 by Brian Aker
Remove uint.
1336
	uint32_t length=item->max_length-used_length;
1 by brian
clean slate
1337
	for (; length > sizeof(space) ; length-=sizeof(space))
1338
	{
481 by Brian Aker
Remove all of uchar.
1339
	  if (my_b_write(&cache,(unsigned char*) space,sizeof(space)))
1 by brian
clean slate
1340
	    goto err;
1341
	}
481 by Brian Aker
Remove all of uchar.
1342
	if (my_b_write(&cache,(unsigned char*) space,length))
1 by brian
clean slate
1343
	  goto err;
1344
      }
1345
    }
1346
    if (res && enclosed)
1347
    {
481 by Brian Aker
Remove all of uchar.
1348
      if (my_b_write(&cache, (unsigned char*) exchange->enclosed->ptr(),
1 by brian
clean slate
1349
                     exchange->enclosed->length()))
1350
        goto err;
1351
    }
1352
    if (--items_left)
1353
    {
481 by Brian Aker
Remove all of uchar.
1354
      if (my_b_write(&cache, (unsigned char*) exchange->field_term->ptr(),
1 by brian
clean slate
1355
                     field_term_length))
1356
        goto err;
1357
    }
1358
  }
481 by Brian Aker
Remove all of uchar.
1359
  if (my_b_write(&cache,(unsigned char*) exchange->line_term->ptr(),
1 by brian
clean slate
1360
		 exchange->line_term->length()))
1361
    goto err;
51.1.50 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
1362
  return(0);
1 by brian
clean slate
1363
err:
51.1.50 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
1364
  return(1);
1 by brian
clean slate
1365
}
1366
1367
1368
/***************************************************************************
1369
** Dump  of select to a binary file
1370
***************************************************************************/
1371
1372
1373
int
848 by Brian Aker
typdef class removal (just... use the name of the class).
1374
select_dump::prepare(List<Item> &, Select_Lex_Unit *u)
1 by brian
clean slate
1375
{
1376
  unit= u;
520.1.22 by Brian Aker
Second pass of thd cleanup
1377
  return (int) ((file= create_file(session, path, exchange, &cache)) < 0);
1 by brian
clean slate
1378
}
1379
1380
1381
bool select_dump::send_data(List<Item> &items)
1382
{
1383
  List_iterator_fast<Item> li(items);
1384
  char buff[MAX_FIELD_WIDTH];
1385
  String tmp(buff,sizeof(buff),&my_charset_bin),*res;
1386
  tmp.length(0);
1387
  Item *item;
1388
1389
  if (unit->offset_limit_cnt)
1390
  {						// using limit offset,count
1391
    unit->offset_limit_cnt--;
51.1.50 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
1392
    return(0);
1 by brian
clean slate
1393
  }
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1394
  if (row_count++ > 1)
1 by brian
clean slate
1395
  {
1396
    my_message(ER_TOO_MANY_ROWS, ER(ER_TOO_MANY_ROWS), MYF(0));
1397
    goto err;
1398
  }
1399
  while ((item=li++))
1400
  {
1401
    res=item->str_result(&tmp);
1402
    if (!res)					// If NULL
1403
    {
481 by Brian Aker
Remove all of uchar.
1404
      if (my_b_write(&cache,(unsigned char*) "",1))
1 by brian
clean slate
1405
	goto err;
1406
    }
481 by Brian Aker
Remove all of uchar.
1407
    else if (my_b_write(&cache,(unsigned char*) res->ptr(),res->length()))
1 by brian
clean slate
1408
    {
1409
      my_error(ER_ERROR_ON_WRITE, MYF(0), path, my_errno);
1410
      goto err;
1411
    }
1412
  }
51.1.50 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
1413
  return(0);
1 by brian
clean slate
1414
err:
51.1.50 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
1415
  return(1);
1 by brian
clean slate
1416
}
1417
1418
1419
select_subselect::select_subselect(Item_subselect *item_arg)
1420
{
1421
  item= item_arg;
1422
}
1423
1424
1425
bool select_singlerow_subselect::send_data(List<Item> &items)
1426
{
1427
  Item_singlerow_subselect *it= (Item_singlerow_subselect *)item;
1428
  if (it->assigned())
1429
  {
1430
    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
1431
    return(1);
1 by brian
clean slate
1432
  }
1433
  if (unit->offset_limit_cnt)
1434
  {				          // Using limit offset,count
1435
    unit->offset_limit_cnt--;
51.1.50 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
1436
    return(0);
1 by brian
clean slate
1437
  }
1438
  List_iterator_fast<Item> li(items);
1439
  Item *val_item;
482 by Brian Aker
Remove uint.
1440
  for (uint32_t i= 0; (val_item= li++); i++)
1 by brian
clean slate
1441
    it->store(i, val_item);
1442
  it->assigned(1);
51.1.50 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
1443
  return(0);
1 by brian
clean slate
1444
}
1445
1446
1447
void select_max_min_finder_subselect::cleanup()
1448
{
1449
  cache= 0;
1450
}
1451
1452
1453
bool select_max_min_finder_subselect::send_data(List<Item> &items)
1454
{
1455
  Item_maxmin_subselect *it= (Item_maxmin_subselect *)item;
1456
  List_iterator_fast<Item> li(items);
1457
  Item *val_item= li++;
1458
  it->register_value();
1459
  if (it->assigned())
1460
  {
1461
    cache->store(val_item);
1462
    if ((this->*op)())
1463
      it->store(0, cache);
1464
  }
1465
  else
1466
  {
1467
    if (!cache)
1468
    {
1469
      cache= Item_cache::get_cache(val_item);
1470
      switch (val_item->result_type())
1471
      {
1472
      case REAL_RESULT:
1473
	op= &select_max_min_finder_subselect::cmp_real;
1474
	break;
1475
      case INT_RESULT:
1476
	op= &select_max_min_finder_subselect::cmp_int;
1477
	break;
1478
      case STRING_RESULT:
1479
	op= &select_max_min_finder_subselect::cmp_str;
1480
	break;
1481
      case DECIMAL_RESULT:
1482
        op= &select_max_min_finder_subselect::cmp_decimal;
1483
        break;
1484
      case ROW_RESULT:
1485
        // This case should never be choosen
51.1.50 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
1486
	assert(0);
1 by brian
clean slate
1487
	op= 0;
1488
      }
1489
    }
1490
    cache->store(val_item);
1491
    it->store(0, cache);
1492
  }
1493
  it->assigned(1);
51.1.50 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
1494
  return(0);
1 by brian
clean slate
1495
}
1496
1497
bool select_max_min_finder_subselect::cmp_real()
1498
{
1499
  Item *maxmin= ((Item_singlerow_subselect *)item)->element_index(0);
1500
  double val1= cache->val_real(), val2= maxmin->val_real();
1501
  if (fmax)
1502
    return (cache->null_value && !maxmin->null_value) ||
1503
      (!cache->null_value && !maxmin->null_value &&
1504
       val1 > val2);
1505
  return (maxmin->null_value && !cache->null_value) ||
1506
    (!cache->null_value && !maxmin->null_value &&
1507
     val1 < val2);
1508
}
1509
1510
bool select_max_min_finder_subselect::cmp_int()
1511
{
1512
  Item *maxmin= ((Item_singlerow_subselect *)item)->element_index(0);
152 by Brian Aker
longlong replacement
1513
  int64_t val1= cache->val_int(), val2= maxmin->val_int();
1 by brian
clean slate
1514
  if (fmax)
1515
    return (cache->null_value && !maxmin->null_value) ||
1516
      (!cache->null_value && !maxmin->null_value &&
1517
       val1 > val2);
1518
  return (maxmin->null_value && !cache->null_value) ||
1519
    (!cache->null_value && !maxmin->null_value &&
1520
     val1 < val2);
1521
}
1522
1523
bool select_max_min_finder_subselect::cmp_decimal()
1524
{
1525
  Item *maxmin= ((Item_singlerow_subselect *)item)->element_index(0);
1526
  my_decimal cval, *cvalue= cache->val_decimal(&cval);
1527
  my_decimal mval, *mvalue= maxmin->val_decimal(&mval);
1528
  if (fmax)
1529
    return (cache->null_value && !maxmin->null_value) ||
1530
      (!cache->null_value && !maxmin->null_value &&
1531
       my_decimal_cmp(cvalue, mvalue) > 0) ;
1532
  return (maxmin->null_value && !cache->null_value) ||
1533
    (!cache->null_value && !maxmin->null_value &&
1534
     my_decimal_cmp(cvalue,mvalue) < 0);
1535
}
1536
1537
bool select_max_min_finder_subselect::cmp_str()
1538
{
1539
  String *val1, *val2, buf1, buf2;
1540
  Item *maxmin= ((Item_singlerow_subselect *)item)->element_index(0);
1541
  /*
1542
    as far as both operand is Item_cache buf1 & buf2 will not be used,
1543
    but added for safety
1544
  */
1545
  val1= cache->val_str(&buf1);
1546
  val2= maxmin->val_str(&buf1);
1547
  if (fmax)
1548
    return (cache->null_value && !maxmin->null_value) ||
1549
      (!cache->null_value && !maxmin->null_value &&
1550
       sortcmp(val1, val2, cache->collation.collation) > 0) ;
1551
  return (maxmin->null_value && !cache->null_value) ||
1552
    (!cache->null_value && !maxmin->null_value &&
1553
     sortcmp(val1, val2, cache->collation.collation) < 0);
1554
}
1555
779.1.27 by Monty Taylor
Got rid of __attribute__((unused)) and the like from the .cc files.
1556
bool select_exists_subselect::send_data(List<Item> &)
1 by brian
clean slate
1557
{
1558
  Item_exists_subselect *it= (Item_exists_subselect *)item;
1559
  if (unit->offset_limit_cnt)
77.1.45 by Monty Taylor
Warning fixes.
1560
  { // Using limit offset,count
1 by brian
clean slate
1561
    unit->offset_limit_cnt--;
51.1.50 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
1562
    return(0);
1 by brian
clean slate
1563
  }
1564
  it->value= 1;
1565
  it->assigned(1);
51.1.50 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
1566
  return(0);
1 by brian
clean slate
1567
}
1568
406 by Brian Aker
Cleanup around Query_arena.
1569
/*
1570
  Don't free mem_root, as mem_root is freed in the end of dispatch_command
1571
  (once for any command).
1572
*/
520.1.21 by Brian Aker
THD -> Session rename
1573
void Session::end_statement()
1 by brian
clean slate
1574
{
1575
  /* Cleanup SQL processing state to reuse this statement in next query. */
1576
  lex_end(lex);
1577
}
1578
520.1.21 by Brian Aker
THD -> Session rename
1579
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.
1580
{
1581
  if (db == NULL)
1582
  {
1583
    my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
1584
    return true;
1585
  }
1586
  *p_db= strmake(db, db_length);
1587
  *p_db_length= db_length;
1588
  return false;
1589
}
1590
1 by brian
clean slate
1591
/****************************************************************************
851 by Brian Aker
Class rewrite of Session (aka get all of the junk out)
1592
  Tmp_Table_Param
1 by brian
clean slate
1593
****************************************************************************/
1594
851 by Brian Aker
Class rewrite of Session (aka get all of the junk out)
1595
void Tmp_Table_Param::init()
1 by brian
clean slate
1596
{
1597
  field_count= sum_func_count= func_count= hidden_field_count= 0;
1598
  group_parts= group_length= group_null_parts= 0;
1599
  quick_group= 1;
1600
  table_charset= 0;
1601
  precomputed_group_by= 0;
1602
  bit_fields_as_long= 0;
1603
}
1604
851 by Brian Aker
Class rewrite of Session (aka get all of the junk out)
1605
void Tmp_Table_Param::cleanup(void)
584.1.14 by Monty Taylor
Removed field.h from common_includes.
1606
{
1607
  /* Fix for Intel compiler */
1608
  if (copy_field)
1609
  {
1610
    delete [] copy_field;
1611
    save_copy_field= copy_field= 0;
1612
  }
1613
}
1614
520.1.21 by Brian Aker
THD -> Session rename
1615
void Session::send_kill_message() const
202.3.6 by Monty Taylor
First pass at gettexizing the error messages.
1616
{
1617
  int err= killed_errno();
1618
  if (err)
1619
    my_message(err, ER(err), MYF(0));
1620
}
1 by brian
clean slate
1621
520.1.21 by Brian Aker
THD -> Session rename
1622
void Session::set_status_var_init()
1 by brian
clean slate
1623
{
212.6.6 by Mats Kindahl
Removing redundant use of casts in drizzled/ for memcmp(), memcpy(), memset(), and memmove().
1624
  memset(&status_var, 0, sizeof(status_var));
1 by brian
clean slate
1625
}
1626
1627
void Security_context::skip_grants()
1628
{
1629
  /* privileges for the user are unknown everything is allowed */
1630
}
1631
1632
1633
/****************************************************************************
1634
  Handling of open and locked tables states.
1635
1636
  This is used when we want to open/lock (and then close) some tables when
1637
  we already have a set of tables open and locked. We use these methods for
1638
  access to mysql.proc table to find definitions of stored routines.
1639
****************************************************************************/
1640
520.1.21 by Brian Aker
THD -> Session rename
1641
void Session::reset_n_backup_open_tables_state(Open_tables_state *backup)
1 by brian
clean slate
1642
{
1643
  backup->set_open_tables_state(this);
1644
  reset_open_tables_state();
1089.1.6 by Brian Aker
Removed dead flag code, style cleanup in FK. Removed dead structs.
1645
  backups_available= false;
1 by brian
clean slate
1646
}
1647
1648
520.1.21 by Brian Aker
THD -> Session rename
1649
void Session::restore_backup_open_tables_state(Open_tables_state *backup)
1 by brian
clean slate
1650
{
1651
  /*
1652
    Before we will throw away current open tables state we want
1653
    to be sure that it was properly cleaned up.
1654
  */
51.1.50 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
1655
  assert(open_tables == 0 && temporary_tables == 0 &&
1046.1.6 by Brian Aker
Formatting/style cleanup.
1656
              derived_tables == 0 &&
1054.1.8 by Brian Aker
Remove lock_tables list from session.
1657
              lock == 0);
1 by brian
clean slate
1658
  set_open_tables_state(backup);
1659
}
1660
656.1.22 by Monty Taylor
Removed my_malloc related stuff from log_event and session.
1661
1662
bool Session::set_db(const char *new_db, size_t new_db_len)
1663
{
1664
  /* Do not reallocate memory if current chunk is big enough. */
1665
  if (db && new_db && db_length >= new_db_len)
1666
    memcpy(db, new_db, new_db_len+1);
1667
  else
1668
  {
1669
    if (db)
1670
      free(db);
1671
    if (new_db)
656.1.34 by Monty Taylor
Got closer...
1672
    {
1673
      db= (char *)malloc(new_db_len + 1);
1674
      if (db != NULL)
1675
      {
1676
        memcpy(db, new_db, new_db_len);
1677
        db[new_db_len]= 0;
1678
      }
1679
    }
656.1.22 by Monty Taylor
Removed my_malloc related stuff from log_event and session.
1680
    else
1681
      db= NULL;
1682
  }
1683
  db_length= db ? new_db_len : 0;
1684
  return new_db && !db;
1685
}
1686
1687
1 by brian
clean slate
1688
/**
1689
  Check the killed state of a user thread
520.1.22 by Brian Aker
Second pass of thd cleanup
1690
  @param session  user thread
1 by brian
clean slate
1691
  @retval 0 the user thread is active
1692
  @retval 1 the user thread has been killed
1693
*/
520.1.22 by Brian Aker
Second pass of thd cleanup
1694
extern "C" int session_killed(const Session *session)
1 by brian
clean slate
1695
{
520.1.22 by Brian Aker
Second pass of thd cleanup
1696
  return(session->killed);
1 by brian
clean slate
1697
}
1698
1699
/**
1700
  Return the thread id of a user thread
520.1.22 by Brian Aker
Second pass of thd cleanup
1701
  @param session user thread
1 by brian
clean slate
1702
  @return thread id
1703
*/
520.1.22 by Brian Aker
Second pass of thd cleanup
1704
extern "C" unsigned long session_get_thread_id(const Session *session)
1 by brian
clean slate
1705
{
520.1.22 by Brian Aker
Second pass of thd cleanup
1706
  return((unsigned long)session->thread_id);
1 by brian
clean slate
1707
}
1708
1709
520.6.7 by Monty Taylor
Moved a bunch of crap out of common_includes.
1710
extern "C"
1711
LEX_STRING *session_make_lex_string(Session *session, LEX_STRING *lex_str,
1712
                                const char *str, unsigned int size,
1713
                                int allocate_lex_string)
1714
{
1715
  return session->make_lex_string(lex_str, str, size,
1716
                              (bool) allocate_lex_string);
1717
}
1718
1085.1.2 by Monty Taylor
Fixed -Wmissing-declarations
1719
const struct charset_info_st *session_charset(Session *session)
520.1.22 by Brian Aker
Second pass of thd cleanup
1720
{
1721
  return(session->charset());
1722
}
1723
1085.1.2 by Monty Taylor
Fixed -Wmissing-declarations
1724
char **session_query(Session *session)
520.1.22 by Brian Aker
Second pass of thd cleanup
1725
{
1726
  return(&session->query);
1727
}
1728
1085.1.2 by Monty Taylor
Fixed -Wmissing-declarations
1729
int session_non_transactional_update(const Session *session)
520.1.22 by Brian Aker
Second pass of thd cleanup
1730
{
1731
  return(session->transaction.all.modified_non_trans_table);
1732
}
1733
1085.1.2 by Monty Taylor
Fixed -Wmissing-declarations
1734
void session_mark_transaction_to_rollback(Session *session, bool all)
520.1.22 by Brian Aker
Second pass of thd cleanup
1735
{
1736
  mark_transaction_to_rollback(session, all);
1 by brian
clean slate
1737
}
1738
1739
/**
1740
  Mark transaction to rollback and mark error as fatal to a sub-statement.
1741
520.1.22 by Brian Aker
Second pass of thd cleanup
1742
  @param  session   Thread handle
51.1.50 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
1743
  @param  all   true <=> rollback main transaction.
1 by brian
clean slate
1744
*/
520.1.22 by Brian Aker
Second pass of thd cleanup
1745
void mark_transaction_to_rollback(Session *session, bool all)
1 by brian
clean slate
1746
{
520.1.22 by Brian Aker
Second pass of thd cleanup
1747
  if (session)
1 by brian
clean slate
1748
  {
520.1.22 by Brian Aker
Second pass of thd cleanup
1749
    session->is_fatal_sub_stmt_error= true;
1750
    session->transaction_rollback_request= all;
1 by brian
clean slate
1751
  }
1752
}
1753
934.2.6 by Jay Pipes
This changeset removes a few more C functions from sql_connect.cc/connect.h
1754
void Session::disconnect(uint32_t errcode, bool should_lock)
575.4.7 by Monty Taylor
More header cleanup.
1755
{
934.2.6 by Jay Pipes
This changeset removes a few more C functions from sql_connect.cc/connect.h
1756
  /* Allow any plugins to cleanup their session variables */
1757
  plugin_sessionvar_cleanup(this);
1758
1759
  /* If necessary, log any aborted or unauthorized connections */
971.3.19 by Eric Day
Finished first pass at Protocol cleanup, still some things to remove but they are a bit more involved.
1760
  if (killed || protocol->wasAborted())
934.2.6 by Jay Pipes
This changeset removes a few more C functions from sql_connect.cc/connect.h
1761
    statistic_increment(aborted_threads, &LOCK_status);
1762
971.3.19 by Eric Day
Finished first pass at Protocol cleanup, still some things to remove but they are a bit more involved.
1763
  if (protocol->wasAborted())
934.2.6 by Jay Pipes
This changeset removes a few more C functions from sql_connect.cc/connect.h
1764
  {
1765
    if (! killed && variables.log_warnings > 1)
1766
    {
1767
      Security_context *sctx= &security_ctx;
1768
1769
      errmsg_printf(ERRMSG_LVL_WARN, ER(ER_NEW_ABORTING_CONNECTION)
1770
                  , thread_id
1771
                  , (db ? db : "unconnected")
1772
                  , sctx->user.empty() == false ? sctx->user.c_str() : "unauthenticated"
1773
                  , sctx->ip.c_str()
1774
                  , (main_da.is_error() ? main_da.message() : ER(ER_UNKNOWN_ERROR)));
1775
    }
1776
  }
1777
1778
  /* Close out our connection to the client */
779.3.10 by Monty Taylor
Turned on -Wshadow.
1779
  if (should_lock)
575.4.7 by Monty Taylor
More header cleanup.
1780
    (void) pthread_mutex_lock(&LOCK_thread_count);
693 by Brian Aker
Cleaning up session class.
1781
  killed= Session::KILL_CONNECTION;
971.3.12 by Eric Day
Started abstracting Protocol, removed init_connect, init_file.
1782
  if (protocol->isConnected())
575.4.7 by Monty Taylor
More header cleanup.
1783
  {
1784
    if (errcode)
971.3.12 by Eric Day
Started abstracting Protocol, removed init_connect, init_file.
1785
    {
1786
      /*my_error(errcode, ER(errcode));*/
1787
      protocol->sendError(errcode, ER(errcode)); /* purecov: inspected */
1788
    }
971.3.6 by Eric Day
Moved the last of the libdrizzleclient calls into Protocol.
1789
    protocol->close();
575.4.7 by Monty Taylor
More header cleanup.
1790
  }
779.3.10 by Monty Taylor
Turned on -Wshadow.
1791
  if (should_lock)
575.4.7 by Monty Taylor
More header cleanup.
1792
    (void) pthread_mutex_unlock(&LOCK_thread_count);
1793
}
735 by Brian Aker
Refactor session.
1794
1795
void Session::reset_for_next_command()
1796
{
1797
  free_list= 0;
1798
  select_number= 1;
1799
  /*
1800
    Those two lines below are theoretically unneeded as
1801
    Session::cleanup_after_query() should take care of this already.
1802
  */
1803
  auto_inc_intervals_in_cur_stmt_for_binlog.empty();
1804
1055.2.17 by Jay Pipes
More style cleanups in Session
1805
  is_fatal_error= false;
735 by Brian Aker
Refactor session.
1806
  server_status&= ~ (SERVER_MORE_RESULTS_EXISTS |
1807
                          SERVER_QUERY_NO_INDEX_USED |
1808
                          SERVER_QUERY_NO_GOOD_INDEX_USED);
1809
  /*
1810
    If in autocommit mode and not in a transaction, reset
1811
    OPTION_STATUS_NO_TRANS_UPDATE | OPTION_KEEP_LOG to not get warnings
1812
    in ha_rollback_trans() about some tables couldn't be rolled back.
1813
  */
1814
  if (!(options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))
1815
  {
1816
    options&= ~OPTION_KEEP_LOG;
1817
    transaction.all.modified_non_trans_table= false;
1818
  }
1819
1820
  clear_error();
1821
  main_da.reset_diagnostics_area();
1822
  total_warn_count=0;			// Warnings for this query
1823
  sent_row_count= examined_row_count= 0;
1824
}
793 by Brian Aker
Pass through on refactoring functions to clases.
1825
1826
/*
1827
  Close all temporary tables created by 'CREATE TEMPORARY TABLE' for thread
1828
  creates one DROP TEMPORARY Table binlog event for each pseudo-thread
1829
*/
1830
1831
void Session::close_temporary_tables()
1832
{
1833
  Table *table;
798.2.20 by Brian Aker
More cleanup of binlog.isopen
1834
  Table *tmp_next;
793 by Brian Aker
Pass through on refactoring functions to clases.
1835
1836
  if (!temporary_tables)
1837
    return;
1838
798.2.20 by Brian Aker
More cleanup of binlog.isopen
1839
  for (table= temporary_tables; table; table= tmp_next)
1840
  {
1841
    tmp_next= table->next;
1054.1.9 by Brian Aker
This is a large number of refactors against the Session class for its
1842
    close_temporary(table, true, true);
798.2.20 by Brian Aker
More cleanup of binlog.isopen
1843
  }
1046.1.6 by Brian Aker
Formatting/style cleanup.
1844
  temporary_tables= NULL;
793 by Brian Aker
Pass through on refactoring functions to clases.
1845
}
855 by Brian Aker
Refactor reset of status.
1846
1847
1848
/** Clear most status variables. */
1849
extern time_t flush_status_time;
1850
extern uint32_t max_used_connections;
1851
1852
void Session::refresh_status()
1853
{
1854
  pthread_mutex_lock(&LOCK_status);
1855
1856
  /* Add thread's status variabes to global status */
1857
  add_to_status(&global_status_var, &status_var);
1858
1859
  /* Reset thread's status variables */
1860
  memset(&status_var, 0, sizeof(status_var));
1861
1862
  /* Reset some global variables */
1863
  reset_status_vars();
1864
1865
  /* Reset the counters of all key caches (default and named). */
1866
  process_key_caches(reset_key_cache_counters);
1867
  flush_status_time= time((time_t*) 0);
1868
  max_used_connections= 1; /* We set it to one, because we know we exist */
1869
  pthread_mutex_unlock(&LOCK_status);
1870
}
995 by Brian Aker
Refactor get_variable to session
1871
1872
#define extra_size sizeof(double)
1873
1874
user_var_entry *Session::getVariable(LEX_STRING &name, bool create_if_not_exists)
1875
{
1876
  user_var_entry *entry= NULL;
1877
1878
  entry= (user_var_entry*) hash_search(&user_vars, (unsigned char*) name.str, name.length);
1879
1880
  if ((entry == NULL) && create_if_not_exists)
1881
  {
1882
    if (!hash_inited(&user_vars))
1089.1.5 by Brian Aker
Cleanup of user_var
1883
      return NULL;
1884
    entry= new (nothrow) user_var_entry(name.str, query_id);
1885
1886
    if (entry == NULL)
1887
      return NULL;
1888
995 by Brian Aker
Refactor get_variable to session
1889
    if (my_hash_insert(&user_vars, (unsigned char*) entry))
1890
    {
1891
      assert(1);
1892
      free((char*) entry);
1893
      return 0;
1894
    }
1895
1896
  }
1897
1898
  return entry;
1899
}
1039.1.16 by Brian Aker
A lot of little cleanups (most based off lcov)
1900
1901
void Session::mark_temp_tables_as_free_for_reuse()
1902
{
1903
  for (Table *table= temporary_tables ; table ; table= table->next)
1904
  {
1905
    if (table->query_id == query_id)
1906
    {
1907
      table->query_id= 0;
1908
      table->file->ha_reset();
1909
    }
1910
  }
1911
}
1912
1913
void Session::mark_used_tables_as_free_for_reuse(Table *table)
1914
{
1915
  for (; table ; table= table->next)
1916
  {
1917
    if (table->query_id == query_id)
1918
    {
1919
      table->query_id= 0;
1920
      table->file->ha_reset();
1921
    }
1922
  }
1923
}
1924
1925
/*
1055.2.24 by Jay Pipes
Merge with trunk and resolve conflicts.
1926
  Unlocks tables and frees derived tables.
1927
  Put all normal tables used by thread in free list.
1928
1929
  It will only close/mark as free for reuse tables opened by this
1930
  substatement, it will also check if we are closing tables after
1931
  execution of complete query (i.e. we are on upper level) and will
1932
  leave prelocked mode if needed.
1039.1.16 by Brian Aker
A lot of little cleanups (most based off lcov)
1933
*/
1934
void Session::close_thread_tables()
1935
{
1936
  Table *table;
1937
1938
  /*
1939
    We are assuming here that session->derived_tables contains ONLY derived
1940
    tables for this substatement. i.e. instead of approach which uses
1941
    query_id matching for determining which of the derived tables belong
1942
    to this substatement we rely on the ability of substatements to
1943
    save/restore session->derived_tables during their execution.
1944
1945
    TODO: Probably even better approach is to simply associate list of
1946
          derived tables with (sub-)statement instead of thread and destroy
1947
          them at the end of its execution.
1948
  */
1949
  if (derived_tables)
1950
  {
1951
    Table *next;
1952
    /*
1953
      Close all derived tables generated in queries like
1954
      SELECT * FROM (SELECT * FROM t1)
1955
    */
1956
    for (table= derived_tables ; table ; table= next)
1957
    {
1958
      next= table->next;
1959
      table->free_tmp_table(this);
1960
    }
1961
    derived_tables= 0;
1962
  }
1963
1964
  /*
1965
    Mark all temporary tables used by this statement as free for reuse.
1966
  */
1967
  mark_temp_tables_as_free_for_reuse();
1968
  /*
1969
    Let us commit transaction for statement. Since in 5.0 we only have
1970
    one statement transaction and don't allow several nested statement
1971
    transactions this call will do nothing if we are inside of stored
1972
    function or trigger (i.e. statement transaction is already active and
1973
    does not belong to statement for which we do close_thread_tables()).
1974
    TODO: This should be fixed in later releases.
1975
   */
1089.1.6 by Brian Aker
Removed dead flag code, style cleanup in FK. Removed dead structs.
1976
  if (backups_available == false)
1039.1.16 by Brian Aker
A lot of little cleanups (most based off lcov)
1977
  {
1978
    main_da.can_overwrite_status= true;
1979
    ha_autocommit_or_rollback(this, is_error());
1980
    main_da.can_overwrite_status= false;
1981
    transaction.stmt.reset();
1982
  }
1983
1984
  if (lock)
1985
  {
1986
    /*
1987
      For RBR we flush the pending event just before we unlock all the
1988
      tables.  This means that we are at the end of a topmost
1989
      statement, so we ensure that the STMT_END_F flag is set on the
1990
      pending event.  For statements that are *inside* stored
1991
      functions, the pending event will not be flushed: that will be
1992
      handled either before writing a query log event (inside
1993
      binlog_query()) or when preparing a pending event.
1994
     */
1995
    mysql_unlock_tables(this, lock);
1996
    lock= 0;
1997
  }
1998
  /*
1999
    Note that we need to hold LOCK_open while changing the
2000
    open_tables list. Another thread may work on it.
2001
    (See: remove_table_from_cache(), mysql_wait_completed_table())
2002
    Closing a MERGE child before the parent would be fatal if the
2003
    other thread tries to abort the MERGE lock in between.
2004
  */
2005
  if (open_tables)
2006
    close_open_tables();
2007
}
1054.1.9 by Brian Aker
This is a large number of refactors against the Session class for its
2008
2009
void Session::close_tables_for_reopen(TableList **tables)
2010
{
2011
  /*
2012
    If table list consists only from tables from prelocking set, table list
2013
    for new attempt should be empty, so we have to update list's root pointer.
2014
  */
2015
  if (lex->first_not_own_table() == *tables)
2016
    *tables= 0;
2017
  lex->chop_off_not_own_tables();
2018
  for (TableList *tmp= *tables; tmp; tmp= tmp->next_global)
2019
    tmp->table= 0;
2020
  close_thread_tables();
2021
}
2022
2023
int Session::open_and_lock_tables(TableList *tables)
2024
{
2025
  uint32_t counter;
2026
  bool need_reopen;
2027
2028
  for ( ; ; )
2029
  {
2030
    if (open_tables_from_list(&tables, &counter, 0))
2031
      return -1;
2032
2033
    if (!lock_tables(this, tables, counter, &need_reopen))
2034
      break;
2035
    if (!need_reopen)
2036
      return -1;
2037
    close_tables_for_reopen(&tables);
2038
  }
2039
  if ((mysql_handle_derived(lex, &mysql_derived_prepare) ||
2040
       (fill_derived_tables() &&
2041
        mysql_handle_derived(lex, &mysql_derived_filling))))
2042
    return 1; /* purecov: inspected */
2043
2044
  return 0;
2045
}
2046
2047
bool Session::open_normal_and_derived_tables(TableList *tables, uint32_t flags)
2048
{
2049
  uint32_t counter;
2050
  assert(!(fill_derived_tables()));
2051
  if (open_tables_from_list(&tables, &counter, flags) ||
2052
      mysql_handle_derived(lex, &mysql_derived_prepare))
2053
    return true; /* purecov: inspected */
2054
  return false;
2055
}