~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/session.h

  • Committer: Padraig O'Sullivan
  • Date: 2010-12-03 19:16:09 UTC
  • mto: (1975.1.2 build)
  • mto: This revision was merged to the branch mainline in revision 1976.
  • Revision ID: osullivan.padraig@gmail.com-20101203191609-7s81iwt33vrgmz9v
Some re-factoring based on feedback from Monty on IRC.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
3
 *
4
 
 *  Copyright (C) 2008 Sun Microsystems, Inc.
 
4
 *  Copyright (C) 2008 Sun Microsystems
5
5
 *
6
6
 *  This program is free software; you can redistribute it and/or modify
7
7
 *  it under the terms of the GNU General Public License as published by
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
 
23
 
#include <algorithm>
 
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
 
 
41
#include <netdb.h>
 
42
#include <sys/time.h>
 
43
#include <sys/resource.h>
 
44
 
 
45
#include <map>
 
46
#include <string>
24
47
#include <bitset>
25
 
#include <boost/make_shared.hpp>
26
 
#include <boost/thread/condition_variable.hpp>
 
48
#include <deque>
 
49
 
 
50
#include "drizzled/security_context.h"
 
51
#include "drizzled/open_tables_state.h"
 
52
#include "drizzled/internal_error_handler.h"
 
53
#include "drizzled/diagnostics_area.h"
 
54
#include "drizzled/plugin/authorization.h"
 
55
 
 
56
#include <boost/unordered_map.hpp>
 
57
 
 
58
#include <boost/thread/thread.hpp>
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>
35
 
 
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>
 
61
#include <boost/thread/condition_variable.hpp>
68
62
 
69
63
#define MIN_HANDSHAKE_SIZE      6
70
64
 
85
79
class Resultset;
86
80
}
87
81
 
88
 
namespace internal { struct st_my_thread_var; }
89
 
namespace table { class Placeholder; }
90
 
 
 
82
namespace internal
 
83
{
 
84
struct st_my_thread_var;
 
85
}
 
86
 
 
87
namespace table
 
88
{
 
89
class Placeholder;
 
90
}
 
91
 
 
92
class Lex_input_stream;
 
93
class user_var_entry;
91
94
class CopyField;
92
 
class DrizzleXid;
93
 
class Internal_error_handler;
94
 
class Lex_input_stream;
 
95
class Table_ident;
 
96
 
95
97
class TableShareInstance;
96
 
class Table_ident;
97
 
class Time_zone;
98
 
class select_result;
99
 
class user_var_entry;
100
98
 
101
99
extern char internal_table_name[2];
102
100
extern char empty_c_string[1];
106
104
#define TC_HEURISTIC_RECOVER_ROLLBACK 2
107
105
extern uint32_t tc_heuristic_recover;
108
106
 
 
107
/**
 
108
  @brief
 
109
  Local storage for proto that are tmp table. This should be enlarged
 
110
  to hande the entire table-share for a local table. Once Hash is done,
 
111
  we should consider exchanging the map for it.
 
112
*/
 
113
typedef std::map <std::string, message::Table> ProtoCache;
 
114
 
 
115
/**
 
116
  The COPY_INFO structure is used by INSERT/REPLACE code.
 
117
  The schema of the row counting by the INSERT/INSERT ... ON DUPLICATE KEY
 
118
  UPDATE code:
 
119
    If a row is inserted then the copied variable is incremented.
 
120
    If a row is updated by the INSERT ... ON DUPLICATE KEY UPDATE and the
 
121
      new data differs from the old one then the copied and the updated
 
122
      variables are incremented.
 
123
    The touched variable is incremented if a row was touched by the update part
 
124
      of the INSERT ... ON DUPLICATE KEY UPDATE no matter whether the row
 
125
      was actually changed or not.
 
126
*/
 
127
class CopyInfo 
 
128
{
 
129
public:
 
130
  ha_rows records; /**< Number of processed records */
 
131
  ha_rows deleted; /**< Number of deleted records */
 
132
  ha_rows updated; /**< Number of updated records */
 
133
  ha_rows copied;  /**< Number of copied records */
 
134
  ha_rows error_count;
 
135
  ha_rows touched; /* Number of touched records */
 
136
  enum enum_duplicates handle_duplicates;
 
137
  int escape_char, last_errno;
 
138
  bool ignore;
 
139
  /* for INSERT ... UPDATE */
 
140
  List<Item> *update_fields;
 
141
  List<Item> *update_values;
 
142
  /* for VIEW ... WITH CHECK OPTION */
 
143
 
 
144
  CopyInfo() :
 
145
    records(0),
 
146
    deleted(0),
 
147
    updated(0),
 
148
    copied(0),
 
149
    error_count(0),
 
150
    touched(0),
 
151
    escape_char(0),
 
152
    last_errno(0),
 
153
    ignore(0),
 
154
    update_fields(0),
 
155
    update_values(0)
 
156
  { }
 
157
 
 
158
};
 
