~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/session.h

  • Committer: Brian Aker
  • Date: 2010-10-28 01:45:34 UTC
  • mfrom: (1878.5.8 catalogs)
  • Revision ID: brian@tangent.org-20101028014534-b6qp4wp6crj60h7k
Merge in catalog tree.

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
 
84
73
class Statement;
85
74
class Resultset;
86
75
}
87
 
 
88
 
namespace internal { struct st_my_thread_var; }
89
 
namespace table { class Placeholder; }
90
 
 
 
76
namespace internal
 
77
{
 
78
struct st_my_thread_var;
 
79
}
 
80
 
 
81
class Lex_input_stream;
 
82
class user_var_entry;
91
83
class CopyField;
92
 
class DrizzleXid;
93
 
class Internal_error_handler;
94
 
class Lex_input_stream;
 
84
class Table_ident;
 
85
 
95
86
class TableShareInstance;
96
 
class Table_ident;
97
 
class Time_zone;
98
 
class select_result;
99
 
class user_var_entry;
100
87
 
101
88
extern char internal_table_name[2];
102
89
extern char empty_c_string[1];
106
93
#define TC_HEURISTIC_RECOVER_ROLLBACK 2
107
94
extern uint32_t tc_heuristic_recover;
108
95
 
 
96
/**
 
97
  @brief
 
98
  Local storage for proto that are tmp table. This should be enlarged
 
99
  to hande the entire table-share for a local table. Once Hash is done,
 
100
  we should consider exchanging the map for it.
 
101
*/
 
102
typedef std::map <std::string, message::Table> ProtoCache;
 
103
 
 
104
/**
 
105
  The COPY_INFO structure is used by INSERT/REPLACE code.
 
106
  The schema of the row counting by the INSERT/INSERT ... ON DUPLICATE KEY
 
107
  UPDATE code:
 
108
    If a row is inserted then the copied variable is incremented.
 
109
    If a row is updated by the INSERT ... ON DUPLICATE KEY UPDATE and the
 
110
      new data differs from the old one then the copied and the updated
 
111
      variables are incremented.
 
112
    The touched variable is incremented if a row was touched by the update part
 
113
      of the INSERT ... ON DUPLICATE KEY UPDATE no matter whether the row
 
114
      was actually changed or not.
 
115
*/
 
116
struct CopyInfo 
 
117
{
 
118
  ha_rows records; /**< Number of processed records */
 
119
  ha_rows deleted; /**< Number of deleted records */
 
120
  ha_rows updated; /**< Number of updated records */
 
121
  ha_rows copied;  /**< Number of copied records */
 
122
  ha_rows error_count;
 
123
  ha_rows touched; /* Number of touched records */
 
124
  enum enum_duplicates handle_duplicates;
 
125
  int escape_char, last_errno;
 
126
  bool ignore;
 
127
  /* for INSERT ... UPDATE */
 
128
  List<Item> *update_fields;
 
129
  List<Item> *update_values;
 
130
  /* for VIEW ... WITH CHECK OPTION */
 
131
 
 
132
  CopyInfo() :
 
133
    records(0),
 
134
    deleted(0),
 
135
    updated(0),
 
136
    copied(0),
 
137
    error_count(0),
 
138
    touched(0),
 
139
    escape_char(0),
 
140
    last_errno(0),
 
141
    ignore(0),
 
142
    update_fields(0),
 
143
    update_values(0)
 
144
  { }
 
145
 
 
146
};
 
147
 
 
148
} /* namespace drizzled */
 
149
 
 
150
/** @TODO why is this in the middle of the file */
 
151
#include <drizzled/lex_column.h>
 
152
 
 
153
namespace drizzled
 
154
{
 
155
 
 
156
class select_result;
 
157
class Time_zone;
 
158
 
109
159
#define Session_SENTRY_MAGIC 0xfeedd1ff
110
160
#define Session_SENTRY_GONE  0xdeadbeef
111
161
 
112
 
extern DRIZZLED_API struct drizzle_system_variables global_system_variables;
 
162
struct drizzle_system_variables
 
163
{
 
164
  drizzle_system_variables()
 
165
  {};
 
166
  /*
 
167
    How dynamically allocated system variables are handled:
 
168
 
 
169
    The global_system_variables and max_system_variables are "authoritative"
 
170
    They both should have the same 'version' and 'size'.
 
171
    When attempting to access a dynamic variable, if the session version
 
172
    is out of date, then the session version is updated and realloced if
 
173
    neccessary and bytes copied from global to make up for missing data.
 
174
  */
 
175
  ulong dynamic_variables_version;
 
176
  char * dynamic_variables_ptr;
 
177
  uint32_t dynamic_variables_head;  /* largest valid variable offset */
 
178
  uint32_t dynamic_variables_size;  /* how many bytes are in use */
 
179
 
 
180
  uint64_t myisam_max_extra_sort_file_size;
 
181
  uint64_t max_heap_table_size;
 
182
  uint64_t tmp_table_size;
 
183
  ha_rows select_limit;
 
184
  ha_rows max_join_size;
 
185
  uint64_t auto_increment_increment;
 
186
  uint64_t auto_increment_offset;
 
187
  uint64_t bulk_insert_buff_size;
 
188
  uint64_t join_buff_size;
 
189
  uint32_t max_allowed_packet;
 
190
  uint64_t max_error_count;
 
191
  uint64_t max_length_for_sort_data;
 
192
  size_t max_sort_length;
 
193
  uint64_t min_examined_row_limit;
 
194
  bool optimizer_prune_level;
 
195
  bool log_warnings;
 
196
 
 
197
  uint32_t optimizer_search_depth;
 
198
  uint32_t div_precincrement;
 
199
  uint64_t preload_buff_size;
 
200
  uint32_t read_buff_size;
 
201
  uint32_t read_rnd_buff_size;
 
202
  size_t sortbuff_size;
 
203
  uint32_t thread_handling;
 
204
  uint32_t tx_isolation;
 
205
  size_t transaction_message_threshold;
 
206
  uint32_t completion_type;
 
207
  /* Determines which non-standard SQL behaviour should be enabled */
 
208
  uint32_t sql_mode;
 
209
  uint64_t max_seeks_for_key;
 
210
  size_t range_alloc_block_size;
 
211
  uint32_t query_alloc_block_size;
 
212
  uint32_t query_prealloc_size;
 
213
  uint64_t group_concat_max_len;
 
214
  uint64_t pseudo_thread_id;
 
215
 
 
216
  plugin::StorageEngine *storage_engine;
 
217
 
 
218
  /* Only charset part of these variables is sensible */
 
219
  const CHARSET_INFO  *character_set_filesystem;
 
220
 
 
221
  /* Both charset and collation parts of these variables are important */
 
222
  const CHARSET_INFO    *collation_server;
 
223
 
 
224
  inline const CHARSET_INFO  *getCollation(void) 
 
225
  {
 
226
    return collation_server;
 
227
  }
 
228
 
 
229
  /* Locale Support */
 
230
  MY_LOCALE *lc_time_names;
 
231
 
 
232
  Time_zone *time_zone;
 
233
};
 
234
 
 
235
extern struct drizzle_system_variables global_system_variables;
 
236
 
 
237
} /* namespace drizzled */
 
