~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/session.h

  • Committer: Brian Aker
  • Date: 2010-11-22 00:16:44 UTC
  • mto: (1945.2.1 quick)
  • mto: This revision was merged to the branch mainline in revision 1947.
  • Revision ID: brian@tangent.org-20101122001644-pi6jv0d65e82xn38
Merge in lock refactor, this just encapsulates.

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
#ifndef DRIZZLED_SESSION_H
22
22
#define DRIZZLED_SESSION_H
23
23
 
24
 
/* Classes in mysql */
25
 
 
26
24
#include "drizzled/plugin.h"
27
 
#include <drizzled/sql_locale.h>
 
25
#include "drizzled/sql_locale.h"
28
26
#include "drizzled/resource_context.h"
29
 
#include <drizzled/cursor.h>
30
 
#include <drizzled/current_session.h>
31
 
#include <drizzled/sql_error.h>
32
 
#include <drizzled/file_exchange.h>
33
 
#include <drizzled/select_result_interceptor.h>
34
 
#include <drizzled/xid.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"
35
34
#include "drizzled/query_id.h"
36
35
#include "drizzled/named_savepoint.h"
37
36
#include "drizzled/transaction_context.h"
 
37
#include "drizzled/util/storable.h"
 
38
#include "drizzled/my_hash.h"
38
39
 
39
40
#include <netdb.h>
40
41
#include <map>
42
43
#include <bitset>
43
44
#include <deque>
44
45
 
45
 
#include <drizzled/security_context.h>
46
 
#include <drizzled/open_tables_state.h>
47
 
 
48
 
#include <drizzled/internal_error_handler.h>
49
 
#include <drizzled/diagnostics_area.h>
50
 
 
51
 
#include <drizzled/plugin/authorization.h>
 
46
#include "drizzled/internal/getrusage.h"
 
47
#include "drizzled/security_context.h"
 
48
#include "drizzled/open_tables_state.h"
 
49
#include "drizzled/internal_error_handler.h"
 
50
#include "drizzled/diagnostics_area.h"
 
51
#include "drizzled/plugin/authorization.h"
 
52
 
 
53
#include <boost/unordered_map.hpp>
 
54
#include <boost/thread/mutex.hpp>
 
55
#include <boost/thread/shared_mutex.hpp>
 
56
#include <boost/thread/condition_variable.hpp>
52
57
 
53
58
#define MIN_HANDSHAKE_SIZE      6
54
59
 
59
64
{
60
65
class Client;
61
66
class Scheduler;
 
67
class EventObserverList;
62
68
}
 
69
 
63
70
namespace message
64
71
{
65
72
class Transaction;
66
73
class Statement;
 
74
class Resultset;
67
75
}
 
76
 
68
77
namespace internal
69
78
{
70
79
struct st_my_thread_var;
71
80
}
72
81
 
 
82
namespace table
 
83
{
 
84
class Placeholder;
 
85
}
 
86
 
73
87
class Lex_input_stream;
74
88
class user_var_entry;
75
89
class CopyField;
76
90
class Table_ident;
77
91
 
 
92
class TableShareInstance;
 
93
 
78
94
extern char internal_table_name[2];
79
95
extern char empty_c_string[1];
80
96
extern const char **errmesg;
103
119
      of the INSERT ... ON DUPLICATE KEY UPDATE no matter whether the row
104
120
      was actually changed or not.
105
121
*/
106
 
typedef struct st_copy_info 
 
122
class CopyInfo 
107
123
{
 
124
public:
108
125
  ha_rows records; /**< Number of processed records */
109
126
  ha_rows deleted; /**< Number of deleted records */
110
127
  ha_rows updated; /**< Number of updated records */
118
135
  List<Item> *update_fields;
119
136
  List<Item> *update_values;
120
137
  /* for VIEW ... WITH CHECK OPTION */
121
 
} COPY_INFO;
122
 
 
123
 
typedef struct drizzled_lock_st
124
 
{
125
 
  Table **table;
126
 
  uint32_t table_count;
127
 
  uint32_t lock_count;
128
 
  THR_LOCK_DATA **locks;
129
 
} DRIZZLE_LOCK;
 
138
 
 
139
  CopyInfo() :
 
140
    records(0),
 
141
    deleted(0),
 
142
    updated(0),
 
143
    copied(0),
 
144
    error_count(0),
 
145
    touched(0),
 
146
    escape_char(0),
 
147
    last_errno(0),
 
148
    ignore(0),
 
149
    update_fields(0),
 
150
    update_values(0)
 
151
  { }
 
152
 
 
153
};
130
154
 
131
155
} /* namespace drizzled */
132
156
 
142
166
#define Session_SENTRY_MAGIC 0xfeedd1ff
143
167
#define Session_SENTRY_GONE  0xdeadbeef
144
168
 
145
 
struct system_variables
 
169
struct drizzle_system_variables
146
170
{
147
 
  system_variables() {};
 
171
  drizzle_system_variables()
 
172
  {}
148
173
  /*
149
174
    How dynamically allocated system variables are handled:
150
175
 
184
209
  size_t sortbuff_size;
185
210
  uint32_t thread_handling;
186
211
  uint32_t tx_isolation;
 
212
  size_t transaction_message_threshold;
187
213
  uint32_t completion_type;
188
214
  /* Determines which non-standard SQL behaviour should be enabled */
189
215
  uint32_t sql_mode;
213
239
  Time_zone *time_zone;
214
240
};
215
241
 
216
 
extern struct system_variables global_system_variables;
 
242
extern struct drizzle_system_variables global_system_variables;
217
243
 
