~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/session.h

Merge in Monty's rename patch.

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
 
20
21
#ifndef DRIZZLED_SESSION_H
21
22
#define DRIZZLED_SESSION_H
22
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>
 
43
 
23
44
#include <algorithm>
24
45
#include <bitset>
25
 
#include <boost/make_shared.hpp>
26
 
#include <boost/thread/condition_variable.hpp>
 
46
#include <deque>
 
47
#include <map>
 
48
#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>
27
59
#include <boost/thread/mutex.hpp>
28
60
#include <boost/thread/shared_mutex.hpp>
29
 
#include <boost/thread/thread.hpp>
30
 
#include <map>
31
 
#include <netdb.h>
32
 
#include <string>
33
 
#include <sys/resource.h>
34
 
#include <sys/time.h>
 
61
#include <boost/thread/condition_variable.hpp>
 
62
#include <boost/make_shared.hpp>
35
63
 
36
 
#include <drizzled/catalog/instance.h>
37
 
#include <drizzled/catalog/local.h>
38
 
#include <drizzled/copy_info.h>
39
 
#include <drizzled/cursor.h>
40
 
#include <drizzled/diagnostics_area.h>
41
 
#include <drizzled/file_exchange.h>
42
 
#include <drizzled/ha_data.h>
43
 
#include <drizzled/identifier.h>
44
 
#include <drizzled/lex_column.h>
45
 
#include <drizzled/my_hash.h>
46
 
#include <drizzled/named_savepoint.h>
47
 
#include <drizzled/open_tables_state.h>
48
 
#include <drizzled/plugin.h>
49
 
#include <drizzled/plugin/authorization.h>
50
 
#include <drizzled/pthread_globals.h>
51
 
#include <drizzled/query_id.h>
52
 
#include <drizzled/resource_context.h>
53
 
#include <drizzled/session/property_map.h>
54
 
#include <drizzled/session/state.h>
55
 
#include <drizzled/session/table_messages.h>
56
 
#include <drizzled/session/transactions.h>
57
 
#include <drizzled/sql_error.h>
58
 
#include <drizzled/sql_lex.h>
59
 
#include <drizzled/sql_locale.h>
60
 
#include <drizzled/statistics_variables.h>
61
 
#include <drizzled/system_variables.h>
62
 
#include <drizzled/system_variables.h>
63
 
#include <drizzled/table_ident.h>
64
 
#include <drizzled/transaction_context.h>
65
 
#include <drizzled/util/storable.h>
66
 
#include <drizzled/var.h>
67
 
#include <drizzled/visibility.h>
68
64
 
69
65
#define MIN_HANDSHAKE_SIZE      6
70
66
 
85
81
class Resultset;
86
82
}
87
83
 
88
 
namespace internal { struct st_my_thread_var; }
89
 
namespace table { class Placeholder; }
90
 
 
 
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;
91
96
class CopyField;
92
 
class DrizzleXid;
93
 
class Internal_error_handler;
94
 
class Lex_input_stream;
 
97
class Table_ident;
 
98
 
95
99
class TableShareInstance;
96
 
class Table_ident;
97
 
class Time_zone;
98
 
class select_result;
99
 
class user_var_entry;
100
100
 
101
101
extern char internal_table_name[2];
102
102
extern char empty_c_string[1];
106
106
#define TC_HEURISTIC_RECOVER_ROLLBACK 2
107
107
extern uint32_t tc_heuristic_recover;
108
108
 
 
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
 
109
173
#define Session_SENTRY_MAGIC 0xfeedd1ff
110
174
#define Session_SENTRY_GONE  0xdeadbeef
111
175
 
112
 
extern DRIZZLED_API struct drizzle_system_variables global_system_variables;
 
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
};
113
293
 
114
294
/**
115
295
 * Represents a client connection to the database server.
130
310
 * all member variables that are not critical to non-internal operations of the
131
311
 * session object.
132
312
 */
 
313
typedef int64_t session_id_t;
133
314
 
134
 
class DRIZZLED_API Session : public Open_tables_state
 