238
 
 
239
#include "drizzled/sql_lex.h"
 
240
 
 
241
namespace drizzled
 
242
{
 
243
 
 
244
void mark_transaction_to_rollback(Session *session, bool all);
 
245
 
 
246
/**
 
247
  Storage engine specific thread local data.
 
248
*/
 
249
struct Ha_data
 
250
{
 
251
  /**
 
252
    Storage engine specific thread local data.
 
253
    Lifetime: one user connection.
 
254
  */
 
255
  void *ha_ptr;
 
256
  /**
 
257
   * Resource contexts for both the "statement" and "normal"
 
258
   * transactions.
 
259
   *
 
260
   * Resource context at index 0:
 
261
   *
 
262
   * Life time: one statement within a transaction. If @@autocommit is
 
263
   * on, also represents the entire transaction.
 
264
   *
 
265
   * Resource context at index 1:
 
266
   *
 
267
   * Life time: one transaction within a connection. 
 
268
   *
 
269
   * @note
 
270
   *
 
271
   * If the storage engine does not participate in a transaction, 
 
272
   * there will not be a resource context.
 
273
   */
 
274
  drizzled::ResourceContext resource_context[2];
 
275
 
 
276
  Ha_data() :ha_ptr(NULL) {}
 
277
};
113
278
 
114
279
/**
115
280
 * Represents a client connection to the database server.
130
295
 * all member variables that are not critical to non-internal operations of the
131
296
 * session object.
132
297
 */
 
298
typedef int64_t session_id_t;
133
299
 
134
 
class DRIZZLED_API Session : public Open_tables_state
 
300
class Session : public Open_tables_state
135
301
{
136
302
public:
137
303
  // Plugin storage in Session.
138
 
  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
 
  }
 
304
  typedef boost::unordered_map<std::string, util::Storable *, util::insensitive_hash, util::insensitive_equal_to> PropertyMap;
149
305
 
150
306
  /*
151
307
    MARK_COLUMNS_NONE:  Means mark_used_colums is not set and no indicator to
159
315
                        and update_row.
160
316
  */
161
317
  enum enum_mark_columns mark_used_columns;
 
318
  inline void* alloc(size_t size)
 
319
  {
 
320
    return mem_root->alloc_root(size);
 
321
  }
162
322
  inline void* calloc(size_t size)
163
323
  {
164
324
    void *ptr;
166
326
      memset(ptr, 0, size);
167
327
    return ptr;
168
328
  }
 
329
  inline char *strdup(const char *str)
 
330
  {
 
331
    return mem_root->strdup_root(str);
 
332
  }
169
333
  inline char *strmake(const char *str, size_t size)
170
334
  {
171
335
    return mem_root->strmake_root(str,size);
172
336
  }
173
 
 
 
337
  inline void *memdup(const void *str, size_t size)
 
338
  {
 
339
    return mem_root->memdup_root(str, size);
 
340
  }
174
341
  inline void *memdup_w_gap(const void *str, size_t size, uint32_t gap)
175
342
  {
176
343
    void *ptr;
180
347
  }
181
348
  /** Frees all items attached to this Statement */
182
349
  void free_items();
183
 
 
184
350
  /**
185
351
   * List of items created in the parser for this query. Every item puts
186
352
   * itself to the list on creation (see Item::Item() for details))
193
359
  {
194
360
    return mem_root;
195
361
  }
196
 
 
197
 
  uint64_t xa_id;
198
 
 
199
 
  uint64_t getXaId()
200
 
  {
201
 
    return xa_id;
202
 
  }
203
 
 
204
 
  void setXaId(uint64_t in_xa_id)
205
 
  {
206
 
    xa_id= in_xa_id; 
207
 
  }
208
 
 
209
362
  /**
210
363
   * Uniquely identifies each statement object in thread scope; change during
211
364
   * statement lifetime.
213
366
   * @todo should be const
214
367
   */
215
368
  uint32_t id;
216
 
private:
217
369
  LEX *lex; /**< parse tree descriptor */
218
370
 
219
 
public:
220
371
  LEX *getLex() 
221
372
  {
222
373
    return lex;
223
374
  }
224
 
 
225
 
  enum_sql_command getSqlCommand() const
226
 
  {
227
 
    return lex->sql_command;
228
 
  }
229
 
 
230
375
  /** query associated with this statement */
231
 
  typedef boost::shared_ptr<const std::string> QueryString;
232
 
 
233
 
private:
234
 
  boost::shared_ptr<std::string> query;
235
 
 
236
 
  // Never allow for a modification of this outside of the class. c_str()
237
 
  // requires under some setup non const, you must copy the QueryString in
238
 
  // order to use it.
239
 
public:
240
 
  QueryString getQueryString() const
241
 
  {
242
 
    return query;
243
 
  }
244
 
 
245
 
  void resetQueryString()
246
 
  {
247
 
    query.reset();
248
 
    _state.reset();
249
 
  }
250
 
 
251
 
  /*
252
 
    We need to copy the lock on the string in order to make sure we have a stable string.
253
 
    Once this is done we can use it to build a const char* which can be handed off for
254
 
    a method to use (Innodb is currently the only engine using this).
255
 
  */
256
 
  const char *getQueryStringCopy(size_t &length)
257
 
  {
258
 
    QueryString tmp_string(getQueryString());
259
 
 
260
 
    if (not tmp_string)
261
 
    {
262
 
      length= 0;
263
 
      return NULL;
264
 
    }
265
 
 
266
 
    length= tmp_string->length();
267
 
    char *to_return= strmake(tmp_string->c_str(), tmp_string->length());
268
 
    return to_return;
269
 
  }
270
 
 
271
 
private:
272
 
  session::State::shared_ptr  _state; 
273
 
 
274
 
public:
275
 
 
276
 
  session::State::const_shared_ptr state()
277
 
  {
278
 
    return _state;
279
 
  }
 
376
  std::string query;
280
377
 
281
378
  /**
282
379
    Name of the current (default) database.
290
387
    the Session of that thread); that thread is (and must remain, for now) the
291
388
    only responsible for freeing this member.
292
389
  */
293
 
private:
294
 
  util::string::shared_ptr _schema;
295
 
 
296
 
public:
297
 
 
298
 
  util::string::const_shared_ptr schema() const
299
 
  {
300
 
    if (_schema)
301
 
      return _schema;
302
 
 
303
 
    return util::string::const_shared_ptr(new std::string(""));
304
 
  }
305
 
 
 
390
  std::string db;
 
391
  std::string catalog;
306
392
  /* current cache key */
307
393
  std::string query_cache_key;
308
394
  /**
314
400
  static const char * const DEFAULT_WHERE;
315
401
 
316
402
  memory::Root warn_root; /**< Allocation area for warnings and errors */
317
 
private:
318
403
  plugin::Client *client; /**< Pointer to client object */
319
 
 
320
 
public:
321
 
 
322
 
  void setClient(plugin::Client *client_arg);
323
 
 
324
 
  plugin::Client *getClient()
325
 
  {
326
 
    return client;
327
 
  }
328
 
 
329
 
  plugin::Client *getClient() const
330
 
  {
331
 
    return client;
332
 
  }
333
 
 
334
404
  plugin::Scheduler *scheduler; /**< Pointer to scheduler object */
335
405
  void *scheduler_arg; /**< Pointer to the optional scheduler argument */
336
 
 
 
406
private:
337
407
  typedef boost::unordered_map< std::string, user_var_entry *, util::insensitive_hash, util::insensitive_equal_to> UserVars;
338
 
 
339
 
private:
340
408
  typedef std::pair< UserVars::iterator, UserVars::iterator > UserVarsRange;
341
409
  UserVars user_vars; /**< Hash of user variables defined during the session's lifetime */
342
410
 
343
411
public:
344
 
  const UserVars &getUserVariables() const
345
 
  {
346
 
    return user_vars;
347
 
  }
348
 
 
349
412
  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
413
  struct system_status_var status_var; /**< Session-local status counters */
357
414
  THR_LOCK_INFO lock_info; /**< Locking information for this session */
358
415
  THR_LOCK_OWNER main_lock_id; /**< To use for conventional queries */
359
416
  THR_LOCK_OWNER *lock_id; /**< If not main_lock_id, points to the lock_id of a cursor. */
 
417
private:
 
418
  boost::mutex LOCK_delete; /**< Locked before session is deleted */
 
419
public:
 
420
 
 
421
  void lockForDelete()
 
422
  {
 
423
    LOCK_delete.lock();
 
424
  }
 
425
 
 
426
  void unlockForDelete()
 
427
  {
 
428
    LOCK_delete.unlock();
 
429
  }
 
430
 
 
431
  /**
 
432
   * A peek into the query string for the session. This is a best effort
 
433
   * delivery, there is no guarantee whether the content is meaningful.
 
434
   */
 
435
  char process_list_info[PROCESS_LIST_WIDTH+1];
360
436
 
361
437
  /**
362
438
   * A pointer to the stack frame of the scheduler thread
365
441
  char *thread_stack;
366
442
 
367
443
private:
368
 
  identifier::User::shared_ptr security_ctx;
 
444
  SecurityContext security_ctx;
369
445
 
370
446
  int32_t scoreboard_index;
371
447
 
373
449
  {
374
450
    assert(this->dbug_sentry == Session_SENTRY_MAGIC);
375
451
  }
376
 
 
377
452
public:
378
 
  identifier::User::const_shared_ptr user() const
 
453
  const SecurityContext& getSecurityContext() const
379
454
  {
380
 
    if (security_ctx)
381
 
      return security_ctx;
382
 
 
383
 
    return identifier::User::const_shared_ptr();
 
455
    return security_ctx;
384
456
  }
385
457
 
386
 
  void setUser(identifier::User::shared_ptr arg)
 
458
  SecurityContext& getSecurityContext()
387
459
  {
388
 
    security_ctx= arg;
 
460
    return security_ctx;
389
461
  }
390
462
 
391
463
  int32_t getScoreboardIndex()
401
473
  /**
402
474
   * Is this session viewable by the current user?
403
475
   */
404
 
  bool isViewable(identifier::User::const_reference) const;
 
476
  bool isViewable() const
 
477
  {
 
478
    return plugin::Authorization::isAuthorized(current_session->getSecurityContext(),
 
479
                                               this,
 
480
                                               false);
 
481
  }
405
482
 
406
 
private:
407
483
  /**
408
484
    Used in error messages to tell user in what part of MySQL we found an
409
485
    error. E. g. when where= "having clause", if fix_fields() fails, user
410
486
    will know that the error was in having clause.
411
487
  */
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
 
  }
 