159
 
 
160
} /* namespace drizzled */
 
161
 
 
162
/** @TODO why is this in the middle of the file */
 
163
#include <drizzled/lex_column.h>
 
164
 
 
165
namespace drizzled
 
166
{
 
167
 
 
168
class select_result;
 
169
class Time_zone;
 
170
 
109
171
#define Session_SENTRY_MAGIC 0xfeedd1ff
110
172
#define Session_SENTRY_GONE  0xdeadbeef
111
173
 
112
 
extern DRIZZLED_API struct drizzle_system_variables global_system_variables;
 
174
struct drizzle_system_variables
 
175
{
 
176
  drizzle_system_variables()
 
177
  {}
 
178
  /*
 
179
    How dynamically allocated system variables are handled:
 
180
 
 
181
    The global_system_variables and max_system_variables are "authoritative"
 
182
    They both should have the same 'version' and 'size'.
 
183
    When attempting to access a dynamic variable, if the session version
 
184
    is out of date, then the session version is updated and realloced if
 
185
    neccessary and bytes copied from global to make up for missing data.
 
186
  */
 
187
  ulong dynamic_variables_version;
 
188
  char * dynamic_variables_ptr;
 
189
  uint32_t dynamic_variables_head;  /* largest valid variable offset */
 
190
  uint32_t dynamic_variables_size;  /* how many bytes are in use */
 
191
 
 
192
  uint64_t myisam_max_extra_sort_file_size;
 
193
  uint64_t max_heap_table_size;
 
194
  uint64_t tmp_table_size;
 
195
  ha_rows select_limit;
 
196
  ha_rows max_join_size;
 
197
  uint64_t auto_increment_increment;
 
198
  uint64_t auto_increment_offset;
 
199
  uint64_t bulk_insert_buff_size;
 
200
  uint64_t join_buff_size;
 
201
  uint32_t max_allowed_packet;
 
202
  uint64_t max_error_count;
 
203
  uint64_t max_length_for_sort_data;
 
204
  size_t max_sort_length;
 
205
  uint64_t min_examined_row_limit;
 
206
  bool optimizer_prune_level;
 
207
  bool log_warnings;
 
208
 
 
209
  uint32_t optimizer_search_depth;
 
210
  uint32_t div_precincrement;
 
211
  uint64_t preload_buff_size;
 
212
  uint32_t read_buff_size;
 
213
  uint32_t read_rnd_buff_size;
 
214
  bool replicate_query;
 
215
  size_t sortbuff_size;
 
216
  uint32_t thread_handling;
 
217
  uint32_t tx_isolation;
 
218
  size_t transaction_message_threshold;
 
219
  uint32_t completion_type;
 
220
  /* Determines which non-standard SQL behaviour should be enabled */
 
221
  uint32_t sql_mode;
 
222
  uint64_t max_seeks_for_key;
 
223
  size_t range_alloc_block_size;
 
224
  uint32_t query_alloc_block_size;
 
225
  uint32_t query_prealloc_size;
 
226
  uint64_t group_concat_max_len;
 
227
  uint64_t pseudo_thread_id;
 
228
 
 
229
  plugin::StorageEngine *storage_engine;
 
230
 
 
231
  /* Only charset part of these variables is sensible */
 
232
  const CHARSET_INFO  *character_set_filesystem;
 
233
 
 
234
  /* Both charset and collation parts of these variables are important */
 
235
  const CHARSET_INFO    *collation_server;
 
236
 
 
237
  inline const CHARSET_INFO  *getCollation(void) 
 
238
  {
 
239
    return collation_server;
 
240
  }
 
241
 
 
242
  /* Locale Support */
 
243
  MY_LOCALE *lc_time_names;
 
244
 
 
245
  Time_zone *time_zone;
 
246
};
 
247
 
 
248
extern struct drizzle_system_variables global_system_variables;
 
249
 
 
250
} /* namespace drizzled */
 
251
 
 
252
#include "drizzled/sql_lex.h"
 
253
 
 
254
namespace drizzled
 
