~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/session.h

Refactor

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
 
#ifndef DRIZZLED_SESSION_H
21
 
#define DRIZZLED_SESSION_H
 
20
#pragma once
22
21
 
23
22
#include <algorithm>
24
23
#include <bitset>
25
24
#include <boost/make_shared.hpp>
 
25
#include <boost/scoped_ptr.hpp>
26
26
#include <boost/thread/condition_variable.hpp>
27
27
#include <boost/thread/mutex.hpp>
28
28
#include <boost/thread/shared_mutex.hpp>
33
33
#include <sys/resource.h>
34
34
#include <sys/time.h>
35
35
 
36
 
#include <drizzled/catalog/instance.h>
37
 
#include <drizzled/catalog/local.h>
38
 
#include <drizzled/copy_info.h>
39
 
#include <drizzled/cursor.h>
40
 
#include <drizzled/diagnostics_area.h>
41
 
#include <drizzled/file_exchange.h>
42
 
#include <drizzled/ha_data.h>
43
 
#include <drizzled/identifier.h>
44
 
#include <drizzled/lex_column.h>
45
 
#include <drizzled/my_hash.h>
46
 
#include <drizzled/named_savepoint.h>
 
36
#include <drizzled/global_charset_info.h>
 
37
#include <drizzled/base.h>
 
38
#include <drizzled/error.h>
47
39
#include <drizzled/open_tables_state.h>
48
 
#include <drizzled/plugin.h>
49
 
#include <drizzled/plugin/authorization.h>
50
40
#include <drizzled/pthread_globals.h>
51
 
#include <drizzled/query_id.h>
52
 
#include <drizzled/resource_context.h>
53
 
#include <drizzled/session/property_map.h>
54
 
#include <drizzled/session/state.h>
55
 
#include <drizzled/session/table_messages.h>
56
41
#include <drizzled/session/transactions.h>
 
42
#include <drizzled/sql_list.h>
57
43
#include <drizzled/sql_error.h>
58
 
#include <drizzled/sql_lex.h>
59
44
#include <drizzled/sql_locale.h>
60
45
#include <drizzled/statistics_variables.h>
61
46
#include <drizzled/system_variables.h>
62
 
#include <drizzled/system_variables.h>
63
 
#include <drizzled/table_ident.h>
64
 
#include <drizzled/transaction_context.h>
65
 
#include <drizzled/util/storable.h>
66
 
#include <drizzled/var.h>
67
47
#include <drizzled/visibility.h>
68
 
 
69
 
#define MIN_HANDSHAKE_SIZE      6
70
 
 
71
 
namespace drizzled
72
 
{
 
48
#include <drizzled/util/find_ptr.h>
 
49
#include <drizzled/util/string.h>
 
50
#include <drizzled/type/time.h>
 
51
#include <drizzled/sql_lex.h>
 
52
 
 
53
namespace drizzled {
73
54
 
74
55
namespace plugin
75
56
{
76
 
class Client;
77
 
class Scheduler;
78
 
class EventObserverList;
 
57
        class Client;
 
58
        class EventObserverList;
 
59
  class MonitoredInTransaction;
 
60
        class Scheduler;
79
61
}
80
62
 
81
63
namespace message
82
64
{
83
 
class Transaction;
84
 
class Statement;
85
 
class Resultset;
 
65
        class Transaction;
 
66
        class Statement;
 
67
        class Resultset;
86
68
}
87
69
 
88
70
namespace internal { struct st_my_thread_var; }
89
 
namespace table { class Placeholder; }
 
71
 
 
72
namespace session 
 
73
 
74
  class State; 
 
75
  class TableMessages;
 
76
}
 
77
 
 
78
namespace table 
 
79
 
80
  class Placeholder; 
 
81
  class Singular; 
 
82
}
 
83
 
 
84
namespace util
 
85
{
 
86
  class Storable;
 
87
}
90
88
 
91
89
class CopyField;
 
90
class CreateField;
 
91
class Diagnostics_area;
92
92
class DrizzleXid;
 
93
class Field;
93
94
class Internal_error_handler;
 
95
class Item;
 
96
class LEX;
94
97
class Lex_input_stream;
 
98
class ResourceContext;
95
99
class TableShareInstance;
96
100
class Table_ident;
97
101
class Time_zone;
98
102
class select_result;
99
103
class user_var_entry;
 
104
struct Ha_data;
 
105
 
 
106
typedef Item COND;
100
107
 
101
108
extern char internal_table_name[2];
102
109
extern char empty_c_string[1];
106
113
#define TC_HEURISTIC_RECOVER_ROLLBACK 2
107
114
extern uint32_t tc_heuristic_recover;
108
115
 
109
 
#define Session_SENTRY_MAGIC 0xfeedd1ff
110
 
