~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/session.h

  • Committer: Brian Aker
  • Date: 2011-02-14 05:47:07 UTC
  • mto: This revision was merged to the branch mainline in revision 2167.
  • Revision ID: brian@tangent.org-20110214054707-61nsqgg1g4w1zhx1
Merge in all changes for current_session, etc.

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
 
4
 *  Copyright (C) 2008 Sun Microsystems, Inc.
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
 
 
21
20
#ifndef DRIZZLED_SESSION_H
22
21
#define DRIZZLED_SESSION_H
23
22
 
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"
 
23
#include <drizzled/cursor.h>
 
24
#include <drizzled/diagnostics_area.h>
 
25
#include <drizzled/file_exchange.h>
 
26
#include <drizzled/identifier.h>
 
27
#include <drizzled/lex_column.h>
 
28
#include <drizzled/my_hash.h>
 
29
#include <drizzled/named_savepoint.h>
 
30
#include <drizzled/open_tables_state.h>
 
31
#include <drizzled/plugin.h>
 
32
#include <drizzled/plugin/authorization.h>
 
33
#include <drizzled/pthread_globals.h>
 
34
#include <drizzled/query_id.h>
 
35
#include <drizzled/resource_context.h>
 
36
#include <drizzled/sql_error.h>
 
37
#include <drizzled/sql_lex.h>
 
38
#include <drizzled/sql_locale.h>
 
39
#include <drizzled/statistics_variables.h>
 
40
#include <drizzled/table_ident.h>
 
41
#include <drizzled/transaction_context.h>
 
42
#include <drizzled/util/storable.h>
 
43
#include <drizzled/var.h>
 
44
 
 
45
 
40
46
#include <netdb.h>
41
47
#include <sys/time.h>
42
48
#include <sys/resource.h>
43
49
 
44
50
#include <algorithm>
45
51
#include <bitset>
46
 
#include <deque>
47
52
#include <map>
48
53
#include <string>
49
54
 
50
 
#include "drizzled/security_context.h"
51
 
#include "drizzled/open_tables_state.h"
52
 
#include "drizzled/internal_error_handler.h"
53
 
#include "drizzled/diagnostics_area.h"
54
 
#include "drizzled/plugin/authorization.h"
 
55
#include <drizzled/catalog/instance.h>
 
56
#include <drizzled/catalog/local.h>
55
57
 
56
 
#include <boost/unordered_map.hpp>
 
58
#include <drizzled/copy_info.h>
 
59
#include <drizzled/ha_data.h>
 
60
#include <drizzled/session/property_map.h>
 
61
#include <drizzled/session/state.h>
 
62
#include <drizzled/session/table_messages.h>
 
63
#include <drizzled/session/transactions.h>
 
64
#include <drizzled/system_variables.h>
 
65
#include <drizzled/system_variables.h>
57
66
 
58
67
#include <boost/thread/thread.hpp>
59
68
#include <boost/thread/mutex.hpp>
61
70
#include <boost/thread/condition_variable.hpp>
62
71
#include <boost/make_shared.hpp>
63
72
 
 
73
#include "drizzled/visibility.h"
64
74
 
65
75
#define MIN_HANDSHAKE_SIZE      6
66
76
 
81
91
class Resultset;
82
92
}
83
93
 
84
 
namespace internal
85
 
{
86
 
struct st_my_thread_var;
87
 
}
88
 
 
89
 
namespace table
90
 
{
91
 
class Placeholder;
92
 
}
93
 
 
 
94
namespace internal { struct st_my_thread_var; }
 
95
namespace table { class Placeholder; }
 
96
 
 
97
class CopyField;
 
98
class DrizzleXid;
 
99
class Internal_error_handler;
94
100
class Lex_input_stream;
 
101
class TableShareInstance;
 
102
class Table_ident;
 
103
class Time_zone;
 
104
class select_result;
95
105
class user_var_entry;
96
 
class CopyField;
97
 
class Table_ident;
98
 
 
99
 
class TableShareInstance;
100
106
 
101
107
extern char internal_table_name[2];
102
108
extern char empty_c_string[1];
106
112
#define TC_HEURISTIC_RECOVER_ROLLBACK 2
107
113
extern uint32_t tc_heuristic_recover;
108
114
 
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
115
#define Session_SENTRY_MAGIC 0xfeedd1ff
174
116
#define Session_SENTRY_GONE  0xdeadbeef
175
117
 
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
 
};
 
118
extern DRIZZLED_API struct drizzle_system_variables global_system_variables;
 
119
 
 
120
DRIZZLED_API void mark_transaction_to_rollback(Session *session, bool all);
293
121
 