255
{
 
256
 
 
257
void mark_transaction_to_rollback(Session *session, bool all);
 
258
 
 
259
/**
 
260
  Storage engine specific thread local data.
 
261
*/
 
262
struct Ha_data
 
263
{
 
264
  /**
 
265
    Storage engine specific thread local data.
 
266
    Lifetime: one user connection.
 
267
  */
 
268
  void *ha_ptr;
 
269
  /**
 
270
   * Resource contexts for both the "statement" and "normal"
 
271
   * transactions.
 
272
   *
 
273
   * Resource context at index 0:
 
274
   *
 
275
   * Life time: one statement within a transaction. If @@autocommit is
 
276
   * on, also represents the entire transaction.
 
277
   *
 
278
   * Resource context at index 1:
 
279
   *
 
280
   * Life time: one transaction within a connection. 
 
281
   *
 
282
   * @note
 
283
   *
 
284
   * If the storage engine does not participate in a transaction, 
 
285
   * there will not be a resource context.
 
286
   */
 
287
  drizzled::ResourceContext resource_context[2];
 
288
 
 
289
  Ha_data() :ha_ptr(NULL) {}
 
290
};
113
291
 
114
292
/**
115
293
 * Represents a client connection to the database server.
130
308
 * all member variables that are not critical to non-internal operations of the
131
309
 * session object.
132
310
 */
 
311
typedef int64_t session_id_t;
133
312
 
134
 
class DRIZZLED_API Session : public Open_tables_state
 
313
class Session : public Open_tables_state
135
314
{
136
315
public:
137
316
  // Plugin storage in Session.
 
317
  typedef boost::unordered_map<std::string, util::Storable *, util::insensitive_hash, util::insensitive_equal_to> PropertyMap;
 
318
  typedef Session* Ptr;
138
319
  typedef boost::shared_ptr<Session> shared_ptr;
139
 
  typedef Session& reference;
140
 
  typedef const Session& const_reference;
141
 
  typedef const Session* const_pointer;
142
 
  typedef Session* pointer;
143
 
 
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
320
 
150
321
  /*
151
322
    MARK_COLUMNS_NONE:  Means mark_used_colums is not set and no indicator to
159
330
                        and update_row.
160
331
  */
161
332
  enum enum_mark_columns mark_used_columns;
 
333
  inline void* alloc(size_t size)
 
334
  {
 
335
    return mem_root->alloc_root(size);
 
336
  }
162
337
  inline void* calloc(size_t size)
163
338
  {
164
339
    void *ptr;
166
341
      memset(ptr, 0, size);
167
342
    return ptr;
168
343
  }
 
344
  inline char *strdup(const char *str)
 
345
  {
 
346
    return mem_root->strdup_root(str);
 
347
  }
169
348
  inline char *strmake(const char *str, size_t size)
170
349
  {
171
350
    return mem_root->strmake_root(str,size);
172
351
  }
173
 
 
 
352
  inline void *memdup(const void *str, size_t size)
 
353
  {
 
354
    return mem_root->memdup_root(str, size);
 
355
  }
174
356
  inline void *memdup_w_gap(const void *str, size_t size, uint32_t gap)
175
357
  {
176
358
    void *ptr;
180
362
  }
181
363
  /** Frees all items attached to this Statement */
182
364
  void free_items();
183
 
 
184
365
  /**
185
366
   * List of items created in the parser for this query. Every item puts
186
367
   * itself to the list on creation (see Item::Item() for details))
213
394
   * @todo should be const
214
395
   */
215
396
  uint32_t id;
216
 
private:
217
397
  LEX *lex; /**< parse tree descriptor */
218
398
 
219
 
public:
220
399
  LEX *getLex() 
221
400
  {
222
401
    return lex;
223
402
  }
224
 
 
225
 
  enum_sql_command getSqlCommand() const
226
 
  {
227
 
    return lex->sql_command;
228
 
  }
229
 
 
230
403
  /** query associated with this statement */
231
404
  typedef boost::shared_ptr<const std::string> QueryString;
232
 
 
233
405
private:
234
406
  boost::shared_ptr<std::string> query;
235
407
 
244
416
 
245
417
  void resetQueryString()
246
418
  {
247
 
    query.reset();
248
 
    _state.reset();
 
419
    return query.reset(new std::string);
249
420
  }
250
421
 
251
422
  /*
257
428
  {
258
429
    QueryString tmp_string(getQueryString());
259
430
 
260
 
    if (not tmp_string)
261
 
    {
262
 
      length= 0;
263
 
      return NULL;
264
 
    }
265
 
 
266
431
    length= tmp_string->length();
267
432
    char *to_return= strmake(tmp_string->c_str(), tmp_string->length());
268
433
    return to_return;
269
434
  }
270
435
 
271
 
private:
272
 
  session::State::shared_ptr  _state; 
273
 
 
274
 
public:
275
 
 
276
 
  session::State::const_shared_ptr state()
277
 
  {
278
 
    return _state;
279
 
  }
280
 
 
281
436
  /**
282
437
    Name of the current (default) database.
283
438
 
290
445
    the Session of that thread); that thread is (and must remain, for now) the
291
446
    only responsible for freeing this member.
292
447
  */
293
 
private:
294
 
  util::string::shared_ptr _schema;
295
 
 
296
 
public:
297
 
 
298
 
  util::string::const_shared_ptr schema() const
 
448
  std::string db;
 
449
 
 
450
  const std::string &getSchema() const
299
451
  {
300
 
    if (_schema)
301
 
      return _schema;
302
 
 
303
 
    return util::string::const_shared_ptr(new std::string(""));
 
452
    return db;
304
453
  }
305
 
 
 
454
  std::string catalog;
306
455
  /* current cache key */
307
456
  std::string query_cache_key;
308
457
  /**
314
463
  static const char * const DEFAULT_WHERE;
315
464
 
316
465
  memory::Root warn_root; /**< Allocation area for warnings and errors */
317
 
private:
318
466
  plugin::Client *client; /**< Pointer to client object */
319
467
 
320
 
public:
321
 
 
322
468
  void setClient(plugin::Client *client_arg);
323
469
 
324
470
  plugin::Client *getClient()
326
472
    return client;
327
473
  }
328
474
 
329
 
  plugin::Client *getClient() const
330
 
  {
331
 
    return client;
332
 
  }
333
 
 
334
475
  plugin::Scheduler *scheduler; /**< Pointer to scheduler object */
335
476
  void *scheduler_arg; /**< Pointer to the optional scheduler argument */
336
477
 
337
478
  typedef boost::unordered_map< std::string, user_var_entry *, util::insensitive_hash, util::insensitive_equal_to> UserVars;
338
 
 
339
479
private:
340
480
  typedef std::pair< UserVars::iterator, UserVars::iterator > UserVarsRange;
341
481
  UserVars user_vars; /**< Hash of user variables defined during the session's lifetime */
342
482
 
343
483
public:
 
484
 
344
485
  const UserVars &getUserVariables() const
345
486
  {
346
487
    return user_vars;
347
488
  }
348
489
 
349
490
  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
491
  struct system_status_var status_var; /**< Session-local status counters */
357
492
  THR_LOCK_INFO lock_info; /**< Locking information for this session */
358
493
  THR_LOCK_OWNER main_lock_id; /**< To use for conventional queries */
365
500
  char *thread_stack;
366
501
 
367
502
private:
368
 
  identifier::User::shared_ptr security_ctx;
 
503
  SecurityContext security_ctx;
369
504
 
370
505
  int32_t scoreboard_index;
371
506
 
373
508
  {
374
509
    assert(this->dbug_sentry == Session_SENTRY_MAGIC);
375
510
  }
376
 
 
377
511
public:
378
 
  identifier::User::const_shared_ptr user() const
 
512
  const SecurityContext& getSecurityContext() const
379
513
  {
380
 
    if (security_ctx)
381
 
      return security_ctx;
382
 
 
383
 
    return identifier::User::const_shared_ptr();
 
514
    return security_ctx;
384
515
  }
385
516
 
386
 
  void setUser(identifier::User::shared_ptr arg)
 
517
  SecurityContext& getSecurityContext()
387
518
  {
388
 
    security_ctx= arg;
 
519
    return security_ctx;
389
520
  }
390
521
 
391
522
  int32_t getScoreboardIndex()
401
532
  /**
402
533
   * Is this session viewable by the current user?
403
534
   */
404
 
  bool isViewable(identifier::User::const_reference) const;
 
535
  bool isViewable() const;
405
536
 
406
 
private:
407
537
  /**
408
538
    Used in error messages to tell user in what part of MySQL we found an
409
539
    error. E. g. when where= "having clause", if fix_fields() fails, user
410
540
    will know that the error was in having clause.
411
541
  */
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
 
  }
 