#define Session_SENTRY_GONE  0xdeadbeef
111
 
 
112
116
extern DRIZZLED_API struct drizzle_system_variables global_system_variables;
113
117
 
114
118
/**
161
165
  enum enum_mark_columns mark_used_columns;
162
166
  inline void* calloc(size_t size)
163
167
  {
164
 
    void *ptr;
165
 
    if ((ptr= mem_root->alloc_root(size)))
 
168
    void *ptr= mem_root->alloc_root(size);
 
169
    if (ptr)
166
170
      memset(ptr, 0, size);
167
171
    return ptr;
168
172
  }
173
177
 
174
178
  inline void *memdup_w_gap(const void *str, size_t size, uint32_t gap)
175
179
  {
176
 
    void *ptr;
177
 
    if ((ptr= mem_root->alloc_root(size + gap)))
178
 
      memcpy(ptr,str,size);
 
180
    void *ptr= mem_root->alloc_root(size + gap);
 
181
    if (ptr)
 
182
      memcpy(ptr, str, size);
179
183
    return ptr;
180
184
  }
181
185
  /** Frees all items attached to this Statement */
188
192
  Item *free_list;
189
193
  memory::Root *mem_root; /**< Pointer to current memroot */
190
194
 
191
 
 
192
195
  memory::Root *getMemRoot()
193
196
  {
194
197
    return mem_root;
195
198
  }
196
199
 
197
 
  uint64_t xa_id;
198
 
 
199
200
  uint64_t getXaId()
200
201
  {
201
202
    return xa_id;
203
204
 
204
205
  void setXaId(uint64_t in_xa_id)
205
206
  {
206
 
    xa_id= in_xa_id; 
 
207
    xa_id= in_xa_id;
207
208
  }
208
209
 
209
 
  /**
210
 
   * Uniquely identifies each statement object in thread scope; change during
211
 
   * statement lifetime.
212
 
   *
213
 
   * @todo should be const
214
 
   */
215
 
  uint32_t id;
216
 
private:
217
 
  LEX *lex; /**< parse tree descriptor */
218
 
 
219
210
public:
220
 
  LEX *getLex() 
221
 
  {
222
 
    return lex;
223
 
  }
224
 
 
225
 
  enum_sql_command getSqlCommand() const
226
 
  {
227
 
    return lex->sql_command;
228
 
  }
 
211
  Diagnostics_area& main_da();
 
212
  const LEX& lex() const;
 
213
  LEX& lex();
 
214
  enum_sql_command getSqlCommand() const;
229
215
 
230
216
  /** query associated with this statement */
231
217
  typedef boost::shared_ptr<const std::string> QueryString;
269
255
  }
270
256
 
271
257
private:
272
 
  session::State::shared_ptr  _state; 
 
258
  boost::shared_ptr<session::State> _state;
273
259
 
274
260
public:
275
261
 
276
 
  session::State::const_shared_ptr state()
 
262
  const boost::shared_ptr<session::State>& state()
277
263
  {
278
264
    return _state;
279
265
  }
300
286
    if (_schema)
301
287
      return _schema;
302
288
 
303
 
    return util::string::const_shared_ptr(new std::string(""));
 
289
    return util::string::const_shared_ptr(new std::string);
304
290
  }
305
291
 
306
292
  /* current cache key */
314
300
  static const char * const DEFAULT_WHERE;
315
301
 
316
302
  memory::Root warn_root; /**< Allocation area for warnings and errors */
317
 
private:
318
 
  plugin::Client *client; /**< Pointer to client object */
319
 
 
320
303
public:
321
 
 
322
304
  void setClient(plugin::Client *client_arg);
323
305
 
324
 
  plugin::Client *getClient()
325
 
  {
326
 
    return client;
327
 
  }
328
 
 
329
306
  plugin::Client *getClient() const
330
307
  {
331
308
    return client;
347
324
  }
348
325
 
349
326
  drizzle_system_variables variables; /**< Mutable local variables local to the session */
350
 
 
351
 
  enum_tx_isolation getTxIsolation()
352
 
  {
353
 
    return (enum_tx_isolation)variables.tx_isolation;
354
 
  }
355
 
 
356
 
  struct system_status_var status_var; /**< Session-local status counters */
 
327
  enum_tx_isolation getTxIsolation();
 
328
  system_status_var status_var;
 
329
 
357
330
  THR_LOCK_INFO lock_info; /**< Locking information for this session */
358
331
  THR_LOCK_OWNER main_lock_id; /**< To use for conventional queries */
359
332
  THR_LOCK_OWNER *lock_id; /**< If not main_lock_id, points to the lock_id of a cursor. */
364
337
   */
365
338
  char *thread_stack;
366
339
 
367
 
private:
368
 
  identifier::User::shared_ptr security_ctx;
369
 
 
370
 
  int32_t scoreboard_index;
371
 
 
372
 
  inline void checkSentry() const
