~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/session.h

pandora-build v0.71. Added check for avahi.

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
#ifndef DRIZZLED_SESSION_H
22
22
#define DRIZZLED_SESSION_H
23
23
 
 
24
/* Classes in mysql */
 
25
 
24
26
#include "drizzled/plugin.h"
25
 
#include "drizzled/sql_locale.h"
26
 
#include "drizzled/resource_context.h"
27
 
#include "drizzled/cursor.h"
28
 
#include "drizzled/current_session.h"
29
 
#include "drizzled/sql_error.h"
30
 
#include "drizzled/file_exchange.h"
31
 
#include "drizzled/select_result_interceptor.h"
32
 
#include "drizzled/statistics_variables.h"
33
 
#include "drizzled/xid.h"
34
 
#include "drizzled/query_id.h"
35
 
#include "drizzled/named_savepoint.h"
36
 
#include "drizzled/transaction_context.h"
37
 
#include "drizzled/util/storable.h"
38
 
#include "drizzled/my_hash.h"
39
 
#include "drizzled/pthread_globals.h"
 
27
#include <drizzled/sql_locale.h>
 
28
#include <drizzled/ha_trx_info.h>
 
29
#include <mysys/my_alloc.h>
 
30
#include <mysys/my_tree.h>
 
31
#include <drizzled/cursor.h>
 
32
#include <drizzled/current_session.h>
 
33
#include <drizzled/sql_error.h>
 
34
#include <drizzled/file_exchange.h>
 
35
#include <drizzled/select_result_interceptor.h>
 
36
#include <drizzled/db.h>
 
37
#include <drizzled/xid.h>
 
38
 
40
39
#include <netdb.h>
41
 
#include <sys/time.h>
42
 
#include <sys/resource.h>
43
 
 
44
 
#include <algorithm>
45
 
#include <bitset>
46
 
#include <deque>
47
40
#include <map>
48
41
#include <string>
49
 
 
50
 
#include "drizzled/security_context.h"
51
 
#include "drizzled/open_tables_state.h"
52
 
#include "drizzled/internal_error_handler.h"
53
 
#include "drizzled/diagnostics_area.h"
54
 
#include "drizzled/plugin/authorization.h"
55
 
 
56
 
#include <boost/unordered_map.hpp>
57
 
 
58
 
#include <boost/thread/thread.hpp>
59
 
#include <boost/thread/mutex.hpp>
60
 
#include <boost/thread/shared_mutex.hpp>
61
 
#include <boost/thread/condition_variable.hpp>
62
 
#include <boost/make_shared.hpp>
63
 
 
 
42
#include <bitset>
64
43
 
65
44
#define MIN_HANDSHAKE_SIZE      6
66
45
 
67
46
namespace drizzled
68
47
{
69
 
 
70
48
namespace plugin
71
49
{
72
50
class Client;
73
51
class Scheduler;
74
 
class EventObserverList;
75
52
}
76
 
 
77
53
namespace message
78
54
{
79
55
class Transaction;
80
56
class Statement;
81
 
class Resultset;
82
 
}
83
 
 
84
 
namespace internal
85
 
{
86
 
struct st_my_thread_var;
87
 
}
88
 
 
89
 
namespace table
90
 
{
91
 
class Placeholder;
 
57
}
92
58
}
93
59
 
94
60
class Lex_input_stream;
96
62
class CopyField;
97
63
class Table_ident;
98
64
 
99
 
class TableShareInstance;
100
 
 
101
65
extern char internal_table_name[2];
102
66
extern char empty_c_string[1];
103
67
extern const char **errmesg;
112
76
  to hande the entire table-share for a local table. Once Hash is done,
113
77
  we should consider exchanging the map for it.
114
78
*/
115
 
typedef std::map <std::string, message::Table> ProtoCache;
 
79
typedef std::map <std::string, drizzled::message::Table> ProtoCache;
116
80
 
117
81
/**
118
82
  The COPY_INFO structure is used by INSERT/REPLACE code.
126
90
      of the INSERT ... ON DUPLICATE KEY UPDATE no matter whether the row
127
91
      was actually changed or not.
128
92
*/
129
 
class CopyInfo 
 
93
typedef struct st_copy_info 
130
94
{
131
 
public:
132
95
  ha_rows records; /**< Number of processed records */
133
96
  ha_rows deleted; /**< Number of deleted records */
134
97
  ha_rows updated; /**< Number of updated records */
142
105
  List<Item> *update_fields;
143
106
  List<Item> *update_values;
144
107
  /* for VIEW ... WITH CHECK OPTION */
145
 
 
146
 
  CopyInfo() :
147
 
    records(0),
148
 
    deleted(0),
149
 
    updated(0),
150
 
    copied(0),
151
 
    error_count(0),
152
 
    touched(0),
153
 
    escape_char(0),
154
 
    last_errno(0),
155
 
    ignore(0),
156
 
    update_fields(0),
157
 
    update_values(0)
158
 
  { }
159
 
 
160
 
};
161
 
 
162
 
} /* namespace drizzled */
163
 
 
164
 
/** @TODO why is this in the middle of the file */
 
108
} COPY_INFO;
 
109
 
 
110
typedef struct drizzled_lock_st
 
111
{
 
112
  Table **table;
 
113
  uint32_t table_count;
 
114
  uint32_t lock_count;
 
115
  THR_LOCK_DATA **locks;
 
116
} DRIZZLE_LOCK;
 
117
 
165
118
#include <drizzled/lex_column.h>
166
119
 
167
 
namespace drizzled
168
 
{
169
 
 
170
120
class select_result;
171
121
class Time_zone;
172
122
 
173
123
#define Session_SENTRY_MAGIC 0xfeedd1ff
174
124
#define Session_SENTRY_GONE  0xdeadbeef
175
125
 
176
 
struct drizzle_system_variables
 
126
#define Session_CHECK_SENTRY(session) assert(session->dbug_sentry == Session_SENTRY_MAGIC)
 
127
 
 
128
struct system_variables
177
129
{
178
 
  drizzle_system_variables()
179
 
  {}
 
130
  system_variables() {};
180
131
  /*
181
132
    How dynamically allocated system variables are handled:
182
133
 
209
160
  bool log_warnings;
210
161
 
211
162
  uint32_t optimizer_search_depth;
 
163
  /* A bitmap for switching optimizations on/off */
 
164
  uint32_t optimizer_switch;
212
165
  uint32_t div_precincrement;
213
166
  uint64_t preload_buff_size;
214
167
  uint32_t read_buff_size;
215
168
  uint32_t read_rnd_buff_size;
216
 
  bool replicate_query;
217
169
  size_t sortbuff_size;
218
170
  uint32_t thread_handling;
219
171
  uint32_t tx_isolation;
220
 
  size_t transaction_message_threshold;
221
172
  uint32_t completion_type;
222
173
  /* Determines which non-standard SQL behaviour should be enabled */
223
174
  uint32_t sql_mode;
225
176
  size_t range_alloc_block_size;
226
177
  uint32_t query_alloc_block_size;
227
178
  uint32_t query_prealloc_size;
 
179
  uint32_t trans_alloc_block_size;
 
180
  uint32_t trans_prealloc_size;
228
181
  uint64_t group_concat_max_len;
 
182
  /* TODO: change this to my_thread_id - but have to fix set_var first */
229
183
  uint64_t pseudo_thread_id;
230
184
 
231
 
  plugin::StorageEngine *storage_engine;
 
185
  drizzled::plugin::StorageEngine *storage_engine;
232
186
 
233
187
  /* Only charset part of these variables is sensible */
234
188
  const CHARSET_INFO  *character_set_filesystem;
247
201
  Time_zone *time_zone;
248
202
};
249
203
 
250
 
extern struct drizzle_system_variables global_system_variables;
251
 
 
252
 
} /* namespace drizzled */
253
 
 
254
 
#include "drizzled/sql_lex.h"
255
 
 
256
 
namespace drizzled
 
204
extern struct system_variables global_system_variables;
 
205
 
 
206
#include "sql_lex.h"
 
207
 
 
208
/**
 
209
 * Per-session local status counters
 
210
 */
 