218
244
} /* namespace drizzled */
219
245
 
222
248
namespace drizzled
223
249
{
224
250
 
225
 
/**
226
 
 * Per-session local status counters
227
 
 */
228
 
typedef struct system_status_var
229
 
{
230
 
  uint64_t bytes_received;
231
 
  uint64_t bytes_sent;
232
 
  ulong com_other;
233
 
  ulong com_stat[(uint32_t) SQLCOM_END];
234
 
  ulong created_tmp_disk_tables;
235
 
  ulong created_tmp_tables;
236
 
  ulong ha_commit_count;
237
 
  ulong ha_delete_count;
238
 
  ulong ha_read_first_count;
239
 
  ulong ha_read_last_count;
240
 
  ulong ha_read_key_count;
241
 
  ulong ha_read_next_count;
242
 
  ulong ha_read_prev_count;
243
 
  ulong ha_read_rnd_count;
244
 
  ulong ha_read_rnd_next_count;
245
 
  ulong ha_rollback_count;
246
 
  ulong ha_update_count;
247
 
  ulong ha_write_count;
248
 
  ulong ha_prepare_count;
249
 
  ulong ha_savepoint_count;
250
 
  ulong ha_savepoint_rollback_count;
251
 
 
252
 
  /* KEY_CACHE parts. These are copies of the original */
253
 
  ulong key_blocks_changed;
254
 
  ulong key_blocks_used;
255
 
  ulong key_cache_r_requests;
256
 
  ulong key_cache_read;
257
 
  ulong key_cache_w_requests;
258
 
  ulong key_cache_write;
259
 
  /* END OF KEY_CACHE parts */
260
 
 
261
 
  ulong net_big_packet_count;
262
 
  ulong select_full_join_count;
263
 
  ulong select_full_range_join_count;
264
 
  ulong select_range_count;
265
 
  ulong select_range_check_count;
266
 
  ulong select_scan_count;
267
 
  ulong long_query_count;
268
 
  ulong filesort_merge_passes;
269
 
  ulong filesort_range_count;
270
 
  ulong filesort_rows;
271
 
  ulong filesort_scan_count;
272
 
  /*
273
 
    Number of statements sent from the client
274
 
  */
275
 
  ulong questions;
276
 
 
277
 
  /*
278
 
    IMPORTANT!
279
 
    SEE last_system_status_var DEFINITION BELOW.
280
 
 
281
 
    Below 'last_system_status_var' are all variables which doesn't make any
282
 
    sense to add to the /global/ status variable counter.
283
 
  */
284
 
  double last_query_cost;
285
 
} system_status_var;
286
 
 
287
 
/*
288
 
  This is used for 'SHOW STATUS'. It must be updated to the last ulong
289
 
  variable in system_status_var which is makes sens to add to the global
290
 
  counter
291
 
*/
292
 
 
293
 
#define last_system_status_var questions
294
 
 
295
251
void mark_transaction_to_rollback(Session *session, bool all);
296
252
 
297
 
extern pthread_mutex_t LOCK_xid_cache;
298
 
extern HASH xid_cache;
299
 
 
300
 
 
301
253
/**
302
254
  Storage engine specific thread local data.
303
255
*/
350
302
 * all member variables that are not critical to non-internal operations of the
351
303
 * session object.
352
304
 */
 
305
typedef int64_t session_id_t;
 
306
 
353
307
class Session : public Open_tables_state
354
308
{
355
309
public:
 
310
  // Plugin storage in Session.
 
311
  typedef boost::unordered_map<std::string, util::Storable *, util::insensitive_hash, util::insensitive_equal_to> PropertyMap;
 
312
  typedef Session* Ptr;
 
313
  typedef boost::shared_ptr<Session> shared_ptr;
 
314
 
356
315
  /*
357
316
    MARK_COLUMNS_NONE:  Means mark_used_colums is not set and no indicator to
358
317
                        handler of fields used is set
367
326
  enum enum_mark_columns mark_used_columns;
368
327
  inline void* alloc(size_t size)
369
328
  {
370
 
    return alloc_root(mem_root,size);
 
329
    return mem_root->alloc_root(size);
371
330
  }
372
331
  inline void* calloc(size_t size)
373
332
  {
374
333
    void *ptr;
375
 
    if ((ptr= alloc_root(mem_root,size)))
 
334
    if ((ptr= mem_root->alloc_root(size)))
376
335
      memset(ptr, 0, size);
377
336
    return ptr;
378
337
  }
379
338
  inline char *strdup(const char *str)
380
339
  {
381
 
    return strdup_root(mem_root,str);
 
340
    return mem_root->strdup_root(str);
382
341
  }
383
342
  inline char *strmake(const char *str, size_t size)
384
343
  {
385
 
    return strmake_root(mem_root,str,size);
 
344
    return mem_root->strmake_root(str,size);
386
345
  }
387
346
  inline void *memdup(const void *str, size_t size)
388
347
  {
389
 
    return memdup_root(mem_root,str,size);
 
348
    return mem_root->memdup_root(str, size);
390
349
  }
391
350
  inline void *memdup_w_gap(const void *str, size_t size, uint32_t gap)
392
351
  {
393
352
    void *ptr;
394
 
    if ((ptr= alloc_root(mem_root,size+gap)))
 
353
    if ((ptr= mem_root->alloc_root(size + gap)))
395
354
      memcpy(ptr,str,size);
396
355
    return ptr;
397
356
  }
403
362
   */
404
363
  Item *free_list;
405
364
  memory::Root *mem_root; /**< Pointer to current memroot */
 
365
 
 
366
 
 
367
  memory::Root *getMemRoot()
 
368
  {
 
369
    return mem_root;
 
370
  }
 
371
 
 
372
  uint64_t xa_id;
 
373
 
 
374
  uint64_t getXaId()
 
375
  {
 
376
    return xa_id;
 
377
  }
 
378
 
 
379
  void setXaId(uint64_t in_xa_id)
 
380
  {
 
381
    xa_id= in_xa_id; 
 
382
  }
 
383
 
406
384
  /**
407
385
   * Uniquely identifies each statement object in thread scope; change during
408
386
   * statement lifetime.
411
389
   */
412
390
  uint32_t id;
413
391
  LEX *lex; /**< parse tree descriptor */
 
392
 
 
393
  LEX *getLex() 
 
394
  {
 
395
    return lex;
 
396
  }
414
397
  /** query associated with this statement */
415
 
  std::string query;
 
398
  typedef boost::shared_ptr<const std::string> QueryString;
 
399
private:
 
400
  boost::shared_ptr<std::string> query;
 
401
 
 
402
  // Never allow for a modification of this outside of the class. c_str()
 
403
  // requires under some setup non const, you must copy the QueryString in
 
404
  // order to use it.
 
405
public:
 
406
  QueryString getQueryString() const
 
407
  {
 
408
    return query;
 
409
  }
 
410
 
 
411
  void resetQueryString()
 
412
  {
 
413
    return query.reset(new std::string);
 
414
  }
 
415
 
 
416
  /*
 
417
    We need to copy the lock on the string in order to make sure we have a stable string.
 
418
    Once this is done we can use it to build a const char* which can be handed off for
 
419
    a method to use (Innodb is currently the only engine using this).
 
420
  */
 
421
  const char *getQueryStringCopy(size_t &length)
 
422
  {
 
423
    QueryString tmp_string(getQueryString());
 
424
 
 
425
    length= tmp_string->length();
 
426
    char *to_return= strmake(tmp_string->c_str(), tmp_string->length());
 
427
    return to_return;
 
428
  }
416
429
 
417
430
  /**
418
431
    Name of the current (default) database.
428
441
  */
429
442
  std::string db;
430
443
 
 
444
  const std::string &getSchema() const
 
445
  {
 
446
    return db;
 
447
  }
 
448
  std::string catalog;
 
449
  /* current cache key */
 
450
  std::string query_cache_key;
431
451
  /**
432
452
    Constant for Session::where initialization in the beginning of every query.
433
453
 
438
458
 
439
459
  memory::Root warn_root; /**< Allocation area for warnings and errors */
440
460
  plugin::Client *client; /**< Pointer to client object */
 
461
 
 
462
  void setClient(plugin::Client *client_arg);
 
463
 
 
464
  plugin::Client *getClient()
 
465
  {
 
466
    return client;
 
467
  }
 
468
 
441
469
  plugin::Scheduler *scheduler; /**< Pointer to scheduler object */
442
470
  void *scheduler_arg; /**< Pointer to the optional scheduler argument */
443
 
  HASH user_vars; /**< Hash of user variables defined during the session's lifetime */
444
 
  struct system_variables variables; /**< Mutable local variables local to the session */
 
471
 
 
472
  typedef boost::unordered_map< std::string, user_var_entry *, util::insensitive_hash, util::insensitive_equal_to> UserVars;
 
473
private:
 
474
  typedef std::pair< UserVars::iterator, UserVars::iterator > UserVarsRange;
 
475
  UserVars user_vars; /**< Hash of user variables defined during the session's lifetime */
 
476
 
 
477
public:
 
478
 
 
479
  const UserVars &getUserVariables() const
 
480
  {
 
481
    return user_vars;
 
482
  }
 
483
 
 
484
  drizzle_system_variables variables; /**< Mutable local variables local to the session */
445
485
  struct system_status_var status_var; /**< Session-local status counters */
446
 
  struct system_status_var *initial_status_var; /* used by show status */
447
486
  THR_LOCK_INFO lock_info; /**< Locking information for this session */
448
487
  THR_LOCK_OWNER main_lock_id; /**< To use for conventional queries */
449
488
  THR_LOCK_OWNER *lock_id; /**< If not main_lock_id, points to the lock_id of a cursor. */
450
 
  pthread_mutex_t LOCK_delete; /**< Locked before session is deleted */
451
 
 
452
 
  /**
453
 
   * A peek into the query string for the session. This is a best effort
454
 
   * delivery, there is no guarantee whether the content is meaningful.
455
 
   */
456
 
  char process_list_info[PROCESS_LIST_WIDTH+1];
457
489
 
458
490
  /**
459
491
   * A pointer to the stack frame of the scheduler thread
464
496
private:
465
497
  SecurityContext security_ctx;
466
498
 
 
499
  int32_t scoreboard_index;
 
500
 
467
501
  inline void checkSentry() const
468
502
  {
469
503
    assert(this->dbug_sentry == Session_SENTRY_MAGIC);
479
513
    return security_ctx;
480
514
  }
481
515
 
 
516
  int32_t getScoreboardIndex()
 
517
  {
 
518
    return scoreboard_index;
 
519
  }
 
520
 
 
521
  void setScoreboardIndex(int32_t in_scoreboard_index)
 
522
  {
 
523
    scoreboard_index= in_scoreboard_index;
 
524
  }
 
525
 
482
526
  /**
483
527
   * Is this session viewable by the current user?
484
528
   */
485
 
  bool isViewable() const
486
 
  {
487
 
    return plugin::Authorization::isAuthorized(current_session->getSecurityContext(),
488
 
                                               this,
489
 
                                               false);
490
 
  }
 
529
  bool isViewable() const;
491
530
 
492
531
  /**
493
532
    Used in error messages to tell user in what part of MySQL we found an
502
541
    chapter 'Miscellaneous functions', for functions GET_LOCK, RELEASE_LOCK.
503
542
  */
504
543
  uint32_t dbug_sentry; /**< watch for memory corruption */
 
544
private:
505
545
  internal::st_my_thread_var *mysys_var;
 
546
public:
 
547
 
 
548
  internal::st_my_thread_var *getThreadVar()
 
549
  {
 
550
    return mysys_var;
 
551
  }
 
552
 
 
553
  void resetThreadVar()
 
554
  {
 
555
    mysys_var= NULL;
 
556
  }
506
557
  /**
507
558
   * Type of current query: COM_STMT_PREPARE, COM_QUERY, etc. Set from
508
559
   * first byte of the packet in executeStatement()
541
592
  ResourceContext *getResourceContext(const plugin::MonitoredInTransaction *monitored,
542
593
                                      size_t index= 0);
543
594
 
 
595
  /**
 
596
   * Structure used to manage "statement transactions" and
 
597
   * "normal transactions". In autocommit mode, the normal transaction is
 
598
   * equivalent to the statement transaction.
 
599
   *
 
600
   * Storage engines will be registered here when they participate in
 
601
   * a transaction. No engine is registered more than once.
 
602
   */
544
603
  struct st_transactions {
545
604
    std::deque<NamedSavepoint> savepoints;
546
 
    TransactionContext all; ///< Trans since BEGIN WORK
547
 
    TransactionContext stmt; ///< Trans for current statement
 
605
 
 
606
    /**
 
607
     * The normal transaction (since BEGIN WORK).
 
608
     *
 
609
     * Contains a list of all engines that have participated in any of the
 
610
     * statement transactions started within the context of the normal
 
611
     * transaction.
 
612
     *
 
613
     * @note In autocommit mode, this is empty.
 
614
     */
 
615
    TransactionContext all;
 
616
 
 
617
    /**
 
618
     * The statment transaction.
 
619
     *
 
620
     * Contains a list of all engines participating in the given statement.
 
621
     *
 
622
     * @note In autocommit mode, this will be used to commit/rollback the
 
623
     * normal transaction.
 
624
     */
 
625
    TransactionContext stmt;
 
626
 
548
627
    XID_STATE xid_state;
549
628
 
550
629
    void cleanup()
562
641
  Field *dup_field;
563
642
  sigset_t signals;
564
643
 
 
644
  // As of right now we do not allow a concurrent execute to launch itself
 
645
private:
 
646
  bool concurrent_execute_allowed;
 
647
public:
 
648
 
 
649
  void setConcurrentExecute(bool arg)
 
650
  {
 
651
    concurrent_execute_allowed= arg;
 
652
  }
 
653
 
 
654
  bool isConcurrentExecuteAllowed() const
 
655
  {
 
656
    return concurrent_execute_allowed;
 
657
  }
 
658
 
565
659
  /* Tells if LAST_INSERT_ID(#) was called for the current statement */
566
660
  bool arg_of_last_insert_id_function;
 
661
 
567
662
  /*
568
663
    ALL OVER THIS FILE, "insert_id" means "*automatically generated* value for
569
664
    insertion into an auto_increment column".
665
760
    create_sort_index(); may differ from examined_row_count.
666
761
  */
667
762
  uint32_t row_count;
668
 
  pthread_t real_id; /**< For debugging */
669
 
  uint64_t thread_id;
 
763
  session_id_t thread_id;
670
764
  uint32_t tmp_table;
671
 
  uint32_t global_read_lock;
 
765
  enum global_read_lock_t
 
766
  {
 
767
    NONE= 0,
 
768
    GOT_GLOBAL_READ_LOCK= 1,
 
769
    MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT= 2
 
770
  };
 
771
private:
 
772
  global_read_lock_t _global_read_lock;
 
773
 
 
774
public:
 
775
 
 
776
  global_read_lock_t isGlobalReadLock() const
 
777
  {
 
778
    return _global_read_lock;
 
779
  }
 
780
 
 
781
  void setGlobalReadLock(global_read_lock_t arg)
 
782
  {
 
783
    _global_read_lock= arg;
 
784
  }
 
785
 
 
786
  DrizzleLock *lockTables(Table **tables, uint32_t count, uint32_t flags, bool *need_reopen);
 
787
  bool lockGlobalReadLock();
 
788
  bool lock_table_names(TableList *table_list);
 
789
  bool lock_table_names_exclusively(TableList *table_list);
 
790
  bool makeGlobalReadLockBlockCommit();
 
791
  bool abortLockForThread(Table *table);
 
792
  bool wait_if_global_read_lock(bool abort_on_refresh, bool is_not_commit);
 
793
  int lock_table_name(TableList *table_list);
 
794
  void abortLock(Table *table);
 
795
  void removeLock(Table *table);
 
796
  void unlockReadTables(DrizzleLock *sql_lock);
 
797
  void unlockSomeTables(Table **table, uint32_t count);
 
798
  void unlockTables(DrizzleLock *sql_lock);
 
799
  void startWaitingGlobalReadLock();
 
800
  void unlockGlobalReadLock();
 
801
 
 
802
private:
 
803
  int unlock_external(Table **table, uint32_t count);
 
804
  int lock_external(Table **tables, uint32_t count);
 
805
  bool wait_for_locked_table_names(TableList *table_list);
 
806
  DrizzleLock *get_lock_data(Table **table_ptr, uint32_t count,
 
807
                             bool should_lock, Table **write_lock_used);
 
808
public:
 
809
 
672
810
  uint32_t server_status;
673
811
  uint32_t open_options;
674
812
  uint32_t select_number; /**< number of select (used for EXPLAIN) */
676
814
  enum_tx_isolation session_tx_isolation;
677
815
  enum_check_fields count_cuted_fields;
678
816
 
679
 
  enum killed_state
 
817
  enum killed_state_t
680
818
  {
681
819
    NOT_KILLED,
682
820
    KILL_BAD_DATA,
684
822
    KILL_QUERY,
685
823
    KILLED_NO_VALUE /* means none of the above states apply */
686
824
  };
687
 
  killed_state volatile killed;
 
825
private:
 
826
  killed_state_t volatile _killed;
 
827
 
 
828
public:
 
829
 
 
830
  void setKilled(killed_state_t arg)
 
831
  {
 
832
    _killed= arg;
 
833
  }
 
834
 
 
835
  killed_state_t getKilled()
 
836
  {
 
837
    return _killed;
 
838
  }
 
839
 
 
840
  volatile killed_state_t *getKilledPtr() // Do not use this method, it is here for historical convience.
 
841
  {
 
842
    return &_killed;
 
843
  }
688
844
 
689
845
  bool some_tables_deleted;
690
846
  bool no_errors;
774
930
  }
775
931
 
776
932
  /** Returns the current query ID */
777
 
  inline query_id_t getQueryId()  const
 
933
  query_id_t getQueryId()  const
778
934
  {
779
935
    return query_id;
780
936
  }
792
948
    return warn_query_id;
793
949
  }
794
950
 
795
 
  /** Returns the current query text */
796
 
  inline const std::string &getQueryString()  const
797
 
  {
798
 
    return query;
799
 
  }
800
 
 
801
 
  /** Returns the length of the current query text */
802
 
  inline size_t getQueryLength() const
803
 
  {
804
 
    if (! query.empty())
805
 
      return query.length();
806
 
    else
807
 
      return 0;
808
 
  }
809
 
 
810
951
  /** Accessor method returning the session's ID. */
811
 
  inline uint64_t getSessionId()  const
 
952
  inline session_id_t getSessionId()  const
812
953
  {
813
954
    return thread_id;
814
955
  }
899
1040
   */
900
1041
  void cleanup_after_query();
901
1042
  bool storeGlobals();
902
 
  void awake(Session::killed_state state_to_set);
 
1043
  void awake(Session::killed_state_t state_to_set);
903
1044
  /**
904
1045
   * Pulls thread-specific variables into Session state.
905
1046
   *
982
1123
  /**
983
1124
   * Schedule a session to be run on the default scheduler.
984
1125
   */
985
 
  bool schedule();
 
1126
  static bool schedule(Session::shared_ptr&);
 
1127
 
 
1128
  static void unlink(Session::shared_ptr&);
986
1129
 
987
1130
  /*
988
1131
    For enter_cond() / exit_cond() to work the mutex must be got before
989
1132
    enter_cond(); this mutex is then released by exit_cond().
990
1133
    Usage must be: lock mutex; enter_cond(); your code; exit_cond().
991
1134
  */
992
 
  const char* enter_cond(pthread_cond_t *cond, pthread_mutex_t* mutex, const char* msg);
 
1135
  const char* enter_cond(boost::condition_variable_any &cond, boost::mutex &mutex, const char* msg);
993
1136
  void exit_cond(const char* old_msg);
994
1137
 
995
1138
  inline time_t query_start() { return start_time; }
1026
1169
  {
1027
1170
    return server_status & SERVER_STATUS_IN_TRANS;
1028
1171
  }
1029
 
  inline bool fill_derived_tables()
1030
 
  {
1031
 
    return !lex->only_view_structure();
1032
 
  }
1033
 
 
1034
1172
  LEX_STRING *make_lex_string(LEX_STRING *lex_str,
1035
1173
                              const char* str, uint32_t length,
1036
1174
                              bool allocate_lex_string);
1046
1184
    @todo: To silence an error, one should use Internal_error_handler
1047
1185
    mechanism. In future this function will be removed.
1048
1186
  */
1049
 
  inline void clear_error()
 
1187
  inline void clear_error(bool full= false)
1050
1188
  {
1051
1189
    if (main_da.is_error())
1052
1190
      main_da.reset_diagnostics_area();
1053
 
    return;
 
1191
 
 
1192
    if (full)
 
1193
    {
 
1194
      drizzle_reset_errors(this, true);
 
1195
    }
 
1196
  }
 
1197
 
 
1198
  void clearDiagnostics()
 
1199
  {
 
1200
    main_da.reset_diagnostics_area();
1054
1201
  }
1055
1202
 
1056
1203
  /**
1094
1241
  void end_statement();
1095
1242
  inline int killed_errno() const
1096
1243
  {
1097
 
    killed_state killed_val; /* to cache the volatile 'killed' */
1098
 
    return (killed_val= killed) != KILL_BAD_DATA ? killed_val : 0;
 
1244
    killed_state_t killed_val; /* to cache the volatile 'killed' */
 
1245
    return (killed_val= _killed) != KILL_BAD_DATA ? killed_val : 0;
1099
1246
  }