373
 
  {
374
 
    assert(this->dbug_sentry == Session_SENTRY_MAGIC);
375
 
  }
376
 
 
377
 
public:
378
340
  identifier::User::const_shared_ptr user() const
379
341
  {
380
 
    if (security_ctx)
381
 
      return security_ctx;
382
 
 
383
 
    return identifier::User::const_shared_ptr();
 
342
    return security_ctx ? security_ctx : identifier::User::const_shared_ptr();
384
343
  }
385
344
 
386
345
  void setUser(identifier::User::shared_ptr arg)
427
386
    points to a lock object if the lock is present. See item_func.cc and
428
387
    chapter 'Miscellaneous functions', for functions GET_LOCK, RELEASE_LOCK.
429
388
  */
430
 
  uint32_t dbug_sentry; /**< watch for memory corruption */
431
389
 
432
390
private:
433
391
  boost::thread::id boost_thread_id;
514
472
 
515
473
public:
516
474
  void **getEngineData(const plugin::MonitoredInTransaction *monitored);
517
 
  ResourceContext *getResourceContext(const plugin::MonitoredInTransaction *monitored,
518
 
                                      size_t index= 0);
 
475
  ResourceContext& getResourceContext(const plugin::MonitoredInTransaction&, size_t index= 0);
519
476
 
520
477
  session::Transactions transaction;
521
478
 
522
479
  Field *dup_field;
523
480
  sigset_t signals;
524
481
 
 
482
public:
525
483
  // As of right now we do not allow a concurrent execute to launch itself
526
 
private:
527
 
  bool concurrent_execute_allowed;
528
 
 
529
 
public:
530
 
 
531
484
  void setConcurrentExecute(bool arg)
532
485
  {
533
486
    concurrent_execute_allowed= arg;
538
491
    return concurrent_execute_allowed;
539
492
  }
540
493
 
541
 
  /* Tells if LAST_INSERT_ID(#) was called for the current statement */
542
 
  bool arg_of_last_insert_id_function;
543
 
 
544
494
  /*
545
495
    ALL OVER THIS FILE, "insert_id" means "*automatically generated* value for
546
496
    insertion into an auto_increment column".
587
537
    (first_successful_insert_id_in_cur_stmt == 0), but storing "INSERT_ID=3"
588
538
    in the binlog is still needed; the list's minimum will contain 3.
589
539
  */
590
 
  Discrete_intervals_list auto_inc_intervals_in_cur_stmt_for_binlog;
591
 
  /** Used by replication and SET INSERT_ID */
592
 
  Discrete_intervals_list auto_inc_intervals_forced;
593
540
 
594
541
  uint64_t limit_found_rows;
595
542
  uint64_t options; /**< Bitmap of options */
602
549
 
603
550
  ha_rows cuted_fields; /**< Count of "cut" or truncated fields. @todo Kill this friggin thing. */
604
551
 
605
 
  /** 
 
552
  /**
606
553
   * Number of rows we actually sent to the client, including "synthetic"
607
554
   * rows in ROLLUP etc.
608
555
   */
618
565
   * of the query.
619
566
   *
620
567
   * @todo
621
 
   * 
 
568
   *
622
569
   * Possibly this it is incorrect to have used tables in Session because
623
570
   * with more than one subquery, it is not clear what does the field mean.
624
571
   */
626
573
 
627
574
  /**
628
575
    @todo
629
 
    
 
576
 
630
577
    This, and some other variables like 'count_cuted_fields'
631
578
    maybe should be statement/cursor local, that is, moved to Statement
632
579
    class. With current implementation warnings produced in each prepared
635
582
  List<DRIZZLE_ERROR> warn_list;
636
583
  uint32_t warn_count[(uint32_t) DRIZZLE_ERROR::WARN_LEVEL_END];
637
584
  uint32_t total_warn_count;
638
 
  Diagnostics_area main_da;
639
585
 
640
586
  ulong col_access;
641
587
 
770
716
  bool substitute_null_with_insert_id;
771
717
  bool cleanup_done;
772
718
 
773
 
private:
774
 
  bool abort_on_warning;
775
 
  bool tablespace_op; /**< This is true in DISCARD/IMPORT TABLESPACE */
776
 
 
777
719
public:
778
720
  bool got_warning; /**< Set on call to push_warning() */
779
721
  bool no_warnings_for_error; /**< no warnings on call to my_error() */
780
722
  /** set during loop of derived table processing */
781
723
  bool derived_tables_processing;
782
724
 
783
 
  bool doing_tablespace_operation(void)
 
725
  bool doing_tablespace_operation()
784
726
  {
785
727
    return tablespace_op;
786
728
  }
808
750
    and may point to invalid memory after that.
809
751
  */
810
752
  Lex_input_stream *m_lip;
811
 
  
 
753
 