211
typedef struct system_status_var
257
212
{
 
213
  uint64_t bytes_received;
 
214
  uint64_t bytes_sent;
 
215
  ulong com_other;
 
216
  ulong com_stat[(uint32_t) SQLCOM_END];
 
217
  ulong created_tmp_disk_tables;
 
218
  ulong created_tmp_tables;
 
219
  ulong ha_commit_count;
 
220
  ulong ha_delete_count;
 
221
  ulong ha_read_first_count;
 
222
  ulong ha_read_last_count;
 
223
  ulong ha_read_key_count;
 
224
  ulong ha_read_next_count;
 
225
  ulong ha_read_prev_count;
 
226
  ulong ha_read_rnd_count;
 
227
  ulong ha_read_rnd_next_count;
 
228
  ulong ha_rollback_count;
 
229
  ulong ha_update_count;
 
230
  ulong ha_write_count;
 
231
  ulong ha_prepare_count;
 
232
  ulong ha_savepoint_count;
 
233
  ulong ha_savepoint_rollback_count;
 
234
 
 
235
  /* KEY_CACHE parts. These are copies of the original */
 
236
  ulong key_blocks_changed;
 
237
  ulong key_blocks_used;
 
238
  ulong key_cache_r_requests;
 
239
  ulong key_cache_read;
 
240
  ulong key_cache_w_requests;
 
241
  ulong key_cache_write;
 
242
  /* END OF KEY_CACHE parts */
 
243
 
 
244
  ulong net_big_packet_count;
 
245
  ulong opened_tables;
 
246
  ulong opened_shares;
 
247
  ulong select_full_join_count;
 
248
  ulong select_full_range_join_count;
 
249
  ulong select_range_count;
 
250
  ulong select_range_check_count;
 
251
  ulong select_scan_count;
 
252
  ulong long_query_count;
 
253
  ulong filesort_merge_passes;
 
254
  ulong filesort_range_count;
 
255
  ulong filesort_rows;
 
256
  ulong filesort_scan_count;
 
257
  /*
 
258
    Number of statements sent from the client
 
259
  */
 
260
  ulong questions;
 
261
 
 
262
  /*
 
263
    IMPORTANT!
 
264
    SEE last_system_status_var DEFINITION BELOW.
 
265
 
 
266
    Below 'last_system_status_var' are all variables which doesn't make any
 
267
    sense to add to the /global/ status variable counter.
 
268
  */
 
269
  double last_query_cost;
 
270
} STATUS_VAR;
 
271
 
 
272
/*
 
273
  This is used for 'SHOW STATUS'. It must be updated to the last ulong
 
274
  variable in system_status_var which is makes sens to add to the global
 
275
  counter
 
276
*/
 
277
 
 
278
#define last_system_status_var questions
258
279
 
259
280
void mark_transaction_to_rollback(Session *session, bool all);
260
281
 
 
282
struct st_savepoint 
 
283
{
 
284
  struct st_savepoint *prev;
 
285
  char *name;
 
286
  uint32_t length;
 
287
  Ha_trx_info *ha_list;
 
288
};
 
289
 
 
290
extern pthread_mutex_t LOCK_xid_cache;
 
291
extern HASH xid_cache;
 
292
 
 
293
#include <drizzled/security_context.h>
 
294
#include <drizzled/open_tables_state.h>
 
295
 
 
296
#include <drizzled/internal_error_handler.h> 
 
297
#include <drizzled/diagnostics_area.h> 
 
298
 
261
299
/**
262
300
  Storage engine specific thread local data.
263
301
*/
269
307
  */
270
308
  void *ha_ptr;
271
309
  /**
272
 
   * Resource contexts for both the "statement" and "normal"
273
 
   * transactions.
274
 
   *
275
 
   * Resource context at index 0:
276
 
   *
277
 
   * Life time: one statement within a transaction. If @@autocommit is
278
 
   * on, also represents the entire transaction.
279
 
   *
280
 
   * Resource context at index 1:
281
 
   *
282
 
   * Life time: one transaction within a connection. 
283
 
   *
284
 
   * @note
285
 
   *
286
 
   * If the storage engine does not participate in a transaction, 
287
 
   * there will not be a resource context.
288
 
   */
289
 
  drizzled::ResourceContext resource_context[2];
 
310
    0: Life time: one statement within a transaction. If @@autocommit is
 
311
    on, also represents the entire transaction.
 
312
    @sa trans_register_ha()
 
313
 
 
314
    1: Life time: one transaction within a connection.
 
315
    If the storage engine does not participate in a transaction,
 
316
    this should not be used.
 
317
    @sa trans_register_ha()
 
318
  */
 
319
  Ha_trx_info ha_info[2];
290
320
 
291
321
  Ha_data() :ha_ptr(NULL) {}
292
322
};
310
340
 * all member variables that are not critical to non-internal operations of the
311
341
 * session object.
312
342
 */
313
 
