~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/session.h

  • Committer: Monty Taylor
  • Date: 2010-12-27 18:39:11 UTC
  • mto: This revision was merged to the branch mainline in revision 2038.
  • Revision ID: mordred@inaugust.com-20101227183911-atgh0kcubflay0b9
Added back INNOBASE_SKIP_WARNINGS for solaris. Also dealt with unused params.

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
18
 */
19
19
 
20
 
#pragma once
 
20
 
 
21
#ifndef DRIZZLED_SESSION_H
 
22
#define DRIZZLED_SESSION_H
 
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>
21
43
 
22
44
#include <algorithm>
23
45
#include <bitset>
24
 
#include <boost/make_shared.hpp>
25
 
#include <boost/scoped_ptr.hpp>
26
 
#include <boost/thread/condition_variable.hpp>
 
46
#include <deque>
 
47
#include <map>
 
48
#include <string>
 
49
 
 
50
#include "drizzled/identifier.h"
 
51
#include "drizzled/open_tables_state.h"
 
52
#include "drizzled/internal_error_handler.h"
 
53
#include "drizzled/diagnostics_area.h"
 
54
#include "drizzled/plugin/authorization.h"
 
55
 
 
56
#include <boost/unordered_map.hpp>
 
57
 
 
58
#include <boost/thread/thread.hpp>
27
59
#include <boost/thread/mutex.hpp>
28
60
#include <boost/thread/shared_mutex.hpp>
29
 
#include <boost/thread/thread.hpp>
30
 
#include <map>
31
 
#include <netdb.h>
32
 
#include <string>
33
 
#include <sys/resource.h>
34
 
#include <sys/time.h>
35
 
 
36
 
#include <drizzled/charset.h>
37
 
#include <drizzled/base.h>
38
 
#include <drizzled/error.h>
39
 
#include <drizzled/lock.h>
40
 
#include <drizzled/pthread_globals.h>
41
 
#include <drizzled/sql_error.h>
42
 
#include <drizzled/sql_locale.h>
43
 
#include <drizzled/visibility.h>
44
 
#include <drizzled/util/find_ptr.h>
45
 
#include <drizzled/util/string.h>
46
 
#include <drizzled/type/time.h>
47
 
 
48
 
namespace drizzled {
49
 
 
50
 
extern uint32_t server_id;
51
 
extern std::string server_uuid;
 
61
#include <boost/thread/condition_variable.hpp>
 
62
#include <boost/make_shared.hpp>
 
63
 
 
64
 
 
65
#define MIN_HANDSHAKE_SIZE      6
 
66
 
 
67
namespace drizzled
 
68
{
 
69
 
 
70
namespace plugin
 
71
{
 
72
class Client;
 
73
class Scheduler;
 
74
class EventObserverList;
 
75
}
 
76
 
 
77
namespace message
 
78
{
 
79
class Transaction;
 
80
class Statement;
 
81
class Resultset;
 
82
}
 
83
 
 
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;
 
96
class CopyField;
 
97
class Table_ident;
 
98
 
 
99
class TableShareInstance;
 
100
 
 
101
extern char internal_table_name[2];
 
102
extern char empty_c_string[1];
 
103
extern const char **errmesg;
52
104
 
53
105
#define TC_HEURISTIC_RECOVER_COMMIT   1
54
106
#define TC_HEURISTIC_RECOVER_ROLLBACK 2
55
107
extern uint32_t tc_heuristic_recover;
56
108
 
57
 
extern DRIZZLED_API struct drizzle_system_variables global_system_variables;
 
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
 
 
173
#define Session_SENTRY_MAGIC 0xfeedd1ff
 
174
#define Session_SENTRY_GONE  0xdeadbeef
 
175
 
 
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
};
58
293
 
59
294
/**
60
295
 * Represents a client connection to the database server.
75
310
 * all member variables that are not critical to non-internal operations of the
76
311
 * session object.
77
312
 */
78
 
 
79
 
class Open_tables_state;
80
 
 
81
 
class DRIZZLED_API Session
 
313
typedef int64_t session_id_t;
 
314
 
 
315
class Session : public Open_tables_state
82
316
{
83
 
private:
84
 
  class impl_c;
85
 
 
86
 
  boost::scoped_ptr<impl_c> impl_;
87
317
public:
 
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;
88
321
  typedef boost::shared_ptr<Session> shared_ptr;
89
322
 
90
 
  static shared_ptr make_shared(plugin::Client *client, boost::shared_ptr<catalog::Instance> instance_arg)
91
 
  {
92
 
    assert(instance_arg);
93
 
    return boost::make_shared<Session>(client, instance_arg);
94
 
  }
95
 
 
96
323
  /*
97
324
    MARK_COLUMNS_NONE:  Means mark_used_colums is not set and no indicator to
98
325
                        handler of fields used is set
104
331
                        that it needs to update this field in write_row
105
332
                        and update_row.
106
333
  */
107
 
  enum_mark_columns mark_used_columns;
108
 
 
 
334
  enum enum_mark_columns mark_used_columns;
 
335
  inline void* alloc(size_t size)
 
336
  {
 
337
    return mem_root->alloc_root(size);
 
338
  }
 
339
  inline void* calloc(size_t size)
 
340
  {
 
341
    void *ptr;
 
342
    if ((ptr= mem_root->alloc_root(size)))
 
343
      memset(ptr, 0, size);
 
344
    return ptr;
 
345
  }
 
346
  inline char *strdup(const char *str)
 
347
  {
 
348
    return mem_root->strdup_root(str);
 
349
  }
 
350
  inline char *strmake(const char *str, size_t size)
 
351
  {
 
352
    return mem_root->strmake_root(str,size);
 
353
  }
 
354
  inline void *memdup(const void *str, size_t size)
 
355
  {
 
356
    return mem_root->memdup_root(str, size);
 
357
  }
 
358
  inline void *memdup_w_gap(const void *str, size_t size, uint32_t gap)
 
359
  {
 
360
    void *ptr;
 
361
    if ((ptr= mem_root->alloc_root(size + gap)))
 
362
      memcpy(ptr,str,size);
 
363
    return ptr;
 
364
  }
109
365
  /** Frees all items attached to this Statement */
110
366
  void free_items();
111
 
 
112
367
  /**
113
368
   * List of items created in the parser for this query. Every item puts
114
369
   * itself to the list on creation (see Item::Item() for details))
115
370
   */
116
371
  Item *free_list;
117
 
  memory::Root& mem;
118
 
  memory::Root* mem_root; /**< Pointer to current memroot */
119
 
 
120
 
  uint64_t getXaId() const
 
372
  memory::Root *mem_root; /**< Pointer to current memroot */
 
373
 
 
374
 
 
375
  memory::Root *getMemRoot()
 
376
  {
 
377
    return mem_root;
 
378
  }
 
379
 
 
380
  uint64_t xa_id;
 
381
 
 
382
  uint64_t getXaId()
121
383
  {
122
384
    return xa_id;
123
385
  }
124
386
 
125
387
  void setXaId(uint64_t in_xa_id)
126
388
  {
127
 
    xa_id= in_xa_id;
128
 
  }
129
 
 
130
 
public:
131
 
  Diagnostics_area& main_da();
132
 
  const LEX& lex() const;
133
 
  LEX& lex();
134
 
  enum_sql_command getSqlCommand() const;
135
 
 
 
389
    xa_id= in_xa_id; 
 
390
  }
 
391
 
 
392
  /**
 
393
   * Uniquely identifies each statement object in thread scope; change during
 
394
   * statement lifetime.
 
395
   *
 
396
   * @todo should be const
 
397
   */
 
398
  uint32_t id;
 
399
  LEX *lex; /**< parse tree descriptor */
 
400
 
 
401
  LEX *getLex() 
 
402
  {
 
403
    return lex;
 
404
  }
136
405
  /** query associated with this statement */
137
406
  typedef boost::shared_ptr<const std::string> QueryString;
138
 
 
139
407
private:
140
408
  boost::shared_ptr<std::string> query;
141
409
 
143
411
  // requires under some setup non const, you must copy the QueryString in
144
412
  // order to use it.
145
413
public:
146
 
