~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/session.h

modified transaction 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
 
 
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/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>
 
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
 
  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
322
 
150
323
  /*
151
324
    MARK_COLUMNS_NONE:  Means mark_used_colums is not set and no indicator to
159
332
                        and update_row.
160
333
  */
161
334
  enum enum_mark_columns mark_used_columns;
 
335
  inline void* alloc(size_t size)
 
336
  {
 
337
    return mem_root->alloc_root(size);
 
338
  }
162
339
  inline void* calloc(size_t size)
163
340
  {
164
341
    void *ptr;
166
343
      memset(ptr, 0, size);
167
344
    return ptr;
168
345
  }
 
346
  inline char *strdup(const char *str)
 
347
  {
 
348
    return mem_root->strdup_root(str);
 
349
  }
169
350
  inline char *strmake(const char *str, size_t size)
170
351
  {
171
352
    return mem_root->strmake_root(str,size);
172
353
  }
173
 
 
 
354
  inline void *memdup(const void *str, size_t size)
 
355
  {
 
356
    return mem_root->memdup_root(str, size);
 
357
  }
174
358
  inline void *memdup_w_gap(const void *str, size_t size, uint32_t gap)
175
359
  {
176
360
    void *ptr;
180
364
  }
181
365
  /** Frees all items attached to this Statement */
182
366
  void free_items();
183
 
 
184
367
  /**
185
368
   * List of items created in the parser for this query. Every item puts
186
369
   * itself to the list on creation (see Item::Item() for details))
213
396
   * @todo should be const
214
397
   */
215
398
  uint32_t id;
216
 
private:
217
399
  LEX *lex; /**< parse tree descriptor */
218
400
 
219
 
public:
220
401
  LEX *getLex() 
221
402
  {
222
403
    return lex;
223
404
  }
224
 
 
225
 
  enum_sql_command getSqlCommand() const
226
 
  {
227
 
    return lex->sql_command;
228
 
  }
229
 
 
230
405
  /** query associated with this statement */
231
406
  typedef boost::shared_ptr<const std::string> QueryString;
232
 
 
233
407
private:
234
408
  boost::shared_ptr<std::string> query;
235
409
 
257
431
  {
258
432
    QueryString tmp_string(getQueryString());
259
433
 
 
434
    assert(tmp_string);
260
435
    if (not tmp_string)
261
436
    {
262
437
      length= 0;
263
 
      return NULL;
 
438
      return 0;
264
439
    }
265
440
 
266
441
    length= tmp_string->length();
268
443
    return to_return;
269
444
  }
270
445
 
 
446
  class State {
 
447
    std::vector <char> _query;
 
448
 
 
449
  public:
 
450
    typedef boost::shared_ptr<State> const_shared_ptr;
 
451
 
 
452
    State(const char *in_packet, size_t in_packet_length)
 
453
    {
 
454
      if (in_packet_length)
 
455
      {
 
456
        size_t minimum= std::min(in_packet_length, static_cast<size_t>(PROCESS_LIST_WIDTH));
 
457
        _query.resize(minimum + 1);
 
458
        memcpy(&_query[0], in_packet, minimum);
 
459
      }
 
460
      else
 
461
      {
 
462
        _query.resize(0);
 
463
      }
 
464
    }
 
465
 
 
466
    const char *query() const
 
467
    {
 
468
      if (_query.size())
 
469
        return &_query[0];
 
470
 
 
471
      return "";
 
472
    }
 
473
 
 
474
    const char *query(size_t &size) const
 
475
    {
 
476
      if (_query.size())
 
477
      {
 
478
        size= _query.size() -1;
 
479
        return &_query[0];
 
480
      }
 
481
 
 
482
      size= 0;
 
483
      return "";
 
484
    }
 
485
  protected:
 
486
    friend class Session;
 
487
    typedef boost::shared_ptr<State> shared_ptr;
 
488
  };
271
489
private:
272
 
  session::State::shared_ptr  _state; 
