~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/session.h

  • Committer: Marisa Plumb
  • Date: 2010-12-04 02:38:29 UTC
  • mto: This revision was merged to the branch mainline in revision 1984.
  • Revision ID: marisa.plumb@gmail.com-20101204023829-2khzxh30wxi256db
updates to a few sql docs 

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