1100
1247
  void send_kill_message() const;
1101
1248
  /* return true if we will abort query if we make a warning now */
1103
1250
  {
1104
1251
    return (abort_on_warning);
1105
1252
  }
 
1253
 
 
1254
  void setAbort(bool arg);
 
1255
  void lockOnSys();
1106
1256
  void set_status_var_init();
1107
 
  void reset_n_backup_open_tables_state(Open_tables_state *backup);
1108
 
  void restore_backup_open_tables_state(Open_tables_state *backup);
1109
1257
 
1110
1258
  /**
1111
1259
    Set the current database; use deep copy of C-string.
1193
1341
   * Current implementation does not depend on that, but future changes
1194
1342
   * should be done with this in mind; 
1195
1343
   *
1196
 
   * @param  Scrambled password received from client
1197
 
   * @param  Length of scrambled password
1198
 
   * @param  Database name to connect to, may be NULL
 
1344
   * @param passwd Scrambled password received from client
 
1345
   * @param db Database name to connect to, may be NULL
1199
1346
   */
1200
 
  bool checkUser(const char *passwd, uint32_t passwd_len, const char *db);
 
1347
  bool checkUser(const std::string &passwd, const std::string &db);
1201
1348
  
1202
1349
  /**
1203
1350
   * Returns the timestamp (in microseconds) of when the Session 
1226
1373
  {
1227
1374
    return statement_message;
1228
1375
  }
1229
 
 
 
1376
  
 
1377
  /**
 
1378
   * Returns a pointer to the current Resulset message for this
 
1379
   * Session, or NULL if no active message.
 
1380
   */
 