273
 
 
 
490
  State::shared_ptr  _state; 
274
491
public:
275
492
 
276
 
  session::State::const_shared_ptr state()
 
493
  State::const_shared_ptr state()
277
494
  {
278
495
    return _state;
279
496
  }
292
509
  */
293
510
private:
294
511
  util::string::shared_ptr _schema;
295
 
 
296
512
public:
297
513
 
298
514
  util::string::const_shared_ptr schema() const
302
518
 
303
519
    return util::string::const_shared_ptr(new std::string(""));
304
520
  }
305
 
 
 
521
  std::string catalog;
306
522
  /* current cache key */
307
523
  std::string query_cache_key;
308
524
  /**
314
530
  static const char * const DEFAULT_WHERE;
315
531
 
316
532
  memory::Root warn_root; /**< Allocation area for warnings and errors */
317
 
private:
318
533
  plugin::Client *client; /**< Pointer to client object */
319
534
 
320
 
public:
321
 
 
322
535
  void setClient(plugin::Client *client_arg);
323
536
 
324
537
  plugin::Client *getClient()
326
539
    return client;
327
540
  }
328
541
 
329
 
  plugin::Client *getClient() const
330
 
  {
331
 
    return client;
332
 
  }
333
 
 
334
542
  plugin::Scheduler *scheduler; /**< Pointer to scheduler object */
335
543
  void *scheduler_arg; /**< Pointer to the optional scheduler argument */
336
544
 
337
545
  typedef boost::unordered_map< std::string, user_var_entry *, util::insensitive_hash, util::insensitive_equal_to> UserVars;
338
 
 
339
546
private:
340
547
  typedef std::pair< UserVars::iterator, UserVars::iterator > UserVarsRange;
341
548
  UserVars user_vars; /**< Hash of user variables defined during the session's lifetime */
342
549
 
343
550
public:
 
551
 
344
552
  const UserVars &getUserVariables() const
345
553
  {
346
554
    return user_vars;
347
555
  }
348
556
 
349
557
  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
558
  struct system_status_var status_var; /**< Session-local status counters */
357
559
  THR_LOCK_INFO lock_info; /**< Locking information for this session */
358
560
  THR_LOCK_OWNER main_lock_id; /**< To use for conventional queries */
365
567
  char *thread_stack;
366
568
 
367
569
private:
368
 
  identifier::User::shared_ptr security_ctx;
 
570
  SecurityContext security_ctx;
369
571
 
370
572
  int32_t scoreboard_index;
371
573
 
373
575
  {
374
576
    assert(this->dbug_sentry == Session_SENTRY_MAGIC);
375
577
  }
376
 
 
377
578
public:
378
 
  identifier::User::const_shared_ptr user() const
 
579
  const SecurityContext& getSecurityContext() const
379
580
  {
380
 
    if (security_ctx)
381
 
      return security_ctx;
382
 
 
383
 
    return identifier::User::const_shared_ptr();
 
581
    return security_ctx;
384
582
  }
385
583
 
386
 
  void setUser(identifier::User::shared_ptr arg)
 
584
  SecurityContext& getSecurityContext()
387
585
  {
388
 
    security_ctx= arg;
 
586
    return security_ctx;
389
587
  }
390
588
 
391
589
  int32_t getScoreboardIndex()
401
599
  /**
402
600
   * Is this session viewable by the current user?
403
601
   */
404
 
  bool isViewable(identifier::User::const_reference) const;
 
602
  bool isViewable() const;
405
603
 
406
 
private:
407
604
  /**
408
605
    Used in error messages to tell user in what part of MySQL we found an
409
606
    error. E. g. when where= "having clause", if fix_fields() fails, user
410
607
    will know that the error was in having clause.
411
608
  */
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
 
  }
 
609
  const char *where;
424
610
 
425
611
  /*
426
612
    One thread can hold up to one named user-level lock. This variable
428
614
    chapter 'Miscellaneous functions', for functions GET_LOCK, RELEASE_LOCK.
429
615
  */