  void resetQueryString();
147
 
  const boost::shared_ptr<session::State>& state();
148
 
 
149
414
  QueryString getQueryString() const
150
415
  {
151
416
    return query;
152
417
  }
153
418
 
154
 
  const char* getQueryStringCopy(size_t &length)
 
419
  void resetQueryString()
 
420
  {
 
421
    query.reset();
 
422
    _state.reset();
 
423
  }
 
424
 
 
425
  /*
 
426
    We need to copy the lock on the string in order to make sure we have a stable string.
 
427
    Once this is done we can use it to build a const char* which can be handed off for
 
428
    a method to use (Innodb is currently the only engine using this).
 
429
  */
 
430
  const char *getQueryStringCopy(size_t &length)
155
431
  {
156
432
    QueryString tmp_string(getQueryString());
 
433
 
157
434
    if (not tmp_string)
158
435
    {
159
436
      length= 0;
160
437
      return NULL;
161
438
    }
 
439
 
162
440
    length= tmp_string->length();
163
 
    return mem.strdup(*tmp_string);
164
 
  }
165
 
 
166
 
  util::string::ptr schema() const;
167
 
 
 
441
    char *to_return= strmake(tmp_string->c_str(), tmp_string->length());
 
442
    return to_return;
 
443
  }
 
444
 
 
445
  class State {
 
446
    std::vector <char> _query;
 
447
 
 
448
  public:
 
449
    typedef boost::shared_ptr<State> const_shared_ptr;
 
450
 
 
451
    State(const char *in_packet, size_t in_packet_length)
 
452
    {
 
453
      if (in_packet_length)
 
454
      {
 
455
        size_t minimum= std::min(in_packet_length, static_cast<size_t>(PROCESS_LIST_WIDTH));
 
456
        _query.resize(minimum + 1);
 
457
        memcpy(&_query[0], in_packet, minimum);
 
458
      }
 
459
      else
 
460
      {
 
461
        _query.resize(0);
 
462
      }
 
463
    }
 
464
 
 
465
    const char *query() const
 
466
    {
 
467
      if (_query.size())
 
468
        return &_query[0];
 
469
 
 
470
      return "";
 
471
    }
 
472
 
 
473
    const char *query(size_t &size) const
 
474
    {
 
475
      if (_query.size())
 
476
      {
 
477
        size= _query.size() -1;
 
478
        return &_query[0];
 
479
      }
 
480
 
 
481
      size= 0;
 
482
      return "";
 
483
    }
 
484
  protected:
 
485
    friend class Session;
 
486
    typedef boost::shared_ptr<State> shared_ptr;
 
487
  };
 
488
private:
 
489
  State::shared_ptr  _state; 
 
490
public:
 
491
 
 
492
  State::const_shared_ptr state()
 
493
  {
 
494
    return _state;
 
495
  }
 
496
 
 
497
  /**
 
498
    Name of the current (default) database.
 
499
 
 
500
    If there is the current (default) database, "db" contains its name. If
 
501
    there is no current (default) database, "db" is NULL and "db_length" is
 
502
    0. In other words, "db", "db_length" must either be NULL, or contain a
 
503
    valid database name.
 
504
 
 
505
    @note this attribute is set and alloced by the slave SQL thread (for
 
506
    the Session of that thread); that thread is (and must remain, for now) the
 
507
    only responsible for freeing this member.
 
508
  */
 
509
private:
 
510
  util::string::shared_ptr _schema;
 
511
public:
 
512
 
 
513
  util::string::const_shared_ptr schema() const
 
514
  {
 
515
    if (_schema)
 
516
      return _schema;
 
517
 
 
518
    return util::string::const_shared_ptr(new std::string(""));
 
519
  }
 
520
  std::string catalog;
 
521
  /* current cache key */
 
522
  std::string query_cache_key;
168
523
  /**
169
524
    Constant for Session::where initialization in the beginning of every query.
170
525
 
171
526
    It's needed because we do not save/restore Session::where normally during
172
527
    primary (non subselect) query execution.
173
528
  */
174
 
  static const char* const DEFAULT_WHERE;
 
529
  static const char * const DEFAULT_WHERE;
175
530
 
176
531
  memory::Root warn_root; /**< Allocation area for warnings and errors */
177
 
public:
 
532
  plugin::Client *client; /**< Pointer to client object */
 
533
 
178
534
  void setClient(plugin::Client *client_arg);
179
535
 
180
 
  plugin::Client *getClient() const
 
536
  plugin::Client *getClient()
181
537
  {
182
538
    return client;
183
539
  }
184
540
 
185
 
  plugin::Scheduler* scheduler; /**< Pointer to scheduler object */
186
 
 
187
 
  typedef boost::unordered_map<std::string, user_var_entry*, util::insensitive_hash, util::insensitive_equal_to> UserVars;
188
 
 
 
541
  plugin::Scheduler *scheduler; /**< Pointer to scheduler object */
 
542
  void *scheduler_arg; /**< Pointer to the optional scheduler argument */
 
543
 
 
544
  typedef boost::unordered_map< std::string, user_var_entry *, util::insensitive_hash, util::insensitive_equal_to> UserVars;
189
545
private:
190
546
  typedef std::pair< UserVars::iterator, UserVars::iterator > UserVarsRange;
191
547
  UserVars user_vars; /**< Hash of user variables defined during the session's lifetime */
192
548
 
193
549
public:
 
550
 
194
551
  const UserVars &getUserVariables() const
195
552
  {
196
553
    return user_vars;
197
554
  }
198
555
 
199
 
  drizzle_system_variables& variables; /**< Mutable local variables local to the session */
200
 
  enum_tx_isolation getTxIsolation() const;
201
 
  system_status_var& status_var;
202
 
 
 
556
  drizzle_system_variables variables; /**< Mutable local variables local to the session */
 
557
  struct system_status_var status_var; /**< Session-local status counters */
203
558
  THR_LOCK_INFO lock_info; /**< Locking information for this session */
204
559
  THR_LOCK_OWNER main_lock_id; /**< To use for conventional queries */
205
560
  THR_LOCK_OWNER *lock_id; /**< If not main_lock_id, points to the lock_id of a cursor. */
210
565
   */
211
566
  char *thread_stack;
212
567
 
213
 
  identifier::user::ptr user() const
214
 
  {
215
 
    return security_ctx;
216
 
  }
217
 
 
218
 
  void setUser(identifier::user::mptr arg)
 
568
private:
 
569
  identifier::User::shared_ptr security_ctx;
 
570
 
 
571
  int32_t scoreboard_index;
 
572
 
 
573
  inline void checkSentry() const
 
574
  {
 
575
    assert(this->dbug_sentry == Session_SENTRY_MAGIC);
 
576
  }
 
577
public:
 
578
  identifier::User::const_shared_ptr user() const
 
579
  {
 
580
    if (security_ctx)
 
581
      return security_ctx;
 
582
 
 
583
    return identifier::User::const_shared_ptr();
 
584
  }
 
585
 
 
586
  void setUser(identifier::User::shared_ptr arg)
219
587
  {
220
588
    security_ctx= arg;
221
589
  }
222
590
 
223
 
  int32_t getScoreboardIndex() const
 