1381
  message::Resultset *getResultsetMessage() const
 
1382
  {
 
1383
    return resultset;
 
1384
  }
1230
1385
  /**
1231
1386
   * Sets the active transaction message used by the ReplicationServices
1232
1387
   * component.
1248
1403
  {
1249
1404
    statement_message= in_message;
1250
1405
  }
 
1406
 
 
1407
  /**
 
1408
   * Sets the active Resultset message used by the Query Cache
 
1409
   * plugin.
 
1410
   *
 
1411
   * @param[in] Pointer to the message
 
1412
   */
 
1413
  void setResultsetMessage(message::Resultset *in_message)
 
1414
  {
 
1415
    resultset= in_message;
 
1416
  }
 
1417
  /**
 
1418
   * reset the active Resultset message used by the Query Cache
 
1419
   * plugin.
 
1420
   */
 
1421
 
 
1422
  void resetResultsetMessage()
 
1423
  { 
 
1424
    resultset= NULL;
 
1425
  }
 
1426
 
1251
1427
private:
1252
1428
  /** Pointers to memory managed by the ReplicationServices component */
1253
1429
  message::Transaction *transaction_message;
1254
1430
  message::Statement *statement_message;
1255
 
  /** Microsecond timestamp of when Session connected */
 
1431
  /* Pointer to the current resultset of Select query */
 
