~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/session.h

  • Committer: Stewart Smith
  • Date: 2011-03-29 01:30:47 UTC
  • mto: (2257.1.2 build)
  • mto: This revision was merged to the branch mainline in revision 2258.
  • Revision ID: stewart@flamingspork.com-20110329013047-5ujzfx6pahmwuko2
have CachedDirectory print out a warning if we can't stat() something in a directory. We should always have access to at least stat() things in directories Drizzle is running in (otherwise there is likely a problem)

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
18
 */
19
19
 
20
 
 
21
 
#ifndef DRIZZLED_SESSION_H
22
 
#define DRIZZLED_SESSION_H
23
 
 
24
 
#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"
40
 
#include <netdb.h>
41
 
#include <sys/time.h>
42
 
#include <sys/resource.h>
 
20
#pragma once
43
21
 
44
22
#include <algorithm>
45
23
#include <bitset>
46
 
#include <deque>
 
24
#include <boost/make_shared.hpp>
 
25
#include <boost/scoped_ptr.hpp>
 
26
#include <boost/thread/condition_variable.hpp>
 
27
#include <boost/thread/mutex.hpp>
 
28
#include <boost/thread/shared_mutex.hpp>
 
29
#include <boost/thread/thread.hpp>
47
30
#include <map>
 
31
#include <netdb.h>
48
32
#include <string>
49
 
 
50
 
#include "drizzled/identifier.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
 
 
64
 
 
65
 
#define MIN_HANDSHAKE_SIZE      6
66
 
 
67
 
namespace drizzled
68
 