315
class Session : public Open_tables_state
135
316
{
136
317
public:
137
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;
138
321
  typedef boost::shared_ptr<Session> shared_ptr;
139
 
  typedef Session& reference;
140
322
  typedef const Session& const_reference;
141
323
  typedef const Session* const_pointer;
142
324
  typedef Session* pointer;
143
325
 
144
 
  static shared_ptr make_shared(plugin::Client *client, catalog::Instance::shared_ptr instance_arg)
145
 
  {
146
 
    assert(instance_arg);
147
 
    return boost::make_shared<Session>(client, instance_arg);
148
 
  }
149
 
 
150
326
  /*
151
327
    MARK_COLUMNS_NONE:  Means mark_used_colums is not set and no indicator to
152
328
                        handler of fields used is set
159
335
                        and update_row.
160
336
  */
161
337
  enum enum_mark_columns mark_used_columns;
 
338
  inline void* alloc(size_t size)
 
339
  {
 
340
    return mem_root->alloc_root(size);
 
341
  }
162
342
  inline void* calloc(size_t size)
163
343
  {
164
344
    void *ptr;
166
346
      memset(ptr, 0, size);
167
347
    return ptr;
168
348
  }
 
349
  inline char *strdup(const char *str)
 
350
  {
 
351
    return mem_root->strdup_root(str);
 
352
  }
169
353
  inline char *strmake(const char *str, size_t size)
170
354
  {
171
355
    return mem_root->strmake_root(str,size);
172
356
  }
173
 
 
 
357
  inline void *memdup(const void *str, size_t size)
 
358
  {
 
359
    return mem_root->memdup_root(str, size);
 
360
  }
174
361
  inline void *memdup_w_gap(const void *str, size_t size, uint32_t gap)
175
362
  {
176
363
    void *ptr;
180
367
  }
181
368
  /** Frees all items attached to this Statement */
182
369
  void free_items();
183
 
 
184
370
  /**
185
371
   * List of items created in the parser for this query. Every item puts
186
372
   * itself to the list on creation (see Item::Item() for details))
213
399
   * @todo should be const
214
400
   */
215
401
  uint32_t id;
216
 
private:
217
402
  LEX *lex; /**< parse tree descriptor */
218
403
 
219
 
public:
220
404
  LEX *getLex() 
221
405
  {
222
406
    return lex;
223
407
  }
224
 
 
225
 
  enum_sql_command getSqlCommand() const
226
 
  {
227
 
    return lex->sql_command;
228
 
  }
229
 
 
230
408
  /** query associated with this statement */
231
409
  typedef boost::shared_ptr<const std::string> QueryString;
232
 
 
233
410
private:
234
411
  boost::shared_ptr<std::string> query;
235
412
 
268
445
    return to_return;
269
446
  }
270
447
 
 
448
  class State {
 
449
    std::vector <char> _query;
 
450
 
 
451
  public:
 
452
    typedef boost::shared_ptr<State> const_shared_ptr;
 
453
 
 
454
    State(const char *in_packet, size_t in_packet_length)
 
455
    {
 
456
      if (in_packet_length)
 
457
      {
 
458
        size_t minimum= std::min(in_packet_length, static_cast<size_t>(PROCESS_LIST_WIDTH));
 
459
        _query.resize(minimum + 1);
 
460
        memcpy(&_query[0], in_packet, minimum);
 
461
      }
 
462
      else
 
463
      {
 
464
        _query.resize(0);
 
465
      }
 
466
    }
 
467
 
 
468
    const char *query() const
 
469
    {
 
470
      if (_query.size())
 
471
        return &_query[0];
 
472
 
 
473
      return "";
 
474
    }
 
475
 
 
476
    const char *query(size_t &size) const
 
477
    {
 
478
      if (_query.size())
 
479
      {
 
480
        size= _query.size() -1;
 
481
        return &_query[0];
 
482
      }
 
483
 
 
484
      size= 0;
 
485
      return "";
 
486
    }
 
487
  protected:
 
488
    friend class Session;
 
489
    typedef boost::shared_ptr<State> shared_ptr;
 
490
  };
271
491
private:
272
 
  session::State::shared_ptr  _state; 
273
 
 
 
492
  State::shared_ptr  _state; 
274
493
public:
275
494
 
276
 
  session::State::const_shared_ptr state()
 
495
  State::const_shared_ptr state()
277
496
  {
278
497
    return _state;
279
498
  }
292
511
  */
293
512
private:
294
513
  util::string::shared_ptr _schema;
295
 
 
296
514
public:
297
515
 
298
516
  util::string::const_shared_ptr schema() const
302
520
 
303
521
    return util::string::const_shared_ptr(new std::string(""));
304
522
  }
305
 
 
 
523
  std::string catalog;
306
524
  /* current cache key */
307
525
  std::string query_cache_key;