1432
  message::Resultset *resultset;
 
1433
  plugin::EventObserverList *session_event_observers;
 
1434
  
 
1435
  /* Schema observers are mapped to databases. */
 
1436
  std::map<std::string, plugin::EventObserverList *> schema_event_observers;
 
1437
 
 
1438
 
 
1439
public:
 
1440
  plugin::EventObserverList *getSessionObservers() 
 
1441
  { 
 
1442
    return session_event_observers;
 
1443
  }
 
1444
  
 
1445
  void setSessionObservers(plugin::EventObserverList *observers) 
 
1446
  { 
 
1447
    session_event_observers= observers;
 
1448
  }
 
1449
  
 
1450
  /* For schema event observers there is one set of observers per database. */
 
1451
  plugin::EventObserverList *getSchemaObservers(const std::string &db_name) 
 
1452
  { 
 
1453
    std::map<std::string, plugin::EventObserverList *>::iterator it;
 
1454
    
 
1455
    it= schema_event_observers.find(db_name);
 
1456
    if (it == schema_event_observers.end())
 
1457
      return NULL;
 
1458
      
 
1459
    return it->second;
 
1460
  }
 
1461
  
 
1462
  void setSchemaObservers(const std::string &db_name, plugin::EventObserverList *observers) 
 
1463
  { 
 
1464
    std::map<std::string, plugin::EventObserverList *>::iterator it;
 
1465
 
 
1466
    it= schema_event_observers.find(db_name);
 
1467
    if (it != schema_event_observers.end())
 
1468
      schema_event_observers.erase(it);;
 
1469
 
 
1470
    if (observers)
 
1471
      schema_event_observers[db_name] = observers;
 
1472
  }
 