591
  int32_t getScoreboardIndex()
224
592
  {
225
593
    return scoreboard_index;
226
594
  }
230
598
    scoreboard_index= in_scoreboard_index;
231
599
  }
232
600
 
233
 
  bool isOriginatingServerUUIDSet() const
234
 
  {
235
 
    return originating_server_uuid_set;
236
 
  }
237
 
 
238
 
  void setOriginatingServerUUID(std::string in_originating_server_uuid)
239
 
  {
240
 
    originating_server_uuid= in_originating_server_uuid;
241
 
    originating_server_uuid_set= true;
242
 
  }
243
 
 
244
 
  const std::string &getOriginatingServerUUID() const
245
 
  {
246
 
    return originating_server_uuid;
247
 
  }
248
 
 
249
 
  void setOriginatingCommitID(uint64_t in_originating_commit_id)
250
 
  {
251
 
    originating_commit_id= in_originating_commit_id;
252
 
  }
253
 
 
254
 
  uint64_t getOriginatingCommitID() const
255
 
  {
256
 
    return originating_commit_id;
257
 
  }
258
 
 
259
601
  /**
260
602
   * Is this session viewable by the current user?
261
603
   */
262
 
  bool isViewable(const identifier::User&) const;
 
604
  bool isViewable() const;
263
605
 
264
 
private:
265
606
  /**
266
607
    Used in error messages to tell user in what part of MySQL we found an
267
608
    error. E. g. when where= "having clause", if fix_fields() fails, user
268
609
    will know that the error was in having clause.
269
610
  */
270
 
  const char *_where;
271
 
 
272
 
public:
273
 
  const char *where() const
274
 
  {
275
 
    return _where;
276
 
  }
277
 
 
278
 
  void setWhere(const char *arg)
279
 
  {
280
 
    _where= arg;
281
 
  }
 
611
  const char *where;
282
612
 
283
613
  /*
284
614
    One thread can hold up to one named user-level lock. This variable
285
615
    points to a lock object if the lock is present. See item_func.cc and
286
616
    chapter 'Miscellaneous functions', for functions GET_LOCK, RELEASE_LOCK.
287
617
  */
288
 
 
 
618
  uint32_t dbug_sentry; /**< watch for memory corruption */
289
619
private:
290
620
  boost::thread::id boost_thread_id;
291
 
  thread_ptr _thread;
 
621
  boost_thread_shared_ptr _thread;
292
622
  boost::this_thread::disable_interruption *interrupt;
293
623
 
294
624
  internal::st_my_thread_var *mysys_var;
 
625
public:
295
626
 
296
 
public:
297
 
  thread_ptr &getThread()
 
627
  boost_thread_shared_ptr &getThread()
298
628
  {
299
629
    return _thread;
300
630
  }
319
649
   * Type of current query: COM_STMT_PREPARE, COM_QUERY, etc. Set from
320
650
   * first byte of the packet in executeStatement()
321
651
   */
322
 
  enum_server_command command;
 
652
  enum enum_server_command command;
 
653
  uint32_t file_id;     /**< File ID for LOAD DATA INFILE */
 
654
  /* @note the following three members should likely move to Client */
 
655
  uint32_t max_client_packet_length; /**< Maximum number of bytes a client can send in a single packet */
 
656
  time_t start_time;
 
657
  time_t user_time;
 
658
  uint64_t thr_create_utime; /**< track down slow pthread_create */
 
659
  uint64_t start_utime;
 
660
  uint64_t utime_after_lock;
323
661
 
324
662
  thr_lock_type update_lock_default;
325
663
 
340
678
  */
341
679
  query_id_t query_id;
342
680
  query_id_t warn_query_id;
343
 
 
344
681
public:
345
682
  void **getEngineData(const plugin::MonitoredInTransaction *monitored);
346
 
  ResourceContext& getResourceContext(const plugin::MonitoredInTransaction&, size_t index= 0);
347
 
 
348
 
  session::Transactions& transaction;
349
 
  Open_tables_state& open_tables;
350
 
        session::Times& times;
 
683
  ResourceContext *getResourceContext(const plugin::MonitoredInTransaction *monitored,
 
684
                                      size_t index= 0);
 
685
 
 
686
  /**
 
687
   * Structure used to manage "statement transactions" and
 
688
   * "normal transactions". In autocommit mode, the normal transaction is
 
689
   * equivalent to the statement transaction.
 
690
   *
 
691
   * Storage engines will be registered here when they participate in
 
692
   * a transaction. No engine is registered more than once.
 
693
   */
 
694
  struct st_transactions {
 
695
    std::deque<NamedSavepoint> savepoints;
 
696
 
 
697
    /**
 
698
     * The normal transaction (since BEGIN WORK).
 
699
     *
 
700
     * Contains a list of all engines that have participated in any of the
 
701
     * statement transactions started within the context of the normal
 
702
     * transaction.
 
703
     *
 
704
     * @note In autocommit mode, this is empty.
 
705
     */
 
706
    TransactionContext all;
 
707
 
 
708
    /**
 
709
     * The statment transaction.
 
710
     *
 
711
     * Contains a list of all engines participating in the given statement.
 
712
     *
 
713
     * @note In autocommit mode, this will be used to commit/rollback the
 
714
     * normal transaction.
 
715
     */
 
716
    TransactionContext stmt;
 
717
 
 
718
    XID_STATE xid_state;
 
719
 
 
720
    void cleanup()
 
721
    {
 
722
      savepoints.clear();
 
723
    }
 
724
    st_transactions() :
 
725
      savepoints(),
 
726
      all(),
 
727
      stmt(),
 
728
      xid_state()
 
729
    { }
 
730
  } transaction;
351
731
 
352
732
  Field *dup_field;
353
733
  sigset_t signals;
354
734
 
355
 
public:
356
735
  // As of right now we do not allow a concurrent execute to launch itself
 
736
private:
 
737
  bool concurrent_execute_allowed;
 
738
public:
 
739
 
357
740
  void setConcurrentExecute(bool arg)
358
741
  {
359
742
    concurrent_execute_allowed= arg;
364
747
    return concurrent_execute_allowed;
365
748
  }
366
749
 
 
750
  /* Tells if LAST_INSERT_ID(#) was called for the current statement */
 
751
  bool arg_of_last_insert_id_function;
 
752
 
367
753
  /*
368
754
    ALL OVER THIS FILE, "insert_id" means "*automatically generated* value for
369
755
    insertion into an auto_increment column".
410
796
    (first_successful_insert_id_in_cur_stmt == 0), but storing "INSERT_ID=3"
411
797
    in the binlog is still needed; the list's minimum will contain 3.
412
798
  */
 
799
  Discrete_intervals_list auto_inc_intervals_in_cur_stmt_for_binlog;
 
800
  /** Used by replication and SET INSERT_ID */
 
801
  Discrete_intervals_list auto_inc_intervals_forced;
413
802
 
414
803
  uint64_t limit_found_rows;
415
804
  uint64_t options; /**< Bitmap of options */
416
805
  int64_t row_count_func; /**< For the ROW_COUNT() function */
417
 
 
418
 
  int64_t rowCount() const
419
 
  {
420
 
    return row_count_func;
421
 
  }
422
 
 
423
806
  ha_rows cuted_fields; /**< Count of "cut" or truncated fields. @todo Kill this friggin thing. */
424
807
 
425
 
  /**
 
808
  /** 
426
809
   * Number of rows we actually sent to the client, including "synthetic"
427
810
   * rows in ROLLUP etc.
428
811
   */
438
821
   * of the query.
439
822
   *
440
823
   * @todo
441
 
   *
 
824
   * 
442
825
   * Possibly this it is incorrect to have used tables in Session because