typedef int64_t session_id_t;
314
 
 
315
343
class Session : public Open_tables_state
316
344
{
317
345
public:
318
 
  // Plugin storage in Session.
319
 
  typedef boost::unordered_map<std::string, util::Storable *, util::insensitive_hash, util::insensitive_equal_to> PropertyMap;
320
 
  typedef Session* Ptr;
321
 
  typedef boost::shared_ptr<Session> shared_ptr;
322
 
 
323
346
  /*
324
347
    MARK_COLUMNS_NONE:  Means mark_used_colums is not set and no indicator to
325
348
                        handler of fields used is set
334
357
  enum enum_mark_columns mark_used_columns;
335
358
  inline void* alloc(size_t size)
336
359
  {
337
 
    return mem_root->alloc_root(size);
 
360
    return alloc_root(mem_root,size);
338
361
  }
339
362
  inline void* calloc(size_t size)
340
363
  {
341
364
    void *ptr;
342
 
    if ((ptr= mem_root->alloc_root(size)))
 
365
    if ((ptr= alloc_root(mem_root,size)))
343
366
      memset(ptr, 0, size);
344
367
    return ptr;
345
368
  }
346
369
  inline char *strdup(const char *str)
347
370
  {
348
 
    return mem_root->strdup_root(str);
 
371
    return strdup_root(mem_root,str);
349
372
  }
350
373
  inline char *strmake(const char *str, size_t size)
351
374
  {
352
 
    return mem_root->strmake_root(str,size);
 
375
    return strmake_root(mem_root,str,size);
353
376
  }
354
377
  inline void *memdup(const void *str, size_t size)
355
378
  {
356
 
    return mem_root->memdup_root(str, size);
 
379
    return memdup_root(mem_root,str,size);
357
380
  }
358
381
  inline void *memdup_w_gap(const void *str, size_t size, uint32_t gap)
359
382
  {
360
383
    void *ptr;
361
 
    if ((ptr= mem_root->alloc_root(size + gap)))
 
384
    if ((ptr= alloc_root(mem_root,size+gap)))
362
385
      memcpy(ptr,str,size);
363
386
    return ptr;
364
387
  }
369
392
   * itself to the list on creation (see Item::Item() for details))
370
393
   */
371
394
  Item *free_list;
372
 
  memory::Root *mem_root; /**< Pointer to current memroot */
373
 
 
374
 
 
375
 
  memory::Root *getMemRoot()
376
 
  {
377
 
    return mem_root;
378
 
  }
379
 
 
380
 
  uint64_t xa_id;
381
 
 
382
 
  uint64_t getXaId()
383
 
  {
384
 
    return xa_id;
385
 
  }
386
 
 
387
 
  void setXaId(uint64_t in_xa_id)
388
 
  {
389
 
    xa_id= in_xa_id; 
390
 
  }
391
 
 
 
395
  MEM_ROOT *mem_root; /**< Pointer to current memroot */
392
396
  /**
393
397
   * Uniquely identifies each statement object in thread scope; change during
394
398
   * statement lifetime.
397
401
   */
398
402
  uint32_t id;
399
403
  LEX *lex; /**< parse tree descriptor */
400
 
 
401
 
  LEX *getLex() 
402
 
  {
403
 
    return lex;
404
 
  }
405
 
  /** query associated with this statement */
406
 
  typedef boost::shared_ptr<const std::string> QueryString;
407
 
private:
408
 
  boost::shared_ptr<std::string> query;
409
 
 
410
 
  // Never allow for a modification of this outside of the class. c_str()
411
 
  // requires under some setup non const, you must copy the QueryString in
412
 
  // order to use it.
413
 
public:
414
 
  QueryString getQueryString() const
415
 
  {
416
 
    return query;
417
 
  }
418
 
 
419
 
  void resetQueryString()
420
 
  {
421
 
    query.reset();
422
 
    _state.reset();
423
 
  }
424
 
 
425
 
  /*
426
 
    We need to copy the lock on the string in order to make sure we have a stable string.
427
 
    Once this is done we can use it to build a const char* which can be handed off for
428
 
    a method to use (Innodb is currently the only engine using this).
 
404
  /**
 
405
    Points to the query associated with this statement. It's const, but
 
406
    we need to declare it char * because all table handlers are written
 
407
    in C and need to point to it.
 
408
 
 
409
    Note that (A) if we set query = NULL, we must at the same time set
 
410
    query_length = 0, and protect the whole operation with the
 
411
    LOCK_thread_count mutex. And (B) we are ONLY allowed to set query to a
 
412
    non-NULL value if its previous value is NULL. We do not need to protect
 
413
    operation (B) with any mutex. To avoid crashes in races, if we do not
 
414
    know that session->query cannot change at the moment, one should print
 
415
    session->query like this:
 
416
      (1) reserve the LOCK_thread_count mutex;
 
417
      (2) check if session->query is NULL;
 
418
      (3) if not NULL, then print at most session->query_length characters from
 
419
      it. We will see the query_length field as either 0, or the right value
 
420
      for it.
 
421
    Assuming that the write and read of an n-bit memory field in an n-bit
 
422
    computer is atomic, we can avoid races in the above way.
 
423
    This printing is needed at least in SHOW PROCESSLIST and SHOW INNODB
 
424
    STATUS.
429
425
  */
430
 
  const char *getQueryStringCopy(size_t &length)
431
 
  {
432
 
    QueryString tmp_string(getQueryString());
433
 
 
434
 
    assert(tmp_string);
435
 
    if (not tmp_string)
436
 
    {
437
 
      length= 0;
438
 
      return 0;
439
 
    }
440
 
 
441
 
    length= tmp_string->length();
442
 
    char *to_return= strmake(tmp_string->c_str(), tmp_string->length());
443
 
    return to_return;
444
 
  }
445
 
 
446
 
  class State {
447
 
    std::vector <char> _query;
448
 
 
449
 
  public:
450
 
    typedef boost::shared_ptr<State> const_shared_ptr;
451
 
 
452
 
    State(const char *in_packet, size_t in_packet_length)
453
 
    {
454
 
      if (in_packet_length)
455
 
      {
456
 
        size_t minimum= std::min(in_packet_length, static_cast<size_t>(PROCESS_LIST_WIDTH));
457
 
        _query.resize(minimum + 1);
458
 
        memcpy(&_query[0], in_packet, minimum);
459
 
      }
460
 
      else
461
 
      {
462
 
        _query.resize(0);
463
 
      }
464
 
    }
465
 
 
466
 
    const char *query() const
467
 
    {
468
 
      if (_query.size())
469
 
        return &_query[0];
470
 
 
471
 
      return "";
472
 
    }
473
 
 
474
 
    const char *query(size_t &size) const
475
 
    {
476
 
      if (_query.size())
477
 
      {
478
 
        size= _query.size() -1;
479
 
        return &_query[0];
480
 
      }
481
 
 
482
 
      size= 0;
483
 
      return "";
484
 
    }
485
 
  protected:
486
 
    friend class Session;
487
 
    typedef boost::shared_ptr<State> shared_ptr;
488
 
  };
489
 
private:
490
 
  State::shared_ptr  _state; 
491
 
public:
492
 
 
493
 
  State::const_shared_ptr state()
494
 
  {
495
 
    return _state;
496
 
  }
 
426
  char *query;
 
427
  uint32_t query_length; /**< current query length */
497
428
 
498
429
  /**
499
430
    Name of the current (default) database.
507
438
    the Session of that thread); that thread is (and must remain, for now) the
508
439
    only responsible for freeing this member.
509
440
  */
510
 
private:
511
 
  util::string::shared_ptr _schema;
512
 
public:
513
 
 
514
 
  util::string::const_shared_ptr schema() const
515
 
  {
516
 
    if (_schema)
517
 
      return _schema;
518
 
 
519
 
    return util::string::const_shared_ptr(new std::string(""));
520
 
  }
521
 
  std::string catalog;
522
 
  /* current cache key */
523
 
  std::string query_cache_key;
 
441
  char *db;
 
442
  uint32_t db_length; /**< Length of current schema name */
 
443
 
524
444
  /**
525
445
    Constant for Session::where initialization in the beginning of every query.
526
446
 
529
449
  */
530
450
  static const char * const DEFAULT_WHERE;
531
451
 
532
 
  memory::Root warn_root; /**< Allocation area for warnings and errors */
533
 
  plugin::Client *client; /**< Pointer to client object */
534
 
 
535
 
  void setClient(plugin::Client *client_arg);
536
 
 
537
 
  plugin::Client *getClient()
538
 
  {
539
 
    return client;
540
 
  }
541
 
 
542
 
  plugin::Scheduler *scheduler; /**< Pointer to scheduler object */
 
452
  MEM_ROOT warn_root; /**< Allocation area for warnings and errors */
 
453
  drizzled::plugin::Client *client; /**< Pointer to client object */
 
454
  drizzled::plugin::Scheduler *scheduler; /**< Pointer to scheduler object */
543
455
  void *scheduler_arg; /**< Pointer to the optional scheduler argument */
544
 
 
545
 
  typedef boost::unordered_map< std::string, user_var_entry *, util::insensitive_hash, util::insensitive_equal_to> UserVars;
546
 
private:
547
 
  typedef std::pair< UserVars::iterator, UserVars::iterator > UserVarsRange;
548
 
  UserVars user_vars; /**< Hash of user variables defined during the session's lifetime */
549
 
 
550
 
public:
551
 
 
552
 
  const UserVars &getUserVariables() const
553
 
  {
554
 
    return user_vars;
555
 
  }
556
 
 
557
 
  drizzle_system_variables variables; /**< Mutable local variables local to the session */
 
456
  HASH user_vars; /**< Hash of user variables defined during the session's lifetime */
 
457
  struct system_variables variables; /**< Mutable local variables local to the session */
558
458
  struct system_status_var status_var; /**< Session-local status counters */
 
459
  struct system_status_var *initial_status_var; /* used by show status */
559
460
  THR_LOCK_INFO lock_info; /**< Locking information for this session */
560
461
  THR_LOCK_OWNER main_lock_id; /**< To use for conventional queries */
561
462
  THR_LOCK_OWNER *lock_id; /**< If not main_lock_id, points to the lock_id of a cursor. */
 
463
  pthread_mutex_t LOCK_delete; /**< Locked before session is deleted */
 
464
 
 
465
  /**
 
466
   * A peek into the query string for the session. This is a best effort
 
467
   * delivery, there is no guarantee whether the content is meaningful.
 
468
   */
 
469
  char process_list_info[PROCESS_LIST_WIDTH+1];
562
470
 
563
471
  /**
564
472
   * A pointer to the stack frame of the scheduler thread
566
474
   */
567
475
  char *thread_stack;
568
476
 
569
 
private:
570
 
  SecurityContext security_ctx;
571
 
 
572
 
  int32_t scoreboard_index;
573
 
 
574
 
  inline void checkSentry() const
575
 
  {
576
 
    assert(this->dbug_sentry == Session_SENTRY_MAGIC);
577
 
  }
578
 
public:
579
 
  const SecurityContext& getSecurityContext() const
580
 
  {
581
 
    return security_ctx;
582
 
  }
583
 
 
584
 
  SecurityContext& getSecurityContext()
585
 
  {
586
 
    return security_ctx;
587
 
  }
588
 
 
589
 
  int32_t getScoreboardIndex()
590
 
  {
591
 
    return scoreboard_index;
592
 
  }
593
 
 
594
 
  void setScoreboardIndex(int32_t in_scoreboard_index)
595
 
  {
596
 
    scoreboard_index= in_scoreboard_index;
597
 
  }
598
 
 
599
477
  /**
600
 
   * Is this session viewable by the current user?
601
 
   */
602
 
  bool isViewable() const;
 
478
    @note
 
479
    Some members of Session (currently 'Statement::db',
 
480
    'query')  are set and alloced by the slave SQL thread
 
481
    (for the Session of that thread); that thread is (and must remain, for now)
 
482
    the only responsible for freeing these 3 members. If you add members
 
483
    here, and you add code to set them in replication, don't forget to
 
484
    free_them_and_set_them_to_0 in replication properly. For details see
 
485
    the 'err:' label of the handle_slave_sql() in sql/slave.cc.
 
486
 
 
487
    @see handle_slave_sql
 
488
  */
 
489
  Security_context security_ctx;
603
490
 
604
491
  /**
605
492
    Used in error messages to tell user in what part of MySQL we found an
614
501
    chapter 'Miscellaneous functions', for functions GET_LOCK, RELEASE_LOCK.
615
502
  */
616
503
  uint32_t dbug_sentry; /**< watch for memory corruption */
617
 
private:
618
 
  boost::thread::id boost_thread_id;
619
 
  boost_thread_shared_ptr _thread;
620
 
  boost::this_thread::disable_interruption *interrupt;
621
 
 
622
 
  internal::st_my_thread_var *mysys_var;
623
 
public:
624
 
 
625
 
  boost_thread_shared_ptr &getThread()
626
 
  {
627
 
    return _thread;
628
 
  }
629
 
 
630
 
  void pushInterrupt(boost::this_thread::disable_interruption *interrupt_arg)
631
 
  {
632
 
    interrupt= interrupt_arg;
633
 
  }
634
 
 
635
 
  boost::this_thread::disable_interruption &getThreadInterupt()
636
 
  {
637
 
    assert(interrupt);
638
 
    return *interrupt;
639
 
  }
640
 
 
641
 
  internal::st_my_thread_var *getThreadVar()
642
 
  {
643
 
    return mysys_var;
644
 
  }
645
 
 
 
504
  struct st_my_thread_var *mysys_var;
646
505
  /**
647
506
   * Type of current query: COM_STMT_PREPARE, COM_QUERY, etc. Set from
648
507
   * first byte of the packet in executeStatement()
663
522
    Both of the following container points in session will be converted to an API.
664
523
  */
665
524
 
666
 
private:
667
525
  /* container for handler's private per-connection data */
668
 
  std::vector<Ha_data> ha_data;
669
 
  /*
670
 
    Id of current query. Statement can be reused to execute several queries
671
 
    query_id is global in context of the whole MySQL server.
672
 
    ID is automatically generated from an atomic counter.
673
 
    It's used in Cursor code for various purposes: to check which columns
674
 
    from table are necessary for this select, to check if it's necessary to
675
 
    update auto-updatable fields (like auto_increment and timestamp).
676
 
  */
677
 
  query_id_t query_id;
678
 
  query_id_t warn_query_id;
679
 
public:
680
 
  void **getEngineData(const plugin::MonitoredInTransaction *monitored);
681
 
  ResourceContext *getResourceContext(const plugin::MonitoredInTransaction *monitored,
682
 
                                      size_t index= 0);
683
 
 
684
 
  /**
685
 
   * Structure used to manage "statement transactions" and
686
 
   * "normal transactions". In autocommit mode, the normal transaction is
687
 
   * equivalent to the statement transaction.
688
 
   *
689
 
   * Storage engines will be registered here when they participate in
690
 
   * a transaction. No engine is registered more than once.
691
 
   */
 
526
  Ha_data ha_data[MAX_HA];
 
527
 
 
528
  /* container for replication data */
 
529
  void *replication_data;
 
530
 
692
531
  struct st_transactions {
693
 
    std::deque<NamedSavepoint> savepoints;
694
 
 
695
 
    /**
696
 
     * The normal transaction (since BEGIN WORK).
697
 
     *
698
 
     * Contains a list of all engines that have participated in any of the
699
 
     * statement transactions started within the context of the normal
700
 
     * transaction.
701
 
     *
702
 
     * @note In autocommit mode, this is empty.
703
 
     */
704
 
    TransactionContext all;
705
 
 
706
 
    /**
707
 
     * The statment transaction.
708
 
     *
709
 
     * Contains a list of all engines participating in the given statement.
710
 
     *
711
 
     * @note In autocommit mode, this will be used to commit/rollback the
712
 
     * normal transaction.
713
 
     */
714
 
    TransactionContext stmt;
715
 
 
 
532
    SAVEPOINT *savepoints;
 
533
    Session_TRANS all;                  // Trans since BEGIN WORK
 
534
    Session_TRANS stmt;                 // Trans for current statement
 
535
    bool on;                            // see ha_enable_transaction()
716
536
    XID_STATE xid_state;
717
537
 
 
538
    /*
 
539
       Tables changed in transaction (that must be invalidated in query cache).
 
540
       List contain only transactional tables, that not invalidated in query
 
541
       cache (instead of full list of changed in transaction tables).
 
542
    */
 
543
    CHANGED_TableList* changed_tables;
 
544
    MEM_ROOT mem_root; // Transaction-life memory allocation pool
718
545
    void cleanup()
719
546
    {
720
 
      savepoints.clear();
721
 
    }
722
 
    st_transactions() :
723
 
      savepoints(),
724
 
      all(),
725
 
      stmt(),
726
 
      xid_state()
727
 
    { }
 
547
      changed_tables= 0;
 
548
      savepoints= 0;
 
549
      free_root(&mem_root,MYF(MY_KEEP_PREALLOC));
 
550
    }
 
551
    st_transactions()
 
552
    {
 
553
      memset(this, 0, sizeof(*this));
 
554
      xid_state.xid.null();
 
555
      init_sql_alloc(&mem_root, ALLOC_ROOT_MIN_BLOCK_SIZE, 0);
 
556
    }
728
557
  } transaction;