1473
  
 
1474
  
 
1475
 private:
 
1476
 /** Microsecond timestamp of when Session connected */
1256
1477
  uint64_t connect_microseconds;
1257
1478
  const char *proc_info;
1258
1479
 
1294
1515
   * set to query_id of original query.
1295
1516
   */
1296
1517
  void mark_used_tables_as_free_for_reuse(Table *table);
1297
 
  /**
1298
 
    Mark all temporary tables which were used by the current statement or
1299
 
    substatement as free for reuse, but only if the query_id can be cleared.
1300
 
 
1301
 
    @param session thread context
1302
 
 
1303
 
    @remark For temp tables associated with a open SQL HANDLER the query_id
1304
 
            is not reset until the HANDLER is closed.
1305
 
  */
1306
 
  void mark_temp_tables_as_free_for_reuse();
1307
1518
 
1308
1519
public:
1309
1520
 
1345
1556
  }
1346
1557
  void refresh_status();
1347
1558
  user_var_entry *getVariable(LEX_STRING &name, bool create_if_not_exists);
 
1559
  user_var_entry *getVariable(const std::string  &name, bool create_if_not_exists);
 
1560
  void setVariable(const std::string &name, const std::string &value);
1348
1561
  
1349
1562
  /**
1350
1563
   * Closes all tables used by the current substatement, or all tables
1355
1568
                            bool send_refresh= false);
1356
1569
  void close_open_tables();
1357
1570
  void close_data_files_and_morph_locks(TableIdentifier &identifier);
1358
 
  void close_data_files_and_morph_locks(const char *db, const char *table_name);
1359
1571
 
1360
1572
private:
1361
1573
  bool free_cached_table();
1386
1598
   */