812
754
  /** Place to store various things */
813
755
  void *session_marker;
814
756
 
824
766
    macro/function.
825
767
  */
826
768
  inline void set_proc_info(const char *info)
827
 
  { 
 
769
  {
828
770
    proc_info= info;
829
771
  }
830
772
  inline const char* get_proc_info() const
916
858
    if (first_successful_insert_id_in_cur_stmt == 0)
917
859
      first_successful_insert_id_in_cur_stmt= id_arg;
918
860
  }
919
 
  inline uint64_t read_first_successful_insert_id_in_prev_stmt(void)
 
861
  inline uint64_t read_first_successful_insert_id_in_prev_stmt()
920
862
  {
921
863
    return first_successful_insert_id_in_prev_stmt;
922
864
  }
923
 
  /**
924
 
    Used by Intvar_log_event::do_apply_event() and by "SET INSERT_ID=#"
925
 
    (mysqlbinlog). We'll soon add a variant which can take many intervals in
926
 
    argument.
927
 
  */
928
 
  inline void force_one_auto_inc_interval(uint64_t next_id)
929
 
  {
930
 
    auto_inc_intervals_forced.empty(); // in case of multiple SET INSERT_ID
931
 
    auto_inc_intervals_forced.append(next_id, UINT64_MAX, 0);
932
 
  }
933
865
 
934
866
  Session(plugin::Client *client_arg, catalog::Instance::shared_ptr catalog);
935
867
  virtual ~Session();
936
868
 
937
 
  void cleanup(void);
 
869
  void cleanup();
938
870
  /**
939
871
   * Cleans up after query.
940
872
   *
970
902
  void prepareForQueries();
971
903
 
972
904
  /**
973
 
   * Executes a single statement received from the 
 
905
   * Executes a single statement received from the
974
906
   * client connection.
975
907
   *
976
 
   * Returns true if the statement was successful, or false 
 
908
   * Returns true if the statement was successful, or false
977
909
   * otherwise.
978
910
   *
979
911
   * @note
988
920
  /**
989
921
   * Reads a query from packet and stores it.
990
922
   *
991
 
   * Returns true if query is read and allocated successfully, 
 
923
   * Returns true if query is read and allocated successfully,
992
924
   * false otherwise.  On a return of false, Session::fatal_error
993
925
   * is set.
994
926
   *
1006
938
  /**
1007
939
   * Ends the current transaction and (maybe) begins the next.
1008
940
   *
1009
 
   * Returns true if the transaction completed successfully, 
 
941
   * Returns true if the transaction completed successfully,
1010
942
   * otherwise false.
1011
943
   *
1012
944
   * @param Completion type
1063
995
  }
1064
996
 
1065
997
  void set_time_after_lock()
1066
 
  { 
1067
 
    boost::posix_time::ptime mytime(boost::posix_time::microsec_clock::universal_time());
1068
 
    utime_after_lock= (mytime - _epoch).total_microseconds();
1069
 
  }
1070
 
 
1071
 
  void set_end_timer()
1072
998
  {
1073
 
    _end_timer= boost::posix_time::microsec_clock::universal_time();
1074
 
    status_var.execution_time_nsec+=(_end_timer - _start_timer).total_microseconds();
 
999
    utime_after_lock= (boost::posix_time::microsec_clock::universal_time() - _epoch).total_microseconds();
1075
1000
  }
1076
1001
 
 
1002
  void set_end_timer();
 
1003
 
1077
1004
  uint64_t getElapsedTime() const
1078
1005
  {
1079
1006
    return (_end_timer - _start_timer).total_microseconds();
1083
1010
   * Returns the current micro-timestamp
1084
1011
   */
1085
1012
  type::Time::epoch_t getCurrentTimestamp(bool actual= true) const