488
  const char *where;
424
489
 
425
490
  /*
426
491
    One thread can hold up to one named user-level lock. This variable
428
493
    chapter 'Miscellaneous functions', for functions GET_LOCK, RELEASE_LOCK.
429
494
  */
430
495
  uint32_t dbug_sentry; /**< watch for memory corruption */
431
 
 
432
496
private:
433
 
  boost::thread::id boost_thread_id;
434
 
  boost_thread_shared_ptr _thread;
435
 
  boost::this_thread::disable_interruption *interrupt;
436
 
 
437
497
  internal::st_my_thread_var *mysys_var;
438
 
 
439
498
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
499
 
456
500
  internal::st_my_thread_var *getThreadVar()
457
501
  {
458
502
    return mysys_var;
459
503
  }
460
504
 
 
505
  void resetThreadVar()
 
506
  {
 
507
    mysys_var= NULL;
 
508
  }
461
509
  /**
462
510
   * Type of current query: COM_STMT_PREPARE, COM_QUERY, etc. Set from
463
511
   * first byte of the packet in executeStatement()
466
514
  uint32_t file_id;     /**< File ID for LOAD DATA INFILE */
467
515
  /* @note the following three members should likely move to Client */
468
516
  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
 
  }
 
517
  time_t start_time;
 