729
 
 
730
558
  Field *dup_field;
731
559
  sigset_t signals;
732
560
 
733
 
  // As of right now we do not allow a concurrent execute to launch itself
734
 
private:
735
 
  bool concurrent_execute_allowed;
736
 
public:
737
 
 
738
 
  void setConcurrentExecute(bool arg)
739
 
  {
740
 
    concurrent_execute_allowed= arg;
741
 
  }
742
 
 
743
 
  bool isConcurrentExecuteAllowed() const
744
 
  {
745
 
    return concurrent_execute_allowed;
746
 
  }
747
 
 
748
561
  /* Tells if LAST_INSERT_ID(#) was called for the current statement */
749
562
  bool arg_of_last_insert_id_function;
750
 
 
751
563
  /*
752
564
    ALL OVER THIS FILE, "insert_id" means "*automatically generated* value for
753
565
    insertion into an auto_increment column".
838
650
  uint32_t total_warn_count;
839
651
  Diagnostics_area main_da;
840
652
 
 
653
  /*
 
654
    Id of current query. Statement can be reused to execute several queries
 
655
    query_id is global in context of the whole MySQL server.
 
656
    ID is automatically generated from mutex-protected counter.
 
657
    It's used in handler code for various purposes: to check which columns
 
658
    from table are necessary for this select, to check if it's necessary to
 
659
    update auto-updatable fields (like auto_increment and timestamp).
 
660
  */
 
661
  query_id_t query_id;
 
662
  query_id_t warn_id;
841
663
  ulong col_access;
842
664
 
843
665
  /* Statement id is thread-wide. This counter is used to generate ids */
849
671
    create_sort_index(); may differ from examined_row_count.
850
672
  */
851
673
  uint32_t row_count;
852
 
  session_id_t thread_id;
 
674
  pthread_t real_id; /**< For debugging */
 
675
  my_thread_id thread_id;
853
676
  uint32_t tmp_table;
854
 
  enum global_read_lock_t
855
 
  {
856
 
    NONE= 0,
857
 
    GOT_GLOBAL_READ_LOCK= 1,
858
 
    MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT= 2
859
 
  };