1086
 
  { 
1087
 
    type::Time::epoch_t t_mark;
1088
 
 
1089
 
    if (actual)
1090
 
    {
1091
 
      boost::posix_time::ptime mytime(boost::posix_time::microsec_clock::universal_time());
1092
 
      t_mark= (mytime - _epoch).total_microseconds();
1093
 
    }
1094
 
    else
1095
 
    {
1096
 
      t_mark= (_end_timer - _epoch).total_microseconds();
1097
 
    }
1098
 
 
1099
 
    return t_mark; 
 
1013
  {
 
1014
    return ((actual ? boost::posix_time::microsec_clock::universal_time() : _end_timer) - _epoch).total_microseconds();
1100
1015
  }
1101
1016
 
1102
1017
  // We may need to set user on this
1103
1018
  type::Time::epoch_t getCurrentTimestampEpoch() const
1104
 
  { 
1105
 
    if (not _user_time.is_not_a_date_time())
1106
 
      return (_user_time - _epoch).total_seconds();
1107
 
 
1108
 
    return (_start_timer - _epoch).total_seconds();
 
1019
  {
 
1020
                return ((_user_time.is_not_a_date_time() ? _start_timer : _user_time) - _epoch).total_seconds();
1109
1021
  }
1110
1022
 
1111
1023
  type::Time::epoch_t getCurrentTimestampEpoch(type::Time::usec_t &fraction_arg) const
1112
 
  { 
 
1024
  {
1113
1025
    if (not _user_time.is_not_a_date_time())
1114
1026
    {
1115
1027
      fraction_arg= 0;
1120
1032
    return (_start_timer - _epoch).total_seconds();
1121
1033
  }
1122
1034
 
1123
 
  uint64_t found_rows(void) const
 
1035
  uint64_t found_rows() const
1124
1036
  {
1125
1037
    return limit_found_rows;
1126
1038
  }
1141
1053
 
1142
1054
  int send_explain_fields(select_result *result);
1143
1055
 
1144
 
  /**
1145
 
    Clear the current error, if any.
1146
 
    We do not clear is_fatal_error or is_fatal_sub_stmt_error since we
1147
 
    assume this is never called if the fatal error is set.
1148
 
    @todo: To silence an error, one should use Internal_error_handler
1149
 
    mechanism. In future this function will be removed.
1150
 
  */
1151
 
  inline void clear_error(bool full= false)
1152
 
  {
1153
 
    if (main_da.is_error())
1154
 
      main_da.reset_diagnostics_area();
1155
 
 
1156
 
    if (full)
1157
 
    {
1158
 
      drizzle_reset_errors(this, true);
1159
 
    }
1160
 
  }
1161
 
 
1162
 
  void clearDiagnostics()
1163
 
  {
1164
 
    main_da.reset_diagnostics_area();
1165
 
  }
1166
 
 
1167
 
  /**
1168
 
    Mark the current error as fatal. Warning: this does not
1169
 
    set any error, it sets a property of the error, so must be
1170
 
    followed or prefixed with my_error().
1171
 
  */
1172
 
  inline void fatal_error()
1173
 
  {
1174
 
    assert(main_da.is_error());
1175
 
    is_fatal_error= true;
1176
 
  }
1177
 
  /**
1178
 
    true if there is an error in the error stack.
1179
 
 
1180
 
    Please use this method instead of direct access to
1181
 
    net.report_error.
1182
 
 
1183
 
    If true, the current (sub)-statement should be aborted.
1184
 
    The main difference between this member and is_fatal_error
1185
 
    is that a fatal error can not be handled by a stored
1186
 
    procedure continue handler, whereas a normal error can.
1187
 
 
1188
 
    To raise this flag, use my_error().
1189
 
  */
1190
 
  inline bool is_error() const { return main_da.is_error(); }
 
1056
  void clear_error(bool full= false);
 
1057
  void clearDiagnostics();
 
1058
  void fatal_error();
 
1059
  bool is_error() const;
 
1060
 
1191
1061
  inline const CHARSET_INFO *charset() { return default_charset_info; }
1192
1062
 
1193
 
  void change_item_tree(Item **place, Item *new_value)
1194
 
  {
1195
 
    *place= new_value;
1196
 
  }
1197
1063
  /**
1198
1064
    Cleanup statement parse state (parse tree, lex) and execution
1199
1065
    state after execution of a non-prepared SQL statement.
1263
1129
    @param level the error level
1264
1130
    @return true if the error is handled
1265
1131
  */
1266
 
  virtual bool handle_error(drizzled::error_t sql_errno, const char *message,
 
1132
  virtual bool handle_error(error_t sql_errno, const char *message,
1267
1133
                            DRIZZLE_ERROR::enum_warning_level level);
1268
1134
 
1269
1135
  /**
1303
1169
   *
1304
1170
   * @note Host, user and passwd may point to communication buffer.
1305
1171
   * Current implementation does not depend on that, but future changes
1306
 
   * should be done with this in mind; 
 
1172
   * should be done with this in mind;
1307
1173
   *
1308
1174
   * @param passwd Scrambled password received from client
1309
1175
   * @param db Database name to connect to, may be NULL
1310
1176
   */
1311
1177
  bool checkUser(const std::string &passwd, const std::string &db);
1312
 
  
 
1178
 
1313
1179
  /**
1314
 
   * Returns the timestamp (in microseconds) of when the Session 
 
1180
   * Returns the timestamp (in microseconds) of when the Session
1315
1181
   * connected to the server.
1316
1182
   */
1317
1183
  uint64_t getConnectMicroseconds() const
1342
1208
  {
1343
1209
    return statement_message;
1344
1210
  }
1345
 
  
 
1211
 
1346
1212
  /**
1347
1213
   * Returns a pointer to the current Resulset message for this
1348
1214
   * Session, or NULL if no active message.
1389
1255
   */
1390
1256
 
1391
1257
  void resetResultsetMessage()
1392
 
  { 
 
1258
  {
1393
1259
    resultset= NULL;
1394
1260
  }
1395
1261
 
1396
 
private:
1397
 
  /** Pointers to memory managed by the ReplicationServices component */
1398
 
  message::Transaction *transaction_message;
1399
 
  message::Statement *statement_message;
1400
 
  /* Pointer to the current resultset of Select query */
1401
 
  message::Resultset *resultset;
1402
 
  plugin::EventObserverList *session_event_observers;
1403
 
  
1404
 
  /* Schema observers are mapped to databases. */
1405
 
  std::map<std::string, plugin::EventObserverList *> schema_event_observers;
1406
 
 
1407
 
 
1408
1262
public:
1409
 
  plugin::EventObserverList *getSessionObservers() 
1410
 
  { 
 
1263
  plugin::EventObserverList *getSessionObservers()
 
1264
  {
1411
1265
    return session_event_observers;
1412
1266
  }
1413
 
  
1414
 
  void setSessionObservers(plugin::EventObserverList *observers) 
1415
 
  { 
 
1267
 
 
1268
  void setSessionObservers(plugin::EventObserverList *observers)
 
1269
  {
1416
1270
    session_event_observers= observers;
1417
1271
  }
1418
 
  
 
1272
 
1419
1273
  /* For schema event observers there is one set of observers per database. */
1420
 
  plugin::EventObserverList *getSchemaObservers(const std::string &db_name) 
1421
 
  { 
1422
 
    std::map<std::string, plugin::EventObserverList *>::iterator it;
1423
 
    
1424
 
    it= schema_event_observers.find(db_name);
1425
 
    if (it == schema_event_observers.end())
1426
 
      return NULL;
1427
 
      
1428
 
    return it->second;
 
1274
  plugin::EventObserverList *getSchemaObservers(const std::string &db_name)
 
1275
  {
 
1276
    if (schema_event_observers_t::mapped_type* i= find_ptr(schema_event_observers, db_name))
 
1277
      return *i;
 
1278
    return NULL;
1429
1279
  }
1430
 
  
1431
 
  void setSchemaObservers(const std::string &db_name, plugin::EventObserverList *observers) 
1432
 
  { 
1433
 
    std::map<std::string, plugin::EventObserverList *>::iterator it;
1434
 
 
1435
 
    it= schema_event_observers.find(db_name);
1436
 
    if (it != schema_event_observers.end())
1437
 
      schema_event_observers.erase(it);;
1438
 
 
 
1280
 
 
1281
  void setSchemaObservers(const std::string &db_name, plugin::EventObserverList *observers)
 
1282
  {
 
1283
    schema_event_observers.erase(db_name);
1439
1284
    if (observers)
1440
1285
      schema_event_observers[db_name] = observers;
1441
1286
  }
1442
 
  
1443
 
  
 
1287
 
 
1288
 
1444
1289
 private:
1445
 
  const char *proc_info;
1446
1290
 
1447
1291
  /** The current internal error handler for this thread, or NULL. */
1448
1292
  Internal_error_handler *m_internal_handler;
1449
1293
  /**
1450
 
    The lex to hold the parsed tree of conventional (non-prepared) queries.
1451
 
    Whereas for prepared and stored procedure statements we use an own lex
1452
 
    instance for each new query, for conventional statements we reuse
1453
 
    the same lex. (@see mysql_parse for details).
1454
 
  */
1455
 
  LEX main_lex;
1456
 
  /**
1457
1294
    This memory root is used for two purposes:
1458
1295
    - for conventional queries, to allocate structures stored in main_lex
1459
1296
    during parsing, and allocate runtime data (execution plan, etc.)
1475
1312
   * if table->query_id != session->query_id to know if a table is in use.
1476
1313
   *
1477
1314
   * For example
1478
 
   * 
 
1315
   *
1479
1316
   *  SELECT f1_that_uses_t1() FROM t1;
1480
 
   *  
 
1317
   *
1481
1318
   * In f1_that_uses_t1() we will see one instance of t1 where query_id is
1482
1319
   * set to query_id of original query.
1483
1320
   */
1484
1321
  void mark_used_tables_as_free_for_reuse(Table *table);
1485
1322
 
1486
1323
public:
1487
 
 
1488
 
  /** A short cut for session->main_da.set_ok_status(). */
1489
 
  inline void my_ok(ha_rows affected_rows= 0, ha_rows found_rows_arg= 0,
1490
 
                    uint64_t passed_id= 0, const char *message= NULL)
1491
 
  {
1492
 
    main_da.set_ok_status(this, affected_rows, found_rows_arg, passed_id, message);
1493
 
  }
1494
 
 
1495
 
 
1496
 
  /** A short cut for session->main_da.set_eof_status(). */
1497
 
 
1498
 
  inline void my_eof()
1499
 
  {
1500
 
    main_da.set_eof_status(this);
1501
 
  }
1502
 
 
1503
 
  /* Some inline functions for more speed */
1504
 
 
1505
 
  inline bool add_item_to_list(Item *item)
1506
 
  {
1507
 
    return lex->current_select->add_item_to_list(this, item);
1508
 
  }
1509
 
 
1510
 
  inline bool add_value_to_list(Item *value)
1511
 
  {
1512
 
    return lex->value_list.push_back(value);
1513
 
  }
1514
 
 
1515
 
  inline bool add_order_to_list(Item *item, bool asc)
1516
 
  {
1517
 
    return lex->current_select->add_order_to_list(this, item, asc);
1518
 
  }
1519
 
 
1520
 
  inline bool add_group_to_list(Item *item, bool asc)
1521
 
  {
1522
 
    return lex->current_select->add_group_to_list(this, item, asc);
1523
 
  }
 
1324
  void my_ok(ha_rows affected_rows= 0, ha_rows found_rows_arg= 0, uint64_t passed_id= 0, const char *message= NULL);
 
1325
  void my_eof();
 
1326
  bool add_item_to_list(Item *item);
 
1327
  bool add_value_to_list(Item *value);
 
1328
  bool add_order_to_list(Item *item, bool asc);
 
1329
  bool add_group_to_list(Item *item, bool asc);
 
1330
 
1524
1331
  void refresh_status();
1525
1332
  user_var_entry *getVariable(LEX_STRING &name, bool create_if_not_exists);
1526
1333
  user_var_entry *getVariable(const std::string  &name, bool create_if_not_exists);
1527
1334
  void setVariable(const std::string &name, const std::string &value);
1528
 
  
 
1335
 
1529
1336
  /**
1530
1337
   * Closes all tables used by the current substatement, or all tables
1531
1338
   * used by this thread if we are on the upper level.
1536
1343
  void close_open_tables();
1537
1344
  void close_data_files_and_morph_locks(const identifier::Table &identifier);
1538
1345
 
1539
 
private:
1540
 
  bool free_cached_table(boost::mutex::scoped_lock &scopedLock);
1541
 
 
1542
 
public:
1543
 
 
1544
1346
  /**
1545
1347
   * Prepares statement for reopening of tables and recalculation of set of
1546
1348
   * prelocked tables.
1561
1363
   *  true  - error
1562
1364
   *
1563
1365
   * @note
1564
 
   * 
 
1366
   *
1565
1367
   * The lock will automaticaly be freed by close_thread_tables()
1566
1368
   */
1567
1369
  bool openTablesLock(TableList *tables);
1579
1381
  table::Placeholder *table_cache_insert_placeholder(const identifier::Table &identifier);
1580
1382
  bool lock_table_name_if_not_cached(const identifier::Table &identifier, Table **table);
1581
1383
 
1582
 
private:
1583
 
  session::TableMessages _table_message_cache;
1584
 
 
1585
 
public:
1586
 
  session::TableMessages &getMessageCache()
1587
 
  {
1588
 
    return _table_message_cache;
1589
 
  }
 
1384
  session::TableMessages &getMessageCache();
1590
1385
 
1591
1386
  /* Reopen operations */
1592
1387
  bool reopen_tables();
1596
1391
  int setup_conds(TableList *leaves, COND **conds);
1597
1392
  int lock_tables(TableList *tables, uint32_t count, bool *need_reopen);
1598
1393
 
1599
 
  drizzled::util::Storable *getProperty(const std::string &arg)
 
1394
  template <class T>
 
1395
  T* getProperty(const std::string& name)
1600
1396
  {
1601
 
    return life_properties.getProperty(arg);
 
1397
    return static_cast<T*>(getProperty0(name));
1602
1398
  }
1603
1399
 
1604
 
  template<class T>
1605
 
  bool setProperty(const std::string &arg, T *value)
 
1400
  template <class T>
 
1401
  T setProperty(const std::string& name, T value)
1606
1402
  {
1607
 
    life_properties.setProperty(arg, value);
1608
 
 
1609
 
    return true;
 
1403
    setProperty0(name, value);
 
1404
    return value;
1610
1405
  }
1611
1406
 
1612
1407
  /**
1617
1412
    @return
1618
1413
    pointer to plugin::StorageEngine
1619
1414
  */
1620
 
  plugin::StorageEngine *getDefaultStorageEngine()
1621
 
  {
1622
 
    if (variables.storage_engine)
1623
 
      return variables.storage_engine;
1624
 
    return global_system_variables.storage_engine;
1625
 
  }
1626
 
 
 
1415
  plugin::StorageEngine *getDefaultStorageEngine();
1627
1416
  void get_xid(DrizzleXid *xid); // Innodb only
1628
1417
 
1629
1418
  table::Singular *getInstanceTable();
1630
1419
  table::Singular *getInstanceTable(List<CreateField> &field_list);
1631
1420
 
1632
 
private:
1633
 
  bool resetUsage()
1634
 
  {
1635
 
    if (getrusage(RUSAGE_THREAD, &usage))
1636
 
    {
1637
 
      return false;
1638
 
    }
1639
 
 
1640
 
    return true;
1641
 
  }
1642
 
 
1643
 
public:
1644
 
 
1645
1421
  void setUsage(bool arg)
1646
1422
  {
1647
1423
    use_usage= arg;
1648
1424
  }
1649
1425
 
1650
 
  const struct rusage &getUsage()
 
1426
  const rusage &getUsage()
1651
1427
  {
1652
1428
    return usage;
1653
1429
  }
1654
1430
 
1655
1431
  catalog::Instance::const_reference catalog() const
1656
1432
  {
1657
 
    return *(_catalog.get());
 
1433
    return *_catalog;
1658
1434
  }
1659
1435
 
1660
1436
  catalog::Instance::reference catalog()
1661
1437
  {
1662
 
    return *(_catalog.get());
 
1438
    return *_catalog;
1663
1439
  }
1664
1440
 
 
1441
  bool arg_of_last_insert_id_function; // Tells if LAST_INSERT_ID(#) was called for the current statement
1665
1442
private:
 
1443
        class impl_c;
 
1444
 
 
1445
  bool free_cached_table(boost::mutex::scoped_lock &scopedLock);
 
1446
  drizzled::util::Storable* getProperty0(const std::string&);
 
1447
  void setProperty0(const std::string&, drizzled::util::Storable*);
 
1448
 
 
1449
 
 
1450
  bool resetUsage()
 
1451
  {
 
1452
    return not getrusage(RUSAGE_THREAD, &usage);
 
1453
  }
 
1454
 
 
1455
  boost::scoped_ptr<impl_c> impl_;
1666
1456
  catalog::Instance::shared_ptr _catalog;
1667
1457
 
1668
 
  // This lives throughout the life of Session
 
1458
  /** Pointers to memory managed by the ReplicationServices component */
 
1459
  message::Transaction *transaction_message;
 
1460
  message::Statement *statement_message;
 
1461
  /* Pointer to the current resultset of Select query */
 
1462
  message::Resultset *resultset;
 
1463
  plugin::EventObserverList *session_event_observers;
 
1464
 
 
1465
  /* Schema observers are mapped to databases. */
 
1466
  typedef std::map<std::string, plugin::EventObserverList*> schema_event_observers_t;
 
1467
  schema_event_observers_t schema_event_observers;
 
1468
 
 
1469
  uint64_t xa_id;
 
1470
  const char *proc_info;
 
1471
  bool abort_on_warning;
 
1472
  bool concurrent_execute_allowed;
 
1473
  bool tablespace_op; /**< This is true in DISCARD/IMPORT TABLESPACE */
1669
1474
  bool use_usage;
1670
 
  session::PropertyMap life_properties;
1671
1475
  std::vector<table::Singular *> temporary_shares;
1672
 
  struct rusage usage;
 
1476
  rusage usage;
 
1477
  identifier::User::shared_ptr security_ctx;
 
1478
  int32_t scoreboard_index;
 
1479
  plugin::Client *client;
1673
1480
};
1674
1481
 
1675
1482
#define ESCAPE_CHARS "ntrb0ZN" // keep synchronous with READ_INFO::unescape
1676
1483
 
1677
1484
/* Bits in sql_command_flags */
1678
1485
 
1679
 
enum sql_command_flag_bits 
 
1486
enum sql_command_flag_bits
1680
1487
{
1681
1488
  CF_BIT_CHANGES_DATA,
1682
1489
  CF_BIT_HAS_ROW_COUNT,
1692
1499
static const std::bitset<CF_BIT_SIZE> CF_SHOW_TABLE_COMMAND(1 << CF_BIT_SHOW_TABLE_COMMAND);
1693
1500
static const std::bitset<CF_BIT_SIZE> CF_WRITE_LOGS_COMMAND(1 << CF_BIT_WRITE_LOGS_COMMAND);
1694
1501
 
1695
 
namespace display  {
1696
 
const std::string &type(drizzled::Session::global_read_lock_t type);
1697
 
size_t max_string_length(drizzled::Session::global_read_lock_t type);
1698
 
 
 
1502
namespace display  
 
1503
{
 
1504
  const std::string &type(Session::global_read_lock_t);
 
1505
  size_t max_string_length(Session::global_read_lock_t);
1699
1506
} /* namespace display */
1700
1507
 
1701
1508
} /* namespace drizzled */
1702
1509
 
1703
 
#endif /* DRIZZLED_SESSION_H */