518
  time_t user_time;
 
519
  uint64_t thr_create_utime; /**< track down slow pthread_create */
 
520
  uint64_t start_utime;
 
521
  uint64_t utime_after_lock;
494
522
 
495
523
  thr_lock_type update_lock_default;
496
524
 
511
539
  */
512
540
  query_id_t query_id;
513
541
  query_id_t warn_query_id;
514
 
 
515
542
public:
516
543
  void **getEngineData(const plugin::MonitoredInTransaction *monitored);
517
544
  ResourceContext *getResourceContext(const plugin::MonitoredInTransaction *monitored,
518
545
                                      size_t index= 0);
519
546
 
520
 
  session::Transactions transaction;
 
547
  /**
 
548
   * Structure used to manage "statement transactions" and
 
549
   * "normal transactions". In autocommit mode, the normal transaction is
 
550
   * equivalent to the statement transaction.
 
551
   *
 
552
   * Storage engines will be registered here when they participate in
 
553
   * a transaction. No engine is registered more than once.
 
554
   */
 
555
  struct st_transactions {
 
556
    std::deque<NamedSavepoint> savepoints;
 
557
 
 
558
    /**
 
559
     * The normal transaction (since BEGIN WORK).
 
560
     *
 
561
     * Contains a list of all engines that have participated in any of the
 
562
     * statement transactions started within the context of the normal
 
563
     * transaction.
 
564
     *
 
565
     * @note In autocommit mode, this is empty.
 
566
     */
 
567
    TransactionContext all;
 
568
 
 
569
    /**
 
570
     * The statment transaction.
 
571
     *
 
572
     * Contains a list of all engines participating in the given statement.
 
573
     *
 
574
     * @note In autocommit mode, this will be used to commit/rollback the
 
575
     * normal transaction.
 
576
     */
 
577
    TransactionContext stmt;
 
578
 
 
579
    XID_STATE xid_state;
 
580
 
 
581
    void cleanup()
 
582
    {
 
583
      savepoints.clear();
 
584
    }
 
585
    st_transactions() :
 
586
      savepoints(),
 
587
      all(),
 
588
      stmt(),
 
589
      xid_state()
 
590
    { }
 
591
  } transaction;
521
592
 
522
593
  Field *dup_field;
523
594
  sigset_t signals;
524
595
 
525
 
  // As of right now we do not allow a concurrent execute to launch itself
526
 
private:
527
 
  bool concurrent_execute_allowed;
528
 
 
529
 
public:
530
 
 
531
 
  void setConcurrentExecute(bool arg)
532
 
  {
533
 
    concurrent_execute_allowed= arg;
534
 
  }
535
 
 
536
 
  bool isConcurrentExecuteAllowed() const
537
 
  {
538
 
    return concurrent_execute_allowed;
539
 
  }
540
 
 
541
596
  /* Tells if LAST_INSERT_ID(#) was called for the current statement */
542
597
  bool arg_of_last_insert_id_function;
543
 
 
544
598
  /*
545
599
    ALL OVER THIS FILE, "insert_id" means "*automatically generated* value for
546
600
    insertion into an auto_increment column".
594
648
  uint64_t limit_found_rows;
595
649
  uint64_t options; /**< Bitmap of options */
596
650
  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
651
  ha_rows cuted_fields; /**< Count of "cut" or truncated fields. @todo Kill this friggin thing. */
604
652
 
605
653
  /** 
648
696
    create_sort_index(); may differ from examined_row_count.
649
697
  */
650
698
  uint32_t row_count;
651
 
 
652
 
  uint32_t getRowCount() const
653
 
  {
654
 
    return row_count;
655
 
  }
656
 
 
657
699
  session_id_t thread_id;
658
700
  uint32_t tmp_table;
659
 
  enum global_read_lock_t
660
 
  {
661
 
    NONE= 0,
662
 
    GOT_GLOBAL_READ_LOCK= 1,
663
 
    MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT= 2
664
 
  };
665
 
private:
666
 
  global_read_lock_t _global_read_lock;
667
 
 
668
 
public:
669
 
 
670
 
  global_read_lock_t isGlobalReadLock() const