860
 
private:
861
 
  global_read_lock_t _global_read_lock;
862
 
 
863
 
public:
864
 
 
865
 
  global_read_lock_t isGlobalReadLock() const
866
 
  {
867
 
    return _global_read_lock;
868
 
  }
869
 
 
870
 
  void setGlobalReadLock(global_read_lock_t arg)
871
 
  {
872
 
    _global_read_lock= arg;
873
 
  }
874
 
 
875
 
  DrizzleLock *lockTables(Table **tables, uint32_t count, uint32_t flags, bool *need_reopen);
876
 
  bool lockGlobalReadLock();
877
 
  bool lock_table_names(TableList *table_list);
878
 
  bool lock_table_names_exclusively(TableList *table_list);
879
 
  bool makeGlobalReadLockBlockCommit();
880
 
  bool abortLockForThread(Table *table);
881
 
  bool wait_if_global_read_lock(bool abort_on_refresh, bool is_not_commit);
882
 
  int lock_table_name(TableList *table_list);
883
 
  void abortLock(Table *table);
884
 
  void removeLock(Table *table);
885
 
  void unlockReadTables(DrizzleLock *sql_lock);
886
 
  void unlockSomeTables(Table **table, uint32_t count);
887
 
  void unlockTables(DrizzleLock *sql_lock);
888
 
  void startWaitingGlobalReadLock();
889
 
  void unlockGlobalReadLock();
890
 
 
891
 
private:
892
 
  int unlock_external(Table **table, uint32_t count);
893
 
  int lock_external(Table **tables, uint32_t count);
894
 
  bool wait_for_locked_table_names(TableList *table_list);
895
 
  DrizzleLock *get_lock_data(Table **table_ptr, uint32_t count,
896
 
                             bool should_lock, Table **write_lock_used);
897
 
public:
898
 
 
 
677
  uint32_t global_read_lock;
899
678
  uint32_t server_status;
900
679
  uint32_t open_options;
901
680
  uint32_t select_number; /**< number of select (used for EXPLAIN) */
903
682
  enum_tx_isolation session_tx_isolation;
904
683
  enum_check_fields count_cuted_fields;
905
684
 
906
 
  enum killed_state_t
 
685
  enum killed_state
907
686
  {
908
687
    NOT_KILLED,
909
688
    KILL_BAD_DATA,
911
690
    KILL_QUERY,
912
691
    KILLED_NO_VALUE /* means none of the above states apply */
913
692
  };
914
 
private:
915
 
  killed_state_t volatile _killed;
916
 
 
917
 
public:
918
 
 
919
 
  void setKilled(killed_state_t arg)
920
 
  {
921
 
    _killed= arg;
922
 
  }
923
 
 
924
 
  killed_state_t getKilled()
925
 
  {
926
 
    return _killed;
927
 
  }
928
 
 
929
 
  volatile killed_state_t *getKilledPtr() // Do not use this method, it is here for historical convience.
930
 
  {
931
 
    return &_killed;
932
 
  }
933
 
 
934
 
  bool is_admin_connection;
 
693
  killed_state volatile killed;
 
694
 
935
695
  bool some_tables_deleted;
936
696
  bool no_errors;
937
697
  bool password;
1013
773
    return proc_info;
1014
774
  }
1015
775
 
1016
 
  /** Sets this Session's current query ID */
1017
 
  inline void setQueryId(query_id_t in_query_id)
1018
 
  {
1019
 
    query_id= in_query_id;
 
776
  inline void setReplicationData (void *data)
 
777
  {
 
778
    replication_data= data;
 
779
  }
 
780
  inline void *getReplicationData () const
 
781
  {
 
782
    return replication_data;
1020
783
  }
1021
784
 
1022
785
  /** Returns the current query ID */
1023
 
  query_id_t getQueryId()  const
 
786
  inline query_id_t getQueryId()  const
1024
787
  {
1025
788
    return query_id;
1026
789
  }
1027
790
 
1028
 
 
1029
 
  /** Sets this Session's warning query ID */
1030
 
  inline void setWarningQueryId(query_id_t in_query_id)
 
791
  /** Returns the current query text */
 
792
  inline const char *getQueryString()  const
1031
793
  {
1032
 
    warn_query_id= in_query_id;
 
794
    return query;
1033
795
  }
1034
796
 
1035
 
  /** Returns the Session's warning query ID */
1036
 
  inline query_id_t getWarningQueryId()  const
 
797
  /** Returns the length of the current query text */
 
798
  inline size_t getQueryLength() const
1037
799
  {
1038
 
    return warn_query_id;
 
800
    if (query != NULL)
 
801
      return strlen(query);
 
802
    else
 
803
      return 0;
1039
804
  }
1040
805
 
1041
806
  /** Accessor method returning the session's ID. */
1042
 
  inline session_id_t getSessionId()  const
 
807
  inline uint64_t getSessionId()  const
1043
808
  {
1044
809
    return thread_id;
1045
810
  }
1112
877
    auto_inc_intervals_forced.append(next_id, UINT64_MAX, 0);
1113
878
  }
1114
879
 
1115
 
  Session(plugin::Client *client_arg);
 
880
  Session(drizzled::plugin::Client *client_arg);
1116
881
  virtual ~Session();
1117
882
 
1118
883
  void cleanup(void);
1130
895
   */
1131
896
  void cleanup_after_query();
1132
897
  bool storeGlobals();
1133
 
  void awake(Session::killed_state_t state_to_set);
 
898
  void awake(Session::killed_state state_to_set);
1134
899
  /**
1135
900
   * Pulls thread-specific variables into Session state.
1136
901
   *
1213
978
  /**
1214
979
   * Schedule a session to be run on the default scheduler.
1215
980
   */
1216
 
  static bool schedule(Session::shared_ptr&);
1217
 
 
1218
 
  static void unlink(Session::shared_ptr&);
 
981
  bool schedule();
1219
982
 
1220
983
  /*
1221
984
    For enter_cond() / exit_cond() to work the mutex must be got before
1222
985
    enter_cond(); this mutex is then released by exit_cond().
1223
986
    Usage must be: lock mutex; enter_cond(); your code; exit_cond().
1224
987
  */
1225
 
  const char* enter_cond(boost::condition_variable_any &cond, boost::mutex &mutex, const char* msg);
1226
 
  void exit_cond(const char* old_msg);
1227
 
 
 
988
  inline const char* enter_cond(pthread_cond_t *cond, pthread_mutex_t* mutex, const char* msg)
 
989
  {
 
990
    const char* old_msg = get_proc_info();
 
991
    safe_mutex_assert_owner(mutex);
 
992
    mysys_var->current_mutex = mutex;
 
993
    mysys_var->current_cond = cond;
 
994
    this->set_proc_info(msg);
 
995
    return old_msg;
 
996
  }
 
997
  inline void exit_cond(const char* old_msg)
 
998
  {
 
999
    /*
 
1000
      Putting the mutex unlock in exit_cond() ensures that
 
1001
      mysys_var->current_mutex is always unlocked _before_ mysys_var->mutex is
 
1002
      locked (if that would not be the case, you'll get a deadlock if someone
 
1003
      does a Session::awake() on you).
 
1004
    */
 
1005
    pthread_mutex_unlock(mysys_var->current_mutex);
 
1006
    pthread_mutex_lock(&mysys_var->mutex);
 
1007
    mysys_var->current_mutex = 0;
 
1008
    mysys_var->current_cond = 0;
 
1009
    this->set_proc_info(old_msg);
 
1010
    pthread_mutex_unlock(&mysys_var->mutex);
 
1011
  }
1228
1012
  inline time_t query_start() { return start_time; }
1229
1013
  inline void set_time()
1230
1014
  {
1231
 
    boost::posix_time::ptime mytime(boost::posix_time::microsec_clock::local_time());
1232
 
    boost::posix_time::ptime epoch(boost::gregorian::date(1970,1,1));
1233
 
    start_utime= utime_after_lock= (mytime-epoch).total_microseconds();
1234
 
 
1235
1015
    if (user_time)
1236
1016
    {
1237
1017
      start_time= user_time;
1238
 
      connect_microseconds= start_utime;
 
1018
      connect_microseconds= start_utime= utime_after_lock= my_micro_time();
1239
1019
    }
1240
 
    else 
1241
 
      start_time= (mytime-epoch).total_seconds();
 
1020
    else
 
1021
      start_utime= utime_after_lock= my_micro_time_and_time(&start_time);
1242
1022
  }