443
826
   * with more than one subquery, it is not clear what does the field mean.
444
827
   */
446
829
 
447
830
  /**
448
831
    @todo
449
 
 
 
832
    
450
833
    This, and some other variables like 'count_cuted_fields'
451
834
    maybe should be statement/cursor local, that is, moved to Statement
452
835
    class. With current implementation warnings produced in each prepared
453
836
    statement/cursor settle here.
454
837
  */
 
838
  List<DRIZZLE_ERROR> warn_list;
455
839
  uint32_t warn_count[(uint32_t) DRIZZLE_ERROR::WARN_LEVEL_END];
456
840
  uint32_t total_warn_count;
457
 
 
 
841
  Diagnostics_area main_da;
 
842
 
 
843
  ulong col_access;
 
844
 
 
845
  /* Statement id is thread-wide. This counter is used to generate ids */
 
846
  uint32_t statement_id_counter;
 
847
  uint32_t rand_saved_seed1;
 
848
  uint32_t rand_saved_seed2;
458
849
  /**
459
850
    Row counter, mainly for errors and warnings. Not increased in
460
851
    create_sort_index(); may differ from examined_row_count.
461
852
  */
462
853
  uint32_t row_count;
463
 
 
464
854
  session_id_t thread_id;
465
855
  uint32_t tmp_table;
466
856
  enum global_read_lock_t
484
874
    _global_read_lock= arg;
485
875
  }
486
876
 
487
 
  DrizzleLock *lockTables(Table **tables, uint32_t count, uint32_t flags);
 
877
  DrizzleLock *lockTables(Table **tables, uint32_t count, uint32_t flags, bool *need_reopen);
488
878
  bool lockGlobalReadLock();
489
879
  bool lock_table_names(TableList *table_list);
490
880
  bool lock_table_names_exclusively(TableList *table_list);
533
923
    _killed= arg;
534
924
  }
535
925
 
536
 
  killed_state_t getKilled() const
 
926
  killed_state_t getKilled()
537
927
  {
538
928
    return _killed;
539
929
  }
544
934
  }
545
935
 
546
936
  bool is_admin_connection;
 
937
  bool some_tables_deleted;
547
938
  bool no_errors;
 
939
  bool password;
548
940
  /**
549
941
    Set to true if execution of the current compound statement
550
942
    can not continue. In particular, disables activation of
551
943
    CONTINUE or EXIT handlers of stored routines.
552
944
    Reset in the end of processing of the current user request, in
553
 
    @see reset_session_for_next_command().
 
945
    @see mysql_reset_session_for_next_command().
554
946
  */
555
947
  bool is_fatal_error;
556
948
  /**
575
967
  bool substitute_null_with_insert_id;
576
968
  bool cleanup_done;
577
969
 
578
 
public:
 
970
  bool abort_on_warning;
579
971
  bool got_warning; /**< Set on call to push_warning() */
580
972
  bool no_warnings_for_error; /**< no warnings on call to my_error() */
581
973
  /** set during loop of derived table processing */
582
974
  bool derived_tables_processing;
583
 
 
584
 
  bool doing_tablespace_operation() const
585
 
  {
586
 
    return tablespace_op;
587
 
  }
588
 
 
589
 
  void setDoingTablespaceOperation(bool doing)
590
 
  {
591
 
    tablespace_op= doing;
592
 
  }
593
 
 
 
975
  bool tablespace_op; /**< This is true in DISCARD/IMPORT TABLESPACE */
594
976
 
595
977
  /** Used by the sys_var class to store temporary values */
596
978
  union
609
991
    and may point to invalid memory after that.
610
992
  */
611
993
  Lex_input_stream *m_lip;
612
 
 
 
994
  
613
995
  /** Place to store various things */
614
996
  void *session_marker;
615
997
 
 
998
  /** Keeps a copy of the previous table around in case we are just slamming on particular table */
 
999
  Table *cached_table;
 
1000
 
616
1001
  /**
617
1002
    Points to info-string that we show in SHOW PROCESSLIST
618
1003
    You are supposed to call Session_SET_PROC_INFO only if you have coded
622
1007
    macro/function.
623
1008
  */
624
1009
  inline void set_proc_info(const char *info)
625
 
  {
 
1010
  { 
626
1011
    proc_info= info;
627
1012
  }
628
1013
  inline const char* get_proc_info() const
668
1053
    return server_id;
669
1054
  }
670
1055
 
671
 
  inline std::string &getServerUUID() const
 
1056
  /** Returns the current transaction ID for the session's current statement */
 
1057
  inline my_xid getTransactionId()
672
1058
  {
673
 
    return server_uuid;
 
1059
    return transaction.xid_state.xid.quick_get_my_xid();
674
1060
  }
675
 
 
676
1061
  /**
677
1062
    There is BUG#19630 where statement-based replication of stored
678
1063
    functions/triggers with two auto_increment columns breaks.
714
1099
    if (first_successful_insert_id_in_cur_stmt == 0)
715
1100
      first_successful_insert_id_in_cur_stmt= id_arg;
716
1101
  }
717
 
  inline uint64_t read_first_successful_insert_id_in_prev_stmt() const
 
1102
  inline uint64_t read_first_successful_insert_id_in_prev_stmt(void)
718
1103
  {
719
1104
    return first_successful_insert_id_in_prev_stmt;
720
1105
  }
721
 
 
722
 
  Session(plugin::Client*, boost::shared_ptr<catalog::Instance>);
723
 
  ~Session();
724
 
 
725
 
  void cleanup();
 
1106
  /**
 
1107
    Used by Intvar_log_event::do_apply_event() and by "SET INSERT_ID=#"
 
1108
    (mysqlbinlog). We'll soon add a variant which can take many intervals in
 
1109
    argument.
 
1110
  */
 
1111
  inline void force_one_auto_inc_interval(uint64_t next_id)
 
1112
  {
 
1113
    auto_inc_intervals_forced.empty(); // in case of multiple SET INSERT_ID
 
1114
    auto_inc_intervals_forced.append(next_id, UINT64_MAX, 0);
 
1115
  }
 
1116
 
 
1117
  Session(plugin::Client *client_arg);
 
1118
  virtual ~Session();
 
1119
 
 
1120
  void cleanup(void);
726
1121
  /**
727
1122
   * Cleans up after query.
728
1123
   *
736
1131
   * slave.
737
1132
   */
738
1133
  void cleanup_after_query();
739
 
  void storeGlobals();
 
1134
  bool storeGlobals();
740
1135
  void awake(Session::killed_state_t state_to_set);
 
1136
  /**
 
1137
   * Pulls thread-specific variables into Session state.
 
1138
   *
 
1139
   * Returns true most times, or false if there was a problem
 
1140
   * allocating resources for thread-specific storage.
 
1141
   *
 
1142
   * @TODO Kill this.  It's not necessary once my_thr_init() is bye bye.
 
1143
   *
 
1144
   */
 
1145
  bool initGlobals();
741
1146
 
742
1147
  /**
743
1148
    Initialize memory roots necessary for query processing and (!)
748
1153
  void prepareForQueries();
749
1154
 
750
1155
  /**
751
 
   * Executes a single statement received from the
 
1156
   * Executes a single statement received from the 
752
1157
   * client connection.
753
1158
   *
754
 
   * Returns true if the statement was successful, or false
 
1159
   * Returns true if the statement was successful, or false 
755
1160
   * otherwise.
756
1161
   *
757
1162
   * @note
766
1171
  /**
767
1172
   * Reads a query from packet and stores it.
768
1173
   *
769
 
   * Returns true if query is read and allocated successfully,
 
1174
   * Returns true if query is read and allocated successfully, 
770
1175
   * false otherwise.  On a return of false, Session::fatal_error
771
1176
   * is set.
772
1177
   *
779
1184
   * @param The packet pointer to read from
780
1185
   * @param The length of the query to read
781
1186
   */