671
 
  {
672
 
    return _global_read_lock;
673
 
  }
674
 
 
675
 
  void setGlobalReadLock(global_read_lock_t arg)
676
 
  {
677
 
    _global_read_lock= arg;
678
 
  }
679
 
 
680
 
  DrizzleLock *lockTables(Table **tables, uint32_t count, uint32_t flags);
681
 
  bool lockGlobalReadLock();
682
 
  bool lock_table_names(TableList *table_list);
683
 
  bool lock_table_names_exclusively(TableList *table_list);
684
 
  bool makeGlobalReadLockBlockCommit();
685
 
  bool abortLockForThread(Table *table);
686
 
  bool wait_if_global_read_lock(bool abort_on_refresh, bool is_not_commit);
687
 
  int lock_table_name(TableList *table_list);
688
 
  void abortLock(Table *table);
689
 
  void removeLock(Table *table);
690
 
  void unlockReadTables(DrizzleLock *sql_lock);
691
 
  void unlockSomeTables(Table **table, uint32_t count);
692
 
  void unlockTables(DrizzleLock *sql_lock);
693
 
  void startWaitingGlobalReadLock();
694
 
  void unlockGlobalReadLock();
695
 
 
696
 
private:
697
 
  int unlock_external(Table **table, uint32_t count);
698
 
  int lock_external(Table **tables, uint32_t count);
699
 
  bool wait_for_locked_table_names(TableList *table_list);
700
 
  DrizzleLock *get_lock_data(Table **table_ptr, uint32_t count,
701
 
                             bool should_lock, Table **write_lock_used);
702
 
public:
703
 
 
 
701
  uint32_t global_read_lock;
704
702
  uint32_t server_status;
705
703
  uint32_t open_options;
706
704
  uint32_t select_number; /**< number of select (used for EXPLAIN) */
708
706
  enum_tx_isolation session_tx_isolation;
709
707
  enum_check_fields count_cuted_fields;
710
708
 
711
 
  enum killed_state_t
 
709
  enum killed_state
712
710
  {
713
711
    NOT_KILLED,
714
712
    KILL_BAD_DATA,
716
714
    KILL_QUERY,
717
715
    KILLED_NO_VALUE /* means none of the above states apply */
718
716
  };
719
 
private:
720
 
  killed_state_t volatile _killed;
721
 
 
722
 
public:
723
 
 
724
 
  void setKilled(killed_state_t arg)
725
 
  {
726
 
    _killed= arg;
727
 
  }
728
 
 
729
 
  killed_state_t getKilled()
730
 
  {
731
 
    return _killed;
732
 
  }
733
 
 
734
 
  volatile killed_state_t *getKilledPtr() // Do not use this method, it is here for historical convience.
735
 
  {
736
 
    return &_killed;
737
 
  }
738
 
 
739
 
  bool is_admin_connection;
 
717
  killed_state volatile killed;
 
718
 
740
719
  bool some_tables_deleted;
741
720
  bool no_errors;
742
721
  bool password;
745
724
    can not continue. In particular, disables activation of
746
725
    CONTINUE or EXIT handlers of stored routines.
747
726
    Reset in the end of processing of the current user request, in
748
 
    @see reset_session_for_next_command().
 
727
    @see mysql_reset_session_for_next_command().
749
728
  */
750
729
  bool is_fatal_error;
751
730
  /**
770
749
  bool substitute_null_with_insert_id;
771
750
  bool cleanup_done;
772
751
 
773
 
private:
774
752
  bool abort_on_warning;
775
 
  bool tablespace_op; /**< This is true in DISCARD/IMPORT TABLESPACE */
776
 
 
777
 
public:
778
753
  bool got_warning; /**< Set on call to push_warning() */
779
754
  bool no_warnings_for_error; /**< no warnings on call to my_error() */
780
755
  /** set during loop of derived table processing */
781
756
  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
 
 
 
757
  bool tablespace_op; /**< This is true in DISCARD/IMPORT TABLESPACE */
793
758
 
794
759
  /** Used by the sys_var class to store temporary values */
795
760
  union
839
804
  }
840
805
 
841
806
  /** Returns the current query ID */
842
 
  query_id_t getQueryId()  const
 
807
  inline query_id_t getQueryId()  const
843
808
  {
844
809
    return query_id;
845
810
  }
857
822
    return warn_query_id;
858
823
  }
859
824
 
 
825
  /** Returns the current query text */
 
826
  inline const std::string &getQueryString()  const
 
827
  {
 
828
    return query;
 
829
  }
 
830
 
 
831
  /** Returns the length of the current query text */
 
832
  inline size_t getQueryLength() const
 
833
  {
 
834
    if (! query.empty())
 
835
      return query.length();
 
836
    else
 
837
      return 0;
 
838
  }
 
839
 
860
840
  /** Accessor method returning the session's ID. */
861
841
  inline session_id_t getSessionId()  const
862
842
  {
931
911
    auto_inc_intervals_forced.append(next_id, UINT64_MAX, 0);
932
912
  }
933
913
 
934
 
  Session(plugin::Client *client_arg, catalog::Instance::shared_ptr catalog);
 
914
  Session(plugin::Client *client_arg);
935
915
  virtual ~Session();
936
916
 
937
917
  void cleanup(void);
949
929
   */
950
930
  void cleanup_after_query();
951
931
  bool storeGlobals();
952
 
  void awake(Session::killed_state_t state_to_set);
 
932
  void awake(Session::killed_state state_to_set);
953
933
  /**
954
934
   * Pulls thread-specific variables into Session state.
955
935
   *
1014
994
  bool endTransaction(enum enum_mysql_completiontype completion);
1015
995
  bool endActiveTransaction();
1016
996
  bool startTransaction(start_transaction_option_t opt= START_TRANS_NO_OPTIONS);
1017
 
  void markTransactionForRollback(bool all);
1018
997
 
1019
998
  /**
1020
999
   * Authenticates users, with error reporting.
1033
1012
  /**
1034
1013
   * Schedule a session to be run on the default scheduler.
1035
1014
   */