430
616
  uint32_t dbug_sentry; /**< watch for memory corruption */
431
 
 
432
617
private:
433
618
  boost::thread::id boost_thread_id;
434
619
  boost_thread_shared_ptr _thread;
435
620
  boost::this_thread::disable_interruption *interrupt;
436
621
 
437
622
  internal::st_my_thread_var *mysys_var;
 
623
public:
438
624
 
439
 
public:
440
625
  boost_thread_shared_ptr &getThread()
441
626
  {
442
627
    return _thread;
466
651
  uint32_t file_id;     /**< File ID for LOAD DATA INFILE */
467
652
  /* @note the following three members should likely move to Client */
468
653
  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
 
  }
 
654
  time_t start_time;
 
655
  time_t user_time;
 
656
  uint64_t thr_create_utime; /**< track down slow pthread_create */
 
657
  uint64_t start_utime;
 
658
  uint64_t utime_after_lock;
494
659
 
495
660
  thr_lock_type update_lock_default;
496
661
 
511
676
  */
512
677
  query_id_t query_id;
513
678
  query_id_t warn_query_id;
514
 
 
515
679
public:
516
680
  void **getEngineData(const plugin::MonitoredInTransaction *monitored);
517
681
  ResourceContext *getResourceContext(const plugin::MonitoredInTransaction *monitored,
518
682
                                      size_t index= 0);
519
683
 
520
 
  session::Transactions transaction;
 
684
  /**
 
685
   * Structure used to manage "statement transactions" and
 
686
   * "normal transactions". In autocommit mode, the normal transaction is
 
687
   * equivalent to the statement transaction.
 
688
   *
 
689
   * Storage engines will be registered here when they participate in
 
690
   * a transaction. No engine is registered more than once.
 
691
   */
 
692
  struct st_transactions {
 
693
    std::deque<NamedSavepoint> savepoints;
 
694
 
 
695
    /**
 
696
     * The normal transaction (since BEGIN WORK).
 
697
     *
 
698
     * Contains a list of all engines that have participated in any of the
 
699
     * statement transactions started within the context of the normal
 
700
     * transaction.
 
701
     *
 
702
     * @note In autocommit mode, this is empty.
 
703
     */
 
704
    TransactionContext all;
 
705
 
 
706
    /**
 
707
     * The statment transaction.
 
708
     *
 
709
     * Contains a list of all engines participating in the given statement.
 
710
     *
 
711
     * @note In autocommit mode, this will be used to commit/rollback the
 
712
     * normal transaction.
 
713
     */
 
714
    TransactionContext stmt;
 
715
 
 
716
    XID_STATE xid_state;
 
717
 
 
718
    void cleanup()
 
719
    {
 
720
      savepoints.clear();
 
721
    }
 
722
    st_transactions() :
 
723
      savepoints(),
 
724
      all(),
 
725
      stmt(),
 
726
      xid_state()
 
727
    { }
 
728
  } transaction;
521
729
 
522
730
  Field *dup_field;
523
731
  sigset_t signals;
525
733
  // As of right now we do not allow a concurrent execute to launch itself
526
734
private:
527
735
  bool concurrent_execute_allowed;
528
 
 
529
736
public:
530
737
 
531
738
  void setConcurrentExecute(bool arg)
594
801
  uint64_t limit_found_rows;
595
802
  uint64_t options; /**< Bitmap of options */
596
803
  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
804
  ha_rows cuted_fields; /**< Count of "cut" or truncated fields. @todo Kill this friggin thing. */
604
805
 
605
806
  /** 
648
849
    create_sort_index(); may differ from examined_row_count.
649
850
  */
650
851
  uint32_t row_count;
651
 
 
652
 
  uint32_t getRowCount() const
653
 
  {
654
 
    return row_count;
655
 
  }
656
 
 
657
852
  session_id_t thread_id;