308
526
  /**
326
544
    return client;
327
545
  }
328
546
 
329
 
  plugin::Client *getClient() const
330
 
  {
331
 
    return client;
332
 
  }
333
 
 
334
547
  plugin::Scheduler *scheduler; /**< Pointer to scheduler object */
335
548
  void *scheduler_arg; /**< Pointer to the optional scheduler argument */
336
549
 
337
550
  typedef boost::unordered_map< std::string, user_var_entry *, util::insensitive_hash, util::insensitive_equal_to> UserVars;
338
 
 
339
551
private:
340
552
  typedef std::pair< UserVars::iterator, UserVars::iterator > UserVarsRange;
341
553
  UserVars user_vars; /**< Hash of user variables defined during the session's lifetime */
342
554
 
343
555
public:
 
556
 
344
557
  const UserVars &getUserVariables() const
345
558
  {
346
559
    return user_vars;
347
560
  }
348
561
 
349
562
  drizzle_system_variables variables; /**< Mutable local variables local to the session */
350
 
 
351
 
  enum_tx_isolation getTxIsolation()
352
 
  {
353
 
    return (enum_tx_isolation)variables.tx_isolation;
354
 
  }
355
 
 
356
563
  struct system_status_var status_var; /**< Session-local status counters */
357
564
  THR_LOCK_INFO lock_info; /**< Locking information for this session */
358
565
  THR_LOCK_OWNER main_lock_id; /**< To use for conventional queries */
373
580
  {
374
581
    assert(this->dbug_sentry == Session_SENTRY_MAGIC);
375
582
  }
376
 
 
377
583
public:
378
584
  identifier::User::const_shared_ptr user() const