542
  const char *where;
424
543
 
425
544
  /*
426
545
    One thread can hold up to one named user-level lock. This variable
428
547
    chapter 'Miscellaneous functions', for functions GET_LOCK, RELEASE_LOCK.
429
548
  */
430
549
  uint32_t dbug_sentry; /**< watch for memory corruption */
431
 
 
432
550
private:
433
551
  boost::thread::id boost_thread_id;
434
552
  boost_thread_shared_ptr _thread;
435
553
  boost::this_thread::disable_interruption *interrupt;
436
554
 
437
555
  internal::st_my_thread_var *mysys_var;
 
556
public:
438
557
 
439
 
public:
440
558
  boost_thread_shared_ptr &getThread()
441
559
  {
442
560
    return _thread;
466
584
  uint32_t file_id;     /**< File ID for LOAD DATA INFILE */
467
585
  /* @note the following three members should likely move to Client */
468
586
  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
 
  }
 
587
  time_t start_time;
 
588
  time_t user_time;
 
589
  uint64_t thr_create_utime; /**< track down slow pthread_create */
 
590
  uint64_t start_utime;
 
591
  uint64_t utime_after_lock;
494
592
 
495
593
  thr_lock_type update_lock_default;
496
594
 
511
609
  */
512
610
  query_id_t query_id;
513
611
  query_id_t warn_query_id;
514
 
 
515
612
public:
516
613
  void **getEngineData(const plugin::MonitoredInTransaction *monitored);