658
853
  uint32_t tmp_table;
659
854
  enum global_read_lock_t
677
872
    _global_read_lock= arg;
678
873
  }
679
874
 
680
 
  DrizzleLock *lockTables(Table **tables, uint32_t count, uint32_t flags);
 
875
  DrizzleLock *lockTables(Table **tables, uint32_t count, uint32_t flags, bool *need_reopen);
681
876
  bool lockGlobalReadLock();
682
877
  bool lock_table_names(TableList *table_list);
683
878
  bool lock_table_names_exclusively(TableList *table_list);
736
931
    return &_killed;
737
932
  }
738
933
 
739
 
  bool is_admin_connection;
740
934
  bool some_tables_deleted;
741
935
  bool no_errors;
742
936
  bool password;
745
939
    can not continue. In particular, disables activation of
746
940
    CONTINUE or EXIT handlers of stored routines.
747
941
    Reset in the end of processing of the current user request, in
748
 
    @see reset_session_for_next_command().
 
942
    @see mysql_reset_session_for_next_command().
749
943
  */
750
944
  bool is_fatal_error;
751
945
  /**
770
964
  bool substitute_null_with_insert_id;
771
965
  bool cleanup_done;
772
966
 
773
 
private:
774
967
  bool abort_on_warning;
775
 
  bool tablespace_op; /**< This is true in DISCARD/IMPORT TABLESPACE */
776
 
 
777
 
public:
778
968
  bool got_warning; /**< Set on call to push_warning() */
779
969
  bool no_warnings_for_error; /**< no warnings on call to my_error() */
780
970
  /** set during loop of derived table processing */
781
971
  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
 
 
 
972
  bool tablespace_op; /**< This is true in DISCARD/IMPORT TABLESPACE */
793
973
 
794
974
  /** Used by the sys_var class to store temporary values */
795
975
  union
931
1111
    auto_inc_intervals_forced.append(next_id, UINT64_MAX, 0);
932
1112
  }
933
1113
 
934
 
  Session(plugin::Client *client_arg, catalog::Instance::shared_ptr catalog);
 
1114
  Session(plugin::Client *client_arg);
935
1115
  virtual ~Session();
936
1116
 
937
1117
  void cleanup(void);
1014
1194
  bool endTransaction(enum enum_mysql_completiontype completion);
1015
1195
  bool endActiveTransaction();
1016
1196
  bool startTransaction(start_transaction_option_t opt= START_TRANS_NO_OPTIONS);
1017
 
  void markTransactionForRollback(bool all);
1018
1197
 
1019
1198
  /**
1020
1199
   * Authenticates users, with error reporting.
1035
1214
   */
1036
1215
  static bool schedule(Session::shared_ptr&);
1037
1216
 
1038
 
  static void unlink(session_id_t &session_id);
1039
1217
  static void unlink(Session::shared_ptr&);
1040
1218
 
1041
1219
  /*
1046
1224
  const char* enter_cond(boost::condition_variable_any &cond, boost::mutex &mutex, const char* msg);
1047
1225
  void exit_cond(const char* old_msg);
1048
1226
 
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
 
 
 
1227
  inline time_t query_start() { return start_time; }
 
1228
  inline void set_time()
 
1229
  {
 
1230
    boost::posix_time::ptime mytime(boost::posix_time::microsec_clock::local_time());
 
1231
    boost::posix_time::ptime epoch(boost::gregorian::date(1970,1,1));
 
1232
    start_utime= utime_after_lock= (mytime-epoch).total_microseconds();
 
1233
 
 
1234
    if (user_time)
 
1235
    {
 
1236
      start_time= user_time;
 
1237
      connect_microseconds= start_utime;
 
1238
    }
 
1239
    else 
 
1240
      start_time= (mytime-epoch).total_seconds();
 
1241
  }
 
1242
  inline void   set_current_time()    { start_time= time(NULL); }
 
1243
  inline void   set_time(time_t t)
 
1244
  {
 
1245
    start_time= user_time= t;
 
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
    uint64_t t_mark= (mytime-epoch).total_microseconds();
 
1249
 
 
1250
    start_utime= utime_after_lock= t_mark;
 
1251
  }
 
1252
  void set_time_after_lock()  { 
 
1253
     boost::posix_time::ptime mytime(boost::posix_time::microsec_clock::local_time());
 
1254
     boost::posix_time::ptime epoch(boost::gregorian::date(1970,1,1));
 
1255
     utime_after_lock= (mytime-epoch).total_microseconds();
 
1256
  }
1082
1257
  /**
1083
1258
   * Returns the current micro-timestamp
1084
1259
   */