294
122
/**
295
123
 * Represents a client connection to the database server.
310
138
 * all member variables that are not critical to non-internal operations of the
311
139
 * session object.
312
140
 */
313
 
typedef int64_t session_id_t;
314
141
 
315
 
class Session : public Open_tables_state
 
142
class DRIZZLED_API Session : public Open_tables_state
316
143
{
317
144
public:
318
145
  // 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;
321
146
  typedef boost::shared_ptr<Session> shared_ptr;
 
147
  typedef Session& reference;
 
148
  typedef const Session& const_reference;
 
149
  typedef const Session* const_pointer;
 
150
  typedef Session* pointer;
 
151
 
 
152
  static shared_ptr make_shared(plugin::Client *client, catalog::Instance::shared_ptr instance_arg)
 
153
  {
 
154
    assert(instance_arg);
 
155
    return boost::make_shared<Session>(client, instance_arg);
 
156
  }
322
157
 
323
158
  /*
324
159
    MARK_COLUMNS_NONE:  Means mark_used_colums is not set and no indicator to
332
167
                        and update_row.
333
168
  */
334
169
  enum enum_mark_columns mark_used_columns;
335
 
  inline void* alloc(size_t size)
336
 
  {
337
 
    return mem_root->alloc_root(size);
338
 
  }
339
170
  inline void* calloc(size_t size)
340
171
  {
341
172
    void *ptr;
343
174
      memset(ptr, 0, size);
344
175
    return ptr;
345
176
  }
346
 
  inline char *strdup(const char *str)
347
 
  {
348
 
    return mem_root->strdup_root(str);
349
 
  }
350
177
  inline char *strmake(const char *str, size_t size)
351
178
  {
352
179
    return mem_root->strmake_root(str,size);
353
180
  }
354
 
  inline void *memdup(const void *str, size_t size)
355
 
  {
356
 
    return mem_root->memdup_root(str, size);
357
 
  }
 
181
 
358
182
  inline void *memdup_w_gap(const void *str, size_t size, uint32_t gap)
359
183
  {
360
184
    void *ptr;
364
188
  }
365
189
  /** Frees all items attached to this Statement */
366
190
  void free_items();
 
191
 
367
192
  /**
368
193
   * List of items created in the parser for this query. Every item puts
369
194
   * itself to the list on creation (see Item::Item() for details))
404
229
  }
405
230
  /** query associated with this statement */
406
231
  typedef boost::shared_ptr<const std::string> QueryString;
 
232
 
407
233
private:
408
234
  boost::shared_ptr<std::string> query;
409
235
 
431
257
  {
432
258
    QueryString tmp_string(getQueryString());
433
259
 
434
 
    assert(tmp_string);
435
260
    if (not tmp_string)
436
261
    {
437
262
      length= 0;
438
 
      return 0;
 
263
      return NULL;
439
264
    }
440
265
 
441
266
    length= tmp_string->length();
443
268
    return to_return;
444
269
  }
445
270
 
446
 
  class State {
447
 
    std::vector <char> _query;
448
 
 
449
 
  public:
450
 
    typedef boost::shared_ptr<State> const_shared_ptr;
451
 
 
452
 
    State(const char *in_packet, size_t in_packet_length)
453
 
    {
454
 
      if (in_packet_length)
455
 
      {
456
 
        size_t minimum= std::min(in_packet_length, static_cast<size_t>(PROCESS_LIST_WIDTH));
457
 
        _query.resize(minimum + 1);
458
 
        memcpy(&_query[0], in_packet, minimum);
459
 
      }
460
 
      else
461
 
      {
462
 
        _query.resize(0);
463
 
      }
464
 
    }
465
 
 
466
 
    const char *query() const
467
 
    {
468
 
      if (_query.size())
469
 
        return &_query[0];
470
 
 
471
 
      return "";
472
 
    }
473
 
 
474
 
    const char *query(size_t &size) const
475
 
    {
476
 
      if (_query.size())
477
 
      {
478
 
        size= _query.size() -1;
479
 
        return &_query[0];
480
 
      }
481
 
 
482
 
      size= 0;
483
 
      return "";
484
 
    }
485
 
  protected:
486
 
    friend class Session;
487
 
    typedef boost::shared_ptr<State> shared_ptr;
488
 
  };
489
271
private:
490
 
  State::shared_ptr  _state; 
 
272
  session::State::shared_ptr  _state; 
 
273
 
491
274
public:
492
275
 
493
 
  State::const_shared_ptr state()
 
276
  session::State::const_shared_ptr state()
494
277
  {
495
278
    return _state;
496
279
  }
509
292
  */
510
293
private:
511
294
  util::string::shared_ptr _schema;
 
295
 
512
296
public:
513
297
 
514
298
  util::string::const_shared_ptr schema() const
518
302
 
519
303
    return util::string::const_shared_ptr(new std::string(""));
520
304
  }