517
614
  ResourceContext *getResourceContext(const plugin::MonitoredInTransaction *monitored,
518
615
                                      size_t index= 0);
519
616
 
520
 
  session::Transactions transaction;
 
617
  /**
 
618
   * Structure used to manage "statement transactions" and
 
619
   * "normal transactions". In autocommit mode, the normal transaction is
 
620
   * equivalent to the statement transaction.
 
621
   *
 
622
   * Storage engines will be registered here when they participate in
 
623
   * a transaction. No engine is registered more than once.
 
624
   */
 
625
  struct st_transactions {
 
626
    std::deque<NamedSavepoint> savepoints;
 
627
 
 
628
    /**
 
629
     * The normal transaction (since BEGIN WORK).
 
630
     *
 
631
     * Contains a list of all engines that have participated in any of the
 
632
     * statement transactions started within the context of the normal
 
633
     * transaction.
 
634
     *
 
635
     * @note In autocommit mode, this is empty.
 
636
     */
 
637
    TransactionContext all;
 
638
 
 
639
    /**
 
640
     * The statment transaction.
 
641
     *
 
642
     * Contains a list of all engines participating in the given statement.
 
643
     *
 
644
     * @note In autocommit mode, this will be used to commit/rollback the
 
645
     * normal transaction.
 
646
     */
 
647
    TransactionContext stmt;
 
648
 
 
649
    XID_STATE xid_state;
 
650
 
 
651
    void cleanup()
 
652
    {
 
653
      savepoints.clear();
 
654
    }
 
655
    st_transactions() :
 
656
      savepoints(),
 
657
      all(),
 
658
      stmt(),
 
659
      xid_state()
 
660
    { }
 
661
  } transaction;
521
662
 
522
663
  Field *dup_field;
523
664
  sigset_t signals;
525
666
  // As of right now we do not allow a concurrent execute to launch itself
526
667
private:
527
668
  bool concurrent_execute_allowed;
528
 
 
529
669
public:
530
670
 
531
671
  void setConcurrentExecute(bool arg)
594
734
  uint64_t limit_found_rows;
595
735
  uint64_t options; /**< Bitmap of options */
596
736
  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
737
  ha_rows cuted_fields; /**< Count of "cut" or truncated fields. @todo Kill this friggin thing. */
604
738
 
605
739
  /** 
648
782
    create_sort_index(); may differ from examined_row_count.
649
783
  */
650
784
  uint32_t row_count;
651
 
 
652
 
  uint32_t getRowCount() const
653
 
  {
654
 
    return row_count;
655
 
  }
656
 
 
657
785
  session_id_t thread_id;
658
786
  uint32_t tmp_table;
659
787
  enum global_read_lock_t
677
805
    _global_read_lock= arg;
678
806
  }
679
807
 
680
 
  DrizzleLock *lockTables(Table **tables, uint32_t count, uint32_t flags);
 
808
  DrizzleLock *lockTables(Table **tables, uint32_t count, uint32_t flags, bool *need_reopen);
681
809
  bool lockGlobalReadLock();
682
810
  bool lock_table_names(TableList *table_list);
683
811
  bool lock_table_names_exclusively(TableList *table_list);
736
864
    return &_killed;
737
865
  }
738
866
 
739
 
  bool is_admin_connection;
740
867
  bool some_tables_deleted;
741
868
  bool no_errors;
742
869
  bool password;
745
872
    can not continue. In particular, disables activation of
746
873
    CONTINUE or EXIT handlers of stored routines.
747
874
    Reset in the end of processing of the current user request, in
748
 
    @see reset_session_for_next_command().
 
875
    @see mysql_reset_session_for_next_command().
749
876
  */
750
877
  bool is_fatal_error;
751
878
  /**
770
897
  bool substitute_null_with_insert_id;
771
898
  bool cleanup_done;
772
899
 
773
 
private:
774
900
  bool abort_on_warning;
775
 
  bool tablespace_op; /**< This is true in DISCARD/IMPORT TABLESPACE */
776
 
 
777
 
public:
778
901
  bool got_warning; /**< Set on call to push_warning() */
779
902
  bool no_warnings_for_error; /**< no warnings on call to my_error() */
780
903
  /** set during loop of derived table processing */
781
904
  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
 
 
 
905
  bool tablespace_op; /**< This is true in DISCARD/IMPORT TABLESPACE */
793
906
 
794
907
  /** Used by the sys_var class to store temporary values */
795
908
  union
931
1044
    auto_inc_intervals_forced.append(next_id, UINT64_MAX, 0);
932
1045
  }
933
1046
 
934
 
  Session(plugin::Client *client_arg, catalog::Instance::shared_ptr catalog);
 
1047
  Session(plugin::Client *client_arg);
935
1048
  virtual ~Session();
936
1049
 
937
1050
  void cleanup(void);