782
 
  void readAndStoreQuery(const char *in_packet, uint32_t in_packet_length);
 
1187
  bool readAndStoreQuery(const char *in_packet, uint32_t in_packet_length);
783
1188
 
784
1189
  /**
785
1190
   * Ends the current transaction and (maybe) begins the next.
786
1191
   *
787
 
   * Returns true if the transaction completed successfully,
 
1192
   * Returns true if the transaction completed successfully, 
788
1193
   * otherwise false.
789
1194
   *
790
1195
   * @param Completion type
792
1197
  bool endTransaction(enum enum_mysql_completiontype completion);
793
1198
  bool endActiveTransaction();
794
1199
  bool startTransaction(start_transaction_option_t opt= START_TRANS_NO_OPTIONS);
795
 
  void markTransactionForRollback(bool all);
796
1200
 
797
1201
  /**
798
1202
   * Authenticates users, with error reporting.
800
1204
   * Returns true on success, or false on failure.
801
1205
   */
802
1206
  bool authenticate();
 
1207
 
 
1208
  /**
 
1209
   * Run a session.
 
1210
   *
 
1211
   * This will initialize the session and begin the command loop.
 
1212
   */
803
1213
  void run();
804
 
  static bool schedule(const Session::shared_ptr&);
805
 
  static void unlink(session_id_t&);
806
 
  static void unlink(const Session::shared_ptr&);
 
1214
 
 
1215
  /**
 
1216
   * Schedule a session to be run on the default scheduler.
 
1217
   */
 
1218
  static bool schedule(Session::shared_ptr&);
 
1219
 
 
1220
  static void unlink(Session::shared_ptr&);
807
1221
 
808
1222
  /*
809
1223
    For enter_cond() / exit_cond() to work the mutex must be got before
813
1227
  const char* enter_cond(boost::condition_variable_any &cond, boost::mutex &mutex, const char* msg);
814
1228
  void exit_cond(const char* old_msg);
815
1229
 
816
 
  uint64_t found_rows() const
 
1230
  inline time_t query_start() { return start_time; }
 
1231
  inline void set_time()
 
1232
  {
 
1233
    boost::posix_time::ptime mytime(boost::posix_time::microsec_clock::local_time());
 
1234
    boost::posix_time::ptime epoch(boost::gregorian::date(1970,1,1));
 
1235
    start_utime= utime_after_lock= (mytime-epoch).total_microseconds();
 
1236
 
 
1237
    if (user_time)
 
1238
    {
 
1239
      start_time= user_time;
 
1240
      connect_microseconds= start_utime;
 
1241
    }
 
1242
    else 
 
1243
      start_time= (mytime-epoch).total_seconds();
 
1244
  }
 
1245
  inline void   set_current_time()    { start_time= time(NULL); }
 
1246
  inline void   set_time(time_t t)
 
1247
  {
 
1248
    start_time= user_time= t;
 
1249
    boost::posix_time::ptime mytime(boost::posix_time::microsec_clock::local_time());
 
1250
    boost::posix_time::ptime epoch(boost::gregorian::date(1970,1,1));
 
1251
    uint64_t t_mark= (mytime-epoch).total_microseconds();
 
1252
 
 
1253
    start_utime= utime_after_lock= t_mark;
 
1254
  }
 
1255
  void set_time_after_lock()  { 
 
1256
     boost::posix_time::ptime mytime(boost::posix_time::microsec_clock::local_time());
 
1257
     boost::posix_time::ptime epoch(boost::gregorian::date(1970,1,1));
 
1258
     utime_after_lock= (mytime-epoch).total_microseconds();
 
1259
  }
 
1260
  /**
 
1261
   * Returns the current micro-timestamp
 
1262
   */
 
1263
  inline uint64_t getCurrentTimestamp()  
 
1264
  { 
 
1265
    boost::posix_time::ptime mytime(boost::posix_time::microsec_clock::local_time());
 
1266
    boost::posix_time::ptime epoch(boost::gregorian::date(1970,1,1));
 
1267
    uint64_t t_mark= (mytime-epoch).total_microseconds();
 
1268
 
 
1269
    return t_mark; 
 
1270
  }
 
1271
  inline uint64_t found_rows(void)
817
1272
  {
818
1273
    return limit_found_rows;
819
1274
  }
820
 
 
821
1275
  /** Returns whether the session is currently inside a transaction */
822
 
  bool inTransaction() const
 
1276
  inline bool inTransaction()
823
1277
  {
824
1278
    return server_status & SERVER_STATUS_IN_TRANS;
825
1279
  }
826
 
 
827
 
  lex_string_t* make_lex_string(lex_string_t*, str_ref);
828
 
 
829
 
  void send_explain_fields(select_result*);
830
 
 
831
 
  void clear_error(bool full= false);
832
 
  void clearDiagnostics();
833
 
  bool is_error() const;
834
 
 
835
 
  static const charset_info_st *charset() { return default_charset_info; }
836
 
 
 
1280
  LEX_STRING *make_lex_string(LEX_STRING *lex_str,
 
1281
                              const char* str, uint32_t length,
 
1282
                              bool allocate_lex_string);
 
1283
  LEX_STRING *make_lex_string(LEX_STRING *lex_str,
 
1284
                              const std::string &str,
 
1285
                              bool allocate_lex_string);
 
1286
 
 
1287
  int send_explain_fields(select_result *result);
 
1288
  /**
 
1289
    Clear the current error, if any.
 
1290
    We do not clear is_fatal_error or is_fatal_sub_stmt_error since we
 
1291
    assume this is never called if the fatal error is set.
 
1292
    @todo: To silence an error, one should use Internal_error_handler
 
1293
    mechanism. In future this function will be removed.
 
1294
  */
 
1295
  inline void clear_error(bool full= false)
 
1296
  {
 
1297
    if (main_da.is_error())
 
1298
      main_da.reset_diagnostics_area();
 
1299
 
 
1300
    if (full)
 
1301
    {
 
1302
      drizzle_reset_errors(this, true);
 
1303
    }
 
1304
  }
 
1305
 
 
1306
  void clearDiagnostics()
 
1307
  {
 
1308
    main_da.reset_diagnostics_area();
 
1309
  }
 
1310
 
 
1311
  /**
 
1312
    Mark the current error as fatal. Warning: this does not
 
1313
    set any error, it sets a property of the error, so must be
 
1314
    followed or prefixed with my_error().
 
1315
  */
 
1316
  inline void fatal_error()
 
1317
  {
 
1318
    assert(main_da.is_error());
 
1319
    is_fatal_error= true;
 
1320
  }
 
1321
  /**
 
1322
    true if there is an error in the error stack.
 
1323
 
 
1324
    Please use this method instead of direct access to
 
1325
    net.report_error.
 
1326
 
 
1327
    If true, the current (sub)-statement should be aborted.
 
1328
    The main difference between this member and is_fatal_error
 
1329
    is that a fatal error can not be handled by a stored
 
1330
    procedure continue handler, whereas a normal error can.
 
1331
 
 
1332
    To raise this flag, use my_error().
 
1333
  */
 
1334
  inline bool is_error() const { return main_da.is_error(); }
 
1335
  inline const CHARSET_INFO *charset() { return default_charset_info; }
 
1336
 
 
1337
  void change_item_tree(Item **place, Item *new_value)
 
1338
  {
 
1339
    *place= new_value;
 
1340
  }