521
 
  std::string catalog;
 
305
 
522
306
  /* current cache key */
523
307
  std::string query_cache_key;
524
308
  /**
530
314
  static const char * const DEFAULT_WHERE;
531
315
 
532
316
  memory::Root warn_root; /**< Allocation area for warnings and errors */
 
317
private:
533
318
  plugin::Client *client; /**< Pointer to client object */
534
319
 
 
320
public:
 
321
 
535
322
  void setClient(plugin::Client *client_arg);
536
323
 
537
324
  plugin::Client *getClient()
539
326
    return client;
540
327
  }
541
328
 
 
329
  plugin::Client *getClient() const
 
330
  {
 
331
    return client;
 
332
  }
 
333
 
542
334
  plugin::Scheduler *scheduler; /**< Pointer to scheduler object */
543
335
  void *scheduler_arg; /**< Pointer to the optional scheduler argument */
544
336
 
545
337
  typedef boost::unordered_map< std::string, user_var_entry *, util::insensitive_hash, util::insensitive_equal_to> UserVars;
 
338
 
546
339
private:
547
340
  typedef std::pair< UserVars::iterator, UserVars::iterator > UserVarsRange;
548
341
  UserVars user_vars; /**< Hash of user variables defined during the session's lifetime */
549
342
 
550
343
public:
551
 
 
552
344
  const UserVars &getUserVariables() const