1387
1599
  bool openTablesLock(TableList *tables);
1388
1600
 
1389
 
  /**
1390
 
   * Open all tables in list and process derived tables
1391
 
   *
1392
 
   * @param Pointer to a list of tables for open
1393
 
   * @param Bitmap of flags to modify how the tables will be open:
1394
 
   *        DRIZZLE_LOCK_IGNORE_FLUSH - open table even if someone has
1395
 
   *        done a flush or namelock on it.
1396
 
   *
1397
 
   * @retval
1398
 
   *  false - ok
1399
 
   * @retval
1400
 
   *  true  - error
1401
 
   *
1402
 
   * @note
1403
 
   *
1404
 
   * This is to be used on prepare stage when you don't read any
1405
 
   * data from the tables.
1406
 
   */
1407
 
  bool openTables(TableList *tables, uint32_t flags= 0);
1408
 
 
1409
1601
  int open_tables_from_list(TableList **start, uint32_t *counter, uint32_t flags= 0);
1410
1602
 
1411
1603
  Table *openTableLock(TableList *table_list, thr_lock_type lock_type);
1416
1608
  void close_cached_table(Table *table);
1417
1609
 
1418
1610
  /* Create a lock in the cache */
1419
 
  Table *table_cache_insert_placeholder(const char *key, uint32_t key_length);
 
1611
  table::Placeholder *table_cache_insert_placeholder(const TableIdentifier &identifier);
1420
1612
  bool lock_table_name_if_not_cached(TableIdentifier &identifier, Table **table);
1421
 
  bool lock_table_name_if_not_cached(const char *db,
1422
 
                                     const char *table_name, Table **table);
1423
 
 
1424
 
  typedef drizzled::hash_map<std::string, message::Table> TableMessageCache;
1425
 
  TableMessageCache table_message_cache;
1426
 
 
1427
 
  bool storeTableMessage(TableIdentifier &identifier, message::Table &table_message);
1428
 
  bool removeTableMessage(TableIdentifier &identifier);
1429
 
  bool getTableMessage(TableIdentifier &identifier, message::Table &table_message);
1430
 
  bool doesTableMessageExist(TableIdentifier &identifier);
1431
 
  bool renameTableMessage(TableIdentifier &from, TableIdentifier &to);
1432
 
 
1433
 
  /* Work with temporary tables */
1434
 
  Table *find_temporary_table(TableList *table_list);
1435
 
  Table *find_temporary_table(const char *db, const char *table_name);
1436
 
  Table *find_temporary_table(TableIdentifier &identifier);
1437
 
 
1438
 
  void doGetTableNames(CachedDirectory &directory,
1439
 
                       SchemaIdentifier &schema_identifier,
1440
 
                       std::set<std::string>& set_of_names);
1441
 
  void doGetTableNames(SchemaIdentifier &schema_identifier,
1442
 
                       std::set<std::string>& set_of_names);
1443
 
 
1444
 
  void doGetTableIdentifiers(CachedDirectory &directory,
1445
 
                             SchemaIdentifier &schema_identifier,
1446
 
                             TableIdentifiers &set_of_identifiers);
1447
 
  void doGetTableIdentifiers(SchemaIdentifier &schema_identifier,
1448
 
                             TableIdentifiers &set_of_identifiers);
1449
 
 
1450
 
  int doGetTableDefinition(drizzled::TableIdentifier &identifier,
1451
 
                           message::Table &table_proto);
1452
 
  bool doDoesTableExist(TableIdentifier &identifier);
1453
 
 
1454
 
  void close_temporary_tables();
1455
 
  void close_temporary_table(Table *table);
1456
 
  // The method below just handles the de-allocation of the table. In
1457
 
  // a better memory type world, this would not be needed.
 
1613
 
 
1614
  typedef boost::unordered_map<std::string, message::Table, util::insensitive_hash, util::insensitive_equal_to> TableMessageCache;
 
1615
 
 
1616
  class TableMessages
 
1617
  {
 
1618
    TableMessageCache table_message_cache;
 
1619
 
 
1620
  public:
 
1621
    bool storeTableMessage(const TableIdentifier &identifier, message::Table &table_message);
 
1622
    bool removeTableMessage(const TableIdentifier &identifier);
 
1623
    bool getTableMessage(const TableIdentifier &identifier, message::Table &table_message);
 
1624
    bool doesTableMessageExist(const TableIdentifier &identifier);
 
1625
    bool renameTableMessage(const TableIdentifier &from, const TableIdentifier &to);
 
1626
 
 
1627
  };
1458
1628
private:
1459
 
  void nukeTable(Table *table);
 
1629
  TableMessages _table_message_cache;
 
1630
 
1460
1631
public:
1461
 
 
1462
 
  void dumpTemporaryTableNames(const char *id);
1463
 
  int drop_temporary_table(TableList *table_list);
1464
 
  bool rm_temporary_table(plugin::StorageEngine *base, TableIdentifier &identifier);