1243
1023
  inline void   set_current_time()    { start_time= time(NULL); }
1244
1024
  inline void   set_time(time_t t)
1245
1025
  {
1246
1026
    start_time= user_time= t;
1247
 
    boost::posix_time::ptime mytime(boost::posix_time::microsec_clock::local_time());
1248
 
    boost::posix_time::ptime epoch(boost::gregorian::date(1970,1,1));
1249
 
    uint64_t t_mark= (mytime-epoch).total_microseconds();
1250
 
 
1251
 
    start_utime= utime_after_lock= t_mark;
1252
 
  }
1253
 
  void set_time_after_lock()  { 
1254
 
     boost::posix_time::ptime mytime(boost::posix_time::microsec_clock::local_time());
1255
 
     boost::posix_time::ptime epoch(boost::gregorian::date(1970,1,1));
1256
 
     utime_after_lock= (mytime-epoch).total_microseconds();
1257
 
  }
 
1027
    start_utime= utime_after_lock= my_micro_time();
 
1028
  }
 
1029
  void set_time_after_lock()  { utime_after_lock= my_micro_time(); }
1258
1030
  /**
1259
1031
   * Returns the current micro-timestamp
1260
1032
   */
1261
1033
  inline uint64_t getCurrentTimestamp()  
1262
1034
  { 
1263
 
    boost::posix_time::ptime mytime(boost::posix_time::microsec_clock::local_time());
1264
 
    boost::posix_time::ptime epoch(boost::gregorian::date(1970,1,1));
1265
 
    uint64_t t_mark= (mytime-epoch).total_microseconds();
1266
 
 
1267
 
    return t_mark; 
 
1035
    return my_micro_time(); 
1268
1036
  }
1269
1037
  inline uint64_t found_rows(void)
1270
1038
  {
1275
1043
  {
1276
1044
    return server_status & SERVER_STATUS_IN_TRANS;
1277
1045
  }
 
1046
  inline bool fill_derived_tables()
 
1047
  {
 
1048
    return !lex->only_view_structure();
 
1049
  }
 
1050
  inline void* trans_alloc(unsigned int size)
 
1051
  {
 
1052
    return alloc_root(&transaction.mem_root,size);
 
1053
  }
 
1054
 
1278
1055
  LEX_STRING *make_lex_string(LEX_STRING *lex_str,
1279
1056
                              const char* str, uint32_t length,
1280
1057
                              bool allocate_lex_string);
1281
 
  LEX_STRING *make_lex_string(LEX_STRING *lex_str,
1282
 
                              const std::string &str,
1283
 
                              bool allocate_lex_string);
1284
1058
 
 
1059
  void add_changed_table(Table *table);
 
1060
  void add_changed_table(const char *key, long key_length);
 
1061
  CHANGED_TableList * changed_table_dup(const char *key, long key_length);
1285
1062
  int send_explain_fields(select_result *result);
1286
1063
  /**
1287
1064
    Clear the current error, if any.
1290
1067
    @todo: To silence an error, one should use Internal_error_handler
1291
1068
    mechanism. In future this function will be removed.
1292
1069
  */
1293
 
  inline void clear_error(bool full= false)
 
1070
  inline void clear_error()
1294
1071
  {
1295
1072
    if (main_da.is_error())
1296
1073
      main_da.reset_diagnostics_area();
1297
 
 
1298
 
    if (full)
1299
 
    {
1300
 
      drizzle_reset_errors(this, true);
1301
 
    }
1302
 
  }
1303
 
 
1304
 
  void clearDiagnostics()
1305
 
  {
1306
 
    main_da.reset_diagnostics_area();
 
1074
    return;
1307
1075
  }
1308
1076
 
1309
1077
  /**
1347
1115
  void end_statement();
1348
1116
  inline int killed_errno() const
1349
1117
  {
1350
 
    killed_state_t killed_val; /* to cache the volatile 'killed' */
1351
 
    return (killed_val= _killed) != KILL_BAD_DATA ? killed_val : 0;
 
1118
    killed_state killed_val; /* to cache the volatile 'killed' */
 
1119
    return (killed_val= killed) != KILL_BAD_DATA ? killed_val : 0;
1352
1120
  }
1353
1121
  void send_kill_message() const;
1354
1122
  /* return true if we will abort query if we make a warning now */
1356
1124
  {
1357
1125
    return (abort_on_warning);
1358
1126
  }
1359
 
 
1360
 
  void setAbort(bool arg);
1361
 
  void lockOnSys();
1362
1127
  void set_status_var_init();
 
1128
  void reset_n_backup_open_tables_state(Open_tables_state *backup);
 
1129
  void restore_backup_open_tables_state(Open_tables_state *backup);
1363
1130
 
1364
1131
  /**
1365
1132
    Set the current database; use deep copy of C-string.
1377
1144
    database usually involves other actions, like switching other database
1378
1145
    attributes including security context. In the future, this operation
1379
1146
    will be made private and more convenient interface will be provided.
1380
 
  */
1381
 
  void set_db(const std::string &new_db);
1382
 
 
 
1147
 
 
1148
    @return Operation status
 
1149
      @retval false Success
 
1150
      @retval true  Out-of-memory error
 
1151
  */
 
1152
  bool set_db(const char *new_db, size_t new_db_len);
 
1153
 
 
1154
  /**
 
1155
    Set the current database; use shallow copy of C-string.
 
1156
 
 
1157
    @param new_db     a pointer to the new database name.
 
1158
    @param new_db_len length of the new database name.
 
1159
 
 
1160
    @note This operation just sets {db, db_length}. Switching the current
 
1161
    database usually involves other actions, like switching other database
 
1162
    attributes including security context. In the future, this operation
 
1163
    will be made private and more convenient interface will be provided.
 
1164
  */
 
1165
  void reset_db(char *new_db, size_t new_db_len)
 
1166
  {
 
1167
    db= new_db;
 
1168
    db_length= new_db_len;
 
1169
  }
1383
1170
  /*
1384
1171
    Copy the current database to the argument. Use the current arena to
1385
1172
    allocate memory for a deep copy: current database may be freed after
1443
1230
   * Current implementation does not depend on that, but future changes
1444
1231
   * should be done with this in mind; 
1445
1232
   *
1446
 
   * @param passwd Scrambled password received from client
1447
 
   * @param db Database name to connect to, may be NULL
 
1233
   * @param  Scrambled password received from client
 
1234
   * @param  Length of scrambled password
 
1235
   * @param  Database name to connect to, may be NULL
1448
1236
   */
1449
 
  bool checkUser(const std::string &passwd, const std::string &db);
 
1237
  bool checkUser(const char *passwd, uint32_t passwd_len, const char *db);
1450
1238
  
1451
1239
  /**
1452
1240
   * Returns the timestamp (in microseconds) of when the Session 
1462
1250
   * Session being managed by the ReplicationServices component, or
1463
1251
   * NULL if no active message.
1464
1252
   */
1465
 
  message::Transaction *getTransactionMessage() const
 
1253
  drizzled::message::Transaction *getTransactionMessage() const
1466
1254
  {
1467
1255
    return transaction_message;
1468
1256
  }
1471
1259
   * Returns a pointer to the active Statement message for this
1472
1260
   * Session, or NULL if no active message.
1473
1261
   */
1474
 
  message::Statement *getStatementMessage() const
 
1262
  drizzled::message::Statement *getStatementMessage() const
1475
1263
  {
1476
1264
    return statement_message;
1477
1265
  }
1478
 
  
1479
 
  /**
1480
 
   * Returns a pointer to the current Resulset message for this
1481
 
   * Session, or NULL if no active message.
1482
 
   */
1483
 
  message::Resultset *getResultsetMessage() const
1484
 
  {
1485
 
    return resultset;
1486
 
  }
 
1266
 