553
345
  {
554
346
    return user_vars;
567
359
  char *thread_stack;
568
360
 
569
361
private:
570
 
  SecurityContext security_ctx;
 
362
  identifier::User::shared_ptr security_ctx;
571
363
 
572
364
  int32_t scoreboard_index;
573
365
 
575
367
  {
576
368
    assert(this->dbug_sentry == Session_SENTRY_MAGIC);
577
369
  }
 
370
 
578
371
public:
579
 
  const SecurityContext& getSecurityContext() const
 
372
  identifier::User::const_shared_ptr user() const
580
373
  {
581
 
    return security_ctx;
 
374
    if (security_ctx)
 
375
      return security_ctx;
 
376
 
 
377
    return identifier::User::const_shared_ptr();
582
378
  }
583
379
 
584
 
  SecurityContext& getSecurityContext()
 
380
  void setUser(identifier::User::shared_ptr arg)
585
381
  {
586
 
    return security_ctx;
 
382
    security_ctx= arg;
587
383
  }
588
384
 
589
385
  int32_t getScoreboardIndex()
599
395
  /**
600
396
   * Is this session viewable by the current user?
601
397
   */
602
 
  bool isViewable() const;
 
398
  bool isViewable(identifier::User::const_reference) const;
603
399
 
 
400
private:
604
401
  /**
605
402
    Used in error messages to tell user in what part of MySQL we found an
606
403
    error. E. g. when where= "having clause", if fix_fields() fails, user
607
404
    will know that the error was in having clause.
608
405
  */
609
 
  const char *where;
 
406
  const char *_where;
 
407
 
 
408
public:
 
409
  const char *where()
 
410
  {
 
411
    return _where;
 
412
  }
 
413
 
 
414
  void setWhere(const char *arg)
 
415
  {
 
416
    _where= arg;
 
417
  }
610
418
 
611
419
  /*
612
420
    One thread can hold up to one named user-level lock. This variable
614
422
    chapter 'Miscellaneous functions', for functions GET_LOCK, RELEASE_LOCK.
615
423
  */
616
424
  uint32_t dbug_sentry; /**< watch for memory corruption */
 
425
 
617
426
private:
618
427
  boost::thread::id boost_thread_id;
619
428
  boost_thread_shared_ptr _thread;
620
429
  boost::this_thread::disable_interruption *interrupt;
621
430
 
622
431
  internal::st_my_thread_var *mysys_var;
 
432
 
623
433
public:
624
 
 
625
434
  boost_thread_shared_ptr &getThread()
626
435
  {
627
436
    return _thread;
651
460
  uint32_t file_id;     /**< File ID for LOAD DATA INFILE */
652
461
  /* @note the following three members should likely move to Client */
653
462
  uint32_t max_client_packet_length; /**< Maximum number of bytes a client can send in a single packet */
654
 
  time_t start_time;
655
 
  time_t user_time;
656
 
  uint64_t thr_create_utime; /**< track down slow pthread_create */
657
 
  uint64_t start_utime;
658
 
  uint64_t utime_after_lock;
 
463
 
 
464
private:
 
465
  boost::posix_time::ptime _epoch;
 
466
  boost::posix_time::ptime _connect_time;
 
467
  boost::posix_time::ptime _start_timer;
 
468
  boost::posix_time::ptime _end_timer;
 
469
 
 
470
  boost::posix_time::ptime _user_time;
 
471
public:
 
472
  uint64_t utime_after_lock; // This used by Innodb.
 
473
 
 
474
  void resetUserTime()
 
475
  {
 
476
    _user_time= boost::posix_time::not_a_date_time;
 
477
  }
 
478
 
 
479
  const boost::posix_time::ptime &start_timer() const
 
480
  {
 
481
    return _start_timer;
 
482
  }
 
483
 
 
484
  void getTimeDifference(boost::posix_time::time_duration &result_arg, const boost::posix_time::ptime &arg) const
 
485
  {
 
486
    result_arg=  arg - _start_timer;
 
487
  }
659
488
 
660
489
  thr_lock_type update_lock_default;
661
490
 
676
505
  */
677
506
  query_id_t query_id;
678
507
  query_id_t warn_query_id;
 
508
 
679
509
public:
680
510
  void **getEngineData(const plugin::MonitoredInTransaction *monitored);
681
511
  ResourceContext *getResourceContext(const plugin::MonitoredInTransaction *monitored,
682
512
                                      size_t index= 0);
683
513
 
684
 
  /**
685
 
   * Structure used to manage "statement transactions" and
686
 
   * "normal transactions". In autocommit mode, the normal transaction is
687
 
   * equivalent to the statement transaction.
688
 
   *
689
 
   * Storage engines will be registered here when they participate in
690
 
   * a transaction. No engine is registered more than once.
691
 
   */
692
 
  struct st_transactions {
693
 
    std::deque<NamedSavepoint> savepoints;
694
 
 
695
 
    /**
696
 
     * The normal transaction (since BEGIN WORK).
697
 
     *
698
 
     * Contains a list of all engines that have participated in any of the
699
 
     * statement transactions started within the context of the normal
700
 
     * transaction.
701
 
     *
702
 
     * @note In autocommit mode, this is empty.
703
 
     */
704
 
    TransactionContext all;
705
 
 
706
 
    /**
707
 
     * The statment transaction.
708
 
     *
709
 
     * Contains a list of all engines participating in the given statement.
710
 
     *
711
 
     * @note In autocommit mode, this will be used to commit/rollback the
712
 
     * normal transaction.
713
 
     */
714
 
    TransactionContext stmt;
715
 
 
716
 
    XID_STATE xid_state;
717
 
 
718
 
    void cleanup()
719
 
    {
720
 
      savepoints.clear();
721
 
    }
722
 
    st_transactions() :
723
 
      savepoints(),
724
 
      all(),
725
 
      stmt(),
726
 
      xid_state()
727
 
    { }
728
 
  } transaction;
 
514
  session::Transactions transaction;
729
515
 
730
516
  Field *dup_field;
731
517
  sigset_t signals;
733
519
  // As of right now we do not allow a concurrent execute to launch itself
734
520
private:
735
521
  bool concurrent_execute_allowed;
 
522
 
736
523
public:
737
524
 
738
525
  void setConcurrentExecute(bool arg)
801
588
  uint64_t limit_found_rows;
802
589
  uint64_t options; /**< Bitmap of options */
803
590
  int64_t row_count_func; /**< For the ROW_COUNT() function */
 
591
 
 
592
  int64_t rowCount() const
 
593
  {
 
594
    return row_count_func;
 
595
  }
 
596
 
804
597
  ha_rows cuted_fields; /**< Count of "cut" or truncated fields. @todo Kill this friggin thing. */
805
598
 
806
599
  /** 
849
642
    create_sort_index(); may differ from examined_row_count.
850
643
  */
851
644
  uint32_t row_count;
 
645
 
 
646
  uint32_t getRowCount() const
 
647
  {
 
648
    return row_count;
 
649
  }
 
650
 
852
651
  session_id_t thread_id;
853
652
  uint32_t tmp_table;
854
653
  enum global_read_lock_t
872
671
    _global_read_lock= arg;
873
672
  }
874
673
 
875
 
  DrizzleLock *lockTables(Table **tables, uint32_t count, uint32_t flags, bool *need_reopen);
 
674
  DrizzleLock *lockTables(Table **tables, uint32_t count, uint32_t flags);
876
675
  bool lockGlobalReadLock();
877
676
  bool lock_table_names(TableList *table_list);
878
677
  bool lock_table_names_exclusively(TableList *table_list);
940
739
    can not continue. In particular, disables activation of
941
740
    CONTINUE or EXIT handlers of stored routines.
942
741
    Reset in the end of processing of the current user request, in
943
 
    @see mysql_reset_session_for_next_command().
 
742
    @see reset_session_for_next_command().
944
743
  */
945
744
  bool is_fatal_error;
946
745
  /**
965
764
  bool substitute_null_with_insert_id;
966
765
  bool cleanup_done;
967
766
 
 
767
private:
968
768
  bool abort_on_warning;
 
769
 
 
770
public:
969
771
  bool got_warning; /**< Set on call to push_warning() */
970
772
  bool no_warnings_for_error; /**< no warnings on call to my_error() */
971
773
  /** set during loop of derived table processing */
1112
914
    auto_inc_intervals_forced.append(next_id, UINT64_MAX, 0);
1113
915
  }