379
585
  {
403
609
   */
404
610
  bool isViewable(identifier::User::const_reference) const;
405
611
 
406
 
private:
407
612
  /**
408
613
    Used in error messages to tell user in what part of MySQL we found an
409
614
    error. E. g. when where= "having clause", if fix_fields() fails, user
410
615
    will know that the error was in having clause.
411
616
  */
412
 
  const char *_where;
413
 
 
414
 
public:
415
 
  const char *where()
416
 
  {
417
 
    return _where;
418
 
  }
419
 
 
420
 
  void setWhere(const char *arg)
421
 
  {
422
 
    _where= arg;
423
 
  }
 
617
  const char *where;
424
618
 
425
619
  /*
426
620
    One thread can hold up to one named user-level lock. This variable
428
622
    chapter 'Miscellaneous functions', for functions GET_LOCK, RELEASE_LOCK.
429
623
  */
430
624
  uint32_t dbug_sentry; /**< watch for memory corruption */
431
 
 
432
625
private:
433
626
  boost::thread::id boost_thread_id;
434
627
  boost_thread_shared_ptr _thread;
435
628
  boost::this_thread::disable_interruption *interrupt;
436
629
 
437
630
  internal::st_my_thread_var *mysys_var;
 
631
public:
438
632
 
439
 
public:
440
633
  boost_thread_shared_ptr &getThread()
441
634
  {
442
635
    return _thread;
466
659
  uint32_t file_id;     /**< File ID for LOAD DATA INFILE */
467
660
  /* @note the following three members should likely move to Client */
468
661
  uint32_t max_client_packet_length; /**< Maximum number of bytes a client can send in a single packet */
469
 
 
470
 
private:
471
 
  boost::posix_time::ptime _epoch;
472
 
  boost::posix_time::ptime _connect_time;
473
 
  boost::posix_time::ptime _start_timer;
474
 
  boost::posix_time::ptime _end_timer;
475
 
 
476
 
  boost::posix_time::ptime _user_time;
477
 
public:
478
 
  uint64_t utime_after_lock; // This used by Innodb.
479
 
 
480
 
  void resetUserTime()
481
 
  {
482
 
    _user_time= boost::posix_time::not_a_date_time;
483
 
  }
484
 
 
485
 
  const boost::posix_time::ptime &start_timer() const
486
 
  {
487
 
    return _start_timer;
488
 
  }
489
 
 
490
 
  void getTimeDifference(boost::posix_time::time_duration &result_arg, const boost::posix_time::ptime &arg) const
491
 
  {
492
 
    result_arg=  arg - _start_timer;
493
 
  }
 
662
  time_t start_time;
 
663
  time_t user_time;
 
664
  uint64_t thr_create_utime; /**< track down slow pthread_create */
 
665
  uint64_t start_utime;
 
666
  uint64_t utime_after_lock;
494
667
 
495
668
  thr_lock_type update_lock_default;
496
669
 
511
684
  */
512
685
  query_id_t query_id;
513
686
  query_id_t warn_query_id;
514
 
 
515
687
public:
516
688
  void **getEngineData(const plugin::MonitoredInTransaction *monitored);
517
689
  ResourceContext *getResourceContext(const plugin::MonitoredInTransaction *monitored,
518
690
                                      size_t index= 0);
519
691
 
520
 
  session::Transactions transaction;
 
692
  /**
 
693
   * Structure used to manage "statement transactions" and
 
694
   * "normal transactions". In autocommit mode, the normal transaction is
 
695
   * equivalent to the statement transaction.
 
696
   *
 
697
   * Storage engines will be registered here when they participate in
 
698
   * a transaction. No engine is registered more than once.
 
699
   */
 
700
  struct st_transactions {
 
701
    std::deque<NamedSavepoint> savepoints;
 
702
 
 
703
    /**
 
704
     * The normal transaction (since BEGIN WORK).
 
705
     *
 
706
     * Contains a list of all engines that have participated in any of the
 
707
     * statement transactions started within the context of the normal
 
708
     * transaction.
 
709
     *
 
710
     * @note In autocommit mode, this is empty.
 
711
     */
 
712
    TransactionContext all;
 
713
 
 
714
    /**
 
715
     * The statment transaction.
 
716
     *
 
717
     * Contains a list of all engines participating in the given statement.
 
718
     *
 
719
     * @note In autocommit mode, this will be used to commit/rollback the
 
720
     * normal transaction.
 
721
     */
 
722
    TransactionContext stmt;
 
723
 
 
724
    XID_STATE xid_state;
 
725
 
 
726
    void cleanup()
 
727
    {
 
728
      savepoints.clear();
 
729
    }
 
730
    st_transactions() :
 
731
      savepoints(),
 
732
      all(),
 
733
      stmt(),
 
734
      xid_state()
 
735
    { }
 
736
  } transaction;
521
737
 
522
738
  Field *dup_field;
523
739
  sigset_t signals;
525
741
  // As of right now we do not allow a concurrent execute to launch itself
526
742
private:
527
743
  bool concurrent_execute_allowed;
528
 
 
529
744
public:
530
745
 
531
746
  void setConcurrentExecute(bool arg)
594
809
  uint64_t limit_found_rows;
595
810
  uint64_t options; /**< Bitmap of options */
596
811
  int64_t row_count_func; /**< For the ROW_COUNT() function */
597
 
 
598
 
  int64_t rowCount() const
599
 
  {
600
 
    return row_count_func;
601
 
  }
602
 
 
603
812
  ha_rows cuted_fields; /**< Count of "cut" or truncated fields. @todo Kill this friggin thing. */
604
813
 
605
814
  /** 
677
886
    _global_read_lock= arg;
678
887
  }
679
888
 
680
 
  DrizzleLock *lockTables(Table **tables, uint32_t count, uint32_t flags);
 
889
  DrizzleLock *lockTables(Table **tables, uint32_t count, uint32_t flags, bool *need_reopen);
681
890
  bool lockGlobalReadLock();
682
891
  bool lock_table_names(TableList *table_list);
683
892
  bool lock_table_names_exclusively(TableList *table_list);
770
979
  bool substitute_null_with_insert_id;
771
980
  bool cleanup_done;
772
981
 
773
 
private:
774
982
  bool abort_on_warning;
775
 
  bool tablespace_op; /**< This is true in DISCARD/IMPORT TABLESPACE */
776
 
 
777
 
public:
778
983
  bool got_warning; /**< Set on call to push_warning() */
779
984
  bool no_warnings_for_error; /**< no warnings on call to my_error() */
780
985
  /** set during loop of derived table processing */
781
986
  bool derived_tables_processing;
782
 
 
783
 
  bool doing_tablespace_operation(void)
784
 
  {
785
 
    return tablespace_op;
786
 
  }
787
 
 
788
 
  void setDoingTablespaceOperation(bool doing)
789
 
  {
790
 
    tablespace_op= doing;
791
 
  }
792
 
 
 
987
  bool tablespace_op; /**< This is true in DISCARD/IMPORT TABLESPACE */
793
988
 
794
989
  /** Used by the sys_var class to store temporary values */
795
990
  union
931
1126
    auto_inc_intervals_forced.append(next_id, UINT64_MAX, 0);
932
1127
  }
933
1128
 
934
 
  Session(plugin::Client *client_arg, catalog::Instance::shared_ptr catalog);
 
1129
  Session(plugin::Client *client_arg);
935
1130
  virtual ~Session();
936
1131
 
937
1132
  void cleanup(void);
1014
1209
  bool endTransaction(enum enum_mysql_completiontype completion);
1015
1210
  bool endActiveTransaction();
1016
1211
  bool startTransaction(start_transaction_option_t opt= START_TRANS_NO_OPTIONS);
1017
 
  void markTransactionForRollback(bool all);
1018
1212
 
1019
1213
  /**
1020
1214
   * Authenticates users, with error reporting.
1046
1240
  const char* enter_cond(boost::condition_variable_any &cond, boost::mutex &mutex, const char* msg);
1047
1241
  void exit_cond(const char* old_msg);
1048
1242
 
1049
 
  type::Time::epoch_t query_start()
1050
 
  {
1051
 
    return getCurrentTimestampEpoch();
1052
 
  }
1053
 
 
1054
 
  void set_time()
1055
 
  {
1056
 
    _end_timer= _start_timer= boost::posix_time::microsec_clock::universal_time();
1057
 
    utime_after_lock= (_start_timer - _epoch).total_microseconds();
1058
 
  }
1059
 
 
1060
 
  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
1061
 
  {
1062
 
    _user_time= boost::posix_time::from_time_t(t);
1063
 
  }
1064
 
 
1065
 
  void set_time_after_lock()
1066
 
  { 
1067
 
    boost::posix_time::ptime mytime(boost::posix_time::microsec_clock::universal_time());
1068
 
    utime_after_lock= (mytime - _epoch).total_microseconds();
1069
 
  }
1070
 
 
1071
 
  void set_end_timer()
1072
 
  {
1073
 
    _end_timer= boost::posix_time::microsec_clock::universal_time();
1074
 
    status_var.execution_time_nsec+=(_end_timer - _start_timer).total_microseconds();
1075
 
  }
1076
 
 
1077
 
  uint64_t getElapsedTime() const
1078
 
  {
1079
 
    return (_end_timer - _start_timer).total_microseconds();
1080
 
  }
1081
 
 
 
1243
  inline time_t query_start() { return start_time; }
 
1244
  inline void set_time()
 
1245
  {
 
1246
    boost::posix_time::ptime mytime(boost::posix_time::microsec_clock::local_time());
 
1247
    boost::posix_time::ptime epoch(boost::gregorian::date(1970,1,1));
 
1248
    start_utime= utime_after_lock= (mytime-epoch).total_microseconds();
 
1249
 
 
1250
    if (user_time)
 
1251
    {
 
1252
      start_time= user_time;
 
1253
      connect_microseconds= start_utime;
 
1254
    }
 
1255
    else 
 
1256
      start_time= (mytime-epoch).total_seconds();
 
1257
  }
 
1258
  inline void   set_current_time()    { start_time= time(NULL); }
 
1259
  inline void   set_time(time_t t)
 
1260
  {
 
1261
    start_time= user_time= t;
 
1262
    boost::posix_time::ptime mytime(boost::posix_time::microsec_clock::local_time());
 
1263
    boost::posix_time::ptime epoch(boost::gregorian::date(1970,1,1));
 
1264
    uint64_t t_mark= (mytime-epoch).total_microseconds();
 
1265
 
 
1266
    start_utime= utime_after_lock= t_mark;
 
1267
  }
 
1268
  void set_time_after_lock()  { 
 
1269
     boost::posix_time::ptime mytime(boost::posix_time::microsec_clock::local_time());
 
1270
     boost::posix_time::ptime epoch(boost::gregorian::date(1970,1,1));
 
1271
     utime_after_lock= (mytime-epoch).total_microseconds();
 
1272
  }
1082
1273
  /**
1083
1274
   * Returns the current micro-timestamp
1084
1275
   */
1085
 
  type::Time::epoch_t getCurrentTimestamp(bool actual= true) const
 
1276
  inline uint64_t getCurrentTimestamp()  
1086
1277
  { 
1087
 
    type::Time::epoch_t t_mark;
1088
 
 
1089
 
    if (actual)
1090
 
    {
1091
 
      boost::posix_time::ptime mytime(boost::posix_time::microsec_clock::universal_time());
1092
 
      t_mark= (mytime - _epoch).total_microseconds();
1093
 
    }
1094
 
    else
1095
 
    {
1096
 
      t_mark= (_end_timer - _epoch).total_microseconds();
1097
 
    }
 
1278
    boost::posix_time::ptime mytime(boost::posix_time::microsec_clock::local_time());
 
1279
    boost::posix_time::ptime epoch(boost::gregorian::date(1970,1,1));
 
1280
    uint64_t t_mark= (mytime-epoch).total_microseconds();
1098
1281
 
1099
1282
    return t_mark; 
1100
1283
  }
1101
 
 
1102
 
  // We may need to set user on this
1103
 
  type::Time::epoch_t getCurrentTimestampEpoch() const
1104
 
  { 
1105
 
    if (not _user_time.is_not_a_date_time())
1106
 
      return (_user_time - _epoch).total_seconds();
1107
 
 
1108
 
    return (_start_timer - _epoch).total_seconds();
1109
 
  }
1110
 
 
1111
 
  type::Time::epoch_t getCurrentTimestampEpoch(type::Time::usec_t &fraction_arg) const
1112
 
  { 
1113
 
    if (not _user_time.is_not_a_date_time())
1114
 
    {
1115
 
      fraction_arg= 0;
1116
 
      return (_user_time - _epoch).total_seconds();
1117
 
    }
1118
 
 
1119
 
    fraction_arg= _start_timer.time_of_day().fractional_seconds() % 1000000;
1120
 
    return (_start_timer - _epoch).total_seconds();
1121
 
  }
1122
 
 
1123
 
  uint64_t found_rows(void) const
 
1284
  inline uint64_t found_rows(void)
1124
1285
  {
1125
1286
    return limit_found_rows;
1126
1287
  }
1127
 
 
1128
1288
  /** Returns whether the session is currently inside a transaction */
1129
 
  bool inTransaction() const
 
1289
  inline bool inTransaction()
1130
1290
  {
1131
1291
    return server_status & SERVER_STATUS_IN_TRANS;
1132
1292
  }
1133
 
 
1134
1293
  LEX_STRING *make_lex_string(LEX_STRING *lex_str,
1135
1294
                              const char* str, uint32_t length,
1136
1295
                              bool allocate_lex_string);
1137
 
 
1138
1296
  LEX_STRING *make_lex_string(LEX_STRING *lex_str,
1139
1297
                              const std::string &str,
1140
1298
                              bool allocate_lex_string);
1141
1299
 
1142
1300
  int send_explain_fields(select_result *result);
1143
 
 
1144
1301
  /**
1145
1302
    Clear the current error, if any.
1146
1303
    We do not clear is_fatal_error or is_fatal_sub_stmt_error since we
1210
1367
  }
1211
1368
  void send_kill_message() const;
1212
1369
  /* return true if we will abort query if we make a warning now */
1213
 
  inline bool abortOnWarning()
1214
 
  {
1215
 
    return abort_on_warning;
1216
 
  }
1217
 
 
1218
 
  inline void setAbortOnWarning(bool arg)
1219
 
  {
1220
 
    abort_on_warning= arg;
 
1370
  inline bool really_abort_on_warning()
 
1371
  {
 
1372
    return (abort_on_warning);
1221
1373
  }
1222
1374
 
1223
1375
  void setAbort(bool arg);
1263
1415
    @param level the error level
1264
1416
    @return true if the error is handled
1265
1417
  */
1266
 
  virtual bool handle_error(drizzled::error_t sql_errno, const char *message,
 
1418
  virtual bool handle_error(uint32_t sql_errno, const char *message,
1267
1419
                            DRIZZLE_ERROR::enum_warning_level level);
1268
1420
 
1269
1421
  /**
1294
1446
   *
1295
1447
   * @note  For the connection that is doing shutdown, this is called twice
1296
1448
   */
1297
 
  void disconnect(enum error_t errcode= EE_OK);
 
1449
  void disconnect(enum drizzled_error_code errcode= EE_OK);
1298
1450
 
1299
1451
  /**
1300
1452
   * Check if user exists and the password supplied is correct.
1314
1466
   * Returns the timestamp (in microseconds) of when the Session 
1315
1467
   * connected to the server.
1316
1468
   */
1317
 
  uint64_t getConnectMicroseconds() const
1318
 
  {
1319
 
    return (_connect_time - _epoch).total_microseconds();
1320
 
  }
1321
 
 
1322
 
  uint64_t getConnectSeconds() const
1323
 
  {
1324
 
    return (_connect_time - _epoch).total_seconds();
 
1469
  inline uint64_t getConnectMicroseconds() const
 
1470
  {
 
1471
    return connect_microseconds;
1325
1472
  }
1326
1473
 
1327
1474
  /**
1442
1589
  
1443
1590
  
1444
1591
 private:
 
1592
 /** Microsecond timestamp of when Session connected */
 
1593
  uint64_t connect_microseconds;
1445
1594
  const char *proc_info;
1446
1595
 
1447
1596
  /** The current internal error handler for this thread, or NULL. */
1534
1683
  void close_old_data_files(bool morph_locks= false,
1535
1684
                            bool send_refresh= false);
1536
1685
  void close_open_tables();
1537
 
  void close_data_files_and_morph_locks(const identifier::Table &identifier);
 
1686
  void close_data_files_and_morph_locks(const TableIdentifier &identifier);
1538
1687
 
1539
1688
private:
1540
 
  bool free_cached_table(boost::mutex::scoped_lock &scopedLock);
1541
 
 
 
1689
  bool free_cached_table();
1542
1690
public:
1543
1691
 
1544
1692
  /**
1572
1720
  Table *openTable(TableList *table_list, bool *refresh, uint32_t flags= 0);
1573
1721
 
1574
1722
  void unlink_open_table(Table *find);
1575
 
  void drop_open_table(Table *table, const identifier::Table &identifier);
 
1723
  void drop_open_table(Table *table, const TableIdentifier &identifier);
1576
1724
  void close_cached_table(Table *table);
1577
1725
 
1578
1726
  /* Create a lock in the cache */
1579
 
  table::Placeholder *table_cache_insert_placeholder(const identifier::Table &identifier);
1580
 
  bool lock_table_name_if_not_cached(const identifier::Table &identifier, Table **table);
1581
 
 
 
1727
  table::Placeholder *table_cache_insert_placeholder(const TableIdentifier &identifier);
 
1728
  bool lock_table_name_if_not_cached(const TableIdentifier &identifier, Table **table);
 
1729
 
 
1730
  typedef boost::unordered_map<std::string, message::Table, util::insensitive_hash, util::insensitive_equal_to> TableMessageCache;
 
1731
 
 
1732
  class TableMessages
 
1733
  {
 
1734
    TableMessageCache table_message_cache;
 
1735
 
 
1736
  public:
 
1737
    bool storeTableMessage(const TableIdentifier &identifier, message::Table &table_message);
 
1738
    bool removeTableMessage(const TableIdentifier &identifier);
 
1739
    bool getTableMessage(const TableIdentifier &identifier, message::Table &table_message);
 
1740
    bool doesTableMessageExist(const TableIdentifier &identifier);
 
1741
    bool renameTableMessage(const TableIdentifier &from, const TableIdentifier &to);
 
1742
 
 
1743
  };
1582
1744
private:
1583
 
  session::TableMessages _table_message_cache;
 
1745
  TableMessages _table_message_cache;
1584
1746
 
1585
1747
public:
1586
 
  session::TableMessages &getMessageCache()
 
1748
  TableMessages &getMessageCache()
1587
1749
  {
1588
1750
    return _table_message_cache;
1589
1751
  }
1590
1752
 
1591
1753
  /* Reopen operations */
1592
 
  bool reopen_tables();
 
1754
  bool reopen_tables(bool get_locks, bool mark_share_as_old);
1593
1755
  bool close_cached_tables(TableList *tables, bool wait_for_refresh, bool wait_for_placeholders);
1594
1756
 
1595
1757
  void wait_for_condition(boost::mutex &mutex, boost::condition_variable_any &cond);
1598
1760
 
1599
1761
  drizzled::util::Storable *getProperty(const std::string &arg)
1600
1762
  {
1601
 
    return life_properties.getProperty(arg);
 
1763
    return life_properties[arg];
1602
1764
  }
1603
1765
 
1604
1766
  template<class T>
1605
1767
  bool setProperty(const std::string &arg, T *value)
1606
1768
  {
1607
 
    life_properties.setProperty(arg, value);
 
1769
    life_properties[arg]= value;
1608
1770
 
1609
1771
    return true;
1610
1772
  }
1624
1786
    return global_system_variables.storage_engine;
1625
1787
  }
1626
1788
 
1627
 
  void get_xid(DrizzleXid *xid); // Innodb only
 
1789
  void get_xid(DRIZZLE_XID *xid); // Innodb only
1628
1790
 
1629
 
  table::Singular *getInstanceTable();
1630
 
  table::Singular *getInstanceTable(List<CreateField> &field_list);
 
1791
  table::Instance *getInstanceTable();
 
1792
  table::Instance *getInstanceTable(List<CreateField> &field_list);
1631
1793
 
1632
1794
private:
1633
1795
  bool resetUsage()
1639
1801
 
1640
1802
    return true;
1641
1803
  }
1642
 
 
1643
1804
public:
1644
1805
 
1645
1806
  void setUsage(bool arg)
1652
1813
    return usage;
1653
1814
  }
1654
1815
 
1655
 
  catalog::Instance::const_reference catalog() const
1656
 
  {
1657
 
    return *(_catalog.get());
1658
 
  }
1659
 
 
1660
 
  catalog::Instance::reference catalog()
1661
 
  {
1662
 
    return *(_catalog.get());
1663
 
  }
1664
 
 
1665
1816
private:
1666
 
  catalog::Instance::shared_ptr _catalog;
1667
 
 
1668
1817
  // This lives throughout the life of Session
1669
1818
  bool use_usage;
1670
 
  session::PropertyMap life_properties;
1671
 
  std::vector<table::Singular *> temporary_shares;
 
1819
  PropertyMap life_properties;
 
1820
  std::vector<table::Instance *> temporary_shares;
1672
1821
  struct rusage usage;
1673
1822
};
1674
1823
 
 
1824
class Join;
 