1465
 
  bool rm_temporary_table(TableIdentifier &identifier);
1466
 
  Table *open_temporary_table(TableIdentifier &identifier,
1467
 
                              bool link_in_list= true);
 
1632
  TableMessages &getMessageCache()
 
1633
  {
 
1634
    return _table_message_cache;
 
1635
  }
1468
1636
 
1469
1637
  /* Reopen operations */
1470
1638
  bool reopen_tables(bool get_locks, bool mark_share_as_old);
1471
 
  bool reopen_name_locked_table(TableList* table_list, bool link_in);
1472
1639
  bool close_cached_tables(TableList *tables, bool wait_for_refresh, bool wait_for_placeholders);
1473
1640
 
1474
 
  void wait_for_condition(pthread_mutex_t *mutex, pthread_cond_t *cond);
 
1641
  void wait_for_condition(boost::mutex &mutex, boost::condition_variable_any &cond);
1475
1642
  int setup_conds(TableList *leaves, COND **conds);
1476
1643
  int lock_tables(TableList *tables, uint32_t count, bool *need_reopen);
1477
1644
 
 
1645
  drizzled::util::Storable *getProperty(const std::string &arg)
 
1646
  {
 
1647
    return life_properties[arg];
 
1648
  }
 
1649
 
 
1650
  template<class T>
 
1651
  bool setProperty(const std::string &arg, T *value)
 
1652
  {
 
1653
    life_properties[arg]= value;
 
1654
 
 
1655
    return true;
 
1656
  }
1478
1657
 
1479
1658
  /**
1480
1659
    Return the default storage engine
1489
1668
    if (variables.storage_engine)
1490
1669
      return variables.storage_engine;
1491
1670
    return global_system_variables.storage_engine;
1492
 
  };
1493
 
 
1494
 
  static void unlink(Session *session);
1495
 
 
 
1671
  }
 
1672
 
 
1673
  void get_xid(DRIZZLE_XID *xid); // Innodb only
 
1674
 
 
1675
  table::Instance *getInstanceTable();
 
1676
  table::Instance *getInstanceTable(List<CreateField> &field_list);
 
1677
 
 
1678
private:
 
1679
  bool resetUsage()
 
1680
  {
 
1681
    if (getrusage(RUSAGE_THREAD, &usage))
 
1682
    {
 
1683
      return false;
 
1684
    }
 
1685
 
 
1686
    return true;
 
1687
  }
 
1688
public:
 
1689
 
 
1690
  void setUsage(bool arg)
 
1691
  {
 
1692
    use_usage= arg;
 
1693
  }
 
1694
 
 
1695
  const struct rusage &getUsage()
 
1696
  {
 
1697
    return usage;
 
1698
  }
 
1699
 
 
1700
private:
 
1701
  // This lives throughout the life of Session
 
1702
  bool use_usage;
 
1703
  PropertyMap life_properties;
 
1704
  std::vector<table::Instance *> temporary_shares;
 
1705
  struct rusage usage;
1496
1706
};
1497
1707
 
1498
 
class JOIN;
 
1708
class Join;
1499
1709
 
1500
1710
#define ESCAPE_CHARS "ntrb0ZN" // keep synchronous with READ_INFO::unescape
1501
1711
 
1521
1731
 * A structure used to describe sort information
1522
1732
 * for a field or item used in ORDER BY.
1523
1733
 */
1524
 
typedef struct st_sort_field 
 
1734
class SortField 
1525
1735
{
 
1736
public:
1526
1737
  Field *field; /**< Field to sort */
1527
1738
  Item  *item; /**< Item if not sorting fields */
1528
1739
  size_t length; /**< Length of sort field */
1530
1741
  Item_result result_type; /**< Type of item */
1531
1742
  bool reverse; /**< if descending sort */
1532
1743
  bool need_strxnfrm;   /**< If we have to use strxnfrm() */
1533
 
} SORT_FIELD;
1534
 
 
1535
 
typedef struct st_sort_buffer 
1536
 
{
1537
 
  uint32_t index;       /* 0 or 1 */
1538
 
  uint32_t sort_orders;
1539
 
  uint32_t change_pos; /* If sort-fields changed */
1540
 
  char **buff;
1541
 
  SORT_FIELD *sortorder;
1542
 
} SORT_BUFFER;
 
1744
 
 
1745
  SortField() :
 
1746
    field(0),
 
1747
    item(0),
 
1748
    length(0),
 
1749
    suffix_length(0),
 
1750
    result_type(STRING_RESULT),
 
1751
    reverse(0),
 
1752
    need_strxnfrm(0)
 
1753
  { }
 
1754
 
 
1755
};
1543
1756
 
1544
1757
} /* namespace drizzled */
1545
1758
 
1572
1785
static const std::bitset<CF_BIT_SIZE> CF_SHOW_TABLE_COMMAND(1 << CF_BIT_SHOW_TABLE_COMMAND);
1573
1786
static const std::bitset<CF_BIT_SIZE> CF_WRITE_LOGS_COMMAND(1 << CF_BIT_WRITE_LOGS_COMMAND);
1574
1787
 
1575
 
/* Functions in sql_class.cc */
1576
 
void add_to_status(system_status_var *to_var, system_status_var *from_var);
1577
 
 
1578
 
void add_diff_to_status(system_status_var *to_var, system_status_var *from_var,
1579
 
                        system_status_var *dec_var);
1580
 
 
1581
1788
} /* namespace drizzled */
1582
1789
 
1583
1790
#endif /* DRIZZLED_SESSION_H */