1036
 
  static bool schedule(Session::shared_ptr&);
1037
 
 
1038
 
  static void unlink(session_id_t &session_id);
1039
 
  static void unlink(Session::shared_ptr&);
 
1015
  bool schedule();
1040
1016
 
1041
1017
  /*
1042
1018
    For enter_cond() / exit_cond() to work the mutex must be got before
1046
1022
  const char* enter_cond(boost::condition_variable_any &cond, boost::mutex &mutex, const char* msg);
1047
1023
  void exit_cond(const char* old_msg);
1048
1024
 
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
 
 
 
1025
  inline time_t query_start() { return start_time; }
 
1026
  inline void set_time()
 
1027
  {
 
1028
    if (user_time)
 
1029
    {
 
1030
      start_time= user_time;
 
1031
      connect_microseconds= start_utime= utime_after_lock= my_micro_time();
 
1032
    }
 
1033
    else
 
1034
      start_utime= utime_after_lock= my_micro_time_and_time(&start_time);
 
1035
  }
 
1036
  inline void   set_current_time()    { start_time= time(NULL); }
 
1037
  inline void   set_time(time_t t)
 
1038
  {
 
1039
    start_time= user_time= t;
 
1040
    start_utime= utime_after_lock= my_micro_time();
 
1041
  }
 
1042
  void set_time_after_lock()  { utime_after_lock= my_micro_time(); }
1082
1043
  /**
1083
1044
   * Returns the current micro-timestamp
1084
1045
   */
1085
 
  type::Time::epoch_t getCurrentTimestamp(bool actual= true) const
1086
 
  { 
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
 
    }
1098
 
 
1099
 
    return t_mark; 
1100
 
  }
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
 
1046
  inline uint64_t getCurrentTimestamp()  
 
1047
  { 
 
1048
    return my_micro_time(); 
 
1049
  }
 
1050
  inline uint64_t found_rows(void)
1124
1051
  {
1125
1052
    return limit_found_rows;
1126
1053
  }
1127
 
 
1128
1054
  /** Returns whether the session is currently inside a transaction */
1129
 
  bool inTransaction() const
 
1055
  inline bool inTransaction()
1130
1056
  {
1131
1057
    return server_status & SERVER_STATUS_IN_TRANS;
1132
1058
  }
1133
 
 
1134
1059
  LEX_STRING *make_lex_string(LEX_STRING *lex_str,
1135
1060
                              const char* str, uint32_t length,
1136
1061
                              bool allocate_lex_string);
1137
 
 
1138
1062
  LEX_STRING *make_lex_string(LEX_STRING *lex_str,
1139
1063
                              const std::string &str,
1140
1064
                              bool allocate_lex_string);
1141
1065
 
1142
1066
  int send_explain_fields(select_result *result);
1143
 
 
1144
1067
  /**
1145
1068
    Clear the current error, if any.
1146
1069
    We do not clear is_fatal_error or is_fatal_sub_stmt_error since we
1148
1071
    @todo: To silence an error, one should use Internal_error_handler
1149
1072
    mechanism. In future this function will be removed.
1150
1073
  */
1151
 
  inline void clear_error(bool full= false)
 
1074
  inline void clear_error()
1152
1075
  {
1153
1076
    if (main_da.is_error())
1154
1077
      main_da.reset_diagnostics_area();
1155
 
 
1156
 
    if (full)
1157
 
    {
1158
 
      drizzle_reset_errors(this, true);
1159
 
    }
1160
 
  }
1161
 
 
1162
 
  void clearDiagnostics()
1163
 
  {
1164
 
    main_da.reset_diagnostics_area();
 
1078
    return;
1165
1079
  }
1166
1080
 
1167
1081
  /**
1205
1119
  void end_statement();
1206
1120
  inline int killed_errno() const
1207
1121
  {
1208
 
    killed_state_t killed_val; /* to cache the volatile 'killed' */
1209
 
    return (killed_val= _killed) != KILL_BAD_DATA ? killed_val : 0;
 
1122
    killed_state killed_val; /* to cache the volatile 'killed' */
 
1123
    return (killed_val= killed) != KILL_BAD_DATA ? killed_val : 0;
1210
1124
  }
1211
1125
  void send_kill_message() const;
1212
1126
  /* 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;
 
1127
  inline bool really_abort_on_warning()
 
1128
  {
 
1129
    return (abort_on_warning);
1221
1130
  }
1222
1131
 
1223
1132
  void setAbort(bool arg);
1240
1149
    database usually involves other actions, like switching other database
1241
1150
    attributes including security context. In the future, this operation
1242
1151
    will be made private and more convenient interface will be provided.
 
1152
 
 
1153
    @return Operation status
 
1154
      @retval false Success
 
1155
      @retval true  Out-of-memory error
1243
1156
  */
1244
 
  void set_db(const std::string &new_db);
 
1157
  bool set_db(const std::string &new_db);
1245
1158
 
1246
1159
  /*
1247
1160
    Copy the current database to the argument. Use the current arena to
1263
1176
    @param level the error level
1264
1177
    @return true if the error is handled
1265
1178
  */