1085
 
  type::Time::epoch_t getCurrentTimestamp(bool actual= true) const
 
1260
  inline uint64_t getCurrentTimestamp()  
1086
1261
  { 
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
 
    }
 
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();
1098
1265
 
1099
1266
    return t_mark; 
1100
1267
  }
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
 
1268
  inline uint64_t found_rows(void)
1124
1269
  {
1125
1270
    return limit_found_rows;
1126
1271
  }
1127
 
 
1128
1272
  /** Returns whether the session is currently inside a transaction */
1129
 
  bool inTransaction() const
 
1273
  inline bool inTransaction()
1130
1274
  {
1131
1275
    return server_status & SERVER_STATUS_IN_TRANS;
1132
1276
  }
1133
 
 
1134
1277
  LEX_STRING *make_lex_string(LEX_STRING *lex_str,
1135
1278
                              const char* str, uint32_t length,
1136
1279
                              bool allocate_lex_string);
1137
 
 
1138
1280
  LEX_STRING *make_lex_string(LEX_STRING *lex_str,
1139
1281
                              const std::string &str,
1140
1282
                              bool allocate_lex_string);
1141
1283
 
1142
1284
  int send_explain_fields(select_result *result);
1143
 
 
1144
1285
  /**
1145
1286
    Clear the current error, if any.
1146
1287
    We do not clear is_fatal_error or is_fatal_sub_stmt_error since we
1210
1351
  }
1211
1352
  void send_kill_message() const;
1212
1353
  /* 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;
 
1354
  inline bool really_abort_on_warning()
 
1355
  {
 
1356
    return (abort_on_warning);
1221
1357
  }
1222
1358
 
1223
1359
  void setAbort(bool arg);
1263
1399
    @param level the error level
1264
1400
    @return true if the error is handled
1265
1401
  */