1114
916
 
1115
 
  Session(plugin::Client *client_arg);
 
917
  Session(plugin::Client *client_arg, catalog::Instance::shared_ptr catalog);
1116
918
  virtual ~Session();
1117
919
 
1118
920
  void cleanup(void);
1215
1017
   */
1216
1018
  static bool schedule(Session::shared_ptr&);
1217
1019
 
 
1020
  static void unlink(session_id_t &session_id);
1218
1021
  static void unlink(Session::shared_ptr&);
1219
1022
 
1220
1023
  /*
1225
1028
  const char* enter_cond(boost::condition_variable_any &cond, boost::mutex &mutex, const char* msg);
1226
1029
  void exit_cond(const char* old_msg);
1227
1030
 
1228
 
  inline time_t query_start() { return start_time; }
1229
 
  inline void set_time()
1230
 
  {
1231
 
    boost::posix_time::ptime mytime(boost::posix_time::microsec_clock::local_time());
1232
 
    boost::posix_time::ptime epoch(boost::gregorian::date(1970,1,1));
1233
 
    start_utime= utime_after_lock= (mytime-epoch).total_microseconds();
1234
 
 
1235
 
    if (user_time)
1236
 
    {
1237
 
      start_time= user_time;
1238
 
      connect_microseconds= start_utime;
1239
 
    }
1240
 
    else 
1241
 
      start_time= (mytime-epoch).total_seconds();
1242
 
  }
1243
 
  inline void   set_current_time()    { start_time= time(NULL); }
1244
 
  inline void   set_time(time_t t)
1245
 
  {
1246
 
    start_time= user_time= t;
1247
 
    boost::posix_time::ptime mytime(boost::posix_time::microsec_clock::local_time());
1248
 
    boost::posix_time::ptime epoch(boost::gregorian::date(1970,1,1));
1249
 
    uint64_t t_mark= (mytime-epoch).total_microseconds();
1250
 
 
1251
 
    start_utime= utime_after_lock= t_mark;
1252
 
  }
1253
 
  void set_time_after_lock()  { 
1254
 
     boost::posix_time::ptime mytime(boost::posix_time::microsec_clock::local_time());
1255
 
     boost::posix_time::ptime epoch(boost::gregorian::date(1970,1,1));
1256
 
     utime_after_lock= (mytime-epoch).total_microseconds();
1257
 
  }
 
1031
  type::Time::epoch_t query_start()
 
1032
  {
 
1033
    return getCurrentTimestampEpoch();
 
1034
  }
 
1035
 
 
1036
  void set_time()
 
1037
  {
 
1038
    _end_timer= _start_timer= boost::posix_time::microsec_clock::universal_time();
 
1039
    utime_after_lock= (_start_timer - _epoch).total_microseconds();
 
1040
  }
 
1041
 
 
1042
  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
 
1043
  {
 
1044
    _user_time= boost::posix_time::from_time_t(t);
 
1045
  }
 
1046
 
 
1047
  void set_time_after_lock()
 
1048
  { 
 
1049
    boost::posix_time::ptime mytime(boost::posix_time::microsec_clock::universal_time());
 
1050
    utime_after_lock= (mytime - _epoch).total_microseconds();
 
1051
  }
 
1052
 
 
1053
  void set_end_timer()
 
1054
  {
 
1055
    _end_timer= boost::posix_time::microsec_clock::universal_time();
 
1056
    status_var.execution_time_nsec+=(_end_timer - _start_timer).total_microseconds();
 
1057
  }
 
1058
 
 
1059
  uint64_t getElapsedTime() const
 
1060
  {
 
1061
    return (_end_timer - _start_timer).total_microseconds();
 
1062
  }
 
1063
 
1258
1064
  /**
1259
1065
   * Returns the current micro-timestamp
1260
1066
   */
1261
 
  inline uint64_t getCurrentTimestamp()  
 