1487
1267
  /**
1488
1268
   * Sets the active transaction message used by the ReplicationServices
1489
1269
   * component.
1490
1270
   *
1491
1271
   * @param[in] Pointer to the message
1492
1272
   */
1493
 
  void setTransactionMessage(message::Transaction *in_message)
 
1273
  void setTransactionMessage(drizzled::message::Transaction *in_message)
1494
1274
  {
1495
1275
    transaction_message= in_message;
1496
1276
  }
1501
1281
   *
1502
1282
   * @param[in] Pointer to the message
1503
1283
   */
1504
 
  void setStatementMessage(message::Statement *in_message)
 
1284
  void setStatementMessage(drizzled::message::Statement *in_message)
1505
1285
  {
1506
1286
    statement_message= in_message;
1507
1287
  }
1508
 
 
1509
 
  /**
1510
 
   * Sets the active Resultset message used by the Query Cache
1511
 
   * plugin.
1512
 
   *
1513
 
   * @param[in] Pointer to the message
1514
 
   */
1515
 
  void setResultsetMessage(message::Resultset *in_message)
1516
 
  {
1517
 
    resultset= in_message;
1518
 
  }
1519
 
  /**
1520
 
   * reset the active Resultset message used by the Query Cache
1521
 
   * plugin.
1522
 
   */
1523
 
 
1524
 
  void resetResultsetMessage()
1525
 
  { 
1526
 
    resultset= NULL;
1527
 
  }
1528
 
 
1529
1288
private:
1530
1289
  /** Pointers to memory managed by the ReplicationServices component */
1531
 
  message::Transaction *transaction_message;
1532
 
  message::Statement *statement_message;
1533
 
  /* Pointer to the current resultset of Select query */
1534
 
  message::Resultset *resultset;
1535
 
  plugin::EventObserverList *session_event_observers;
1536
 
  
1537
 
  /* Schema observers are mapped to databases. */
1538
 
  std::map<std::string, plugin::EventObserverList *> schema_event_observers;
1539
 
 
1540
 
 
1541
 
public:
1542
 
  plugin::EventObserverList *getSessionObservers() 
1543
 
  { 
1544
 
    return session_event_observers;
1545
 
  }
1546
 
  
1547
 
  void setSessionObservers(plugin::EventObserverList *observers) 
1548
 
  { 
1549
 
    session_event_observers= observers;
1550
 
  }
1551
 
  
1552
 
  /* For schema event observers there is one set of observers per database. */
1553
 
  plugin::EventObserverList *getSchemaObservers(const std::string &db_name) 
1554
 
  { 
1555
 
    std::map<std::string, plugin::EventObserverList *>::iterator it;
1556
 
    
1557
 
    it= schema_event_observers.find(db_name);
1558
 
    if (it == schema_event_observers.end())
1559
 
      return NULL;
1560
 
      
1561
 
    return it->second;
1562
 
  }
1563
 
  
1564
 
  void setSchemaObservers(const std::string &db_name, plugin::EventObserverList *observers) 
1565
 
  { 
1566
 
    std::map<std::string, plugin::EventObserverList *>::iterator it;
1567
 
 
1568
 
    it= schema_event_observers.find(db_name);
1569
 
    if (it != schema_event_observers.end())
1570
 
      schema_event_observers.erase(it);;
1571
 
 
1572
 
    if (observers)
1573
 
      schema_event_observers[db_name] = observers;
1574
 
  }
1575
 
  
1576
 
  
1577
 
 private:
1578
 
 /** Microsecond timestamp of when Session connected */
 
1290
  drizzled::message::Transaction *transaction_message;
 
1291
  drizzled::message::Statement *statement_message;
 
1292
  /** Microsecond timestamp of when Session connected */
1579
1293
  uint64_t connect_microseconds;
1580
1294
  const char *proc_info;
1581
1295
 
1596
1310
    - for prepared queries, only to allocate runtime data. The parsed
1597
1311
    tree itself is reused between executions and thus is stored elsewhere.
1598
1312
  */
1599
 
  memory::Root main_mem_root;
 
1313
  MEM_ROOT main_mem_root;
1600
1314
 
1601
1315
  /**
1602
1316
   * Marks all tables in the list which were used by current substatement
1617
1331
   * set to query_id of original query.
1618
1332
   */
1619
1333
  void mark_used_tables_as_free_for_reuse(Table *table);
 
1334
  /**
 
1335
    Mark all temporary tables which were used by the current statement or
 
1336
    substatement as free for reuse, but only if the query_id can be cleared.
 
1337
 
 
1338
    @param session thread context
 
1339
 
 
1340
    @remark For temp tables associated with a open SQL HANDLER the query_id
 
1341
            is not reset until the HANDLER is closed.
 
1342
  */
 
1343
  void mark_temp_tables_as_free_for_reuse();
1620
1344
 
1621
1345
public:
1622
1346
 
1658
1382
  }
1659
1383
  void refresh_status();
1660
1384
  user_var_entry *getVariable(LEX_STRING &name, bool create_if_not_exists);
1661
 
  user_var_entry *getVariable(const std::string  &name, bool create_if_not_exists);
1662
 
  void setVariable(const std::string &name, const std::string &value);
1663
1385
  
1664
1386
  /**
1665
1387
   * Closes all tables used by the current substatement, or all tables
1669
1391
  void close_old_data_files(bool morph_locks= false,
1670
1392
                            bool send_refresh= false);
1671
1393
  void close_open_tables();
1672
 
  void close_data_files_and_morph_locks(const TableIdentifier &identifier);
 
1394
  void close_data_files_and_morph_locks(const char *db, const char *table_name);
1673
1395
 
1674
1396
private:
1675
1397
  bool free_cached_table();
1700
1422
   */
1701
1423
  bool openTablesLock(TableList *tables);
1702
1424
 
 
1425
  /**
 
1426
   * Open all tables in list and process derived tables
 
1427
   *
 
1428
   * @param Pointer to a list of tables for open
 
1429
   * @param Bitmap of flags to modify how the tables will be open:
 
1430
   *        DRIZZLE_LOCK_IGNORE_FLUSH - open table even if someone has
 
1431
   *        done a flush or namelock on it.
 
1432
   *
 
1433
   * @retval
 
1434
   *  false - ok
 
1435
   * @retval
 
1436
   *  true  - error
 
1437
   *
 
1438
   * @note
 
1439
   *
 
1440
   * This is to be used on prepare stage when you don't read any
 
1441
   * data from the tables.
 
1442
   */
 
1443
  bool openTables(TableList *tables, uint32_t flags= 0);
 
1444
 
1703
1445
  int open_tables_from_list(TableList **start, uint32_t *counter, uint32_t flags= 0);
1704
1446
 
1705
1447
  Table *openTableLock(TableList *table_list, thr_lock_type lock_type);
1706
1448
  Table *openTable(TableList *table_list, bool *refresh, uint32_t flags= 0);
1707
1449
 
1708
1450
  void unlink_open_table(Table *find);
1709
 
  void drop_open_table(Table *table, const TableIdentifier &identifier);
 
1451
  void drop_open_table(Table *table, const char *db_name,
 
1452
                       const char *table_name);
1710
1453
  void close_cached_table(Table *table);
1711
1454
 
1712
1455
  /* Create a lock in the cache */
1713
 
  table::Placeholder *table_cache_insert_placeholder(const TableIdentifier &identifier);
1714
 
  bool lock_table_name_if_not_cached(const TableIdentifier &identifier, Table **table);
1715
 
 
1716
 
  typedef boost::unordered_map<std::string, message::Table, util::insensitive_hash, util::insensitive_equal_to> TableMessageCache;
1717
 
 
1718
 
  class TableMessages
1719
 
  {
1720
 
    TableMessageCache table_message_cache;
1721
 
 
1722
 
  public:
1723
 
    bool storeTableMessage(const TableIdentifier &identifier, message::Table &table_message);
1724
 
    bool removeTableMessage(const TableIdentifier &identifier);
1725
 
    bool getTableMessage(const TableIdentifier &identifier, message::Table &table_message);
1726
 
    bool doesTableMessageExist(const TableIdentifier &identifier);
1727
 
    bool renameTableMessage(const TableIdentifier &from, const TableIdentifier &to);
1728
 
 
1729
 
  };