837
1341
  /**
838
1342
    Cleanup statement parse state (parse tree, lex) and execution
839
1343
    state after execution of a non-prepared SQL statement.
850
1354
  }
851
1355
  void send_kill_message() const;
852
1356
  /* return true if we will abort query if we make a warning now */
853
 
  inline bool abortOnWarning()
854
 
  {
855
 
    return abort_on_warning;
856
 
  }
857
 
 
858
 
  inline void setAbortOnWarning(bool arg)
859
 
  {
860
 
    abort_on_warning= arg;
 
1357
  inline bool really_abort_on_warning()
 
1358
  {
 
1359
    return (abort_on_warning);
861
1360
  }
862
1361
 
863
1362
  void setAbort(bool arg);
864
1363
  void lockOnSys();
865
1364
  void set_status_var_init();
 
1365
 
866
1366
  /**
867
1367
    Set the current database; use deep copy of C-string.
868
1368
 
880
1380
    attributes including security context. In the future, this operation
881
1381
    will be made private and more convenient interface will be provided.
882
1382
  */
883
 
  void set_schema(const std::string&);
 
1383
  void set_db(const std::string &new_db);
884
1384
 
885
1385
  /*
886
1386
    Copy the current database to the argument. Use the current arena to
887
1387
    allocate memory for a deep copy: current database may be freed after
888
1388
    a statement is parsed but before it's executed.
889
1389
  */
890
 
  bool copy_db_to(char*& p_db, size_t& p_db_length);
 
1390
  bool copy_db_to(char **p_db, size_t *p_db_length);
891
1391
 
892
1392
public:
 
1393
  /**
 
1394
    Add an internal error handler to the thread execution context.
 
1395
    @param handler the exception handler to add
 
1396
  */
 
1397
  void push_internal_handler(Internal_error_handler *handler);
 
1398
 
 
1399
  /**
 
1400
    Handle an error condition.
 
1401
    @param sql_errno the error number
 
1402
    @param level the error level
 
1403
    @return true if the error is handled
 
1404
  */
 
1405
  virtual bool handle_error(uint32_t sql_errno, const char *message,
 
1406
                            DRIZZLE_ERROR::enum_warning_level level);
 
1407
 
 
1408
  /**
 
1409
    Remove the error handler last pushed.
 
1410
  */
 
1411
  void pop_internal_handler();
893
1412
 
894
1413
  /**
895
1414
    Resets Session part responsible for command processing state.
911
1430
   * updates any status variables necessary.
912
1431
   *
913
1432
   * @param errcode     Error code to print to console
 
1433
   * @param should_lock 1 if we have have to lock LOCK_thread_count
914
1434
   *
915
1435
   * @note  For the connection that is doing shutdown, this is called twice
916
1436
   */
917
 
  void disconnect(enum error_t errcode= EE_OK);
 
1437
  void disconnect(uint32_t errcode, bool lock);
918
1438
 
919
1439
  /**
920
1440
   * Check if user exists and the password supplied is correct.
923
1443
   *
924
1444
   * @note Host, user and passwd may point to communication buffer.
925
1445
   * Current implementation does not depend on that, but future changes
926
 
   * should be done with this in mind;
 
1446
   * should be done with this in mind; 
927
1447
   *
928
1448
   * @param passwd Scrambled password received from client
929
1449
   * @param db Database name to connect to, may be NULL
930
1450
   */
931
1451
  bool checkUser(const std::string &passwd, const std::string &db);
 
1452
  
 
1453
  /**
 
1454
   * Returns the timestamp (in microseconds) of when the Session 
 
1455
   * connected to the server.
 
1456
   */
 
1457
  inline uint64_t getConnectMicroseconds() const
 
1458
  {
 
1459
    return connect_microseconds;
 
1460
  }
932
1461
 
933
1462
  /**
934
1463
   * Returns a pointer to the active Transaction message for this
948
1477
  {
949
1478
    return statement_message;
950
1479
  }
951
 
 
 
1480
  
952
1481
  /**
953
1482
   * Returns a pointer to the current Resulset message for this
954
1483
   * Session, or NULL if no active message.
995
1524
   */
996
1525
 
997
1526
  void resetResultsetMessage()
998
 
  {
 
1527
  { 
999
1528
    resultset= NULL;
1000
1529
  }
1001
1530
 
1002
 
  plugin::EventObserverList *getSessionObservers()
1003
 
  {
 
1531
private:
 
1532
  /** Pointers to memory managed by the ReplicationServices component */
 
1533
  message::Transaction *transaction_message;
 
1534
  message::Statement *statement_message;
 
1535
  /* Pointer to the current resultset of Select query */
 
1536
  message::Resultset *resultset;
 
1537
  plugin::EventObserverList *session_event_observers;
 
1538
  
 
1539
  /* Schema observers are mapped to databases. */
 
1540
  std::map<std::string, plugin::EventObserverList *> schema_event_observers;
 
1541
 
 
1542
 
 
1543
public:
 
1544
  plugin::EventObserverList *getSessionObservers() 
 
1545
  { 
1004
1546
    return session_event_observers;
1005
1547
  }
1006
 
 
1007
 
  void setSessionObservers(plugin::EventObserverList *observers)
1008
 
  {
 
1548
  
 
1549
  void setSessionObservers(plugin::EventObserverList *observers) 
 
1550
  { 
1009
1551
    session_event_observers= observers;
1010
1552
  }
1011
 
 
1012
 
  plugin::EventObserverList* getSchemaObservers(const std::string& schema);
1013
 
  plugin::EventObserverList* setSchemaObservers(const std::string& schema, plugin::EventObserverList*);
 
1553
  
 
1554
  /* For schema event observers there is one set of observers per database. */
 
1555
  plugin::EventObserverList *getSchemaObservers(const std::string &db_name) 
 
1556
  { 
 
1557
    std::map<std::string, plugin::EventObserverList *>::iterator it;
 
1558
    
 
1559
    it= schema_event_observers.find(db_name);
 
1560
    if (it == schema_event_observers.end())
 
1561
      return NULL;
 
1562
      
 
1563
    return it->second;
 
1564
  }
 
1565
  
 
1566
  void setSchemaObservers(const std::string &db_name, plugin::EventObserverList *observers) 
 
1567
  { 
 
1568
    std::map<std::string, plugin::EventObserverList *>::iterator it;
 
1569
 
 
1570
    it= schema_event_observers.find(db_name);
 
1571
    if (it != schema_event_observers.end())
 
1572
      schema_event_observers.erase(it);;
 
1573
 
 
1574
    if (observers)
 
1575
      schema_event_observers[db_name] = observers;
 
1576
  }
 
1577
  
 
1578
  
 
1579
 private:
 
1580
 /** Microsecond timestamp of when Session connected */
 
1581
  uint64_t connect_microseconds;
 
1582
  const char *proc_info;
 
1583
 
 
1584
  /** The current internal error handler for this thread, or NULL. */
 
1585
  Internal_error_handler *m_internal_handler;
 
1586
  /**
 
1587
    The lex to hold the parsed tree of conventional (non-prepared) queries.
 
1588
    Whereas for prepared and stored procedure statements we use an own lex
 
1589
    instance for each new query, for conventional statements we reuse
 
1590
    the same lex. (@see mysql_parse for details).
 
1591
  */
 
1592
  LEX main_lex;
 
1593
  /**
 
1594
    This memory root is used for two purposes:
 
1595
    - for conventional queries, to allocate structures stored in main_lex
 
1596
    during parsing, and allocate runtime data (execution plan, etc.)
 
1597
    during execution.
 
1598
    - for prepared queries, only to allocate runtime data. The parsed
 
1599
    tree itself is reused between executions and thus is stored elsewhere.
 
1600
  */
 
1601
  memory::Root main_mem_root;
 
1602
 
 
1603
  /**
 
1604
   * Marks all tables in the list which were used by current substatement
 
1605
   * as free for reuse.
 
1606
   *
 
1607
   * @param Head of the list of tables
 
1608
   *
 
1609
   * @note
 
1610
   *
 
1611
   * The reason we reset query_id is that it's not enough to just test
 
1612
   * if table->query_id != session->query_id to know if a table is in use.
 
1613
   *
 
1614
   * For example
 
1615
   * 
 
1616
   *  SELECT f1_that_uses_t1() FROM t1;
 
1617
   *  
 
1618
   * In f1_that_uses_t1() we will see one instance of t1 where query_id is
 
1619
   * set to query_id of original query.
 
1620
   */
 
1621
  void mark_used_tables_as_free_for_reuse(Table *table);
1014
1622
 
1015
1623
public:
1016
 
  void my_ok(ha_rows affected_rows= 0, ha_rows found_rows_arg= 0, uint64_t passed_id= 0, const char *message= NULL);
1017
 
  void my_eof();
1018
 
  void add_item_to_list(Item *item);
1019
 
  void add_value_to_list(Item *value);
1020
 
  void add_order_to_list(Item *item, bool asc);
1021
 
  void add_group_to_list(Item *item, bool asc);
1022
 
 
 
1624
 
 
1625
  /** A short cut for session->main_da.set_ok_status(). */
 
1626
  inline void my_ok(ha_rows affected_rows= 0, ha_rows found_rows_arg= 0,
 
1627
                    uint64_t passed_id= 0, const char *message= NULL)
 
1628
  {
 
1629
    main_da.set_ok_status(this, affected_rows, found_rows_arg, passed_id, message);
 
1630
  }
 
1631
 
 
1632
 
 
1633
  /** A short cut for session->main_da.set_eof_status(). */
 
1634
 
 
1635
  inline void my_eof()
 
1636
  {
 
1637
    main_da.set_eof_status(this);
 
1638
  }
 
1639
 
 
1640
  /* Some inline functions for more speed */
 
1641
 
 
1642
  inline bool add_item_to_list(Item *item)
 
1643
  {
 
1644
    return lex->current_select->add_item_to_list(this, item);
 
1645
  }
 
1646
 
 
1647
  inline bool add_value_to_list(Item *value)
 
1648
  {
 
1649
    return lex->value_list.push_back(value);
 
1650
  }
 
1651
 
 
1652
  inline bool add_order_to_list(Item *item, bool asc)
 
1653
  {
 
1654
    return lex->current_select->add_order_to_list(this, item, asc);
 
1655
  }
 
1656
 
 
1657
  inline bool add_group_to_list(Item *item, bool asc)
 
1658
  {
 
1659
    return lex->current_select->add_group_to_list(this, item, asc);
 
1660
  }
1023
1661
  void refresh_status();
1024
 
  user_var_entry *getVariable(lex_string_t &name, bool create_if_not_exists);
 
1662
  user_var_entry *getVariable(LEX_STRING &name, bool create_if_not_exists);
1025
1663
  user_var_entry *getVariable(const std::string  &name, bool create_if_not_exists);
1026
1664
  void setVariable(const std::string &name, const std::string &value);
1027
 
 
 
1665
  
1028
1666
  /**
1029
1667
   * Closes all tables used by the current substatement, or all tables
1030
1668
   * used by this thread if we are on the upper level.
1032
1670
  void close_thread_tables();
1033
1671
  void close_old_data_files(bool morph_locks= false,
1034
1672
                            bool send_refresh= false);
1035
 
  void close_data_files_and_morph_locks(const identifier::Table &identifier);
 
1673
  void close_open_tables();
 
1674
  void close_data_files_and_morph_locks(const TableIdentifier &identifier);
 
1675
 
 
1676
private:
 
1677
  bool free_cached_table();
 
1678
public:
1036
1679
 
1037
1680
  /**
1038
1681
   * Prepares statement for reopening of tables and recalculation of set of
1054
1697
   *  true  - error
1055
1698
   *
1056
1699
   * @note
1057
 
   *
 
1700
   * 
1058
1701
   * The lock will automaticaly be freed by close_thread_tables()
1059
1702
   */
1060
 
  bool openTablesLock(TableList*);
1061
 
  Table *open_temporary_table(const identifier::Table &identifier, bool link_in_list= true);
 
1703
  bool openTablesLock(TableList *tables);
1062
1704
 
1063
1705
  int open_tables_from_list(TableList **start, uint32_t *counter, uint32_t flags= 0);
1064
1706
 
1066
1708
  Table *openTable(TableList *table_list, bool *refresh, uint32_t flags= 0);
1067
1709
 
1068
1710
  void unlink_open_table(Table *find);
1069
 
  void drop_open_table(Table *table, const identifier::Table &identifier);
 
1711
  void drop_open_table(Table *table, const TableIdentifier &identifier);
1070
1712
  void close_cached_table(Table *table);
1071
1713
 
1072
1714
  /* Create a lock in the cache */
1073
 
  table::Placeholder& table_cache_insert_placeholder(const identifier::Table&);
1074
 
  Table* lock_table_name_if_not_cached(const identifier::Table&);
1075
 
 
1076
 
  session::TableMessages &getMessageCache();
 
1715
  table::Placeholder *table_cache_insert_placeholder(const TableIdentifier &identifier);
 
1716
  bool lock_table_name_if_not_cached(const TableIdentifier &identifier, Table **table);
 
1717
 
 
1718
  typedef boost::unordered_map<std::string, message::Table, util::insensitive_hash, util::insensitive_equal_to> TableMessageCache;
 
1719
 
 
1720
  class TableMessages
 
1721
  {
 
1722
    TableMessageCache table_message_cache;
 
1723
 
 
1724
  public:
 
1725
    bool storeTableMessage(const TableIdentifier &identifier, message::Table &table_message);
 
1726
    bool removeTableMessage(const TableIdentifier &identifier);
 
1727
    bool getTableMessage(const TableIdentifier &identifier, message::Table &table_message);
 
1728
    bool doesTableMessageExist(const TableIdentifier &identifier);
 
1729
    bool renameTableMessage(const TableIdentifier &from, const TableIdentifier &to);
 
1730
 
 
1731
  };
 
1732
private:
 
1733
  TableMessages _table_message_cache;
 
1734
 
 
1735
public:
 
1736
  TableMessages &getMessageCache()
 
1737
  {
 
1738
    return _table_message_cache;
 
1739
  }
1077
1740
 
1078
1741
  /* Reopen operations */
1079
 
  bool reopen_tables();
 
1742
  bool reopen_tables(bool get_locks, bool mark_share_as_old);
1080
1743
  bool close_cached_tables(TableList *tables, bool wait_for_refresh, bool wait_for_placeholders);
1081
1744
 
1082
1745
  void wait_for_condition(boost::mutex &mutex, boost::condition_variable_any &cond);
1083
1746
  int setup_conds(TableList *leaves, COND **conds);
1084
1747
  int lock_tables(TableList *tables, uint32_t count, bool *need_reopen);
1085
1748
 
1086
 
  template <class T>
1087
 
  T* getProperty(const std::string& name)
 
1749
  drizzled::util::Storable *getProperty(const std::string &arg)
1088
1750
  {
1089
 
    return static_cast<T*>(getProperty0(name));
 
1751
    return life_properties[arg];
1090
1752
  }
1091
1753
 
1092
 
  template <class T>
1093
 
  T setProperty(const std::string& name, T value)
 
1754
  template<class T>
 
1755
  bool setProperty(const std::string &arg, T *value)
1094
1756
  {
1095
 
    setProperty0(name, value);
1096
 
    return value;
 
1757
    life_properties[arg]= value;
 
1758
 
 
1759
    return true;
1097
1760
  }
1098
1761
 
1099
1762
  /**
1104
1767
    @return
1105
1768
    pointer to plugin::StorageEngine
1106
1769
  */
1107
 
  plugin::StorageEngine *getDefaultStorageEngine();
1108
 
  void get_xid(DrizzleXid *xid) const; // Innodb only
1109
 
 
1110
 
  table::Singular& getInstanceTable();
1111
 
  table::Singular& getInstanceTable(std::list<CreateField>&);
 
1770
  plugin::StorageEngine *getDefaultStorageEngine()
 
1771
  {
 
1772
    if (variables.storage_engine)
 
1773
      return variables.storage_engine;
 
1774
    return global_system_variables.storage_engine;
 
1775
  }
 
1776
 
 
1777
  void get_xid(DRIZZLE_XID *xid); // Innodb only
 
1778
 
 
1779
  table::Instance *getInstanceTable();
 
1780
  table::Instance *getInstanceTable(List<CreateField> &field_list);
 
1781
 
 
1782
private:
 
1783
  bool resetUsage()
 
1784
  {
 
1785
    if (getrusage(RUSAGE_THREAD, &usage))
 
1786
    {
 
1787
      return false;
 
1788
    }
 
1789
 
 
1790
    return true;
 
1791
  }
 
1792
public:
1112
1793
 
1113
1794
  void setUsage(bool arg)
1114
1795
  {
1115
1796
    use_usage= arg;
1116
1797
  }
1117
1798
 
1118
 
  const rusage &getUsage()
 
1799
  const struct rusage &getUsage()
1119
1800
  {
1120
1801
    return usage;
1121
1802
  }
1122
1803
 
1123
 
  const catalog::Instance& catalog() const
1124
 
  {
1125
 
    return *_catalog;
1126
 
  }
1127
 
 
1128
 
  catalog::Instance& catalog()
1129
 
  {
1130
 
    return *_catalog;
1131
 
  }
1132
 
 
1133
 
  bool arg_of_last_insert_id_function; // Tells if LAST_INSERT_ID(#) was called for the current statement
1134
1804
private:
1135
 
  drizzled::util::Storable* getProperty0(const std::string&);
1136
 
  void setProperty0(const std::string&, drizzled::util::Storable*);
1137
 
 
1138
 
  bool resetUsage()
1139
 
  {
1140
 
    return not getrusage(RUSAGE_THREAD, &usage);
1141
 
  }
1142
 
 
1143
 
  boost::shared_ptr<catalog::Instance> _catalog;
1144
 
 
1145
 
  /** Pointers to memory managed by the ReplicationServices component */
1146
 
  message::Transaction *transaction_message;
1147
 
  message::Statement *statement_message;
1148
 
  /* Pointer to the current resultset of Select query */
1149
 
  message::Resultset *resultset;
1150
 
  plugin::EventObserverList *session_event_observers;
1151
 
 
1152
 
  uint64_t xa_id;
1153
 
  const char *proc_info;
1154
 
  bool abort_on_warning;
1155
 
  bool concurrent_execute_allowed;
1156
 
  bool tablespace_op; /**< This is true in DISCARD/IMPORT TABLESPACE */
 
1805
  // This lives throughout the life of Session
1157
1806
  bool use_usage;
1158
 
  rusage usage;
1159
 
  identifier::user::mptr security_ctx;
1160
 
  int32_t scoreboard_index;
1161
 
  bool originating_server_uuid_set;
1162
 
  std::string originating_server_uuid;
1163
 
  uint64_t originating_commit_id;
1164
 
  plugin::Client *client;
 
1807
  PropertyMap life_properties;
 
1808
  std::vector<table::Instance *> temporary_shares;
 
1809
  struct rusage usage;
1165
1810
};
1166
1811
 
 
1812
class Join;
 
1813
 
1167
1814
#define ESCAPE_CHARS "ntrb0ZN" // keep synchronous with READ_INFO::unescape
1168
1815
 
 
1816
} /* namespace drizzled */
 
1817
 
 
1818
/** @TODO why is this in the middle of the file */
 
1819
#include <drizzled/select_to_file.h>
 
1820
#include <drizzled/select_export.h>
 
1821
#include <drizzled/select_dump.h>
 
1822
#include <drizzled/select_insert.h>
 
1823
#include <drizzled/select_create.h>
 
1824
#include <drizzled/tmp_table_param.h>
 
1825
#include <drizzled/select_union.h>
 
1826
#include <drizzled/select_subselect.h>
 
1827
#include <drizzled/select_singlerow_subselect.h>
 
1828
#include <drizzled/select_max_min_finder_subselect.h>
 
1829
#include <drizzled/select_exists_subselect.h>
 
1830
 
 
1831
namespace drizzled
 
1832
{
 
1833
 
 
1834
/**
 
1835
 * A structure used to describe sort information
 
1836
 * for a field or item used in ORDER BY.
 
1837
 */
 
1838
class SortField 
 
1839
{
 
1840
public:
 
1841
  Field *field; /**< Field to sort */
 
1842
  Item  *item; /**< Item if not sorting fields */
 
1843
  size_t length; /**< Length of sort field */
 
1844
  uint32_t suffix_length; /**< Length suffix (0-4) */
 
1845
  Item_result result_type; /**< Type of item */
 
1846
  bool reverse; /**< if descending sort */
 
1847
  bool need_strxnfrm;   /**< If we have to use strxnfrm() */
 
1848
 
 
1849
  SortField() :
 
1850
    field(0),
 
1851
    item(0),
 
1852
    length(0),
 
1853
    suffix_length(0),
 
1854
    result_type(STRING_RESULT),
 
1855
    reverse(0),
 
1856
    need_strxnfrm(0)
 
1857
  { }
 
1858
 
 
1859
};
 
1860
 
 
1861
} /* namespace drizzled */
 
1862
 
 
1863
/** @TODO why is this in the middle of the file */
 
1864
 
 
1865
#include <drizzled/table_ident.h>
 
1866
#include <drizzled/user_var_entry.h>
 
1867
#include <drizzled/unique.h>
 
1868
#include <drizzled/var.h>
 
1869
#include <drizzled/select_dumpvar.h>
 
1870
 
 
1871
namespace drizzled
 
1872
{
 
1873
 
1169
1874
/* Bits in sql_command_flags */
1170
1875
 
1171
 
enum sql_command_flag_bits
 
1876
enum sql_command_flag_bits 
1172
1877
{
1173
1878
  CF_BIT_CHANGES_DATA,
1174
1879
  CF_BIT_HAS_ROW_COUNT,
1184
1889
static const std::bitset<CF_BIT_SIZE> CF_SHOW_TABLE_COMMAND(1 << CF_BIT_SHOW_TABLE_COMMAND);
1185
1890
static const std::bitset<CF_BIT_SIZE> CF_WRITE_LOGS_COMMAND(1 << CF_BIT_WRITE_LOGS_COMMAND);
1186
1891
 
1187
 
namespace display  
1188
 
{
1189
 
  const std::string &type(Session::global_read_lock_t);
1190
 
  size_t max_string_length(Session::global_read_lock_t);
 
1892
namespace display  {
 
1893
const std::string &type(drizzled::Session::global_read_lock_t type);
 
1894
size_t max_string_length(drizzled::Session::global_read_lock_t type);
1191
1895
} /* namespace display */
1192
1896
 
1193
1897
} /* namespace drizzled */
1194
1898
 
 
1899
#endif /* DRIZZLED_SESSION_H */