1067
  type::Time::epoch_t getCurrentTimestamp(bool actual= true) const
1262
1068
  { 
1263
 
    boost::posix_time::ptime mytime(boost::posix_time::microsec_clock::local_time());
1264
 
    boost::posix_time::ptime epoch(boost::gregorian::date(1970,1,1));
1265
 
    uint64_t t_mark= (mytime-epoch).total_microseconds();
 
1069
    type::Time::epoch_t t_mark;
 
1070
 
 
1071
    if (actual)
 
1072
    {
 
1073
      boost::posix_time::ptime mytime(boost::posix_time::microsec_clock::universal_time());
 
1074
      t_mark= (mytime - _epoch).total_microseconds();
 
1075
    }
 
1076
    else
 
1077
    {
 
1078
      t_mark= (_end_timer - _epoch).total_microseconds();
 
1079
    }
1266
1080
 
1267
1081
    return t_mark; 
1268
1082
  }
1269
 
  inline uint64_t found_rows(void)
 
1083
 
 
1084
  // We may need to set user on this
 
1085
  type::Time::epoch_t getCurrentTimestampEpoch() const
 
1086
  { 
 
1087
    if (not _user_time.is_not_a_date_time())
 
1088
      return (_user_time - _epoch).total_seconds();
 
1089
 
 
1090
    return (_start_timer - _epoch).total_seconds();
 
1091
  }
 
1092
 
 
1093
  type::Time::epoch_t getCurrentTimestampEpoch(type::Time::usec_t &fraction_arg) const
 
1094
  { 
 
1095
    if (not _user_time.is_not_a_date_time())
 
1096
    {
 
1097
      fraction_arg= 0;
 
1098
      return (_user_time - _epoch).total_seconds();
 
1099
    }
 
1100
 
 
1101
    fraction_arg= _start_timer.time_of_day().fractional_seconds() % 1000000;
 
1102
    return (_start_timer - _epoch).total_seconds();
 
1103
  }
 
1104
 
 
1105
  uint64_t found_rows(void) const
1270
1106
  {
1271
1107
    return limit_found_rows;
1272
1108
  }
 
1109
 
1273
1110
  /** Returns whether the session is currently inside a transaction */
1274
 
  inline bool inTransaction()
 
1111
  bool inTransaction() const
1275
1112
  {
1276
1113
    return server_status & SERVER_STATUS_IN_TRANS;
1277
1114
  }
 
1115
 
1278
1116
  LEX_STRING *make_lex_string(LEX_STRING *lex_str,
1279
1117
                              const char* str, uint32_t length,
1280
1118
                              bool allocate_lex_string);
 
1119
 
1281
1120
  LEX_STRING *make_lex_string(LEX_STRING *lex_str,
1282
1121
                              const std::string &str,
1283
1122
                              bool allocate_lex_string);
1284
1123
 
1285
1124
  int send_explain_fields(select_result *result);
 
1125
 
1286
1126
  /**
1287
1127
    Clear the current error, if any.
1288
1128
    We do not clear is_fatal_error or is_fatal_sub_stmt_error since we
1352
1192
  }
1353
1193
  void send_kill_message() const;
1354
1194
  /* return true if we will abort query if we make a warning now */
1355
 
  inline bool really_abort_on_warning()