1014
1127
  bool endTransaction(enum enum_mysql_completiontype completion);
1015
1128
  bool endActiveTransaction();
1016
1129
  bool startTransaction(start_transaction_option_t opt= START_TRANS_NO_OPTIONS);
1017
 
  void markTransactionForRollback(bool all);
1018
1130
 
1019
1131
  /**
1020
1132
   * Authenticates users, with error reporting.
1035
1147
   */
1036
1148
  static bool schedule(Session::shared_ptr&);
1037
1149
 
1038
 
  static void unlink(session_id_t &session_id);
1039
1150
  static void unlink(Session::shared_ptr&);
1040
1151
 
1041
1152
  /*
1046
1157
  const char* enter_cond(boost::condition_variable_any &cond, boost::mutex &mutex, const char* msg);
1047
1158
  void exit_cond(const char* old_msg);
1048
1159
 
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
 
 
 
1160
  inline time_t query_start() { return start_time; }
 
1161
  inline void set_time()
 
1162
  {
 
1163
    boost::posix_time::ptime mytime(boost::posix_time::microsec_clock::local_time());
 
1164
    boost::posix_time::ptime epoch(boost::gregorian::date(1970,1,1));
 
1165
    start_utime= utime_after_lock= (mytime-epoch).total_microseconds();
 
1166
 
 
1167
    if (user_time)
 
1168
    {
 
1169
      start_time= user_time;
 
1170
      connect_microseconds= start_utime;
 
1171
    }
 
1172
    else 
 
1173
      start_time= (mytime-epoch).total_seconds();
 
1174
  }
 
1175
  inline void   set_current_time()    { start_time= time(NULL); }
 
1176
  inline void   set_time(time_t t)
 
1177
  {
 
1178
    start_time= user_time= t;
 
1179
    boost::posix_time::ptime mytime(boost::posix_time::microsec_clock::local_time());
 
1180
    boost::posix_time::ptime epoch(boost::gregorian::date(1970,1,1));
 
1181
    uint64_t t_mark= (mytime-epoch).total_microseconds();
 
1182
 
 
1183
    start_utime= utime_after_lock= t_mark;
 
1184
  }
 
1185
  void set_time_after_lock()  { 
 
1186
     boost::posix_time::ptime mytime(boost::posix_time::microsec_clock::local_time());
 
1187
     boost::posix_time::ptime epoch(boost::gregorian::date(1970,1,1));
 
1188
     utime_after_lock= (mytime-epoch).total_microseconds();
 
1189
  }
1082
1190
  /**
1083
1191
   * Returns the current micro-timestamp
1084
1192
   */
1085
 
  type::Time::epoch_t getCurrentTimestamp(bool actual= true) const
 
1193
  inline uint64_t getCurrentTimestamp()  
1086
1194
  { 
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
 
    }
 
1195
    boost::posix_time::ptime mytime(boost::posix_time::microsec_clock::local_time());
 
1196
    boost::posix_time::ptime epoch(boost::gregorian::date(1970,1,1));
 
1197
    uint64_t t_mark= (mytime-epoch).total_microseconds();
1098
1198
 
1099
1199
    return t_mark; 
1100
1200
  }
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
 
1201
  inline uint64_t found_rows(void)
1124
1202
  {
1125
1203
    return limit_found_rows;
1126
1204
  }
1127
 
 
1128
1205
  /** Returns whether the session is currently inside a transaction */
1129
 
  bool inTransaction() const
 
1206
  inline bool inTransaction()
1130
1207
  {
1131
1208
    return server_status & SERVER_STATUS_IN_TRANS;
1132
1209
  }
1133
 
 
1134
1210
  LEX_STRING *make_lex_string(LEX_STRING *lex_str,
1135
1211
                              const char* str, uint32_t length,
1136
1212
                              bool allocate_lex_string);
1137
 
 
1138
1213
  LEX_STRING *make_lex_string(LEX_STRING *lex_str,
1139
1214
                              const std::string &str,
1140
1215
                              bool allocate_lex_string);
1141
1216
 
1142
1217
  int send_explain_fields(select_result *result);
1143
 
 
1144
1218
  /**
1145
1219
    Clear the current error, if any.
1146
1220
    We do not clear is_fatal_error or is_fatal_sub_stmt_error since we
1210
1284
  }
1211
1285
  void send_kill_message() const;
1212
1286
  /* 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;
 
1287
  inline bool really_abort_on_warning()
 
1288
  {
 
1289
    return (abort_on_warning);
1221
1290
  }
1222
1291
 
1223
1292
  void setAbort(bool arg);
1240
1309
    database usually involves other actions, like switching other database
1241
1310
    attributes including security context. In the future, this operation
1242
1311
    will be made private and more convenient interface will be provided.
 
1312
 
 
1313
    @return Operation status
 
1314
      @retval false Success
 
1315
      @retval true  Out-of-memory error
1243
1316
  */