1266
 
  virtual bool handle_error(drizzled::error_t sql_errno, const char *message,
 
1402
  virtual bool handle_error(uint32_t sql_errno, const char *message,
1267
1403
                            DRIZZLE_ERROR::enum_warning_level level);
1268
1404
 
1269
1405
  /**
1291
1427
   * updates any status variables necessary.
1292
1428
   *
1293
1429
   * @param errcode     Error code to print to console
 
1430
   * @param should_lock 1 if we have have to lock LOCK_thread_count
1294
1431
   *
1295
1432
   * @note  For the connection that is doing shutdown, this is called twice
1296
1433
   */
1297
 
  void disconnect(enum error_t errcode= EE_OK);
 
1434
  void disconnect(uint32_t errcode, bool lock);
1298
1435
 
1299
1436
  /**
1300
1437
   * Check if user exists and the password supplied is correct.
1314
1451
   * Returns the timestamp (in microseconds) of when the Session 
1315
1452
   * connected to the server.
1316
1453
   */
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();
 
1454
  inline uint64_t getConnectMicroseconds() const
 
1455
  {
 
1456
    return connect_microseconds;
1325
1457
  }
1326
1458
 
1327
1459
  /**
1442
1574
  
1443
1575
  
1444
1576
 private:
 
1577
 /** Microsecond timestamp of when Session connected */
 
1578
  uint64_t connect_microseconds;
1445
1579
  const char *proc_info;
1446
1580
 
1447
1581
  /** The current internal error handler for this thread, or NULL. */
1534
1668
  void close_old_data_files(bool morph_locks= false,
1535
1669
                            bool send_refresh= false);
1536
1670
  void close_open_tables();
1537
 
  void close_data_files_and_morph_locks(const identifier::Table &identifier);
 
1671
  void close_data_files_and_morph_locks(const TableIdentifier &identifier);
1538
1672
 
1539
1673
private:
1540
 
  bool free_cached_table(boost::mutex::scoped_lock &scopedLock);
1541
 
 
 
1674
  bool free_cached_table();
1542
1675
public:
1543
1676
 
1544
1677
  /**
1572
1705
  Table *openTable(TableList *table_list, bool *refresh, uint32_t flags= 0);
1573
1706
 
1574
1707
  void unlink_open_table(Table *find);
1575
 
  void drop_open_table(Table *table, const identifier::Table &identifier);
 
1708
  void drop_open_table(Table *table, const TableIdentifier &identifier);
1576
1709
  void close_cached_table(Table *table);
1577
1710
 
1578
1711
  /* 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
 
 
 
1712
  table::Placeholder *table_cache_insert_placeholder(const TableIdentifier &identifier);
 
1713
  bool lock_table_name_if_not_cached(const TableIdentifier &identifier, Table **table);
 
1714
 
 
1715
  typedef boost::unordered_map<std::string, message::Table, util::insensitive_hash, util::insensitive_equal_to> TableMessageCache;
 
1716
 
 
1717
  class TableMessages
 
1718
  {
 
1719
    TableMessageCache table_message_cache;
 
1720
 
 
1721
  public:
 
1722
    bool storeTableMessage(const TableIdentifier &identifier, message::Table &table_message);
 
1723
    bool removeTableMessage(const TableIdentifier &identifier);
 
1724
    bool getTableMessage(const TableIdentifier &identifier, message::Table &table_message);
 
1725
    bool doesTableMessageExist(const TableIdentifier &identifier);
 
1726
    bool renameTableMessage(const TableIdentifier &from, const TableIdentifier &to);
 
1727
 
 
1728
  };
1582
1729
private:
1583
 
  session::TableMessages _table_message_cache;
 
1730
  TableMessages _table_message_cache;
1584
1731
 
1585
1732
public:
1586
 
  session::TableMessages &getMessageCache()
 
1733
  TableMessages &getMessageCache()
1587
1734
  {
1588
1735
    return _table_message_cache;
1589
1736
  }
1590
1737
 
1591
1738
  /* Reopen operations */
1592
 
  bool reopen_tables();
 
1739
  bool reopen_tables(bool get_locks, bool mark_share_as_old);
1593
1740
  bool close_cached_tables(TableList *tables, bool wait_for_refresh, bool wait_for_placeholders);
1594
1741
 
1595
1742
  void wait_for_condition(boost::mutex &mutex, boost::condition_variable_any &cond);
1598
1745
 
1599
1746
  drizzled::util::Storable *getProperty(const std::string &arg)
1600
1747
  {
1601
 
    return life_properties.getProperty(arg);
 
1748
    return life_properties[arg];
1602
1749
  }
1603
1750
 
1604
1751
  template<class T>
1605
1752
  bool setProperty(const std::string &arg, T *value)
1606
1753
  {
1607
 
    life_properties.setProperty(arg, value);
 
1754
    life_properties[arg]= value;
1608
1755
 
1609
1756
    return true;
1610
1757
  }
1624
1771
    return global_system_variables.storage_engine;
1625
1772
  }
1626
1773
 
1627
 
  void get_xid(DrizzleXid *xid); // Innodb only
 
1774
  void get_xid(DRIZZLE_XID *xid); // Innodb only
1628
1775
 
1629
 
  table::Singular *getInstanceTable();
1630
 
  table::Singular *getInstanceTable(List<CreateField> &field_list);
 