{
69
 
 
70
 
namespace plugin
71
 
{
72
 
class Client;
73
 
class Scheduler;
74
 
class EventObserverList;
75
 
}
76
 
 
77
 
namespace message
78
 
{
79
 
class Transaction;
80
 
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;
92
 
}
93
 
 
94
 
class Lex_input_stream;
95
 
class user_var_entry;
96
 
class CopyField;
97
 
class Table_ident;
98
 
 
99
 
class TableShareInstance;
 
33
#include <sys/resource.h>
 
34
#include <sys/time.h>
 
35
 
 
36
#include <drizzled/global_charset_info.h>
 
37
#include <drizzled/base.h>
 
38
#include <drizzled/error.h>
 
39
#include <drizzled/open_tables_state.h>
 
40
#include <drizzled/pthread_globals.h>
 
41
#include <drizzled/sql_error.h>
 
42
#include <drizzled/sql_locale.h>
 
43
#include <drizzled/visibility.h>
 
44
#include <drizzled/util/find_ptr.h>
 
45
#include <drizzled/util/string.h>
 
46
#include <drizzled/type/time.h>
 
47
 
 
48
namespace drizzled {
100
49
 
101
50
extern char internal_table_name[2];
102
51
extern char empty_c_string[1];
103
52
extern const char **errmesg;
 
53
extern uint32_t server_id;
104
54
 
105
55
#define TC_HEURISTIC_RECOVER_COMMIT   1
106
56
#define TC_HEURISTIC_RECOVER_ROLLBACK 2
107
57
extern uint32_t tc_heuristic_recover;
108
58
 
109
 
/**
110
 
  @brief
111
 
  Local storage for proto that are tmp table. This should be enlarged
112
 
  to hande the entire table-share for a local table. Once Hash is done,
113
 
  we should consider exchanging the map for it.
114
 
*/
115
 
typedef std::map <std::string, message::Table> ProtoCache;
116
 
 
117
 
/**
118
 
  The COPY_INFO structure is used by INSERT/REPLACE code.
119
 
  The schema of the row counting by the INSERT/INSERT ... ON DUPLICATE KEY
120
 
  UPDATE code:
121
 
    If a row is inserted then the copied variable is incremented.
122
 
    If a row is updated by the INSERT ... ON DUPLICATE KEY UPDATE and the
123
 
      new data differs from the old one then the copied and the updated
124
 
      variables are incremented.
125
 
    The touched variable is incremented if a row was touched by the update part
126
 
      of the INSERT ... ON DUPLICATE KEY UPDATE no matter whether the row
127
 
      was actually changed or not.
128
 
*/
129
 
class CopyInfo 
130
 
{
131
 
public:
132
 
  ha_rows records; /**< Number of processed records */
133
 
  ha_rows deleted; /**< Number of deleted records */
134
 
  ha_rows updated; /**< Number of updated records */
135
 
  ha_rows copied;  /**< Number of copied records */
136
 
  ha_rows error_count;
137
 
  ha_rows touched; /* Number of touched records */
138
 
  enum enum_duplicates handle_duplicates;
139
 
  int escape_char, last_errno;
140
 
  bool ignore;
141
 
  /* for INSERT ... UPDATE */
142
 
  List<Item> *update_fields;
143
 
  List<Item> *update_values;
144
 
  /* 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 */
165
 
#include <drizzled/lex_column.h>
166
 
 
167
 
namespace drizzled
168
 
{
169
 
 
170
 
class select_result;
171
 
class Time_zone;
172
 
 
173
 
#define Session_SENTRY_MAGIC 0xfeedd1ff
174
 
#define Session_SENTRY_GONE  0xdeadbeef
175
 
 
176
 
struct drizzle_system_variables
177
 
{
178
 
  drizzle_system_variables()
179
 
  {}
180
 
  /*
181
 
    How dynamically allocated system variables are handled:
182
 
 
183
 
    The global_system_variables and max_system_variables are "authoritative"
184
 
    They both should have the same 'version' and 'size'.
185
 
    When attempting to access a dynamic variable, if the session version
186
 
    is out of date, then the session version is updated and realloced if
187
 
    neccessary and bytes copied from global to make up for missing data.
188
 
  */
189
 
  ulong dynamic_variables_version;
190
 
  char * dynamic_variables_ptr;
191
 
  uint32_t dynamic_variables_head;  /* largest valid variable offset */
192
 
  uint32_t dynamic_variables_size;  /* how many bytes are in use */
193
 
 
194
 
  uint64_t myisam_max_extra_sort_file_size;
195
 
  uint64_t max_heap_table_size;
196
 
  uint64_t tmp_table_size;
197
 
  ha_rows select_limit;
198
 
  ha_rows max_join_size;
199
 
  uint64_t auto_increment_increment;
200
 
  uint64_t auto_increment_offset;
201
 
  uint64_t bulk_insert_buff_size;
202
 
  uint64_t join_buff_size;
203
 
  uint32_t max_allowed_packet;
204
 
  uint64_t max_error_count;
205
 
  uint64_t max_length_for_sort_data;
206
 
  size_t max_sort_length;
207
 
  uint64_t min_examined_row_limit;
208
 
  bool optimizer_prune_level;
209
 
  bool log_warnings;
210
 
 
211
 
  uint32_t optimizer_search_depth;
212
 
  uint32_t div_precincrement;
213
 
  uint64_t preload_buff_size;
214
 
  uint32_t read_buff_size;
215
 
  uint32_t read_rnd_buff_size;
216
 
  bool replicate_query;
217
 
  size_t sortbuff_size;
218
 
  uint32_t thread_handling;
219
 
  uint32_t tx_isolation;
220
 
  size_t transaction_message_threshold;
221
 
  uint32_t completion_type;
222
 
  /* Determines which non-standard SQL behaviour should be enabled */
223
 
  uint32_t sql_mode;
224
 
  uint64_t max_seeks_for_key;
225
 
  size_t range_alloc_block_size;
226
 
  uint32_t query_alloc_block_size;
227
 
  uint32_t query_prealloc_size;
228
 
  uint64_t group_concat_max_len;
229
 
  uint64_t pseudo_thread_id;
230
 
 
231
 
  plugin::StorageEngine *storage_engine;
232
 
 
233
 
  /* Only charset part of these variables is sensible */
234
 
  const CHARSET_INFO  *character_set_filesystem;
235
 
 
236
 
  /* Both charset and collation parts of these variables are important */
237
 
  const CHARSET_INFO    *collation_server;
238
 
 
239
 
  inline const CHARSET_INFO  *getCollation(void) 
240
 
  {
241
 
    return collation_server;
242
 
  }
243
 
 
244
 
  /* Locale Support */
245
 
  MY_LOCALE *lc_time_names;
246
 
 
247
 
  Time_zone *time_zone;
248
 
};
249
 
 
250
 
extern struct drizzle_system_variables global_system_variables;
251
 
 
252
 
} /* namespace drizzled */
253
 
 
254
 
#include "drizzled/sql_lex.h"
255
 
 
256
 
namespace drizzled
257
 
{
258
 
 
259
 
void mark_transaction_to_rollback(Session *session, bool all);
260
 
 
261
 
/**
262
 
  Storage engine specific thread local data.
263
 
*/
264
 
struct Ha_data
265
 
{
266
 
  /**
267
 
    Storage engine specific thread local data.
268
 
    Lifetime: one user connection.
269
 
  */
270
 
  void *ha_ptr;
271
 
  /**
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];
290
 
 
291
 
  Ha_data() :ha_ptr(NULL) {}
292
 
};
 
59
extern DRIZZLED_API struct drizzle_system_variables global_system_variables;
293
60
 
294
61
/**
295
62
 * Represents a client connection to the database server.
310
77
 * all member variables that are not critical to non-internal operations of the
311
78
 * session object.
312
79
 */
313
 
typedef int64_t session_id_t;
314
80
 
315
 
class Session : public Open_tables_state
 
81
class DRIZZLED_API Session : public Open_tables_state
316
82
{
 
83
private:
 
84
  class impl_c;
 
85
 
 
86
  boost::scoped_ptr<impl_c> impl_;
317
87
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
88
  typedef boost::shared_ptr<Session> shared_ptr;
322
89
 
 
90
  static shared_ptr make_shared(plugin::Client *client, boost::shared_ptr<catalog::Instance> instance_arg)
 
91
  {
 
92
    assert(instance_arg);
 
93
    return boost::make_shared<Session>(client, instance_arg);
 
94
  }
 
95
 
323
96
  /*
324
97
    MARK_COLUMNS_NONE:  Means mark_used_colums is not set and no indicator to
325
98
                        handler of fields used is set
331
104
                        that it needs to update this field in write_row
332
105
                        and update_row.
333
106
  */
334
 
  enum enum_mark_columns mark_used_columns;
335
 
  inline void* alloc(size_t size)
336
 
  {
337
 
    return mem_root->alloc_root(size);
338
 
  }
 
107
  enum_mark_columns mark_used_columns;
339
108
  inline void* calloc(size_t size)
340
109
  {
341
 
    void *ptr;
342
 
    if ((ptr= mem_root->alloc_root(size)))
 
110
    void *ptr= mem_root->alloc_root(size);
 
111
    if (ptr)
343
112
      memset(ptr, 0, size);
344
113
    return ptr;
345
114
  }
346
 
  inline char *strdup(const char *str)
347
 
  {
348
 
    return mem_root->strdup_root(str);
349
 
  }
350
115
  inline char *strmake(const char *str, size_t size)
351
116
  {
352
117
    return mem_root->strmake_root(str,size);
353
118
  }
354
 
  inline void *memdup(const void *str, size_t size)
355
 
  {
356
 
    return mem_root->memdup_root(str, size);
357
 
  }
 
119
 
358
120
  inline void *memdup_w_gap(const void *str, size_t size, uint32_t gap)
359
121
  {
360
 
    void *ptr;
361
 
    if ((ptr= mem_root->alloc_root(size + gap)))
362
 
      memcpy(ptr,str,size);
 
122
    void *ptr= mem_root->alloc_root(size + gap);
 
123
    if (ptr)
 
124
      memcpy(ptr, str, size);
363
125
    return ptr;
364
126
  }
365
127
  /** Frees all items attached to this Statement */
366
128
  void free_items();
 
129
 
367
130
  /**
368
131
   * List of items created in the parser for this query. Every item puts
369
132
   * itself to the list on creation (see Item::Item() for details))
371
134
  Item *free_list;
372
135
  memory::Root *mem_root; /**< Pointer to current memroot */
373
136
 
374
 
 
375
137
  memory::Root *getMemRoot()
376
138
  {
377
139
    return mem_root;
378
140
  }
379
141
 
380
 
  uint64_t xa_id;
381
 
 
382
142
  uint64_t getXaId()
383
143
  {
384
144
    return xa_id;
386
146
 
387
147
  void setXaId(uint64_t in_xa_id)
388
148
  {
389
 
    xa_id= in_xa_id; 
390
 
  }
391
 
 
392
 
  /**
393
 
   * Uniquely identifies each statement object in thread scope; change during
394
 
   * statement lifetime.
395
 
   *
396
 
   * @todo should be const
397
 
   */
398
 
  uint32_t id;
399
 
  LEX *lex; /**< parse tree descriptor */
400
 
 
401
 
  LEX *getLex() 
402
 
  {
403
 
    return lex;
404
 
  }
 
149
    xa_id= in_xa_id;
 
150
  }
 
151
 
 
152
public:
 
153
  Diagnostics_area& main_da();
 
154
  const LEX& lex() const;
 
155
  LEX& lex();
 
156
  enum_sql_command getSqlCommand() const;
 
157
 
405
158
  /** query associated with this statement */
406
159
  typedef boost::shared_ptr<const std::string> QueryString;
 
160
 
407
161
private:
408
162
  boost::shared_ptr<std::string> query;
409
163
 
442
196
    return to_return;
443
197
  }
444
198
 
445
 
  class State {
446
 
    std::vector <char> _query;
447
 
 
448
 
  public:
449
 
    typedef boost::shared_ptr<State> const_shared_ptr;
450
 
 
451
 
    State(const char *in_packet, size_t in_packet_length)
452
 
    {
453
 
      if (in_packet_length)
454
 
      {
455
 
        size_t minimum= std::min(in_packet_length, static_cast<size_t>(PROCESS_LIST_WIDTH));
456
 
        _query.resize(minimum + 1);
457
 
        memcpy(&_query[0], in_packet, minimum);
458
 
      }
459
 
      else
460
 
      {
461
 
        _query.resize(0);
462
 
      }
463
 
    }
464
 
 
465
 
    const char *query() const
466
 
    {
467
 
      if (_query.size())
468
 
        return &_query[0];
469
 
 
470
 
      return "";
471
 
    }
472
 
 
473
 
    const char *query(size_t &size) const
474
 
    {
475
 
      if (_query.size())
476
 
      {
477
 
        size= _query.size() -1;
478
 
        return &_query[0];
479
 
      }
480
 
 
481
 
      size= 0;
482
 
      return "";
483
 
    }
484
 
  protected:
485
 
    friend class Session;
486
 
    typedef boost::shared_ptr<State> shared_ptr;
487
 
  };
488
199
private:
489
 
  State::shared_ptr  _state; 
 
200
  boost::shared_ptr<session::State> _state;
 
201
 
490
202
public:
491
203
 
492
 
  State::const_shared_ptr state()
 
204
  const boost::shared_ptr<session::State>& state()
493
205
  {
494
206
    return _state;
495
207
  }
506
218
    the Session of that thread); that thread is (and must remain, for now) the
507
219
    only responsible for freeing this member.
508
220
  */
509
 
private:
510
 
  util::string::shared_ptr _schema;
511
221
public:
512
222
 
513
223
  util::string::const_shared_ptr schema() const
514
224
  {
515
 
    if (_schema)
516
 
      return _schema;
 
225
    return _schema ? _schema : util::string::const_shared_ptr(new std::string);
 
226
  }
517
227
 
518
 
    return util::string::const_shared_ptr(new std::string(""));
519
 
  }
520
 
  std::string catalog;
521
228
  /* current cache key */
522
229
  std::string query_cache_key;
523
230
  /**
529
236
  static const char * const DEFAULT_WHERE;
530
237
 
531
238
  memory::Root warn_root; /**< Allocation area for warnings and errors */
532
 
  plugin::Client *client; /**< Pointer to client object */
533
 
 
 
239
public:
534
240
  void setClient(plugin::Client *client_arg);
535
241
 
536
 
  plugin::Client *getClient()
 
242
  plugin::Client *getClient() const
537
243
  {
538
244
    return client;
539
245
  }
542
248
  void *scheduler_arg; /**< Pointer to the optional scheduler argument */
543
249
 
544
250
  typedef boost::unordered_map< std::string, user_var_entry *, util::insensitive_hash, util::insensitive_equal_to> UserVars;
 
251
 
545
252
private:
546
253
  typedef std::pair< UserVars::iterator, UserVars::iterator > UserVarsRange;
547
254
  UserVars user_vars; /**< Hash of user variables defined during the session's lifetime */
548
255
 
549
256
public:
550
 
 
551
257
  const UserVars &getUserVariables() const
552
258
  {
553
259
    return user_vars;
554
260
  }
555
261
 
556
 
  drizzle_system_variables variables; /**< Mutable local variables local to the session */
557
 
  struct system_status_var status_var; /**< Session-local status counters */
 
262
  drizzle_system_variables& variables; /**< Mutable local variables local to the session */
 
263
  enum_tx_isolation getTxIsolation();
 
264
  system_status_var& status_var;
 
265
 
558
266
  THR_LOCK_INFO lock_info; /**< Locking information for this session */
559
267
  THR_LOCK_OWNER main_lock_id; /**< To use for conventional queries */
560
268
  THR_LOCK_OWNER *lock_id; /**< If not main_lock_id, points to the lock_id of a cursor. */
565
273
   */
566
274
  char *thread_stack;
567
275
 
568
 
private:
569
 
  identifier::User::shared_ptr security_ctx;
570
 
 
571
 
  int32_t scoreboard_index;
572
 
 
573
 
  inline void checkSentry() const
574
 
  {
575
 
    assert(this->dbug_sentry == Session_SENTRY_MAGIC);
576
 
  }
577
 
public:
578
276
  identifier::User::const_shared_ptr user() const
579
277
  {
580
 
    if (security_ctx)
581
 
      return security_ctx;
582
 
 
583
 
    return identifier::User::const_shared_ptr();
 
278
    return security_ctx ? security_ctx : identifier::User::const_shared_ptr();
584
279
  }
585
280
 
586
281
  void setUser(identifier::User::shared_ptr arg)
601
296
  /**
602
297
   * Is this session viewable by the current user?
603
298
   */
604
 
  bool isViewable() const;
 
299
  bool isViewable(const identifier::User&) const;
605
300
 
 
301
private:
606
302
  /**
607
303
    Used in error messages to tell user in what part of MySQL we found an
608
304
    error. E. g. when where= "having clause", if fix_fields() fails, user
609
305
    will know that the error was in having clause.
610
306
  */
611
 
  const char *where;
 
307
  const char *_where;
 
308
 
 
309
public:
 
310
  const char *where()
 
311
  {
 
312
    return _where;
 
313
  }
 
314
 
 
315
  void setWhere(const char *arg)
 
316
  {
 
317
    _where= arg;
 
318
  }
612
319
 
613
320
  /*
614
321
    One thread can hold up to one named user-level lock. This variable
615
322
    points to a lock object if the lock is present. See item_func.cc and
616
323
    chapter 'Miscellaneous functions', for functions GET_LOCK, RELEASE_LOCK.
617
324
  */
618
 
  uint32_t dbug_sentry; /**< watch for memory corruption */
 
325
 
619
326
private:
620
327
  boost::thread::id boost_thread_id;
621
328
  boost_thread_shared_ptr _thread;
622
329
  boost::this_thread::disable_interruption *interrupt;
623
330
 
624
331
  internal::st_my_thread_var *mysys_var;
 
332
 
625
333
public:
626
 
 
627
334
  boost_thread_shared_ptr &getThread()
628
335
  {
629
336
    return _thread;
653
360
  uint32_t file_id;     /**< File ID for LOAD DATA INFILE */
654
361
  /* @note the following three members should likely move to Client */
655
362
  uint32_t max_client_packet_length; /**< Maximum number of bytes a client can send in a single packet */
656
 
  time_t start_time;
657
 
  time_t user_time;
658
 
  uint64_t thr_create_utime; /**< track down slow pthread_create */
659
 
  uint64_t start_utime;
660
 
  uint64_t utime_after_lock;
 
363
 
 
364
private:
 
365
  boost::posix_time::ptime _epoch;
 
366
  boost::posix_time::ptime _connect_time;
 
367
  boost::posix_time::ptime _start_timer;
 
368
  boost::posix_time::ptime _end_timer;
 
369
 
 
370
  boost::posix_time::ptime _user_time;
 
371
public:
 
372
  uint64_t utime_after_lock; // This used by Innodb.
 
373
 
 
374
  void resetUserTime()
 
375
  {
 
376
    _user_time= boost::posix_time::not_a_date_time;
 
377
  }
 
378
 
 
379
  const boost::posix_time::ptime &start_timer() const
 
380
  {
 
381
    return _start_timer;
 
382
  }
 
383
 
 
384
  void getTimeDifference(boost::posix_time::time_duration &result_arg, const boost::posix_time::ptime &arg) const
 
385
  {
 
386
    result_arg=  arg - _start_timer;
 
387
  }
661
388
 
662
389
  thr_lock_type update_lock_default;
663
390
 
678
405
  */
679
406
  query_id_t query_id;
680
407
  query_id_t warn_query_id;
 
408
 
681
409
public:
682
410
  void **getEngineData(const plugin::MonitoredInTransaction *monitored);
683
 
  ResourceContext *getResourceContext(const plugin::MonitoredInTransaction *monitored,
684
 
                                      size_t index= 0);
685
 
 
686
 
  /**
687
 
   * Structure used to manage "statement transactions" and
688
 
   * "normal transactions". In autocommit mode, the normal transaction is
689
 
   * equivalent to the statement transaction.
690
 
   *
691
 
   * Storage engines will be registered here when they participate in
692
 
   * a transaction. No engine is registered more than once.
693
 
   */
694
 
  struct st_transactions {
695
 
    std::deque<NamedSavepoint> savepoints;
696
 
 
697
 
    /**
698
 
     * The normal transaction (since BEGIN WORK).
699
 
     *
700
 
     * Contains a list of all engines that have participated in any of the
701
 
     * statement transactions started within the context of the normal
702
 
     * transaction.
703
 
     *
704
 
     * @note In autocommit mode, this is empty.
705
 
     */
706
 
    TransactionContext all;
707
 
 
708
 
    /**
709
 
     * The statment transaction.
710
 
     *
711
 
     * Contains a list of all engines participating in the given statement.
712
 
     *
713
 
     * @note In autocommit mode, this will be used to commit/rollback the
714
 
     * normal transaction.
715
 
     */
716
 
    TransactionContext stmt;
717
 
 
718
 
    XID_STATE xid_state;
719
 
 
720
 
    void cleanup()
721
 
    {
722
 
      savepoints.clear();
723
 
    }
724
 
    st_transactions() :
725
 
      savepoints(),
726
 
      all(),
727
 
      stmt(),
728
 
      xid_state()
729
 
    { }
730
 
  } transaction;
 
411
  ResourceContext& getResourceContext(const plugin::MonitoredInTransaction&, size_t index= 0);
 
412
 
 
413
  session::Transactions& transaction;
731
414
 
732
415
  Field *dup_field;
733
416
  sigset_t signals;
734
417
 
 
418
public:
735
419
  // As of right now we do not allow a concurrent execute to launch itself
736
 
private:
737
 
  bool concurrent_execute_allowed;
738
 
public:
739
 
 
740
420
  void setConcurrentExecute(bool arg)
741
421
  {
742
422
    concurrent_execute_allowed= arg;
747
427
    return concurrent_execute_allowed;
748
428
  }
749
429
 
750
 
  /* Tells if LAST_INSERT_ID(#) was called for the current statement */
751
 
  bool arg_of_last_insert_id_function;
752
 
 
753
430
  /*
754
431
    ALL OVER THIS FILE, "insert_id" means "*automatically generated* value for
755
432
    insertion into an auto_increment column".
796
473
    (first_successful_insert_id_in_cur_stmt == 0), but storing "INSERT_ID=3"
797
474
    in the binlog is still needed; the list's minimum will contain 3.
798
475
  */
799
 
  Discrete_intervals_list auto_inc_intervals_in_cur_stmt_for_binlog;
800
 
  /** Used by replication and SET INSERT_ID */
801
 
  Discrete_intervals_list auto_inc_intervals_forced;
802
476
 
803
477
  uint64_t limit_found_rows;
804
478
  uint64_t options; /**< Bitmap of options */
805
479
  int64_t row_count_func; /**< For the ROW_COUNT() function */
 
480
 
 
481
  int64_t rowCount() const
 
482
  {
 
483
    return row_count_func;
 
484
  }
 
485
 
806
486
  ha_rows cuted_fields; /**< Count of "cut" or truncated fields. @todo Kill this friggin thing. */
807
487
 
808
 
  /** 
 
488
  /**
809
489
   * Number of rows we actually sent to the client, including "synthetic"
810
490
   * rows in ROLLUP etc.
811
491
   */
821
501
   * of the query.
822
502
   *
823
503
   * @todo
824
 
   * 
 
504
   *
825
505
   * Possibly this it is incorrect to have used tables in Session because
826
506
   * with more than one subquery, it is not clear what does the field mean.
827
507
   */
829
509
 
830
510
  /**
831
511
    @todo
832
 
    
 
512
 
833
513
    This, and some other variables like 'count_cuted_fields'
834
514
    maybe should be statement/cursor local, that is, moved to Statement
835
515
    class. With current implementation warnings produced in each prepared
836
516
    statement/cursor settle here.
837
517
  */
838
 
  List<DRIZZLE_ERROR> warn_list;
839
518
  uint32_t warn_count[(uint32_t) DRIZZLE_ERROR::WARN_LEVEL_END];
840
519
  uint32_t total_warn_count;
841
 
  Diagnostics_area main_da;
842
 
 
843
 
  ulong col_access;
844
 
 
845
 
  /* Statement id is thread-wide. This counter is used to generate ids */
846
 
  uint32_t statement_id_counter;
847
 
  uint32_t rand_saved_seed1;
848
 
  uint32_t rand_saved_seed2;
 
520
 
849
521
  /**
850
522
    Row counter, mainly for errors and warnings. Not increased in
851
523
    create_sort_index(); may differ from examined_row_count.
852
524
  */
853
525
  uint32_t row_count;
 
526
 
854
527
  session_id_t thread_id;
855
528
  uint32_t tmp_table;
856
529
  enum global_read_lock_t
874
547
    _global_read_lock= arg;
875
548
  }
876
549
 
877
 
  DrizzleLock *lockTables(Table **tables, uint32_t count, uint32_t flags, bool *need_reopen);
 
550
  DrizzleLock *lockTables(Table **tables, uint32_t count, uint32_t flags);
878
551
  bool lockGlobalReadLock();
879
552
  bool lock_table_names(TableList *table_list);
880
553
  bool lock_table_names_exclusively(TableList *table_list);
936
609
  bool is_admin_connection;
937
610
  bool some_tables_deleted;
938
611
  bool no_errors;
939
 
  bool password;
940
612
  /**
941
613
    Set to true if execution of the current compound statement
942
614
    can not continue. In particular, disables activation of
943
615
    CONTINUE or EXIT handlers of stored routines.
944
616
    Reset in the end of processing of the current user request, in
945
 
    @see mysql_reset_session_for_next_command().
 
617
    @see reset_session_for_next_command().
946
618
  */
947
619
  bool is_fatal_error;
948
620
  /**
967
639
  bool substitute_null_with_insert_id;
968
640
  bool cleanup_done;
969
641
 
970
 
  bool abort_on_warning;
 
642
public:
971
643
  bool got_warning; /**< Set on call to push_warning() */
972
644
  bool no_warnings_for_error; /**< no warnings on call to my_error() */
973
645
  /** set during loop of derived table processing */
974
646
  bool derived_tables_processing;
975
 
  bool tablespace_op; /**< This is true in DISCARD/IMPORT TABLESPACE */
 
647
 
 
648
  bool doing_tablespace_operation()
 
649
  {
 
650
    return tablespace_op;
 
651
  }
 
652
 
 
653
  void setDoingTablespaceOperation(bool doing)
 
654
  {
 
655
    tablespace_op= doing;
 
656
  }
 
657
 
976
658
 
977
659
  /** Used by the sys_var class to store temporary values */
978
660
  union
991
673
    and may point to invalid memory after that.
992
674
  */
993
675
  Lex_input_stream *m_lip;
994
 
  
 
676
 
995
677
  /** Place to store various things */
996
678
  void *session_marker;
997
679
 
998
 
  /** Keeps a copy of the previous table around in case we are just slamming on particular table */
999
 
  Table *cached_table;
1000
 
 
1001
680
  /**
1002
681
    Points to info-string that we show in SHOW PROCESSLIST
1003
682
    You are supposed to call Session_SET_PROC_INFO only if you have coded
1007
686
    macro/function.
1008
687
  */
1009
688
  inline void set_proc_info(const char *info)
1010
 
  { 
 
689
  {
1011
690
    proc_info= info;
1012
691
  }
1013
692
  inline const char* get_proc_info() const
1054
733
  }
1055
734
 
1056
735
  /** Returns the current transaction ID for the session's current statement */
1057
 
  inline my_xid getTransactionId()
1058
 
  {
1059
 
    return transaction.xid_state.xid.quick_get_my_xid();
1060
 
  }
 
736
  my_xid getTransactionId();
 
737
 
1061
738
  /**
1062
739
    There is BUG#19630 where statement-based replication of stored
1063
740
    functions/triggers with two auto_increment columns breaks.
1099
776
    if (first_successful_insert_id_in_cur_stmt == 0)
1100
777
      first_successful_insert_id_in_cur_stmt= id_arg;
1101
778
  }
1102
 
  inline uint64_t read_first_successful_insert_id_in_prev_stmt(void)
 
779
  inline uint64_t read_first_successful_insert_id_in_prev_stmt()
1103
780
  {
1104
781
    return first_successful_insert_id_in_prev_stmt;
1105
782
  }
1106
 
  /**
1107
 
    Used by Intvar_log_event::do_apply_event() and by "SET INSERT_ID=#"
1108
 
    (mysqlbinlog). We'll soon add a variant which can take many intervals in
1109
 
    argument.
1110
 
  */
1111
 
  inline void force_one_auto_inc_interval(uint64_t next_id)
1112
 
  {
1113
 
    auto_inc_intervals_forced.empty(); // in case of multiple SET INSERT_ID
1114
 
    auto_inc_intervals_forced.append(next_id, UINT64_MAX, 0);
1115
 
  }
1116
783
 
1117
 
  Session(plugin::Client *client_arg);
 
784
  Session(plugin::Client *client_arg, boost::shared_ptr<catalog::Instance> catalog);
1118
785
  virtual ~Session();
1119
786
 
1120
 
  void cleanup(void);
 
787
  void cleanup();
1121
788
  /**
1122
789
   * Cleans up after query.
1123
790
   *
1153
820
  void prepareForQueries();
1154
821
 
1155
822
  /**
1156
 
   * Executes a single statement received from the 
 
823
   * Executes a single statement received from the
1157
824
   * client connection.
1158
825
   *
1159
 
   * Returns true if the statement was successful, or false 
 
826
   * Returns true if the statement was successful, or false
1160
827
   * otherwise.
1161
828
   *
1162
829
   * @note
1171
838
  /**
1172
839
   * Reads a query from packet and stores it.
1173
840
   *
1174
 
   * Returns true if query is read and allocated successfully, 
 
841
   * Returns true if query is read and allocated successfully,
1175
842
   * false otherwise.  On a return of false, Session::fatal_error
1176
843
   * is set.
1177
844
   *
1189
856
  /**
1190
857
   * Ends the current transaction and (maybe) begins the next.
1191
858
   *
1192
 
   * Returns true if the transaction completed successfully, 
 
859
   * Returns true if the transaction completed successfully,
1193
860
   * otherwise false.
1194
861
   *
1195
862
   * @param Completion type
1197
864
  bool endTransaction(enum enum_mysql_completiontype completion);
1198
865
  bool endActiveTransaction();
1199
866
  bool startTransaction(start_transaction_option_t opt= START_TRANS_NO_OPTIONS);
 
867
  void markTransactionForRollback(bool all);
1200
868
 
1201
869
  /**
1202
870
   * Authenticates users, with error reporting.
1217
885
   */
1218
886
  static bool schedule(Session::shared_ptr&);
1219
887
 
 
888
  static void unlink(session_id_t &session_id);
1220
889
  static void unlink(Session::shared_ptr&);
1221
890
 
1222
891
  /*
1227
896
  const char* enter_cond(boost::condition_variable_any &cond, boost::mutex &mutex, const char* msg);
1228
897
  void exit_cond(const char* old_msg);
1229
898
 
1230
 
  inline time_t query_start() { return start_time; }
1231
 
  inline void set_time()
1232
 
  {
1233
 
    boost::posix_time::ptime mytime(boost::posix_time::microsec_clock::local_time());
1234
 
    boost::posix_time::ptime epoch(boost::gregorian::date(1970,1,1));
1235
 
    start_utime= utime_after_lock= (mytime-epoch).total_microseconds();
1236
 
 
1237
 
    if (user_time)
1238
 
    {
1239
 
      start_time= user_time;
1240
 
      connect_microseconds= start_utime;
1241
 
    }
1242
 
    else 
1243
 
      start_time= (mytime-epoch).total_seconds();
1244
 
  }
1245
 
  inline void   set_current_time()    { start_time= time(NULL); }
1246
 
  inline void   set_time(time_t t)
1247
 
  {
1248
 
    start_time= user_time= t;
1249
 
    boost::posix_time::ptime mytime(boost::posix_time::microsec_clock::local_time());
1250
 
    boost::posix_time::ptime epoch(boost::gregorian::date(1970,1,1));
1251
 
    uint64_t t_mark= (mytime-epoch).total_microseconds();
1252
 
 
1253
 
    start_utime= utime_after_lock= t_mark;
1254
 
  }
1255
 
  void set_time_after_lock()  { 
1256
 
     boost::posix_time::ptime mytime(boost::posix_time::microsec_clock::local_time());
1257
 
     boost::posix_time::ptime epoch(boost::gregorian::date(1970,1,1));
1258
 
     utime_after_lock= (mytime-epoch).total_microseconds();
1259
 
  }
 
899
  type::Time::epoch_t query_start()
 
900
  {
 
901
    return getCurrentTimestampEpoch();
 
902
  }
 
903
 
 
904
  void set_time()
 
905
  {
 
906
    _end_timer= _start_timer= boost::posix_time::microsec_clock::universal_time();
 
907
    utime_after_lock= (_start_timer - _epoch).total_microseconds();
 
908
  }
 
909
 
 
910
  void set_time(time_t t) // This is done by a sys_var, as long as user_time is set, we will use that for all references to time
 
911
  {
 
912
    _user_time= boost::posix_time::from_time_t(t);
 
913
  }
 
914
 
 
915
  void set_time_after_lock()
 
916
  {
 
917
    utime_after_lock= (boost::posix_time::microsec_clock::universal_time() - _epoch).total_microseconds();
 
918
  }
 
919
 
 
920
  void set_end_timer();
 
921
 
 
922
  uint64_t getElapsedTime() const
 
923
  {
 
924
    return (_end_timer - _start_timer).total_microseconds();
 
925
  }
 
926
 
1260
927
  /**
1261
928
   * Returns the current micro-timestamp
1262
929
   */
1263
 
  inline uint64_t getCurrentTimestamp()  
1264
 
  { 
1265
 
    boost::posix_time::ptime mytime(boost::posix_time::microsec_clock::local_time());
1266
 
    boost::posix_time::ptime epoch(boost::gregorian::date(1970,1,1));
1267
 
    uint64_t t_mark= (mytime-epoch).total_microseconds();
1268
 
 
1269
 
    return t_mark; 
1270
 
  }
1271
 
  inline uint64_t found_rows(void)
 
930
  type::Time::epoch_t getCurrentTimestamp(bool actual= true) const
 
931
  {
 
932
    return ((actual ? boost::posix_time::microsec_clock::universal_time() : _end_timer) - _epoch).total_microseconds();
 
933
  }
 
934
 
 
935
  // We may need to set user on this
 
936
  type::Time::epoch_t getCurrentTimestampEpoch() const
 
937
  {
 
938
                return ((_user_time.is_not_a_date_time() ? _start_timer : _user_time) - _epoch).total_seconds();
 
939
  }
 
940
 
 
941
  type::Time::epoch_t getCurrentTimestampEpoch(type::Time::usec_t &fraction_arg) const
 
942
  {
 
943
    if (not _user_time.is_not_a_date_time())
 
944
    {
 
945
      fraction_arg= 0;
 
946
      return (_user_time - _epoch).total_seconds();
 
947
    }
 
948
 
 
949
    fraction_arg= _start_timer.time_of_day().fractional_seconds() % 1000000;
 
950
    return (_start_timer - _epoch).total_seconds();
 
951
  }
 
952
 
 
953
  uint64_t found_rows() const
1272
954
  {
1273
955
    return limit_found_rows;
1274
956
  }
 
957
 
1275
958
  /** Returns whether the session is currently inside a transaction */
1276
 
  inline bool inTransaction()
 
959
  bool inTransaction() const
1277
960
  {
1278
961
    return server_status & SERVER_STATUS_IN_TRANS;
1279
962
  }
 
963
 
1280
964
  LEX_STRING *make_lex_string(LEX_STRING *lex_str,
1281
965
                              const char* str, uint32_t length,
1282
966
                              bool allocate_lex_string);
 
967
 
1283
968
  LEX_STRING *make_lex_string(LEX_STRING *lex_str,
1284
969
                              const std::string &str,
1285
970
                              bool allocate_lex_string);
1286
971
 
1287
972
  int send_explain_fields(select_result *result);
1288
 
  /**
1289
 
    Clear the current error, if any.
1290
 
    We do not clear is_fatal_error or is_fatal_sub_stmt_error since we
1291
 
    assume this is never called if the fatal error is set.
1292
 
    @todo: To silence an error, one should use Internal_error_handler
1293
 
    mechanism. In future this function will be removed.
1294
 
  */
1295
 
  inline void clear_error(bool full= false)
1296
 
  {
1297
 
    if (main_da.is_error())
1298
 
      main_da.reset_diagnostics_area();
1299
 
 
1300
 
    if (full)
1301
 
    {
1302
 
      drizzle_reset_errors(this, true);
1303
 
    }
1304
 
  }
1305
 
 
1306
 
  void clearDiagnostics()
1307
 
  {
1308
 
    main_da.reset_diagnostics_area();
1309
 
  }
1310
 
 
1311
 
  /**
1312
 
    Mark the current error as fatal. Warning: this does not
1313
 
    set any error, it sets a property of the error, so must be
1314
 
    followed or prefixed with my_error().
1315
 
  */
1316
 
  inline void fatal_error()
1317
 
  {
1318
 
    assert(main_da.is_error());
1319
 
    is_fatal_error= true;
1320
 
  }
1321
 
  /**
1322
 
    true if there is an error in the error stack.
1323
 
 
1324
 
    Please use this method instead of direct access to
1325
 
    net.report_error.
1326
 
 
1327
 
    If true, the current (sub)-statement should be aborted.
1328
 
    The main difference between this member and is_fatal_error
1329
 
    is that a fatal error can not be handled by a stored
1330
 
    procedure continue handler, whereas a normal error can.
1331
 
 
1332
 
    To raise this flag, use my_error().
1333
 
  */
1334
 
  inline bool is_error() const { return main_da.is_error(); }
1335
 
  inline const CHARSET_INFO *charset() { return default_charset_info; }
1336
 
 
1337
 
  void change_item_tree(Item **place, Item *new_value)
1338
 
  {
1339
 
    *place= new_value;
1340
 
  }
 
973
 
 
974
  void clear_error(bool full= false);
 
975
  void clearDiagnostics();
 
976
  void fatal_error();
 
977
  bool is_error() const;
 
978
 
 
979
  inline const charset_info_st *charset() { return default_charset_info; }
 
980
 
1341
981
  /**
1342
982
    Cleanup statement parse state (parse tree, lex) and execution
1343
983
    state after execution of a non-prepared SQL statement.
1354
994
  }
1355
995
  void send_kill_message() const;
1356
996
  /* return true if we will abort query if we make a warning now */
1357
 
  inline bool really_abort_on_warning()
1358
 
  {
1359
 
    return (abort_on_warning);
 
997
  inline bool abortOnWarning()
 
998
  {
 
999
    return abort_on_warning;
 
1000
  }
 
1001
 
 
1002
  inline void setAbortOnWarning(bool arg)
 
1003
  {
 
1004
    abort_on_warning= arg;
1360
1005
  }
1361
1006
 
1362
1007
  void setAbort(bool arg);
1402
1047
    @param level the error level
1403
1048
    @return true if the error is handled
1404
1049
  */
1405
 
  virtual bool handle_error(uint32_t sql_errno, const char *message,
 
1050
  virtual bool handle_error(error_t sql_errno, const char *message,
1406
1051
                            DRIZZLE_ERROR::enum_warning_level level);
1407
1052
 
1408
1053
  /**
1430
1075
   * updates any status variables necessary.
1431
1076
   *
1432
1077
   * @param errcode     Error code to print to console
1433
 
   * @param should_lock 1 if we have have to lock LOCK_thread_count
1434
1078
   *
1435
1079
   * @note  For the connection that is doing shutdown, this is called twice
1436
1080
   */
1437
 
  void disconnect(uint32_t errcode, bool lock);
 
1081
  void disconnect(enum error_t errcode= EE_OK);
1438
1082
 
1439
1083
  /**
1440
1084
   * Check if user exists and the password supplied is correct.
1443
1087
   *
1444
1088
   * @note Host, user and passwd may point to communication buffer.
1445
1089
   * Current implementation does not depend on that, but future changes
1446
 
   * should be done with this in mind; 
 
1090
   * should be done with this in mind;
1447
1091
   *
1448
1092
   * @param passwd Scrambled password received from client
1449
1093
   * @param db Database name to connect to, may be NULL
1450
1094
   */
1451
1095
  bool checkUser(const std::string &passwd, const std::string &db);
1452
 
  
 
1096
 
1453
1097
  /**
1454
 
   * Returns the timestamp (in microseconds) of when the Session 
 
1098
   * Returns the timestamp (in microseconds) of when the Session
1455
1099
   * connected to the server.
1456
1100
   */
1457
 
  inline uint64_t getConnectMicroseconds() const
1458
 
  {
1459
 
    return connect_microseconds;
 
1101
  uint64_t getConnectMicroseconds() const
 
1102
  {
 
1103
    return (_connect_time - _epoch).total_microseconds();
 
1104
  }
 
1105
 
 
1106
  uint64_t getConnectSeconds() const
 
1107
  {
 
1108
    return (_connect_time - _epoch).total_seconds();
1460
1109
  }
1461
1110
 
1462
1111
  /**
1477
1126
  {
1478
1127
    return statement_message;
1479
1128
  }
1480
 
  
 
1129
 
1481
1130
  /**
1482
1131
   * Returns a pointer to the current Resulset message for this
1483
1132
   * Session, or NULL if no active message.
1524
1173
   */
1525
1174
 
1526
1175
  void resetResultsetMessage()
1527
 
  { 
 
1176
  {
1528
1177
    resultset= NULL;
1529
1178
  }
1530
1179
 
1531
 
private:
1532
 
  /** Pointers to memory managed by the ReplicationServices component */
1533
 
  message::Transaction *transaction_message;
1534
 
  message::Statement *statement_message;
1535
 
  /* Pointer to the current resultset of Select query */
1536
 
  message::Resultset *resultset;
1537
 
  plugin::EventObserverList *session_event_observers;
1538
 
  
1539
 
  /* Schema observers are mapped to databases. */
1540
 
  std::map<std::string, plugin::EventObserverList *> schema_event_observers;
1541
 
 
1542
 
 
1543
 
public:
1544
 
  plugin::EventObserverList *getSessionObservers() 
1545
 
  { 
 
1180
  plugin::EventObserverList *getSessionObservers()
 
1181
  {
1546
1182
    return session_event_observers;
1547
1183
  }
1548
 
  
1549
 
  void setSessionObservers(plugin::EventObserverList *observers) 
1550
 
  { 
 
1184
 
 
1185
  void setSessionObservers(plugin::EventObserverList *observers)
 
1186
  {
1551
1187
    session_event_observers= observers;
1552
1188
  }
1553
 
  
1554
 
  /* For schema event observers there is one set of observers per database. */
1555
 
  plugin::EventObserverList *getSchemaObservers(const std::string &db_name) 
1556
 
  { 
1557
 
    std::map<std::string, plugin::EventObserverList *>::iterator it;
1558
 
    
1559
 
    it= schema_event_observers.find(db_name);
1560
 
    if (it == schema_event_observers.end())
1561
 
      return NULL;
1562
 
      
1563
 
    return it->second;
1564
 
  }
1565
 
  
1566
 
  void setSchemaObservers(const std::string &db_name, plugin::EventObserverList *observers) 
1567
 
  { 
1568
 
    std::map<std::string, plugin::EventObserverList *>::iterator it;
1569
 
 
1570
 
    it= schema_event_observers.find(db_name);
1571
 
    if (it != schema_event_observers.end())
1572
 
      schema_event_observers.erase(it);;
1573
 
 
1574
 
    if (observers)
1575
 
      schema_event_observers[db_name] = observers;
1576
 
  }
1577
 
  
1578
 
  
 
1189
 
 
1190
  plugin::EventObserverList* getSchemaObservers(const std::string& schema);
 
1191
  plugin::EventObserverList* setSchemaObservers(const std::string& schema, plugin::EventObserverList*);
 
1192
 
1579
1193
 private:
1580
 
 /** Microsecond timestamp of when Session connected */
1581
 
  uint64_t connect_microseconds;
1582
 
  const char *proc_info;
1583
1194
 
1584
1195
  /** The current internal error handler for this thread, or NULL. */
1585
1196
  Internal_error_handler *m_internal_handler;
1586
1197
  /**
1587
 
    The lex to hold the parsed tree of conventional (non-prepared) queries.
1588
 
    Whereas for prepared and stored procedure statements we use an own lex
1589
 
    instance for each new query, for conventional statements we reuse
1590
 
    the same lex. (@see mysql_parse for details).
1591
 
  */
1592
 
  LEX main_lex;
1593
 
  /**
1594
1198
    This memory root is used for two purposes:
1595
1199
    - for conventional queries, to allocate structures stored in main_lex
1596
1200
    during parsing, and allocate runtime data (execution plan, etc.)
1612
1216
   * if table->query_id != session->query_id to know if a table is in use.
1613
1217
   *
1614
1218
   * For example
1615
 
   * 
 
1219
   *
1616
1220
   *  SELECT f1_that_uses_t1() FROM t1;
1617
 
   *  
 
1221
   *
1618
1222
   * In f1_that_uses_t1() we will see one instance of t1 where query_id is
1619
1223
   * set to query_id of original query.
1620
1224
   */
1621
1225
  void mark_used_tables_as_free_for_reuse(Table *table);
1622
1226
 
1623
1227
public:
1624
 
 
1625
 
  /** A short cut for session->main_da.set_ok_status(). */
1626
 
  inline void my_ok(ha_rows affected_rows= 0, ha_rows found_rows_arg= 0,
1627
 
                    uint64_t passed_id= 0, const char *message= NULL)
1628
 
  {
1629
 
    main_da.set_ok_status(this, affected_rows, found_rows_arg, passed_id, message);
1630
 
  }
1631
 
 
1632
 
 
1633
 
  /** A short cut for session->main_da.set_eof_status(). */
1634
 
 
1635
 
  inline void my_eof()
1636
 
  {
1637
 
    main_da.set_eof_status(this);
1638
 
  }
1639
 
 
1640
 
  /* Some inline functions for more speed */
1641
 
 
1642
 
  inline bool add_item_to_list(Item *item)
1643
 
  {
1644
 
    return lex->current_select->add_item_to_list(this, item);
1645
 
  }
1646
 
 
1647
 
  inline bool add_value_to_list(Item *value)
1648
 
  {
1649
 
    return lex->value_list.push_back(value);
1650
 
  }
1651
 
 
1652
 
  inline bool add_order_to_list(Item *item, bool asc)
1653
 
  {
1654
 
    return lex->current_select->add_order_to_list(this, item, asc);
1655
 
  }
1656
 
 
1657
 
  inline bool add_group_to_list(Item *item, bool asc)
1658
 
  {
1659
 
    return lex->current_select->add_group_to_list(this, item, asc);
1660
 
  }
 
1228
  void my_ok(ha_rows affected_rows= 0, ha_rows found_rows_arg= 0, uint64_t passed_id= 0, const char *message= NULL);
 
1229
  void my_eof();
 
1230
  bool add_item_to_list(Item *item);
 
1231
  bool add_value_to_list(Item *value);
 
1232
  bool add_order_to_list(Item *item, bool asc);
 
1233
  bool add_group_to_list(Item *item, bool asc);
 
1234
 
1661
1235
  void refresh_status();
1662
1236
  user_var_entry *getVariable(LEX_STRING &name, bool create_if_not_exists);
1663
1237
  user_var_entry *getVariable(const std::string  &name, bool create_if_not_exists);
1664
1238
  void setVariable(const std::string &name, const std::string &value);
1665
 
  
 
1239
 
1666
1240
  /**
1667
1241
   * Closes all tables used by the current substatement, or all tables
1668
1242
   * used by this thread if we are on the upper level.
1671
1245
  void close_old_data_files(bool morph_locks= false,
1672
1246
                            bool send_refresh= false);
1673
1247
  void close_open_tables();
1674
 
  void close_data_files_and_morph_locks(const TableIdentifier &identifier);
1675
 
 
1676
 
private:
1677
 
  bool free_cached_table();
1678
 
public:
 
1248
  void close_data_files_and_morph_locks(const identifier::Table &identifier);
1679
1249
 
1680
1250
  /**
1681
1251
   * Prepares statement for reopening of tables and recalculation of set of
1697
1267
   *  true  - error
1698
1268
   *
1699
1269
   * @note
1700
 
   * 
 
1270
   *
1701
1271
   * The lock will automaticaly be freed by close_thread_tables()
1702
1272
   */
1703
1273
  bool openTablesLock(TableList *tables);
1708
1278
  Table *openTable(TableList *table_list, bool *refresh, uint32_t flags= 0);
1709
1279
 
1710
1280
  void unlink_open_table(Table *find);
1711
 
  void drop_open_table(Table *table, const TableIdentifier &identifier);
 
1281
  void drop_open_table(Table *table, const identifier::Table &identifier);
1712
1282
  void close_cached_table(Table *table);
1713
1283
 
1714
1284
  /* Create a lock in the cache */
1715
 
  table::Placeholder *table_cache_insert_placeholder(const TableIdentifier &identifier);
1716
 
  bool lock_table_name_if_not_cached(const TableIdentifier &identifier, Table **table);
1717
 
 
1718
 
  typedef boost::unordered_map<std::string, message::Table, util::insensitive_hash, util::insensitive_equal_to> TableMessageCache;
1719
 
 
1720
 
  class TableMessages
1721
 
  {
1722
 
    TableMessageCache table_message_cache;
1723
 
 
1724
 
  public:
1725
 
    bool storeTableMessage(const TableIdentifier &identifier, message::Table &table_message);
1726
 
    bool removeTableMessage(const TableIdentifier &identifier);
1727
 
    bool getTableMessage(const TableIdentifier &identifier, message::Table &table_message);
1728
 
    bool doesTableMessageExist(const TableIdentifier &identifier);
1729
 
    bool renameTableMessage(const TableIdentifier &from, const TableIdentifier &to);
1730
 
 
1731
 
  };
1732
 
private:
1733
 
  TableMessages _table_message_cache;
1734
 
 
1735
 
public:
1736
 
  TableMessages &getMessageCache()
1737
 
  {
1738
 
    return _table_message_cache;
1739
 
  }
 
1285
  table::Placeholder *table_cache_insert_placeholder(const identifier::Table &identifier);
 
1286
  bool lock_table_name_if_not_cached(const identifier::Table &identifier, Table **table);
 
1287
 
 
1288
  session::TableMessages &getMessageCache();
1740
1289
 
1741
1290
  /* Reopen operations */
1742
 
  bool reopen_tables(bool get_locks, bool mark_share_as_old);
 
1291
  bool reopen_tables();
1743
1292
  bool close_cached_tables(TableList *tables, bool wait_for_refresh, bool wait_for_placeholders);
1744
1293
 
1745
1294
  void wait_for_condition(boost::mutex &mutex, boost::condition_variable_any &cond);
1746
1295
  int setup_conds(TableList *leaves, COND **conds);
1747
1296
  int lock_tables(TableList *tables, uint32_t count, bool *need_reopen);
1748
1297
 
1749
 
  drizzled::util::Storable *getProperty(const std::string &arg)
 
1298
  template <class T>
 
1299
  T* getProperty(const std::string& name)
1750
1300
  {
1751
 
    return life_properties[arg];
 
1301
    return static_cast<T*>(getProperty0(name));
1752
1302
  }
1753
1303
 
1754
 
  template<class T>
1755
 
  bool setProperty(const std::string &arg, T *value)
 
1304
  template <class T>
 
1305
  T setProperty(const std::string& name, T value)
1756
1306
  {
1757
 
    life_properties[arg]= value;
1758
 
 
1759
 
    return true;
 
1307
    setProperty0(name, value);
 
1308
    return value;
1760
1309
  }
1761
1310
 
1762
1311
  /**
1767
1316
    @return
1768
1317
    pointer to plugin::StorageEngine
1769
1318
  */
1770
 
  plugin::StorageEngine *getDefaultStorageEngine()
1771
 
  {
1772
 
    if (variables.storage_engine)
1773
 
      return variables.storage_engine;
1774
 
    return global_system_variables.storage_engine;
1775
 
  }
1776
 
 
1777
 
  void get_xid(DRIZZLE_XID *xid); // Innodb only
1778
 
 
1779
 
  table::Instance *getInstanceTable();
1780
 
  table::Instance *getInstanceTable(List<CreateField> &field_list);
1781
 
 
1782
 
private:
1783
 
  bool resetUsage()
1784
 
  {
1785
 
    if (getrusage(RUSAGE_THREAD, &usage))
1786
 
    {
1787
 
      return false;
1788
 
    }
1789
 
 
1790
 
    return true;
1791
 
  }
1792
 
public:
 
1319
  plugin::StorageEngine *getDefaultStorageEngine();
 
1320
  void get_xid(DrizzleXid *xid); // Innodb only
 
1321
 
 
1322
  table::Singular& getInstanceTable();
 
1323
  table::Singular& getInstanceTable(std::list<CreateField>&);
1793
1324
 
1794
1325
  void setUsage(bool arg)
1795
1326
  {
1796
1327
    use_usage= arg;
1797
1328
  }
1798
1329
 
1799
 
  const struct rusage &getUsage()
 
1330
  const rusage &getUsage()
1800
1331
  {
1801
1332
    return usage;
1802
1333
  }
1803
1334
 
 
1335
  const catalog::Instance& catalog() const
 
1336
  {
 
1337
    return *_catalog;
 
1338
  }
 
1339
 
 
1340
  catalog::Instance& catalog()
 
1341
  {
 
1342
    return *_catalog;
 
1343
  }
 
1344
 
 
1345
  bool arg_of_last_insert_id_function; // Tells if LAST_INSERT_ID(#) was called for the current statement
1804
1346
private:
1805
 
  // This lives throughout the life of Session
 
1347
  bool free_cached_table(boost::mutex::scoped_lock &scopedLock);
 
1348
  drizzled::util::Storable* getProperty0(const std::string&);
 
1349
  void setProperty0(const std::string&, drizzled::util::Storable*);
 
1350
 
 
1351
 
 
1352
  bool resetUsage()
 
1353
  {
 
1354
    return not getrusage(RUSAGE_THREAD, &usage);
 
1355
  }
 
1356
 
 
1357
  boost::shared_ptr<catalog::Instance> _catalog;
 
1358
 
 
1359
  /** Pointers to memory managed by the ReplicationServices component */
 
1360
  message::Transaction *transaction_message;
 
1361
  message::Statement *statement_message;
 
1362
  /* Pointer to the current resultset of Select query */
 
1363
  message::Resultset *resultset;
 
1364
  plugin::EventObserverList *session_event_observers;
 
1365
 
 
1366
  uint64_t xa_id;
 
1367
  const char *proc_info;
 
1368
  bool abort_on_warning;
 
1369
  bool concurrent_execute_allowed;
 
1370
  bool tablespace_op; /**< This is true in DISCARD/IMPORT TABLESPACE */
1806
1371
  bool use_usage;
1807
 
  PropertyMap life_properties;
1808
 
  std::vector<table::Instance *> temporary_shares;
1809
 
  struct rusage usage;
 
1372
  rusage usage;
 
1373
  identifier::User::shared_ptr security_ctx;
 
1374
  int32_t scoreboard_index;
 
1375
  plugin::Client *client;
 
1376
  util::string::shared_ptr _schema;
1810
1377
};
1811
1378
 
1812
 
class Join;
1813
 
 
1814
1379
#define ESCAPE_CHARS "ntrb0ZN" // keep synchronous with READ_INFO::unescape
1815
1380
 
1816
 
} /* namespace drizzled */
1817
 
 
1818
 
/** @TODO why is this in the middle of the file */
1819
 
#include <drizzled/select_to_file.h>
1820
 
#include <drizzled/select_export.h>
1821
 
#include <drizzled/select_dump.h>
1822
 
#include <drizzled/select_insert.h>
1823
 
#include <drizzled/select_create.h>
1824
 
#include <drizzled/tmp_table_param.h>
1825
 
#include <drizzled/select_union.h>
1826
 
#include <drizzled/select_subselect.h>
1827
 
#include <drizzled/select_singlerow_subselect.h>
1828
 
#include <drizzled/select_max_min_finder_subselect.h>
1829
 
#include <drizzled/select_exists_subselect.h>
1830
 
 
1831
 
namespace drizzled
1832
 
{
1833
 
 
1834
 
/**
1835
 
 * A structure used to describe sort information
1836
 
 * for a field or item used in ORDER BY.
1837
 
 */
1838
 
class SortField 
1839
 
{
1840
 
public:
1841
 
  Field *field; /**< Field to sort */
1842
 
  Item  *item; /**< Item if not sorting fields */
1843
 
  size_t length; /**< Length of sort field */
1844
 
  uint32_t suffix_length; /**< Length suffix (0-4) */
1845
 
  Item_result result_type; /**< Type of item */
1846
 
  bool reverse; /**< if descending sort */
1847
 
  bool need_strxnfrm;   /**< If we have to use strxnfrm() */
1848
 
 
1849
 
  SortField() :
1850
 
    field(0),
1851
 
    item(0),
1852
 
    length(0),
1853
 
    suffix_length(0),
1854
 
    result_type(STRING_RESULT),
1855
 
    reverse(0),
1856
 
    need_strxnfrm(0)
1857
 
  { }
1858
 
 
1859
 
};
1860
 
 
1861
 
} /* namespace drizzled */
1862
 
 
1863
 
/** @TODO why is this in the middle of the file */
1864
 
 
1865
 
#include <drizzled/table_ident.h>
1866
 
#include <drizzled/user_var_entry.h>
1867
 
#include <drizzled/unique.h>
1868
 
#include <drizzled/var.h>
1869
 
#include <drizzled/select_dumpvar.h>
1870
 
 
1871
 
namespace drizzled
1872
 
{
1873
 
 
1874
1381
/* Bits in sql_command_flags */
1875
1382
 
1876
 
enum sql_command_flag_bits 
 
1383
enum sql_command_flag_bits
1877
1384
{
1878
1385
  CF_BIT_CHANGES_DATA,
1879
1386
  CF_BIT_HAS_ROW_COUNT,
1889
1396
static const std::bitset<CF_BIT_SIZE> CF_SHOW_TABLE_COMMAND(1 << CF_BIT_SHOW_TABLE_COMMAND);
1890
1397
static const std::bitset<CF_BIT_SIZE> CF_WRITE_LOGS_COMMAND(1 << CF_BIT_WRITE_LOGS_COMMAND);
1891
1398
 
1892
 
namespace display  {
1893
 
const std::string &type(drizzled::Session::global_read_lock_t type);
1894
 
size_t max_string_length(drizzled::Session::global_read_lock_t type);
 
1399
namespace display  
 
1400
{
 
1401
  const std::string &type(Session::global_read_lock_t);
 
1402
  size_t max_string_length(Session::global_read_lock_t);
1895
1403
} /* namespace display */
1896
1404
 
1897
1405
} /* namespace drizzled */
1898
1406
 
1899
 
#endif /* DRIZZLED_SESSION_H */