1266
 
  virtual bool handle_error(drizzled::error_t sql_errno, const char *message,
 
1179
  virtual bool handle_error(uint32_t sql_errno, const char *message,
1267
1180
                            DRIZZLE_ERROR::enum_warning_level level);
1268
1181
 
1269
1182
  /**
1291
1204
   * updates any status variables necessary.
1292
1205
   *
1293
1206
   * @param errcode     Error code to print to console
 
1207
   * @param should_lock 1 if we have have to lock LOCK_thread_count
1294
1208
   *
1295
1209
   * @note  For the connection that is doing shutdown, this is called twice
1296
1210
   */
1297
 
  void disconnect(enum error_t errcode= EE_OK);
 
1211
  void disconnect(uint32_t errcode, bool lock);
1298
1212
 
1299
1213
  /**
1300
1214
   * Check if user exists and the password supplied is correct.
1314
1228
   * Returns the timestamp (in microseconds) of when the Session 
1315
1229
   * connected to the server.
1316
1230
   */
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();
 
1231
  inline uint64_t getConnectMicroseconds() const
 
1232
  {
 
1233
    return connect_microseconds;
1325
1234
  }
1326
1235
 
1327
1236
  /**
1442
1351
  
1443
1352
  
1444
1353
 private:
 
1354
 /** Microsecond timestamp of when Session connected */
 
1355
  uint64_t connect_microseconds;
1445
1356
  const char *proc_info;
1446
1357
 
1447
1358
  /** The current internal error handler for this thread, or NULL. */
1482
1393
   * set to query_id of original query.
1483
1394
   */
1484
1395
  void mark_used_tables_as_free_for_reuse(Table *table);
 
1396
  /**
 
1397
    Mark all temporary tables which were used by the current statement or
 
1398
    substatement as free for reuse, but only if the query_id can be cleared.
 
1399
 
 
1400
    @param session thread context
 
1401
 
 
1402
    @remark For temp tables associated with a open SQL HANDLER the query_id
 
1403
            is not reset until the HANDLER is closed.
 
1404
  */
 
1405
  void mark_temp_tables_as_free_for_reuse();
1485
1406
 
1486
1407
public:
1487
1408
 
1534
1455
  void close_old_data_files(bool morph_locks= false,
1535
1456
                            bool send_refresh= false);
1536
1457
  void close_open_tables();
1537
 
  void close_data_files_and_morph_locks(const identifier::Table &identifier);
 
1458
  void close_data_files_and_morph_locks(TableIdentifier &identifier);
1538
1459
 
1539
1460
private:
1540
 
  bool free_cached_table(boost::mutex::scoped_lock &scopedLock);
1541
 
 
 
1461
  bool free_cached_table();
1542
1462
public:
1543
1463
 
1544
1464
  /**
1572
1492
  Table *openTable(TableList *table_list, bool *refresh, uint32_t flags= 0);
1573
1493
 
1574
1494
  void unlink_open_table(Table *find);
1575
 
  void drop_open_table(Table *table, const identifier::Table &identifier);
 
1495
  void drop_open_table(Table *table, TableIdentifier &identifier);
1576
1496
  void close_cached_table(Table *table);
1577
1497
 
1578
1498
  /* 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
 
 
 
1499
  Table *table_cache_insert_placeholder(const TableIdentifier &identifier);
 
1500
  bool lock_table_name_if_not_cached(TableIdentifier &identifier, Table **table);
 
1501
 
 
1502
  typedef boost::unordered_map<std::string, message::Table, util::insensitive_hash, util::insensitive_equal_to> TableMessageCache;
 
1503
  TableMessageCache table_message_cache;
 
1504
 
 
1505
  bool storeTableMessage(const TableIdentifier &identifier, message::Table &table_message);
 
1506
  bool removeTableMessage(const TableIdentifier &identifier);
 
1507
  bool getTableMessage(const TableIdentifier &identifier, message::Table &table_message);
 
1508
  bool doesTableMessageExist(const TableIdentifier &identifier);
 
1509
  bool renameTableMessage(const TableIdentifier &from, const TableIdentifier &to);
 
1510
 
 
1511
  /* Work with temporary tables */
 
1512
  Table *find_temporary_table(const TableIdentifier &identifier);
 
1513
 
 
1514
  void doGetTableNames(CachedDirectory &directory,
 
1515
                       const SchemaIdentifier &schema_identifier,
 
1516
                       std::set<std::string>& set_of_names);
 
1517
  void doGetTableNames(const SchemaIdentifier &schema_identifier,
 
1518
                       std::set<std::string>& set_of_names);
 
1519
 
 
1520
  void doGetTableIdentifiers(CachedDirectory &directory,
 
1521
                             const SchemaIdentifier &schema_identifier,
 
1522
                             TableIdentifiers &set_of_identifiers);
 
1523
  void doGetTableIdentifiers(const SchemaIdentifier &schema_identifier,
 
1524
                             TableIdentifiers &set_of_identifiers);
 
1525
 
 
1526
  int doGetTableDefinition(const drizzled::TableIdentifier &identifier,
 
1527
                           message::Table &table_proto);
 
1528
  bool doDoesTableExist(const drizzled::TableIdentifier &identifier);
 
1529
 
 
1530
  void close_temporary_tables();
 
1531
  void close_temporary_table(Table *table);
 
1532
  // The method below just handles the de-allocation of the table. In
 
1533
  // a better memory type world, this would not be needed.
1582
1534
private:
1583
 
  session::TableMessages _table_message_cache;
1584
 
 
 
1535
  void nukeTable(Table *table);
1585
1536
public:
1586
 
  session::TableMessages &getMessageCache()
1587
 
  {
1588
 
    return _table_message_cache;
1589
 
  }
 
1537
 
 
1538
  void dumpTemporaryTableNames(const char *id);
 
1539
  int drop_temporary_table(const drizzled::TableIdentifier &identifier);
 
1540
  bool rm_temporary_table(plugin::StorageEngine *base, TableIdentifier &identifier);
 
1541
  bool rm_temporary_table(TableIdentifier &identifier, bool best_effort= false);
 
1542
  Table *open_temporary_table(TableIdentifier &identifier,
 
1543
                              bool link_in_list= true);
1590
1544
 
1591
1545
  /* Reopen operations */
1592
 
  bool reopen_tables();
 
1546
  bool reopen_tables(bool get_locks, bool mark_share_as_old);
1593
1547
  bool close_cached_tables(TableList *tables, bool wait_for_refresh, bool wait_for_placeholders);
1594
1548
 
1595
1549
  void wait_for_condition(boost::mutex &mutex, boost::condition_variable_any &cond);
1596
1550
  int setup_conds(TableList *leaves, COND **conds);
1597
1551
  int lock_tables(TableList *tables, uint32_t count, bool *need_reopen);
1598
1552
 
 
1553
  Table *create_virtual_tmp_table(List<CreateField> &field_list);
 
1554
  
1599
1555
  drizzled::util::Storable *getProperty(const std::string &arg)
1600
1556
  {
1601
 
    return life_properties.getProperty(arg);
 
1557
    return life_properties[arg];
1602
1558
  }
1603
1559
 
1604
1560
  template<class T>
1605
1561
  bool setProperty(const std::string &arg, T *value)
1606
1562
  {
1607
 
    life_properties.setProperty(arg, value);
 
1563
    life_properties[arg]= value;
1608
1564
 
1609
1565
    return true;
1610
1566
  }
1622
1578
    if (variables.storage_engine)
1623
1579
      return variables.storage_engine;
1624
1580
    return global_system_variables.storage_engine;
1625
 
  }