1776
  table::Instance *getInstanceTable();
 
1777
  table::Instance *getInstanceTable(List<CreateField> &field_list);
1631
1778
 
1632
1779
private:
1633
1780
  bool resetUsage()
1639
1786
 
1640
1787
    return true;
1641
1788
  }
1642
 
 
1643
1789
public:
1644
1790
 
1645
1791
  void setUsage(bool arg)
1652
1798
    return usage;
1653
1799
  }
1654
1800
 
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
1801
private:
1666
 
  catalog::Instance::shared_ptr _catalog;
1667
 
 
1668
1802
  // This lives throughout the life of Session
1669
1803
  bool use_usage;
1670
 
  session::PropertyMap life_properties;
1671
 
  std::vector<table::Singular *> temporary_shares;
 
1804
  PropertyMap life_properties;
 
1805
  std::vector<table::Instance *> temporary_shares;
1672
1806
  struct rusage usage;
1673
1807
};
1674
1808
 
 
1809
class Join;
 
1810
 
1675
1811
#define ESCAPE_CHARS "ntrb0ZN" // keep synchronous with READ_INFO::unescape
1676
1812
 
 
1813
} /* namespace drizzled */
 
1814
 
 
1815
/** @TODO why is this in the middle of the file */
 
1816
#include <drizzled/select_to_file.h>
 
1817
#include <drizzled/select_export.h>
 
1818
#include <drizzled/select_dump.h>
 
1819
#include <drizzled/select_insert.h>
 
1820
#include <drizzled/select_create.h>
 
1821
#include <drizzled/tmp_table_param.h>
 
1822
#include <drizzled/select_union.h>
 
1823
#include <drizzled/select_subselect.h>
 
1824
#include <drizzled/select_singlerow_subselect.h>
 
1825
#include <drizzled/select_max_min_finder_subselect.h>
 
1826
#include <drizzled/select_exists_subselect.h>
 
1827
 
 
1828
namespace drizzled
 
1829
{
 
1830
 
 
1831
/**
 
1832
 * A structure used to describe sort information
 
1833
 * for a field or item used in ORDER BY.
 
1834
 */
 
1835
class SortField 
 
1836
{
 
1837
public:
 
1838
  Field *field; /**< Field to sort */
 
1839
  Item  *item; /**< Item if not sorting fields */
 
1840
  size_t length; /**< Length of sort field */
 
1841
  uint32_t suffix_length; /**< Length suffix (0-4) */
 
1842
  Item_result result_type; /**< Type of item */
 
1843
  bool reverse; /**< if descending sort */
 
1844
  bool need_strxnfrm;   /**< If we have to use strxnfrm() */
 
1845
 
 
1846
  SortField() :
 
1847
    field(0),
 
1848
    item(0),
 
1849
    length(0),
 
1850
    suffix_length(0),
 
1851
    result_type(STRING_RESULT),
 
1852
    reverse(0),
 
1853
    need_strxnfrm(0)
 
1854
  { }
 
1855
 
 
1856
};
 
1857
 
 
1858
} /* namespace drizzled */
 
1859
 
 
1860
/** @TODO why is this in the middle of the file */
 
1861
 
 
1862
#include <drizzled/table_ident.h>
 
1863
#include <drizzled/user_var_entry.h>
 
1864
#include <drizzled/unique.h>
 
1865
#include <drizzled/var.h>
 
1866
#include <drizzled/select_dumpvar.h>
 
1867
 
 
1868
namespace drizzled
 
1869
{
 
1870
 
1677
1871
/* Bits in sql_command_flags */
1678
1872
 
1679
1873
enum sql_command_flag_bits 
1695
1889
namespace display  {
1696
1890
const std::string &type(drizzled::Session::global_read_lock_t type);
1697
1891
size_t max_string_length(drizzled::Session::global_read_lock_t type);
1698
 
 
1699
1892
} /* namespace display */
1700
1893
 
1701
1894
} /* namespace drizzled */