1244
 
  void set_db(const std::string &new_db);
 
1317
  bool set_db(const std::string &new_db);
1245
1318
 
1246
1319
  /*
1247
1320
    Copy the current database to the argument. Use the current arena to
1263
1336
    @param level the error level
1264
1337
    @return true if the error is handled
1265
1338
  */
1266
 
  virtual bool handle_error(drizzled::error_t sql_errno, const char *message,
 
1339
  virtual bool handle_error(uint32_t sql_errno, const char *message,
1267
1340
                            DRIZZLE_ERROR::enum_warning_level level);
1268
1341
 
1269
1342
  /**
1291
1364
   * updates any status variables necessary.
1292
1365
   *
1293
1366
   * @param errcode     Error code to print to console
 
1367
   * @param should_lock 1 if we have have to lock LOCK_thread_count
1294
1368
   *
1295
1369
   * @note  For the connection that is doing shutdown, this is called twice
1296
1370
   */
1297
 
  void disconnect(enum error_t errcode= EE_OK);
 
1371
  void disconnect(uint32_t errcode, bool lock);
1298
1372
 
1299
1373
  /**
1300
1374
   * Check if user exists and the password supplied is correct.
1314
1388
   * Returns the timestamp (in microseconds) of when the Session 
1315
1389
   * connected to the server.
1316
1390
   */
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();
 
1391
  inline uint64_t getConnectMicroseconds() const
 
1392
  {
 
1393
    return connect_microseconds;
1325
1394
  }
1326
1395
 
1327
1396
  /**
1442
1511
  
1443
1512
  
1444
1513
 private:
 
1514
 /** Microsecond timestamp of when Session connected */
 
1515
  uint64_t connect_microseconds;
1445
1516
  const char *proc_info;
1446
1517
 
1447
1518
  /** The current internal error handler for this thread, or NULL. */
1534
1605
  void close_old_data_files(bool morph_locks= false,
1535
1606
                            bool send_refresh= false);
1536
1607
  void close_open_tables();
1537
 
  void close_data_files_and_morph_locks(const identifier::Table &identifier);
 
1608
  void close_data_files_and_morph_locks(const TableIdentifier &identifier);
1538
1609
 
1539
1610
private:
1540
 
  bool free_cached_table(boost::mutex::scoped_lock &scopedLock);
1541
 
 
 
1611
  bool free_cached_table();
1542
1612
public:
1543
1613
 
1544
1614
  /**
1572
1642
  Table *openTable(TableList *table_list, bool *refresh, uint32_t flags= 0);
1573
1643
 
1574
1644
  void unlink_open_table(Table *find);
1575
 
  void drop_open_table(Table *table, const identifier::Table &identifier);
 
1645
  void drop_open_table(Table *table, const TableIdentifier &identifier);
1576
1646
  void close_cached_table(Table *table);
1577
1647
 
1578
1648
  /* 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
 
 
 
1649
  table::Placeholder *table_cache_insert_placeholder(const TableIdentifier &identifier);
 
1650
  bool lock_table_name_if_not_cached(const TableIdentifier &identifier, Table **table);
 
1651
 
 
1652
  typedef boost::unordered_map<std::string, message::Table, util::insensitive_hash, util::insensitive_equal_to> TableMessageCache;
 
1653
 
 
1654
  class TableMessages
 
1655
  {
 
1656
    TableMessageCache table_message_cache;
 
1657
 
 
1658
  public:
 
1659
    bool storeTableMessage(const TableIdentifier &identifier, message::Table &table_message);
 
1660
    bool removeTableMessage(const TableIdentifier &identifier);
 
1661
    bool getTableMessage(const TableIdentifier &identifier, message::Table &table_message);
 
1662
    bool doesTableMessageExist(const TableIdentifier &identifier);
 
1663
    bool renameTableMessage(const TableIdentifier &from, const TableIdentifier &to);
 
1664
 
 
1665
  };
1582
1666
private:
1583
 
  session::TableMessages _table_message_cache;
 
1667
  TableMessages _table_message_cache;
1584
1668
 
1585
1669
public:
1586
 
  session::TableMessages &getMessageCache()
 
1670
  TableMessages &getMessageCache()
1587
1671
  {
1588
1672
    return _table_message_cache;
1589
1673
  }
1590
1674
 
1591
1675
  /* Reopen operations */
1592
 
  bool reopen_tables();
 
1676
  bool reopen_tables(bool get_locks, bool mark_share_as_old);
1593
1677
  bool close_cached_tables(TableList *tables, bool wait_for_refresh, bool wait_for_placeholders);
1594
1678
 
1595
1679
  void wait_for_condition(boost::mutex &mutex, boost::condition_variable_any &cond);
1598
1682
 
1599
1683
  drizzled::util::Storable *getProperty(const std::string &arg)
1600
1684
  {
1601
 
    return life_properties.getProperty(arg);
 
1685
    return life_properties[arg];
1602
1686
  }
1603
1687
 
1604
1688
  template<class T>
1605
1689
  bool setProperty(const std::string &arg, T *value)
1606
1690
  {
1607
 
    life_properties.setProperty(arg, value);
 
1691
    life_properties[arg]= value;
1608
1692
 
1609
1693
    return true;
1610
1694
  }
1624
1708
    return global_system_variables.storage_engine;
1625
1709
  }