1356
 
  {
1357
 
    return (abort_on_warning);
 
1195
  inline bool abortOnWarning()
 
1196
  {
 
1197
    return abort_on_warning;
 
1198
  }
 
1199
 
 
1200
  inline void setAbortOnWarning(bool arg)
 
1201
  {
 
1202
    abort_on_warning= arg;
1358
1203
  }
1359
1204
 
1360
1205
  void setAbort(bool arg);
1400
1245
    @param level the error level
1401
1246
    @return true if the error is handled
1402
1247
  */
1403
 
  virtual bool handle_error(uint32_t sql_errno, const char *message,
 
1248
  virtual bool handle_error(drizzled::error_t sql_errno, const char *message,
1404
1249
                            DRIZZLE_ERROR::enum_warning_level level);
1405
1250
 
1406
1251
  /**
1428
1273
   * updates any status variables necessary.
1429
1274
   *
1430
1275
   * @param errcode     Error code to print to console
1431
 
   * @param should_lock 1 if we have have to lock LOCK_thread_count
1432
1276
   *
1433
1277
   * @note  For the connection that is doing shutdown, this is called twice
1434
1278
   */
1435
 
  void disconnect(uint32_t errcode, bool lock);
 
1279
  void disconnect(enum error_t errcode= EE_OK);
1436
1280
 
1437
1281
  /**
1438
1282
   * Check if user exists and the password supplied is correct.
1452
1296
   * Returns the timestamp (in microseconds) of when the Session 
1453
1297
   * connected to the server.
1454
1298
   */
1455
 
  inline uint64_t getConnectMicroseconds() const
1456
 
  {
1457
 
    return connect_microseconds;
 
1299
  uint64_t getConnectMicroseconds() const
 
1300
  {
 
1301
    return (_connect_time - _epoch).total_microseconds();
 
1302
  }
 
1303
 
 
1304
  uint64_t getConnectSeconds() const
 
1305
  {
 
1306
    return (_connect_time - _epoch).total_seconds();
1458
1307
  }
1459
1308
 
1460
1309
  /**
1575
1424
  
1576
1425
  
1577
1426
 private:
1578
 
 /** Microsecond timestamp of when Session connected */
1579
 
  uint64_t connect_microseconds;
1580
1427
  const char *proc_info;
1581
1428
 
1582
1429
  /** The current internal error handler for this thread, or NULL. */
1669
1516
  void close_old_data_files(bool morph_locks= false,
1670
1517
                            bool send_refresh= false);
1671
1518
  void close_open_tables();
1672
 
  void close_data_files_and_morph_locks(const TableIdentifier &identifier);
 
1519
  void close_data_files_and_morph_locks(const identifier::Table &identifier);
1673
1520
 
1674
1521
private:
1675
 
  bool free_cached_table();
 
1522
  bool free_cached_table(boost::mutex::scoped_lock &scopedLock);
 
1523
 
1676
1524
public:
1677
1525
 
1678
1526
  /**
1706
1554
  Table *openTable(TableList *table_list, bool *refresh, uint32_t flags= 0);
1707
1555
 
1708
1556
  void unlink_open_table(Table *find);
1709
 
  void drop_open_table(Table *table, const TableIdentifier &identifier);
 
1557
  void drop_open_table(Table *table, const identifier::Table &identifier);
1710
1558
  void close_cached_table(Table *table);
1711
1559
 
1712
1560
  /* Create a lock in the cache */
1713
 
  table::Placeholder *table_cache_insert_placeholder(const TableIdentifier &identifier);
1714
 
  bool lock_table_name_if_not_cached(const TableIdentifier &identifier, Table **table);
1715
 
 
1716
 
  typedef boost::unordered_map<std::string, message::Table, util::insensitive_hash, util::insensitive_equal_to> TableMessageCache;
1717
 
 
1718
 
  class TableMessages
1719
 
  {
1720
 
    TableMessageCache table_message_cache;
1721
 
 
1722
 
  public:
1723
 
    bool storeTableMessage(const TableIdentifier &identifier, message::Table &table_message);
1724
 
    bool removeTableMessage(const TableIdentifier &identifier);
1725
 
    bool getTableMessage(const TableIdentifier &identifier, message::Table &table_message);
1726
 
    bool doesTableMessageExist(const TableIdentifier &identifier);
1727
 
    bool renameTableMessage(const TableIdentifier &from, const TableIdentifier &to);
1728
 
 
1729
 
  };
 
1561
  table::Placeholder *table_cache_insert_placeholder(const identifier::Table &identifier);
 
1562
  bool lock_table_name_if_not_cached(const identifier::Table &identifier, Table **table);
 
1563
 
1730
1564
private:
1731
 
  TableMessages _table_message_cache;
 
1565
  session::TableMessages _table_message_cache;
1732
1566
 
1733
1567
public:
1734
 
  TableMessages &getMessageCache()
 
1568
  session::TableMessages &getMessageCache()
1735
1569
  {
1736
1570
    return _table_message_cache;
1737
1571
  }
1738
1572
 
1739
1573
  /* Reopen operations */
1740
 
  bool reopen_tables(bool get_locks, bool mark_share_as_old);
 
1574
  bool reopen_tables();
1741
1575
  bool close_cached_tables(TableList *tables, bool wait_for_refresh, bool wait_for_placeholders);
1742
1576
 
1743
1577
  void wait_for_condition(boost::mutex &mutex, boost::condition_variable_any &cond);
1746
1580
 
1747
1581
  drizzled::util::Storable *getProperty(const std::string &arg)
1748
1582
  {
1749
 
    return life_properties[arg];
 
1583
    return life_properties.getProperty(arg);
1750
1584
  }
1751
1585
 
1752
1586
  template<class T>
1753
1587
  bool setProperty(const std::string &arg, T *value)
1754
1588
  {
1755
 
    life_properties[arg]= value;
 
1589
    life_properties.setProperty(arg, value);
1756
1590
 
1757
1591
    return true;
1758
1592
  }
1772
1606
    return global_system_variables.storage_engine;
1773
1607
  }
1774
1608
 
1775
 
  void get_xid(DRIZZLE_XID *xid); // Innodb only
 
1609
  void get_xid(DrizzleXid *xid); // Innodb only
1776
1610
 
1777
 
  table::Instance *getInstanceTable();
1778
 
  table::Instance *getInstanceTable(List<CreateField> &field_list);
 
1611
  table::Singular *getInstanceTable();
 
1612
  table::Singular *getInstanceTable(List<CreateField> &field_list);
1779
1613
 
1780
1614
private:
1781
1615
  bool resetUsage()
1787
1621
 
1788
1622
    return true;
1789
1623
  }
 
1624
 
1790
1625
public:
1791
1626
 
1792
1627
  void setUsage(bool arg)
1799
1634
    return usage;
1800
1635
  }