1730
 
private:
1731
 
  TableMessages _table_message_cache;
1732
 
 
1733
 
public:
1734
 
  TableMessages &getMessageCache()
1735
 
  {
1736
 
    return _table_message_cache;
1737
 
  }
1738
 
 
 
1456
  Table *table_cache_insert_placeholder(const char *key, uint32_t key_length);
 
1457
  bool lock_table_name_if_not_cached(const char *db, 
 
1458
                                     const char *table_name, Table **table);
 
1459
 
 
1460
  /* Work with temporary tables */
 
1461
  Table *find_temporary_table(TableList *table_list);
 
1462
  Table *find_temporary_table(const char *db, const char *table_name);
 
1463
  void close_temporary_tables();
 
1464
  void close_temporary_table(Table *table, bool free_share, bool delete_table);
 
1465
  void close_temporary(Table *table, bool free_share, bool delete_table);
 
1466
  int drop_temporary_table(TableList *table_list);
 
1467
  bool rm_temporary_table(drizzled::plugin::StorageEngine *base, char *path);
 
1468
  Table *open_temporary_table(const char *path, const char *db,
 
1469
                              const char *table_name, bool link_in_list);
 
1470
  
1739
1471
  /* Reopen operations */
1740
1472
  bool reopen_tables(bool get_locks, bool mark_share_as_old);
 
1473
  bool reopen_name_locked_table(TableList* table_list, bool link_in);
1741
1474
  bool close_cached_tables(TableList *tables, bool wait_for_refresh, bool wait_for_placeholders);
1742
1475
 
1743
 
  void wait_for_condition(boost::mutex &mutex, boost::condition_variable_any &cond);
 
1476
  void wait_for_condition(pthread_mutex_t *mutex, pthread_cond_t *cond);
1744
1477
  int setup_conds(TableList *leaves, COND **conds);
1745
1478
  int lock_tables(TableList *tables, uint32_t count, bool *need_reopen);
1746
1479
 
1747
 
  drizzled::util::Storable *getProperty(const std::string &arg)
1748
 
  {
1749
 
    return life_properties[arg];
1750
 
  }
1751
 
 
1752
 
  template<class T>
1753
 
  bool setProperty(const std::string &arg, T *value)
1754
 
  {
1755
 
    life_properties[arg]= value;
1756
 
 
1757
 
    return true;
1758
 
  }
1759
1480
 
1760
1481
  /**
1761
1482
    Return the default storage engine
1765
1486
    @return
1766
1487
    pointer to plugin::StorageEngine
1767
1488
  */
1768
 
  plugin::StorageEngine *getDefaultStorageEngine()
 
1489
  drizzled::plugin::StorageEngine *getDefaultStorageEngine()
1769
1490
  {
1770
1491
    if (variables.storage_engine)
1771
1492
      return variables.storage_engine;
1772
1493
    return global_system_variables.storage_engine;
1773
 
  }
1774
 
 
1775
 
  void get_xid(DRIZZLE_XID *xid); // Innodb only
1776
 
 
1777
 
  table::Instance *getInstanceTable();
1778
 
  table::Instance *getInstanceTable(List<CreateField> &field_list);
1779
 
 
1780
 
private:
1781
 
  bool resetUsage()
1782
 
  {
1783
 
    if (getrusage(RUSAGE_THREAD, &usage))
1784
 
    {
1785
 
      return false;
1786
 
    }
1787
 
 
1788
 
    return true;
1789
 
  }
1790
 
public:
1791
 
 
1792
 
  void setUsage(bool arg)
1793
 
  {
1794
 
    use_usage= arg;
1795
 
  }
1796
 
 
1797
 
  const struct rusage &getUsage()
1798
 
  {
1799
 
    return usage;
1800
 
  }
1801
 
 
1802
 
private:
1803
 
  // This lives throughout the life of Session
1804
 
  bool use_usage;
1805
 
  PropertyMap life_properties;
1806
 
  std::vector<table::Instance *> temporary_shares;
1807
 
  struct rusage usage;
 
1494
  };
1808
1495
};
1809
1496
 
1810
 
class Join;
 
1497
class JOIN;
1811
1498
 
1812
1499
#define ESCAPE_CHARS "ntrb0ZN" // keep synchronous with READ_INFO::unescape
1813
1500
 
1814
 
} /* namespace drizzled */
1815
 
 
1816
 
/** @TODO why is this in the middle of the file */
1817
1501
#include <drizzled/select_to_file.h>
1818
1502
#include <drizzled/select_export.h>
1819
1503
#include <drizzled/select_dump.h>
1820
1504
#include <drizzled/select_insert.h>
1821
1505
#include <drizzled/select_create.h>
 
1506
#include <plugin/myisam/myisam.h>
1822
1507
#include <drizzled/tmp_table_param.h>
1823
1508
#include <drizzled/select_union.h>
1824
1509
#include <drizzled/select_subselect.h>
1826
1511
#include <drizzled/select_max_min_finder_subselect.h>
1827
1512
#include <drizzled/select_exists_subselect.h>
1828
1513
 
1829
 
namespace drizzled
1830
 
{
1831
 
 
1832
1514
/**
1833
1515
 * A structure used to describe sort information
1834
1516
 * for a field or item used in ORDER BY.
1835
1517
 */
1836
 
class SortField 
 
1518
typedef struct st_sort_field 
1837
1519
{
1838
 
public:
1839
1520
  Field *field; /**< Field to sort */
1840
1521
  Item  *item; /**< Item if not sorting fields */
1841
1522
  size_t length; /**< Length of sort field */
1843
1524
  Item_result result_type; /**< Type of item */
1844
1525
  bool reverse; /**< if descending sort */
1845
1526
  bool need_strxnfrm;   /**< If we have to use strxnfrm() */
1846
 
 
1847
 
  SortField() :
1848
 
    field(0),
1849
 
    item(0),
1850
 
    length(0),
1851
 
    suffix_length(0),
1852
 
    result_type(STRING_RESULT),
1853
 
    reverse(0),
1854
 
    need_strxnfrm(0)
1855
 
  { }
1856
 
 
1857
 
};
1858
 
 
1859
 
} /* namespace drizzled */
1860
 
 
1861
 
/** @TODO why is this in the middle of the file */
 
1527
} SORT_FIELD;
 
1528
 
 
1529
typedef struct st_sort_buffer 
 
1530
{
 
1531
  uint32_t index;       /* 0 or 1 */
 
1532
  uint32_t sort_orders;
 
1533
  uint32_t change_pos; /* If sort-fields changed */
 
1534
  char **buff;
 
1535
  SORT_FIELD *sortorder;
 
1536
} SORT_BUFFER;
1862
1537
 
1863
1538
#include <drizzled/table_ident.h>
1864
1539
#include <drizzled/user_var_entry.h>
1865
1540
#include <drizzled/unique.h>
1866
 
#include <drizzled/var.h>
 
1541
#include <drizzled/my_var.h>
1867
1542
#include <drizzled/select_dumpvar.h>
1868
1543
 
1869
 
namespace drizzled
1870
 
{
1871
 
 
1872
1544
/* Bits in sql_command_flags */
1873
1545
 
1874
1546
enum sql_command_flag_bits 
1887
1559
static const std::bitset<CF_BIT_SIZE> CF_SHOW_TABLE_COMMAND(1 << CF_BIT_SHOW_TABLE_COMMAND);
1888
1560
static const std::bitset<CF_BIT_SIZE> CF_WRITE_LOGS_COMMAND(1 << CF_BIT_WRITE_LOGS_COMMAND);
1889
1561
 
1890
 
namespace display  {
1891
 
const std::string &type(drizzled::Session::global_read_lock_t type);
1892
 
size_t max_string_length(drizzled::Session::global_read_lock_t type);
1893
 
} /* namespace display */
 
1562
/* Functions in sql_class.cc */
 
1563
void add_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var);
1894
1564
 
1895
 
} /* namespace drizzled */
 
1565
void add_diff_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var,
 
1566
                        STATUS_VAR *dec_var);
1896
1567
 
1897
1568
#endif /* DRIZZLED_SESSION_H */