1626
1710
 
1627
 
  void get_xid(DrizzleXid *xid); // Innodb only
 
1711
  void get_xid(DRIZZLE_XID *xid); // Innodb only
1628
1712
 
1629
 
  table::Singular *getInstanceTable();
1630
 
  table::Singular *getInstanceTable(List<CreateField> &field_list);
 
1713
  table::Instance *getInstanceTable();
 
1714
  table::Instance *getInstanceTable(List<CreateField> &field_list);
1631
1715
 
1632
1716
private:
1633
1717
  bool resetUsage()
1639
1723
 
1640
1724
    return true;
1641
1725
  }
1642
 
 
1643
1726
public:
1644
1727
 
1645
1728
  void setUsage(bool arg)
1652
1735
    return usage;
1653
1736
  }
1654
1737
 
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
1738
private:
1666
 
  catalog::Instance::shared_ptr _catalog;
1667
 
 
1668
1739
  // This lives throughout the life of Session
1669
1740
  bool use_usage;
1670
 
  session::PropertyMap life_properties;
1671
 
  std::vector<table::Singular *> temporary_shares;
 
1741
  PropertyMap life_properties;
 
1742
  std::vector<table::Instance *> temporary_shares;
1672
1743
  struct rusage usage;
1673
1744
};
1674
1745
 
 
1746
class Join;
 
1747
 
1675
1748
#define ESCAPE_CHARS "ntrb0ZN" // keep synchronous with READ_INFO::unescape
1676
1749
 
 
1750
} /* namespace drizzled */
 
1751
 
 
1752
/** @TODO why is this in the middle of the file */
 
1753
#include <drizzled/select_to_file.h>
 
1754
#include <drizzled/select_export.h>
 
1755
#include <drizzled/select_dump.h>
 
1756
#include <drizzled/select_insert.h>
 
1757
#include <drizzled/select_create.h>
 
1758
#include <drizzled/tmp_table_param.h>
 
1759
#include <drizzled/select_union.h>
 
1760
#include <drizzled/select_subselect.h>
 
1761
#include <drizzled/select_singlerow_subselect.h>
 
1762
#include <drizzled/select_max_min_finder_subselect.h>
 
1763
#include <drizzled/select_exists_subselect.h>
 
1764
 
 
1765
namespace drizzled
 
1766
{
 
1767
 
 
1768
/**
 
1769
 * A structure used to describe sort information
 
1770
 * for a field or item used in ORDER BY.
 
1771
 */
 
1772
class SortField 
 
1773
{
 
1774
public:
 
1775
  Field *field; /**< Field to sort */
 
1776
  Item  *item; /**< Item if not sorting fields */
 
1777
  size_t length; /**< Length of sort field */
 
1778
  uint32_t suffix_length; /**< Length suffix (0-4) */
 
1779
  Item_result result_type; /**< Type of item */
 
1780
  bool reverse; /**< if descending sort */
 
1781
  bool need_strxnfrm;   /**< If we have to use strxnfrm() */
 
1782
 
 
1783
  SortField() :
 
1784
    field(0),
 
1785
    item(0),
 
1786
    length(0),
 
1787
    suffix_length(0),
 
1788
    result_type(STRING_RESULT),
 
1789
    reverse(0),
 
1790
    need_strxnfrm(0)
 
1791
  { }
 
1792
 
 
1793
};
 
1794
 
 
1795
} /* namespace drizzled */
 
1796
 
 
1797
/** @TODO why is this in the middle of the file */
 
1798
 
 
1799
#include <drizzled/table_ident.h>
 
1800
#include <drizzled/user_var_entry.h>
 
1801
#include <drizzled/unique.h>
 
1802
#include <drizzled/var.h>
 
1803
#include <drizzled/select_dumpvar.h>
 
1804
 
 
1805
namespace drizzled
 
1806
{
 
1807
 
1677
1808
/* Bits in sql_command_flags */
1678
1809
 
1679
1810
enum sql_command_flag_bits 
1695
1826
namespace display  {
1696
1827
const std::string &type(drizzled::Session::global_read_lock_t type);
1697
1828
size_t max_string_length(drizzled::Session::global_read_lock_t type);
1698
 
 
1699
1829
} /* namespace display */
1700
1830
 
1701
1831
} /* namespace drizzled */