1801
1636
 
 
1637
  catalog::Instance::const_reference catalog() const
 
1638
  {
 
1639
    return *(_catalog.get());
 
1640
  }
 
1641
 
 
1642
  catalog::Instance::reference catalog()
 
1643
  {
 
1644
    return *(_catalog.get());
 
1645
  }
 
1646
 
1802
1647
private:
 
1648
  catalog::Instance::shared_ptr _catalog;
 
1649
 
1803
1650
  // This lives throughout the life of Session
1804
1651
  bool use_usage;
1805
 
  PropertyMap life_properties;
1806
 
  std::vector<table::Instance *> temporary_shares;
 
1652
  session::PropertyMap life_properties;
 
1653
  std::vector<table::Singular *> temporary_shares;
1807
1654
  struct rusage usage;
1808
1655
};
1809
1656
 
1810
 
class Join;
1811
 
 
1812
1657
#define ESCAPE_CHARS "ntrb0ZN" // keep synchronous with READ_INFO::unescape
1813
1658
 
1814
 
} /* namespace drizzled */
1815
 
 
1816
 
/** @TODO why is this in the middle of the file */
1817
 
#include <drizzled/select_to_file.h>
1818
 
#include <drizzled/select_export.h>
1819
 
#include <drizzled/select_dump.h>
1820
 
#include <drizzled/select_insert.h>
1821
 
#include <drizzled/select_create.h>
1822
 
#include <drizzled/tmp_table_param.h>
1823
 
#include <drizzled/select_union.h>
1824
 
#include <drizzled/select_subselect.h>
1825
 
#include <drizzled/select_singlerow_subselect.h>
1826
 
#include <drizzled/select_max_min_finder_subselect.h>
1827
 
#include <drizzled/select_exists_subselect.h>
1828
 
 
1829
 
namespace drizzled
1830
 
{
1831
 
 
1832
 
/**
1833
 
 * A structure used to describe sort information
1834
 
 * for a field or item used in ORDER BY.
1835
 
 */
1836
 
class SortField 
1837
 
{
1838
 
public:
1839
 
  Field *field; /**< Field to sort */
1840
 
  Item  *item; /**< Item if not sorting fields */
1841
 
  size_t length; /**< Length of sort field */
1842
 
  uint32_t suffix_length; /**< Length suffix (0-4) */
1843
 
  Item_result result_type; /**< Type of item */
1844
 
  bool reverse; /**< if descending sort */
1845
 
  bool need_strxnfrm;   /**< If we have to use strxnfrm() */
1846
 
 
1847
 
  SortField() :
1848
 
    field(0),
1849
 
    item(0),
1850
 
    length(0),
1851
 
    suffix_length(0),
1852
 
    result_type(STRING_RESULT),
1853
 
    reverse(0),
1854
 
    need_strxnfrm(0)
1855
 
  { }
1856
 
 
1857
 
};
1858
 
 
1859
 
} /* namespace drizzled */
1860
 
 
1861
 
/** @TODO why is this in the middle of the file */
1862
 
 
1863
 
#include <drizzled/table_ident.h>
1864
 
#include <drizzled/user_var_entry.h>
1865
 
#include <drizzled/unique.h>
1866
 
#include <drizzled/var.h>
1867
 
#include <drizzled/select_dumpvar.h>
1868
 
 
1869
 
namespace drizzled
1870
 
{
1871
 
 
1872
1659
/* Bits in sql_command_flags */
1873
1660
 
1874
1661
enum sql_command_flag_bits 
1890
1677
namespace display  {
1891
1678
const std::string &type(drizzled::Session::global_read_lock_t type);
1892
1679
size_t max_string_length(drizzled::Session::global_read_lock_t type);
 
1680
 
1893
1681
} /* namespace display */
1894
1682
 
1895
1683
} /* namespace drizzled */