1626
 
 
1627
 
  void get_xid(DrizzleXid *xid); // Innodb only
1628
 
 
1629
 
  table::Singular *getInstanceTable();
1630
 
  table::Singular *getInstanceTable(List<CreateField> &field_list);
 
1581
  };
 
1582
 
 
1583
  static void unlink(Session *session);
 
1584
 
 
1585
  void get_xid(DRIZZLE_XID *xid); // Innodb only
 
1586
 
 
1587
  table::Instance *getInstanceTable();
 
1588
  table::Instance *getInstanceTable(List<CreateField> &field_list);
1631
1589
 
1632
1590
private:
1633
1591
  bool resetUsage()
1639
1597
 
1640
1598
    return true;
1641
1599
  }
1642
 
 
1643
1600
public:
1644
1601
 
1645
1602
  void setUsage(bool arg)
1652
1609
    return usage;
1653
1610
  }
1654
1611
 
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
1612
private:
1666
 
  catalog::Instance::shared_ptr _catalog;
1667
 
 
1668
1613
  // This lives throughout the life of Session
1669
1614
  bool use_usage;
1670
 
  session::PropertyMap life_properties;
1671
 
  std::vector<table::Singular *> temporary_shares;
 
1615
  PropertyMap life_properties;
 
1616
  std::vector<table::Instance *> temporary_shares;
1672
1617
  struct rusage usage;
1673
1618
};
1674
1619
 
 
1620
class Join;
 
1621
 
1675
1622
#define ESCAPE_CHARS "ntrb0ZN" // keep synchronous with READ_INFO::unescape
1676
1623
 
 
1624
} /* namespace drizzled */
 
1625
 
 
1626
/** @TODO why is this in the middle of the file */
 
1627
#include <drizzled/select_to_file.h>
 
1628
#include <drizzled/select_export.h>
 
1629
#include <drizzled/select_dump.h>
 
1630
#include <drizzled/select_insert.h>
 
1631
#include <drizzled/select_create.h>
 
1632
#include <drizzled/tmp_table_param.h>
 
1633
#include <drizzled/select_union.h>
 
1634
#include <drizzled/select_subselect.h>
 
1635
#include <drizzled/select_singlerow_subselect.h>
 
1636
#include <drizzled/select_max_min_finder_subselect.h>
 
1637
#include <drizzled/select_exists_subselect.h>
 
1638
 
 
1639
namespace drizzled
 
1640
{
 
1641
 
 
1642
/**
 
1643
 * A structure used to describe sort information
 
1644
 * for a field or item used in ORDER BY.
 
1645
 */
 
1646
struct SortField 
 
1647
{
 
1648
  Field *field; /**< Field to sort */
 
1649
  Item  *item; /**< Item if not sorting fields */
 
1650
  size_t length; /**< Length of sort field */
 
1651
  uint32_t suffix_length; /**< Length suffix (0-4) */
 
1652
  Item_result result_type; /**< Type of item */
 
1653
  bool reverse; /**< if descending sort */
 
1654
  bool need_strxnfrm;   /**< If we have to use strxnfrm() */
 
1655
 
 
1656
  SortField() :
 
1657
    field(0),
 
1658
    item(0),
 
1659
    length(0),
 
1660
    suffix_length(0),
 
1661
    result_type(STRING_RESULT),
 
1662
    reverse(0),
 
1663
    need_strxnfrm(0)
 
1664
  { }
 
1665
 
 
1666
};
 
1667
 
 
1668
} /* namespace drizzled */
 
1669
 
 
1670
/** @TODO why is this in the middle of the file */
 
1671
 
 
1672
#include <drizzled/table_ident.h>
 
1673
#include <drizzled/user_var_entry.h>
 
1674
#include <drizzled/unique.h>
 
1675
#include <drizzled/var.h>
 
1676
#include <drizzled/select_dumpvar.h>
 
1677
 
 
1678
namespace drizzled
 
1679
{
 
1680
 
1677
1681
/* Bits in sql_command_flags */
1678
1682
 
1679
1683
enum sql_command_flag_bits 
1692
1696
static const std::bitset<CF_BIT_SIZE> CF_SHOW_TABLE_COMMAND(1 << CF_BIT_SHOW_TABLE_COMMAND);
1693
1697
static const std::bitset<CF_BIT_SIZE> CF_WRITE_LOGS_COMMAND(1 << CF_BIT_WRITE_LOGS_COMMAND);
1694
1698
 
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
1699
} /* namespace drizzled */
1702
1700
 
1703
1701
#endif /* DRIZZLED_SESSION_H */