~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/session.h

  • Committer: Olaf van der Spek
  • Date: 2011-04-05 12:26:58 UTC
  • mto: (2278.1.2 build)
  • mto: This revision was merged to the branch mainline in revision 2272.
  • Revision ID: olafvdspek@gmail.com-20110405122658-xxrvmobwwwwf3oct
Refactor Open_tables_state

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
 
#include <drizzled/session/transactions.h>
57
41
#include <drizzled/sql_error.h>
58
 
#include <drizzled/sql_lex.h>
59
42
#include <drizzled/sql_locale.h>
60
 
#include <drizzled/statistics_variables.h>
61
 
#include <drizzled/system_variables.h>
62
 
#include <drizzled/system_variables.h>
63
 
#include <drizzled/table_ident.h>
64
 
#include <drizzled/transaction_context.h>
65
 
#include <drizzled/util/storable.h>
66
 
#include <drizzled/var.h>
67
43
#include <drizzled/visibility.h>
68
 
 
69
 
#define MIN_HANDSHAKE_SIZE      6
70
 
 
71
 
namespace drizzled
72
 
{
73
 
 
74
 
namespace plugin
75
 
{
76
 
class Client;
77
 
class Scheduler;
78
 
class EventObserverList;
79
 
}
80
 
 
81
 
namespace message
82
 
{
83
 
class Transaction;
84
 
class Statement;
85
 
class Resultset;
86
 
}
87
 
 
88
 
namespace internal { struct st_my_thread_var; }
89
 
namespace table { class Placeholder; }
90
 
 
91
 
class CopyField;
92
 
class DrizzleXid;
93
 
class Internal_error_handler;
94
 
class Lex_input_stream;
95
 
class TableShareInstance;
96
 
class Table_ident;
97
 
class Time_zone;
98
 
class select_result;
99
 
class user_var_entry;
 
44
#include <drizzled/util/find_ptr.h>
 
45
#include <drizzled/util/string.h>
 
46
#include <drizzled/type/time.h>
 
47
 
 
48
namespace drizzled {
100
49
 
101
50
extern char internal_table_name[2];
102
51
extern char empty_c_string[1];
103
52
extern const char **errmesg;
 
53
extern uint32_t server_id;
104
54
 
105
55
#define TC_HEURISTIC_RECOVER_COMMIT   1
106
56
#define TC_HEURISTIC_RECOVER_ROLLBACK 2
107
57
extern uint32_t tc_heuristic_recover;
108
58
 
109
 
#define Session_SENTRY_MAGIC 0xfeedd1ff
110
 
#define Session_SENTRY_GONE  0xdeadbeef
111
 
 
112
59
extern DRIZZLED_API struct drizzle_system_variables global_system_variables;
113
60
 
114
61
/**
131
78
 * session object.
132
79
 */
133
80
 
134
 
class DRIZZLED_API Session : public Open_tables_state
 
81
class DRIZZLED_API Session : private Open_tables_state
135
82
{
 
83
private:
 
84
  class impl_c;
 
85
 
 
86
  boost::scoped_ptr<impl_c> impl_;
136
87
public:
137
 
  // Plugin storage in Session.
138
88
  typedef boost::shared_ptr<Session> shared_ptr;
139
 
  typedef Session& reference;
140
 
  typedef const Session& const_reference;
141
 
  typedef const Session* const_pointer;
142
 
  typedef Session* pointer;
143
89
 
144
 
  static shared_ptr make_shared(plugin::Client *client, catalog::Instance::shared_ptr instance_arg)
 
90
  static shared_ptr make_shared(plugin::Client *client, boost::shared_ptr<catalog::Instance> instance_arg)
145
91
  {
146
92
    assert(instance_arg);
147
93
    return boost::make_shared<Session>(client, instance_arg);
158
104
                        that it needs to update this field in write_row
159
105
                        and update_row.
160
106
  */
161
 
  enum enum_mark_columns mark_used_columns;
 
107
  enum_mark_columns mark_used_columns;
162
108
  inline void* calloc(size_t size)
163
109
  {
164
 
    void *ptr;
165
 
    if ((ptr= mem_root->alloc_root(size)))
 
110
    void *ptr= mem_root->alloc_root(size);
 
111
    if (ptr)
166
112
      memset(ptr, 0, size);
167
113
    return ptr;
168
114
  }
173
119
 
174
120
  inline void *memdup_w_gap(const void *str, size_t size, uint32_t gap)
175
121
  {
176
 
    void *ptr;
177
 
    if ((ptr= mem_root->alloc_root(size + gap)))
178
 
      memcpy(ptr,str,size);
 
122
    void *ptr= mem_root->alloc_root(size + gap);
 
123
    if (ptr)
 
124
      memcpy(ptr, str, size);
179
125
    return ptr;
180
126
  }
181
127
  /** Frees all items attached to this Statement */
188
134
  Item *free_list;
189
135
  memory::Root *mem_root; /**< Pointer to current memroot */
190
136
 
191
 
 
192
137
  memory::Root *getMemRoot()
193
138
  {
194
139
    return mem_root;
195
140
  }
196
141
 
197
 
  uint64_t xa_id;
198
 
 
199
142
  uint64_t getXaId()
200
143
  {
201
144
    return xa_id;
203
146
 
204
147
  void setXaId(uint64_t in_xa_id)
205
148
  {
206
 
    xa_id= in_xa_id; 
 
149
    xa_id= in_xa_id;
207
150
  }
208
151
 
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
152
public:
220
 
  LEX *getLex() 
221
 
  {
222
 
    return lex;
223
 
  }
224
 
 
225
 
  enum_sql_command getSqlCommand() const
226
 
  {
227
 
    return lex->sql_command;
228
 
  }
 
153
  Diagnostics_area& main_da();
 
154
  const LEX& lex() const;
 
155
  LEX& lex();
 
156
  enum_sql_command getSqlCommand() const;
229
157
 
230
158
  /** query associated with this statement */
231
159
  typedef boost::shared_ptr<const std::string> QueryString;
269
197
  }
270
198
 
271
199
private:
272
 
  session::State::shared_ptr  _state; 
 
200
  boost::shared_ptr<session::State> _state;
273
201
 
274
202
public:
275
203
 
276
 
  session::State::const_shared_ptr state()
 
204
  const boost::shared_ptr<session::State>& state()
277
205
  {
278
206
    return _state;
279
207
  }
290
218
    the Session of that thread); that thread is (and must remain, for now) the
291
219
    only responsible for freeing this member.
292
220
  */
293
 
private:
294
 
  util::string::shared_ptr _schema;
295
 
 
296
221
public:
297
222
 
298
223
  util::string::const_shared_ptr schema() const
299
224
  {
300
 
    if (_schema)
301
 
      return _schema;
302
 
 
303
 
    return util::string::const_shared_ptr(new std::string(""));
 
225
    return _schema ? _schema : util::string::const_shared_ptr(new std::string);
304
226
  }
305
227
 
306
228
  /* current cache key */
314
236
  static const char * const DEFAULT_WHERE;
315
237
 
316
238
  memory::Root warn_root; /**< Allocation area for warnings and errors */
317
 
private:
318
 
  plugin::Client *client; /**< Pointer to client object */
319
 
 
320
239
public:
321
 
 
322
240
  void setClient(plugin::Client *client_arg);
323
241
 
324
 
  plugin::Client *getClient()
325
 
  {
326
 
    return client;
327
 
  }
328
 
 
329
242
  plugin::Client *getClient() const
330
243
  {
331
244
    return client;
346
259
    return user_vars;
347
260
  }
348
261
 
349
 
  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 */
 
262
  drizzle_system_variables& variables; /**< Mutable local variables local to the session */
 
263
  enum_tx_isolation getTxIsolation();
 
264
  system_status_var& status_var;
 
265
 
357
266
  THR_LOCK_INFO lock_info; /**< Locking information for this session */
358
267
  THR_LOCK_OWNER main_lock_id; /**< To use for conventional queries */
359
268
  THR_LOCK_OWNER *lock_id; /**< If not main_lock_id, points to the lock_id of a cursor. */
364
273
   */
365
274
  char *thread_stack;
366
275
 
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
 
  identifier::User::const_shared_ptr user() const
379
 
  {
380
 
    if (security_ctx)
381
 
      return security_ctx;
382
 
 
383
 
    return identifier::User::const_shared_ptr();
384
 
  }
385
 
 
386
 
  void setUser(identifier::User::shared_ptr arg)
 
276
  identifier::user::ptr user() const
 
277
  {
 
278
    return security_ctx ? security_ctx : identifier::user::ptr();
 
279
  }
 
280
 
 
281
  void setUser(identifier::user::mptr arg)
387
282
  {
388
283
    security_ctx= arg;
389
284
  }
401
296
  /**
402
297
   * Is this session viewable by the current user?
403
298
   */
404
 
  bool isViewable(identifier::User::const_reference) const;
 
299
  bool isViewable(const identifier::User&) const;
405
300
 
406
301
private:
407
302
  /**
427
322
    points to a lock object if the lock is present. See item_func.cc and
428
323
    chapter 'Miscellaneous functions', for functions GET_LOCK, RELEASE_LOCK.
429
324
  */
430
 
  uint32_t dbug_sentry; /**< watch for memory corruption */
431
325
 
432
326
private:
433
327
  boost::thread::id boost_thread_id;
514
408
 
515
409
public:
516
410
  void **getEngineData(const plugin::MonitoredInTransaction *monitored);
517
 
  ResourceContext *getResourceContext(const plugin::MonitoredInTransaction *monitored,
518
 
                                      size_t index= 0);
 
411
  ResourceContext& getResourceContext(const plugin::MonitoredInTransaction&, size_t index= 0);
519
412
 
520
 
  session::Transactions transaction;
 
413
  session::Transactions& transaction;
 
414
  Open_tables_state& open_tables;
521
415
 
522
416
  Field *dup_field;
523
417
  sigset_t signals;
524
418
 
 
419
public:
525
420
  // 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
421
  void setConcurrentExecute(bool arg)
532
422
  {
533
423
    concurrent_execute_allowed= arg;
538
428
    return concurrent_execute_allowed;
539
429
  }
540
430
 
541
 
  /* Tells if LAST_INSERT_ID(#) was called for the current statement */
542
 
  bool arg_of_last_insert_id_function;
543
 
 
544
431
  /*
545
432
    ALL OVER THIS FILE, "insert_id" means "*automatically generated* value for
546
433
    insertion into an auto_increment column".
587
474
    (first_successful_insert_id_in_cur_stmt == 0), but storing "INSERT_ID=3"
588
475
    in the binlog is still needed; the list's minimum will contain 3.
589
476
  */
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
477
 
594
478
  uint64_t limit_found_rows;
595
479
  uint64_t options; /**< Bitmap of options */
602
486
 
603
487
  ha_rows cuted_fields; /**< Count of "cut" or truncated fields. @todo Kill this friggin thing. */
604
488
 
605
 
  /** 
 
489
  /**
606
490
   * Number of rows we actually sent to the client, including "synthetic"
607
491
   * rows in ROLLUP etc.
608
492
   */
618
502
   * of the query.
619
503
   *
620
504
   * @todo
621
 
   * 
 
505
   *
622
506
   * Possibly this it is incorrect to have used tables in Session because
623
507
   * with more than one subquery, it is not clear what does the field mean.
624
508
   */
626
510
 
627
511
  /**
628
512
    @todo
629
 
    
 
513
 
630
514
    This, and some other variables like 'count_cuted_fields'
631
515
    maybe should be statement/cursor local, that is, moved to Statement
632
516
    class. With current implementation warnings produced in each prepared
633
517
    statement/cursor settle here.
634
518
  */
635
 
  List<DRIZZLE_ERROR> warn_list;
636
519
  uint32_t warn_count[(uint32_t) DRIZZLE_ERROR::WARN_LEVEL_END];
637
520
  uint32_t total_warn_count;
638
 
  Diagnostics_area main_da;
639
 
 
640
 
  ulong col_access;
641
 
 
642
 
  /* Statement id is thread-wide. This counter is used to generate ids */
643
 
  uint32_t statement_id_counter;
644
 
  uint32_t rand_saved_seed1;
645
 
  uint32_t rand_saved_seed2;
 
521
 
646
522
  /**
647
523
    Row counter, mainly for errors and warnings. Not increased in
648
524
    create_sort_index(); may differ from examined_row_count.
649
525
  */
650
526
  uint32_t row_count;
651
527
 
652
 
  uint32_t getRowCount() const
653
 
  {
654
 
    return row_count;
655
 
  }
656
 
 
657
528
  session_id_t thread_id;
658
529
  uint32_t tmp_table;
659
530
  enum global_read_lock_t
739
610
  bool is_admin_connection;
740
611
  bool some_tables_deleted;
741
612
  bool no_errors;
742
 
  bool password;
743
613
  /**
744
614
    Set to true if execution of the current compound statement
745
615
    can not continue. In particular, disables activation of
770
640
  bool substitute_null_with_insert_id;
771
641
  bool cleanup_done;
772
642
 
773
 
private:
774
 
  bool abort_on_warning;
775
 
  bool tablespace_op; /**< This is true in DISCARD/IMPORT TABLESPACE */
776
 
 
777
643
public:
778
644
  bool got_warning; /**< Set on call to push_warning() */
779
645
  bool no_warnings_for_error; /**< no warnings on call to my_error() */
780
646
  /** set during loop of derived table processing */
781
647
  bool derived_tables_processing;
782
648
 
783
 
  bool doing_tablespace_operation(void)
 
649
  bool doing_tablespace_operation()
784
650
  {
785
651
    return tablespace_op;
786
652
  }
808
674
    and may point to invalid memory after that.
809
675
  */
810
676
  Lex_input_stream *m_lip;
811
 
  
 
677
 
812
678
  /** Place to store various things */
813
679
  void *session_marker;
814
680
 
815
 
  /** Keeps a copy of the previous table around in case we are just slamming on particular table */
816
 
  Table *cached_table;
817
 
 
818
681
  /**
819
682
    Points to info-string that we show in SHOW PROCESSLIST
820
683
    You are supposed to call Session_SET_PROC_INFO only if you have coded
824
687
    macro/function.
825
688
  */
826
689
  inline void set_proc_info(const char *info)
827
 
  { 
 
690
  {
828
691
    proc_info= info;
829
692
  }
830
693
  inline const char* get_proc_info() const
871
734
  }
872
735
 
873
736
  /** Returns the current transaction ID for the session's current statement */
874
 
  inline my_xid getTransactionId()
875
 
  {
876
 
    return transaction.xid_state.xid.quick_get_my_xid();
877
 
  }
 
737
  my_xid getTransactionId();
 
738
 
878
739
  /**
879
740
    There is BUG#19630 where statement-based replication of stored
880
741
    functions/triggers with two auto_increment columns breaks.
916
777
    if (first_successful_insert_id_in_cur_stmt == 0)
917
778
      first_successful_insert_id_in_cur_stmt= id_arg;
918
779
  }
919
 
  inline uint64_t read_first_successful_insert_id_in_prev_stmt(void)
 
780
  inline uint64_t read_first_successful_insert_id_in_prev_stmt()
920
781
  {
921
782
    return first_successful_insert_id_in_prev_stmt;
922
783
  }
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
784
 
934
 
  Session(plugin::Client *client_arg, catalog::Instance::shared_ptr catalog);
 
785
  Session(plugin::Client *client_arg, boost::shared_ptr<catalog::Instance> catalog);
935
786
  virtual ~Session();
936
787
 
937
 
  void cleanup(void);
 
788
  void cleanup();
938
789
  /**
939
790
   * Cleans up after query.
940
791
   *
970
821
  void prepareForQueries();
971
822
 
972
823
  /**
973
 
   * Executes a single statement received from the 
 
824
   * Executes a single statement received from the
974
825
   * client connection.
975
826
   *
976
 
   * Returns true if the statement was successful, or false 
 
827
   * Returns true if the statement was successful, or false
977
828
   * otherwise.
978
829
   *
979
830
   * @note
988
839
  /**
989
840
   * Reads a query from packet and stores it.
990
841
   *
991
 
   * Returns true if query is read and allocated successfully, 
 
842
   * Returns true if query is read and allocated successfully,
992
843
   * false otherwise.  On a return of false, Session::fatal_error
993
844
   * is set.
994
845
   *
1006
857
  /**
1007
858
   * Ends the current transaction and (maybe) begins the next.
1008
859
   *
1009
 
   * Returns true if the transaction completed successfully, 
 
860
   * Returns true if the transaction completed successfully,
1010
861
   * otherwise false.
1011
862
   *
1012
863
   * @param Completion type
1063
914
  }
1064
915
 
1065
916
  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
917
  {
1073
 
    _end_timer= boost::posix_time::microsec_clock::universal_time();
1074
 
    status_var.execution_time_nsec+=(_end_timer - _start_timer).total_microseconds();
 
918
    utime_after_lock= (boost::posix_time::microsec_clock::universal_time() - _epoch).total_microseconds();
1075
919
  }
1076
920
 
 
921
  void set_end_timer();
 
922
 
1077
923
  uint64_t getElapsedTime() const
1078
924
  {
1079
925
    return (_end_timer - _start_timer).total_microseconds();
1083
929
   * Returns the current micro-timestamp
1084
930
   */
1085
931
  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; 
 
932
  {
 
933
    return ((actual ? boost::posix_time::microsec_clock::universal_time() : _end_timer) - _epoch).total_microseconds();
1100
934
  }
1101
935
 
1102
936
  // We may need to set user on this
1103
937
  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();
 
938
  {
 
939
                return ((_user_time.is_not_a_date_time() ? _start_timer : _user_time) - _epoch).total_seconds();
1109
940
  }
1110
941
 
1111
942
  type::Time::epoch_t getCurrentTimestampEpoch(type::Time::usec_t &fraction_arg) const
1112
 
  { 
 
943
  {
1113
944
    if (not _user_time.is_not_a_date_time())
1114
945
    {
1115
946
      fraction_arg= 0;
1120
951
    return (_start_timer - _epoch).total_seconds();
1121
952
  }
1122
953
 
1123
 
  uint64_t found_rows(void) const
 
954
  uint64_t found_rows() const
1124
955
  {
1125
956
    return limit_found_rows;
1126
957
  }
1141
972
 
1142
973
  int send_explain_fields(select_result *result);
1143
974
 
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(); }
1191
 
  inline const CHARSET_INFO *charset() { return default_charset_info; }
1192
 
 
1193
 
  void change_item_tree(Item **place, Item *new_value)
1194
 
  {
1195
 
    *place= new_value;
1196
 
  }
 
975
  void clear_error(bool full= false);
 
976
  void clearDiagnostics();
 
977
  void fatal_error();
 
978
  bool is_error() const;
 
979
 
 
980
  inline const charset_info_st *charset() { return default_charset_info; }
 
981
 
1197
982
  /**
1198
983
    Cleanup statement parse state (parse tree, lex) and execution
1199
984
    state after execution of a non-prepared SQL statement.
1263
1048
    @param level the error level
1264
1049
    @return true if the error is handled
1265
1050
  */
1266
 
  virtual bool handle_error(drizzled::error_t sql_errno, const char *message,
 
1051
  virtual bool handle_error(error_t sql_errno, const char *message,
1267
1052
                            DRIZZLE_ERROR::enum_warning_level level);
1268
1053
 
1269
1054
  /**
1303
1088
   *
1304
1089
   * @note Host, user and passwd may point to communication buffer.
1305
1090
   * Current implementation does not depend on that, but future changes
1306
 
   * should be done with this in mind; 
 
1091
   * should be done with this in mind;
1307
1092
   *
1308
1093
   * @param passwd Scrambled password received from client
1309
1094
   * @param db Database name to connect to, may be NULL
1310
1095
   */
1311
1096
  bool checkUser(const std::string &passwd, const std::string &db);
1312
 
  
 
1097
 
1313
1098
  /**
1314
 
   * Returns the timestamp (in microseconds) of when the Session 
 
1099
   * Returns the timestamp (in microseconds) of when the Session
1315
1100
   * connected to the server.
1316
1101
   */
1317
1102
  uint64_t getConnectMicroseconds() const
1342
1127
  {
1343
1128
    return statement_message;
1344
1129
  }
1345
 
  
 
1130
 
1346
1131
  /**
1347
1132
   * Returns a pointer to the current Resulset message for this
1348
1133
   * Session, or NULL if no active message.
1389
1174
   */
1390
1175
 
1391
1176
  void resetResultsetMessage()
1392
 
  { 
 
1177
  {
1393
1178
    resultset= NULL;
1394
1179
  }
1395
1180
 
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
 
public:
1409
 
  plugin::EventObserverList *getSessionObservers() 
1410
 
  { 
 
1181
  plugin::EventObserverList *getSessionObservers()
 
1182
  {
1411
1183
    return session_event_observers;
1412
1184
  }
1413
 
  
1414
 
  void setSessionObservers(plugin::EventObserverList *observers) 
1415
 
  { 
 
1185
 
 
1186
  void setSessionObservers(plugin::EventObserverList *observers)
 
1187
  {
1416
1188
    session_event_observers= observers;
1417
1189
  }
1418
 
  
1419
 
  /* 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;
1429
 
  }
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
 
 
1439
 
    if (observers)
1440
 
      schema_event_observers[db_name] = observers;
1441
 
  }
1442
 
  
1443
 
  
 
1190
 
 
1191
  plugin::EventObserverList* getSchemaObservers(const std::string& schema);
 
1192
  plugin::EventObserverList* setSchemaObservers(const std::string& schema, plugin::EventObserverList*);
 
1193
 
1444
1194
 private:
1445
 
  const char *proc_info;
1446
1195
 
1447
1196
  /** The current internal error handler for this thread, or NULL. */
1448
1197
  Internal_error_handler *m_internal_handler;
1449
1198
  /**
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
1199
    This memory root is used for two purposes:
1458
1200
    - for conventional queries, to allocate structures stored in main_lex
1459
1201
    during parsing, and allocate runtime data (execution plan, etc.)
1475
1217
   * if table->query_id != session->query_id to know if a table is in use.
1476
1218
   *
1477
1219
   * For example
1478
 
   * 
 
1220
   *
1479
1221
   *  SELECT f1_that_uses_t1() FROM t1;
1480
 
   *  
 
1222
   *
1481
1223
   * In f1_that_uses_t1() we will see one instance of t1 where query_id is
1482
1224
   * set to query_id of original query.
1483
1225
   */
1484
1226
  void mark_used_tables_as_free_for_reuse(Table *table);
1485
1227
 
1486
1228
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
 
  }
 
1229
  void my_ok(ha_rows affected_rows= 0, ha_rows found_rows_arg= 0, uint64_t passed_id= 0, const char *message= NULL);
 
1230
  void my_eof();
 
1231
  bool add_item_to_list(Item *item);
 
1232
  bool add_value_to_list(Item *value);
 
1233
  bool add_order_to_list(Item *item, bool asc);
 
1234
  bool add_group_to_list(Item *item, bool asc);
 
1235
 
1524
1236
  void refresh_status();
1525
1237
  user_var_entry *getVariable(LEX_STRING &name, bool create_if_not_exists);
1526
1238
  user_var_entry *getVariable(const std::string  &name, bool create_if_not_exists);
1527
1239
  void setVariable(const std::string &name, const std::string &value);
1528
 
  
 
1240
 
1529
1241
  /**
1530
1242
   * Closes all tables used by the current substatement, or all tables
1531
1243
   * used by this thread if we are on the upper level.
1536
1248
  void close_open_tables();
1537
1249
  void close_data_files_and_morph_locks(const identifier::Table &identifier);
1538
1250
 
1539
 
private:
1540
 
  bool free_cached_table(boost::mutex::scoped_lock &scopedLock);
1541
 
 
1542
 
public:
1543
 
 
1544
1251
  /**
1545
1252
   * Prepares statement for reopening of tables and recalculation of set of
1546
1253
   * prelocked tables.
1561
1268
   *  true  - error
1562
1269
   *
1563
1270
   * @note
1564
 
   * 
 
1271
   *
1565
1272
   * The lock will automaticaly be freed by close_thread_tables()
1566
1273
   */
1567
 
  bool openTablesLock(TableList *tables);
 
1274
  void close_temporary_table(Table*);
 
1275
  int drop_temporary_table(const identifier::Table&);
 
1276
  bool openTablesLock(TableList*);
 
1277
  bool rm_temporary_table(plugin::StorageEngine&, const identifier::Table&);
 
1278
  bool rm_temporary_table(const identifier::Table &identifier, bool best_effort= false);
 
1279
  Table *open_temporary_table(const identifier::Table &identifier, bool link_in_list= true);
1568
1280
 
1569
1281
  int open_tables_from_list(TableList **start, uint32_t *counter, uint32_t flags= 0);
1570
1282
 
1579
1291
  table::Placeholder *table_cache_insert_placeholder(const identifier::Table &identifier);
1580
1292
  bool lock_table_name_if_not_cached(const identifier::Table &identifier, Table **table);
1581
1293
 
1582
 
private:
1583
 
  session::TableMessages _table_message_cache;
1584
 
 
1585
 
public:
1586
 
  session::TableMessages &getMessageCache()
1587
 
  {
1588
 
    return _table_message_cache;
1589
 
  }
 
1294
  session::TableMessages &getMessageCache();
1590
1295
 
1591
1296
  /* Reopen operations */
1592
1297
  bool reopen_tables();
1596
1301
  int setup_conds(TableList *leaves, COND **conds);
1597
1302
  int lock_tables(TableList *tables, uint32_t count, bool *need_reopen);
1598
1303
 
1599
 
  drizzled::util::Storable *getProperty(const std::string &arg)
 
1304
  template <class T>
 
1305
  T* getProperty(const std::string& name)
1600
1306
  {
1601
 
    return life_properties.getProperty(arg);
 
1307
    return static_cast<T*>(getProperty0(name));
1602
1308
  }
1603
1309
 
1604
 
  template<class T>
1605
 
  bool setProperty(const std::string &arg, T *value)
 
1310
  template <class T>
 
1311
  T setProperty(const std::string& name, T value)
1606
1312
  {
1607
 
    life_properties.setProperty(arg, value);
1608
 
 
1609
 
    return true;
 
1313
    setProperty0(name, value);
 
1314
    return value;
1610
1315
  }
1611
1316
 
1612
1317
  /**
1617
1322
    @return
1618
1323
    pointer to plugin::StorageEngine
1619
1324
  */
1620
 
  plugin::StorageEngine *getDefaultStorageEngine()
1621
 
  {
1622
 
    if (variables.storage_engine)
1623
 
      return variables.storage_engine;
1624
 
    return global_system_variables.storage_engine;
1625
 
  }
1626
 
 
 
1325
  plugin::StorageEngine *getDefaultStorageEngine();
1627
1326
  void get_xid(DrizzleXid *xid); // Innodb only
1628
1327
 
1629
 
  table::Singular *getInstanceTable();
1630
 
  table::Singular *getInstanceTable(List<CreateField> &field_list);
1631
 
 
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:
 
1328
  table::Singular& getInstanceTable();
 
1329
  table::Singular& getInstanceTable(std::list<CreateField>&);
1644
1330
 
1645
1331
  void setUsage(bool arg)
1646
1332
  {
1647
1333
    use_usage= arg;
1648
1334
  }
1649
1335
 
1650
 
  const struct rusage &getUsage()
 
1336
  const rusage &getUsage()
1651
1337
  {
1652
1338
    return usage;
1653
1339
  }
1654
1340
 
1655
 
  catalog::Instance::const_reference catalog() const
1656
 
  {
1657
 
    return *(_catalog.get());
1658
 
  }
1659
 
 
1660
 
  catalog::Instance::reference catalog()
1661
 
  {
1662
 
    return *(_catalog.get());
1663
 
  }
1664
 
 
 
1341
  const catalog::Instance& catalog() const
 
1342
  {
 
1343
    return *_catalog;
 
1344
  }
 
1345
 
 
1346
  catalog::Instance& catalog()
 
1347
  {
 
1348
    return *_catalog;
 
1349
  }
 
1350
 
 
1351
  bool arg_of_last_insert_id_function; // Tells if LAST_INSERT_ID(#) was called for the current statement
1665
1352
private:
1666
 
  catalog::Instance::shared_ptr _catalog;
1667
 
 
1668
 
  // This lives throughout the life of Session
 
1353
  void close_temporary_tables();
 
1354
  bool free_cached_table(boost::mutex::scoped_lock &scopedLock);
 
1355
  void nukeTable(Table*);
 
1356
  drizzled::util::Storable* getProperty0(const std::string&);
 
1357
  void setProperty0(const std::string&, drizzled::util::Storable*);
 
1358
 
 
1359
 
 
1360
  bool resetUsage()
 
1361
  {
 
1362
    return not getrusage(RUSAGE_THREAD, &usage);
 
1363
  }
 
1364
 
 
1365
  boost::shared_ptr<catalog::Instance> _catalog;
 
1366
 
 
1367
  /** Pointers to memory managed by the ReplicationServices component */
 
1368
  message::Transaction *transaction_message;
 
1369
  message::Statement *statement_message;
 
1370
  /* Pointer to the current resultset of Select query */
 
1371
  message::Resultset *resultset;
 
1372
  plugin::EventObserverList *session_event_observers;
 
1373
 
 
1374
  uint64_t xa_id;
 
1375
  const char *proc_info;
 
1376
  bool abort_on_warning;
 
1377
  bool concurrent_execute_allowed;
 
1378
  bool tablespace_op; /**< This is true in DISCARD/IMPORT TABLESPACE */
1669
1379
  bool use_usage;
1670
 
  session::PropertyMap life_properties;
1671
 
  std::vector<table::Singular *> temporary_shares;
1672
 
  struct rusage usage;
 
1380
  rusage usage;
 
1381
  identifier::user::mptr security_ctx;
 
1382
  int32_t scoreboard_index;
 
1383
  plugin::Client *client;
 
1384
  util::string::shared_ptr _schema;
1673
1385
};
1674
1386
 
1675
1387
#define ESCAPE_CHARS "ntrb0ZN" // keep synchronous with READ_INFO::unescape
1676
1388
 
1677
1389
/* Bits in sql_command_flags */
1678
1390
 
1679
 
enum sql_command_flag_bits 
 
1391
enum sql_command_flag_bits
1680
1392
{
1681
1393
  CF_BIT_CHANGES_DATA,
1682
1394
  CF_BIT_HAS_ROW_COUNT,
1692
1404
static const std::bitset<CF_BIT_SIZE> CF_SHOW_TABLE_COMMAND(1 << CF_BIT_SHOW_TABLE_COMMAND);
1693
1405
static const std::bitset<CF_BIT_SIZE> CF_WRITE_LOGS_COMMAND(1 << CF_BIT_WRITE_LOGS_COMMAND);
1694
1406
 
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
 
 
 
1407
namespace display  
 
1408
{
 
1409
  const std::string &type(Session::global_read_lock_t);
 
1410
  size_t max_string_length(Session::global_read_lock_t);
1699
1411
} /* namespace display */
1700
1412
 
1701
1413
} /* namespace drizzled */
1702
1414
 
1703
 
#endif /* DRIZZLED_SESSION_H */