1825
 
1675
1826
#define ESCAPE_CHARS "ntrb0ZN" // keep synchronous with READ_INFO::unescape
1676
1827
 
 
1828
} /* namespace drizzled */
 
1829
 
 
1830
/** @TODO why is this in the middle of the file */
 
1831
#include <drizzled/select_to_file.h>
 
1832
#include <drizzled/select_export.h>
 
1833
#include <drizzled/select_dump.h>
 
1834
#include <drizzled/select_insert.h>
 
1835
#include <drizzled/select_create.h>
 
1836
#include <drizzled/tmp_table_param.h>
 
1837
#include <drizzled/select_union.h>
 
1838
#include <drizzled/select_subselect.h>
 
1839
#include <drizzled/select_singlerow_subselect.h>
 
1840
#include <drizzled/select_max_min_finder_subselect.h>
 
1841
#include <drizzled/select_exists_subselect.h>
 
1842
 
 
1843
namespace drizzled
 
1844
{
 
1845
 
 
1846
/**
 
1847
 * A structure used to describe sort information
 
1848
 * for a field or item used in ORDER BY.
 
1849
 */
 
1850
class SortField 
 
1851
{
 
1852
public:
 
1853
  Field *field; /**< Field to sort */
 
1854
  Item  *item; /**< Item if not sorting fields */
 
1855
  size_t length; /**< Length of sort field */
 
1856
  uint32_t suffix_length; /**< Length suffix (0-4) */
 
1857
  Item_result result_type; /**< Type of item */
 
1858
  bool reverse; /**< if descending sort */
 
1859
  bool need_strxnfrm;   /**< If we have to use strxnfrm() */
 
1860
 
 
1861
  SortField() :
 
1862
    field(0),
 
1863
    item(0),
 
1864
    length(0),
 
1865
    suffix_length(0),
 
1866
    result_type(STRING_RESULT),
 
1867
    reverse(0),
 
1868
    need_strxnfrm(0)
 
1869
  { }
 
1870
 
 
1871
};
 
1872
 
 
1873
} /* namespace drizzled */
 
1874
 
 
1875
/** @TODO why is this in the middle of the file */
 
1876
 
 
1877
#include <drizzled/table_ident.h>
 
1878
#include <drizzled/user_var_entry.h>
 
1879
#include <drizzled/unique.h>
 
1880
#include <drizzled/var.h>
 
1881
#include <drizzled/select_dumpvar.h>
 
1882
 
 
1883
namespace drizzled
 
1884
{
 
1885
 
1677
1886
/* Bits in sql_command_flags */
1678
1887
 
1679
1888
enum sql_command_flag_bits 
1695
1904
namespace display  {
1696
1905
const std::string &type(drizzled::Session::global_read_lock_t type);
1697
1906
size_t max_string_length(drizzled::Session::global_read_lock_t type);
1698
 
 
1699
1907
} /* namespace display */
1700
1908
 
1701
1909
} /* namespace drizzled */