17
17
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20
21
#ifndef DRIZZLED_SESSION_H
21
22
#define DRIZZLED_SESSION_H
24
#include "drizzled/plugin.h"
25
#include "drizzled/sql_locale.h"
26
#include "drizzled/resource_context.h"
23
27
#include "drizzled/cursor.h"
24
#include "drizzled/diagnostics_area.h"
28
#include "drizzled/current_session.h"
29
#include "drizzled/sql_error.h"
25
30
#include "drizzled/file_exchange.h"
26
#include "drizzled/identifier.h"
27
#include "drizzled/internal_error_handler.h"
28
#include "drizzled/my_hash.h"
29
#include "drizzled/named_savepoint.h"
30
#include "drizzled/open_tables_state.h"
31
#include "drizzled/plugin.h"
32
#include "drizzled/plugin/authorization.h"
33
#include "drizzled/pthread_globals.h"
34
#include "drizzled/query_id.h"
35
#include "drizzled/resource_context.h"
36
31
#include "drizzled/select_result_interceptor.h"
37
#include "drizzled/sql_error.h"
38
#include "drizzled/sql_locale.h"
39
32
#include "drizzled/statistics_variables.h"
33
#include "drizzled/xid.h"
34
#include "drizzled/query_id.h"
35
#include "drizzled/named_savepoint.h"
40
36
#include "drizzled/transaction_context.h"
41
37
#include "drizzled/util/storable.h"
42
#include "drizzled/xid.h"
38
#include "drizzled/my_hash.h"
39
#include "drizzled/pthread_globals.h"
46
42
#include <sys/time.h>
47
43
#include <sys/resource.h>
54
#include "drizzled/catalog/instance.h"
55
#include "drizzled/catalog/local.h"
57
#include <drizzled/session/property_map.h>
58
#include <drizzled/session/state.h>
59
#include <drizzled/session/table_messages.h>
60
#include <drizzled/session/transactions.h>
61
#include <drizzled/system_variables.h>
62
#include <drizzled/copy_info.h>
63
#include <drizzled/system_variables.h>
64
#include <drizzled/ha_data.h>
50
#include "drizzled/security_context.h"
51
#include "drizzled/open_tables_state.h"
52
#include "drizzled/internal_error_handler.h"
53
#include "drizzled/diagnostics_area.h"
54
#include "drizzled/plugin/authorization.h"
56
#include <boost/unordered_map.hpp>
66
58
#include <boost/thread/thread.hpp>
67
59
#include <boost/thread/mutex.hpp>
68
60
#include <boost/thread/shared_mutex.hpp>
69
61
#include <boost/thread/condition_variable.hpp>
70
#include <boost/make_shared.hpp>
72
#include <drizzled/lex_column.h>
73
#include "drizzled/sql_lex.h"
75
#include "drizzled/visibility.h"
77
63
#define MIN_HANDSHAKE_SIZE 6
112
104
#define TC_HEURISTIC_RECOVER_ROLLBACK 2
113
105
extern uint32_t tc_heuristic_recover;
109
Local storage for proto that are tmp table. This should be enlarged
110
to hande the entire table-share for a local table. Once Hash is done,
111
we should consider exchanging the map for it.
113
typedef std::map <std::string, message::Table> ProtoCache;
116
The COPY_INFO structure is used by INSERT/REPLACE code.
117
The schema of the row counting by the INSERT/INSERT ... ON DUPLICATE KEY
119
If a row is inserted then the copied variable is incremented.
120
If a row is updated by the INSERT ... ON DUPLICATE KEY UPDATE and the
121
new data differs from the old one then the copied and the updated
122
variables are incremented.
123
The touched variable is incremented if a row was touched by the update part
124
of the INSERT ... ON DUPLICATE KEY UPDATE no matter whether the row
125
was actually changed or not.
130
ha_rows records; /**< Number of processed records */
131
ha_rows deleted; /**< Number of deleted records */
132
ha_rows updated; /**< Number of updated records */
133
ha_rows copied; /**< Number of copied records */
135
ha_rows touched; /* Number of touched records */
136
enum enum_duplicates handle_duplicates;
137
int escape_char, last_errno;
139
/* for INSERT ... UPDATE */
140
List<Item> *update_fields;
141
List<Item> *update_values;
142
/* for VIEW ... WITH CHECK OPTION */
160
} /* namespace drizzled */
162
/** @TODO why is this in the middle of the file */
163
#include <drizzled/lex_column.h>
115
168
class select_result;
118
171
#define Session_SENTRY_MAGIC 0xfeedd1ff
119
172
#define Session_SENTRY_GONE 0xdeadbeef
121
extern DRIZZLED_API struct drizzle_system_variables global_system_variables;
174
struct drizzle_system_variables
176
drizzle_system_variables()
179
How dynamically allocated system variables are handled:
181
The global_system_variables and max_system_variables are "authoritative"
182
They both should have the same 'version' and 'size'.
183
When attempting to access a dynamic variable, if the session version
184
is out of date, then the session version is updated and realloced if
185
neccessary and bytes copied from global to make up for missing data.
187
ulong dynamic_variables_version;
188
char * dynamic_variables_ptr;
189
uint32_t dynamic_variables_head; /* largest valid variable offset */
190
uint32_t dynamic_variables_size; /* how many bytes are in use */
192
uint64_t myisam_max_extra_sort_file_size;
193
uint64_t max_heap_table_size;
194
uint64_t tmp_table_size;
195
ha_rows select_limit;
196
ha_rows max_join_size;
197
uint64_t auto_increment_increment;
198
uint64_t auto_increment_offset;
199
uint64_t bulk_insert_buff_size;
200
uint64_t join_buff_size;
201
uint32_t max_allowed_packet;
202
uint64_t max_error_count;
203
uint64_t max_length_for_sort_data;
204
size_t max_sort_length;
205
uint64_t min_examined_row_limit;
206
bool optimizer_prune_level;
209
uint32_t optimizer_search_depth;
210
uint32_t div_precincrement;
211
uint64_t preload_buff_size;
212
uint32_t read_buff_size;
213
uint32_t read_rnd_buff_size;
214
bool replicate_query;
215
size_t sortbuff_size;
216
uint32_t thread_handling;
217
uint32_t tx_isolation;
218
size_t transaction_message_threshold;
219
uint32_t completion_type;
220
/* Determines which non-standard SQL behaviour should be enabled */
222
uint64_t max_seeks_for_key;
223
size_t range_alloc_block_size;
224
uint32_t query_alloc_block_size;
225
uint32_t query_prealloc_size;
226
uint64_t group_concat_max_len;
227
uint64_t pseudo_thread_id;
229
plugin::StorageEngine *storage_engine;
231
/* Only charset part of these variables is sensible */
232
const CHARSET_INFO *character_set_filesystem;
234
/* Both charset and collation parts of these variables are important */
235
const CHARSET_INFO *collation_server;
237
inline const CHARSET_INFO *getCollation(void)
239
return collation_server;
243
MY_LOCALE *lc_time_names;
245
Time_zone *time_zone;
248
extern struct drizzle_system_variables global_system_variables;
250
} /* namespace drizzled */
252
#include "drizzled/sql_lex.h"
257
void mark_transaction_to_rollback(Session *session, bool all);
260
Storage engine specific thread local data.
265
Storage engine specific thread local data.
266
Lifetime: one user connection.
270
* Resource contexts for both the "statement" and "normal"
273
* Resource context at index 0:
275
* Life time: one statement within a transaction. If @@autocommit is
276
* on, also represents the entire transaction.
278
* Resource context at index 1:
280
* Life time: one transaction within a connection.
284
* If the storage engine does not participate in a transaction,
285
* there will not be a resource context.
287
drizzled::ResourceContext resource_context[2];
289
Ha_data() :ha_ptr(NULL) {}
124
293
* Represents a client connection to the database server.
139
308
* all member variables that are not critical to non-internal operations of the
140
309
* session object.
311
typedef int64_t session_id_t;
143
class DRIZZLED_API Session : public Open_tables_state
313
class Session : public Open_tables_state
146
316
// Plugin storage in Session.
317
typedef boost::unordered_map<std::string, util::Storable *, util::insensitive_hash, util::insensitive_equal_to> PropertyMap;
318
typedef Session* Ptr;
147
319
typedef boost::shared_ptr<Session> shared_ptr;
148
typedef Session& reference;
149
typedef const Session& const_reference;
150
typedef const Session* const_pointer;
151
typedef Session* pointer;
153
static shared_ptr make_shared(plugin::Client *client, catalog::Instance::shared_ptr instance_arg)
155
assert(instance_arg);
156
return boost::make_shared<Session>(client, instance_arg);
160
322
MARK_COLUMNS_NONE: Means mark_used_colums is not set and no indicator to
473
584
uint32_t file_id; /**< File ID for LOAD DATA INFILE */
474
585
/* @note the following three members should likely move to Client */
475
586
uint32_t max_client_packet_length; /**< Maximum number of bytes a client can send in a single packet */
478
boost::posix_time::ptime _epoch;
479
boost::posix_time::ptime _connect_time;
480
boost::posix_time::ptime _start_timer;
481
boost::posix_time::ptime _end_timer;
483
boost::posix_time::ptime _user_time;
485
uint64_t utime_after_lock; // This used by Innodb.
489
_user_time= boost::posix_time::not_a_date_time;
492
const boost::posix_time::ptime &start_timer() const
497
void getTimeDifference(boost::posix_time::time_duration &result_arg, const boost::posix_time::ptime &arg) const
499
result_arg= arg - _start_timer;
589
uint64_t thr_create_utime; /**< track down slow pthread_create */
590
uint64_t start_utime;
591
uint64_t utime_after_lock;
502
593
thr_lock_type update_lock_default;
519
610
query_id_t query_id;
520
611
query_id_t warn_query_id;
523
613
void **getEngineData(const plugin::MonitoredInTransaction *monitored);
524
614
ResourceContext *getResourceContext(const plugin::MonitoredInTransaction *monitored,
525
615
size_t index= 0);
527
session::Transactions transaction;
618
* Structure used to manage "statement transactions" and
619
* "normal transactions". In autocommit mode, the normal transaction is
620
* equivalent to the statement transaction.
622
* Storage engines will be registered here when they participate in
623
* a transaction. No engine is registered more than once.
625
struct st_transactions {
626
std::deque<NamedSavepoint> savepoints;
629
* The normal transaction (since BEGIN WORK).
631
* Contains a list of all engines that have participated in any of the
632
* statement transactions started within the context of the normal
635
* @note In autocommit mode, this is empty.
637
TransactionContext all;
640
* The statment transaction.
642
* Contains a list of all engines participating in the given statement.
644
* @note In autocommit mode, this will be used to commit/rollback the
645
* normal transaction.
647
TransactionContext stmt;
529
663
Field *dup_field;
530
664
sigset_t signals;
1053
1157
const char* enter_cond(boost::condition_variable_any &cond, boost::mutex &mutex, const char* msg);
1054
1158
void exit_cond(const char* old_msg);
1056
type::Time::epoch_t query_start()
1058
return getCurrentTimestampEpoch();
1063
_end_timer= _start_timer= boost::posix_time::microsec_clock::universal_time();
1064
utime_after_lock= (_start_timer - _epoch).total_microseconds();
1067
void set_time(time_t t) // This is done by a sys_var, as long as user_time is set, we will use that for all references to time
1069
_user_time= boost::posix_time::from_time_t(t);
1072
void set_time_after_lock()
1074
boost::posix_time::ptime mytime(boost::posix_time::microsec_clock::universal_time());
1075
utime_after_lock= (mytime - _epoch).total_microseconds();
1078
void set_end_timer()
1080
_end_timer= boost::posix_time::microsec_clock::universal_time();
1081
status_var.execution_time_nsec+=(_end_timer - _start_timer).total_microseconds();
1084
uint64_t getElapsedTime() const
1086
return (_end_timer - _start_timer).total_microseconds();
1160
inline time_t query_start() { return start_time; }
1161
inline void set_time()
1163
boost::posix_time::ptime mytime(boost::posix_time::microsec_clock::local_time());
1164
boost::posix_time::ptime epoch(boost::gregorian::date(1970,1,1));
1165
start_utime= utime_after_lock= (mytime-epoch).total_microseconds();
1169
start_time= user_time;
1170
connect_microseconds= start_utime;
1173
start_time= (mytime-epoch).total_seconds();
1175
inline void set_current_time() { start_time= time(NULL); }
1176
inline void set_time(time_t t)
1178
start_time= user_time= t;
1179
boost::posix_time::ptime mytime(boost::posix_time::microsec_clock::local_time());
1180
boost::posix_time::ptime epoch(boost::gregorian::date(1970,1,1));
1181
uint64_t t_mark= (mytime-epoch).total_microseconds();
1183
start_utime= utime_after_lock= t_mark;
1185
void set_time_after_lock() {
1186
boost::posix_time::ptime mytime(boost::posix_time::microsec_clock::local_time());
1187
boost::posix_time::ptime epoch(boost::gregorian::date(1970,1,1));
1188
utime_after_lock= (mytime-epoch).total_microseconds();
1090
1191
* Returns the current micro-timestamp
1092
type::Time::epoch_t getCurrentTimestamp(bool actual= true) const
1193
inline uint64_t getCurrentTimestamp()
1094
type::Time::epoch_t t_mark;
1098
boost::posix_time::ptime mytime(boost::posix_time::microsec_clock::universal_time());
1099
t_mark= (mytime - _epoch).total_microseconds();
1103
t_mark= (_end_timer - _epoch).total_microseconds();
1195
boost::posix_time::ptime mytime(boost::posix_time::microsec_clock::local_time());
1196
boost::posix_time::ptime epoch(boost::gregorian::date(1970,1,1));
1197
uint64_t t_mark= (mytime-epoch).total_microseconds();
1109
// We may need to set user on this
1110
type::Time::epoch_t getCurrentTimestampEpoch() const
1112
if (not _user_time.is_not_a_date_time())
1113
return (_user_time - _epoch).total_seconds();
1115
return (_start_timer - _epoch).total_seconds();
1118
type::Time::epoch_t getCurrentTimestampEpoch(type::Time::usec_t &fraction_arg) const
1120
if (not _user_time.is_not_a_date_time())
1123
return (_user_time - _epoch).total_seconds();
1126
fraction_arg= _start_timer.time_of_day().fractional_seconds() % 1000000;
1127
return (_start_timer - _epoch).total_seconds();
1130
uint64_t found_rows(void) const
1201
inline uint64_t found_rows(void)
1132
1203
return limit_found_rows;
1135
1205
/** Returns whether the session is currently inside a transaction */
1136
bool inTransaction() const
1206
inline bool inTransaction()
1138
1208
return server_status & SERVER_STATUS_IN_TRANS;
1141
1210
LEX_STRING *make_lex_string(LEX_STRING *lex_str,
1142
1211
const char* str, uint32_t length,
1143
1212
bool allocate_lex_string);
1145
1213
LEX_STRING *make_lex_string(LEX_STRING *lex_str,
1146
1214
const std::string &str,
1147
1215
bool allocate_lex_string);
1149
1217
int send_explain_fields(select_result *result);
1152
1219
Clear the current error, if any.
1153
1220
We do not clear is_fatal_error or is_fatal_sub_stmt_error since we
1579
1642
Table *openTable(TableList *table_list, bool *refresh, uint32_t flags= 0);
1581
1644
void unlink_open_table(Table *find);
1582
void drop_open_table(Table *table, const identifier::Table &identifier);
1645
void drop_open_table(Table *table, const TableIdentifier &identifier);
1583
1646
void close_cached_table(Table *table);
1585
1648
/* Create a lock in the cache */
1586
table::Placeholder *table_cache_insert_placeholder(const identifier::Table &identifier);
1587
bool lock_table_name_if_not_cached(const identifier::Table &identifier, Table **table);
1649
table::Placeholder *table_cache_insert_placeholder(const TableIdentifier &identifier);
1650
bool lock_table_name_if_not_cached(const TableIdentifier &identifier, Table **table);
1652
typedef boost::unordered_map<std::string, message::Table, util::insensitive_hash, util::insensitive_equal_to> TableMessageCache;
1656
TableMessageCache table_message_cache;
1659
bool storeTableMessage(const TableIdentifier &identifier, message::Table &table_message);
1660
bool removeTableMessage(const TableIdentifier &identifier);
1661
bool getTableMessage(const TableIdentifier &identifier, message::Table &table_message);
1662
bool doesTableMessageExist(const TableIdentifier &identifier);
1663
bool renameTableMessage(const TableIdentifier &from, const TableIdentifier &to);
1590
session::TableMessages _table_message_cache;
1667
TableMessages _table_message_cache;
1593
session::TableMessages &getMessageCache()
1670
TableMessages &getMessageCache()
1595
1672
return _table_message_cache;
1598
1675
/* Reopen operations */
1599
bool reopen_tables();
1676
bool reopen_tables(bool get_locks, bool mark_share_as_old);
1600
1677
bool close_cached_tables(TableList *tables, bool wait_for_refresh, bool wait_for_placeholders);
1602
1679
void wait_for_condition(boost::mutex &mutex, boost::condition_variable_any &cond);