17
17
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21
20
#ifndef DRIZZLED_SESSION_H
22
21
#define DRIZZLED_SESSION_H
24
#include "drizzled/plugin.h"
25
#include "drizzled/sql_locale.h"
26
#include "drizzled/resource_context.h"
27
#include "drizzled/cursor.h"
28
#include "drizzled/current_session.h"
29
#include "drizzled/sql_error.h"
30
#include "drizzled/file_exchange.h"
31
#include "drizzled/select_result_interceptor.h"
32
#include "drizzled/statistics_variables.h"
33
#include "drizzled/xid.h"
34
#include "drizzled/query_id.h"
35
#include "drizzled/named_savepoint.h"
36
#include "drizzled/transaction_context.h"
37
#include "drizzled/util/storable.h"
38
#include "drizzled/my_hash.h"
39
#include "drizzled/pthread_globals.h"
23
#include <drizzled/cursor.h>
24
#include <drizzled/diagnostics_area.h>
25
#include <drizzled/file_exchange.h>
26
#include <drizzled/identifier.h>
27
#include <drizzled/lex_column.h>
28
#include <drizzled/my_hash.h>
29
#include <drizzled/named_savepoint.h>
30
#include <drizzled/open_tables_state.h>
31
#include <drizzled/plugin.h>
32
#include <drizzled/plugin/authorization.h>
33
#include <drizzled/pthread_globals.h>
34
#include <drizzled/query_id.h>
35
#include <drizzled/resource_context.h>
36
#include <drizzled/sql_error.h>
37
#include <drizzled/sql_lex.h>
38
#include <drizzled/sql_locale.h>
39
#include <drizzled/statistics_variables.h>
40
#include <drizzled/table_ident.h>
41
#include <drizzled/transaction_context.h>
42
#include <drizzled/util/storable.h>
43
#include <drizzled/var.h>
41
47
#include <sys/time.h>
42
48
#include <sys/resource.h>
44
50
#include <algorithm>
50
#include "drizzled/security_context.h"
51
#include "drizzled/open_tables_state.h"
52
#include "drizzled/internal_error_handler.h"
53
#include "drizzled/diagnostics_area.h"
54
#include "drizzled/plugin/authorization.h"
55
#include <drizzled/catalog/instance.h>
56
#include <drizzled/catalog/local.h>
56
#include <boost/unordered_map.hpp>
58
#include <drizzled/copy_info.h>
59
#include <drizzled/ha_data.h>
60
#include <drizzled/session/property_map.h>
61
#include <drizzled/session/state.h>
62
#include <drizzled/session/table_messages.h>
63
#include <drizzled/session/transactions.h>
64
#include <drizzled/system_variables.h>
65
#include <drizzled/system_variables.h>
58
67
#include <boost/thread/thread.hpp>
59
68
#include <boost/thread/mutex.hpp>
106
112
#define TC_HEURISTIC_RECOVER_ROLLBACK 2
107
113
extern uint32_t tc_heuristic_recover;
111
Local storage for proto that are tmp table. This should be enlarged
112
to hande the entire table-share for a local table. Once Hash is done,
113
we should consider exchanging the map for it.
115
typedef std::map <std::string, message::Table> ProtoCache;
118
The COPY_INFO structure is used by INSERT/REPLACE code.
119
The schema of the row counting by the INSERT/INSERT ... ON DUPLICATE KEY
121
If a row is inserted then the copied variable is incremented.
122
If a row is updated by the INSERT ... ON DUPLICATE KEY UPDATE and the
123
new data differs from the old one then the copied and the updated
124
variables are incremented.
125
The touched variable is incremented if a row was touched by the update part
126
of the INSERT ... ON DUPLICATE KEY UPDATE no matter whether the row
127
was actually changed or not.
132
ha_rows records; /**< Number of processed records */
133
ha_rows deleted; /**< Number of deleted records */
134
ha_rows updated; /**< Number of updated records */
135
ha_rows copied; /**< Number of copied records */
137
ha_rows touched; /* Number of touched records */
138
enum enum_duplicates handle_duplicates;
139
int escape_char, last_errno;
141
/* for INSERT ... UPDATE */
142
List<Item> *update_fields;
143
List<Item> *update_values;
144
/* for VIEW ... WITH CHECK OPTION */
162
} /* namespace drizzled */
164
/** @TODO why is this in the middle of the file */
165
#include <drizzled/lex_column.h>
173
115
#define Session_SENTRY_MAGIC 0xfeedd1ff
174
116
#define Session_SENTRY_GONE 0xdeadbeef
176
struct drizzle_system_variables
178
drizzle_system_variables()
181
How dynamically allocated system variables are handled:
183
The global_system_variables and max_system_variables are "authoritative"
184
They both should have the same 'version' and 'size'.
185
When attempting to access a dynamic variable, if the session version
186
is out of date, then the session version is updated and realloced if
187
neccessary and bytes copied from global to make up for missing data.
189
ulong dynamic_variables_version;
190
char * dynamic_variables_ptr;
191
uint32_t dynamic_variables_head; /* largest valid variable offset */
192
uint32_t dynamic_variables_size; /* how many bytes are in use */
194
uint64_t myisam_max_extra_sort_file_size;
195
uint64_t max_heap_table_size;
196
uint64_t tmp_table_size;
197
ha_rows select_limit;
198
ha_rows max_join_size;
199
uint64_t auto_increment_increment;
200
uint64_t auto_increment_offset;
201
uint64_t bulk_insert_buff_size;
202
uint64_t join_buff_size;
203
uint32_t max_allowed_packet;
204
uint64_t max_error_count;
205
uint64_t max_length_for_sort_data;
206
size_t max_sort_length;
207
uint64_t min_examined_row_limit;
208
bool optimizer_prune_level;
211
uint32_t optimizer_search_depth;
212
uint32_t div_precincrement;
213
uint64_t preload_buff_size;
214
uint32_t read_buff_size;
215
uint32_t read_rnd_buff_size;
216
bool replicate_query;
217
size_t sortbuff_size;
218
uint32_t thread_handling;
219
uint32_t tx_isolation;
220
size_t transaction_message_threshold;
221
uint32_t completion_type;
222
/* Determines which non-standard SQL behaviour should be enabled */
224
uint64_t max_seeks_for_key;
225
size_t range_alloc_block_size;
226
uint32_t query_alloc_block_size;
227
uint32_t query_prealloc_size;
228
uint64_t group_concat_max_len;
229
uint64_t pseudo_thread_id;
231
plugin::StorageEngine *storage_engine;
233
/* Only charset part of these variables is sensible */
234
const CHARSET_INFO *character_set_filesystem;
236
/* Both charset and collation parts of these variables are important */
237
const CHARSET_INFO *collation_server;
239
inline const CHARSET_INFO *getCollation(void)
241
return collation_server;
245
MY_LOCALE *lc_time_names;
247
Time_zone *time_zone;
250
extern struct drizzle_system_variables global_system_variables;
252
} /* namespace drizzled */
254
#include "drizzled/sql_lex.h"
259
void mark_transaction_to_rollback(Session *session, bool all);
262
Storage engine specific thread local data.
267
Storage engine specific thread local data.
268
Lifetime: one user connection.
272
* Resource contexts for both the "statement" and "normal"
275
* Resource context at index 0:
277
* Life time: one statement within a transaction. If @@autocommit is
278
* on, also represents the entire transaction.
280
* Resource context at index 1:
282
* Life time: one transaction within a connection.
286
* If the storage engine does not participate in a transaction,
287
* there will not be a resource context.
289
drizzled::ResourceContext resource_context[2];
291
Ha_data() :ha_ptr(NULL) {}
118
extern DRIZZLED_API struct drizzle_system_variables global_system_variables;
120
DRIZZLED_API void mark_transaction_to_rollback(Session *session, bool all);
295
123
* Represents a client connection to the database server.
310
138
* all member variables that are not critical to non-internal operations of the
311
139
* session object.
313
typedef int64_t session_id_t;
315
class Session : public Open_tables_state
142
class DRIZZLED_API Session : public Open_tables_state
318
145
// Plugin storage in Session.
319
typedef boost::unordered_map<std::string, util::Storable *, util::insensitive_hash, util::insensitive_equal_to> PropertyMap;
320
typedef Session* Ptr;
321
146
typedef boost::shared_ptr<Session> shared_ptr;
147
typedef Session& reference;
148
typedef const Session& const_reference;
149
typedef const Session* const_pointer;
150
typedef Session* pointer;
152
static shared_ptr make_shared(plugin::Client *client, catalog::Instance::shared_ptr instance_arg)
154
assert(instance_arg);
155
return boost::make_shared<Session>(client, instance_arg);
324
159
MARK_COLUMNS_NONE: Means mark_used_colums is not set and no indicator to
651
460
uint32_t file_id; /**< File ID for LOAD DATA INFILE */
652
461
/* @note the following three members should likely move to Client */
653
462
uint32_t max_client_packet_length; /**< Maximum number of bytes a client can send in a single packet */
656
uint64_t thr_create_utime; /**< track down slow pthread_create */
657
uint64_t start_utime;
658
uint64_t utime_after_lock;
465
boost::posix_time::ptime _epoch;
466
boost::posix_time::ptime _connect_time;
467
boost::posix_time::ptime _start_timer;
468
boost::posix_time::ptime _end_timer;
470
boost::posix_time::ptime _user_time;
472
uint64_t utime_after_lock; // This used by Innodb.
476
_user_time= boost::posix_time::not_a_date_time;
479
const boost::posix_time::ptime &start_timer() const
484
void getTimeDifference(boost::posix_time::time_duration &result_arg, const boost::posix_time::ptime &arg) const
486
result_arg= arg - _start_timer;
660
489
thr_lock_type update_lock_default;
677
506
query_id_t query_id;
678
507
query_id_t warn_query_id;
680
510
void **getEngineData(const plugin::MonitoredInTransaction *monitored);
681
511
ResourceContext *getResourceContext(const plugin::MonitoredInTransaction *monitored,
682
512
size_t index= 0);
685
* Structure used to manage "statement transactions" and
686
* "normal transactions". In autocommit mode, the normal transaction is
687
* equivalent to the statement transaction.
689
* Storage engines will be registered here when they participate in
690
* a transaction. No engine is registered more than once.
692
struct st_transactions {
693
std::deque<NamedSavepoint> savepoints;
696
* The normal transaction (since BEGIN WORK).
698
* Contains a list of all engines that have participated in any of the
699
* statement transactions started within the context of the normal
702
* @note In autocommit mode, this is empty.
704
TransactionContext all;
707
* The statment transaction.
709
* Contains a list of all engines participating in the given statement.
711
* @note In autocommit mode, this will be used to commit/rollback the
712
* normal transaction.
714
TransactionContext stmt;
514
session::Transactions transaction;
730
516
Field *dup_field;
731
517
sigset_t signals;
1225
1028
const char* enter_cond(boost::condition_variable_any &cond, boost::mutex &mutex, const char* msg);
1226
1029
void exit_cond(const char* old_msg);
1228
inline time_t query_start() { return start_time; }
1229
inline void set_time()
1231
boost::posix_time::ptime mytime(boost::posix_time::microsec_clock::local_time());
1232
boost::posix_time::ptime epoch(boost::gregorian::date(1970,1,1));
1233
start_utime= utime_after_lock= (mytime-epoch).total_microseconds();
1237
start_time= user_time;
1238
connect_microseconds= start_utime;
1241
start_time= (mytime-epoch).total_seconds();
1243
inline void set_current_time() { start_time= time(NULL); }
1244
inline void set_time(time_t t)
1246
start_time= user_time= t;
1247
boost::posix_time::ptime mytime(boost::posix_time::microsec_clock::local_time());
1248
boost::posix_time::ptime epoch(boost::gregorian::date(1970,1,1));
1249
uint64_t t_mark= (mytime-epoch).total_microseconds();
1251
start_utime= utime_after_lock= t_mark;
1253
void set_time_after_lock() {
1254
boost::posix_time::ptime mytime(boost::posix_time::microsec_clock::local_time());
1255
boost::posix_time::ptime epoch(boost::gregorian::date(1970,1,1));
1256
utime_after_lock= (mytime-epoch).total_microseconds();
1031
type::Time::epoch_t query_start()
1033
return getCurrentTimestampEpoch();
1038
_end_timer= _start_timer= boost::posix_time::microsec_clock::universal_time();
1039
utime_after_lock= (_start_timer - _epoch).total_microseconds();
1042
void set_time(time_t t) // This is done by a sys_var, as long as user_time is set, we will use that for all references to time
1044
_user_time= boost::posix_time::from_time_t(t);
1047
void set_time_after_lock()
1049
boost::posix_time::ptime mytime(boost::posix_time::microsec_clock::universal_time());
1050
utime_after_lock= (mytime - _epoch).total_microseconds();
1053
void set_end_timer()
1055
_end_timer= boost::posix_time::microsec_clock::universal_time();
1056
status_var.execution_time_nsec+=(_end_timer - _start_timer).total_microseconds();
1059
uint64_t getElapsedTime() const
1061
return (_end_timer - _start_timer).total_microseconds();
1259
1065
* Returns the current micro-timestamp
1261
inline uint64_t getCurrentTimestamp()
1067
type::Time::epoch_t getCurrentTimestamp(bool actual= true) const
1263
boost::posix_time::ptime mytime(boost::posix_time::microsec_clock::local_time());
1264
boost::posix_time::ptime epoch(boost::gregorian::date(1970,1,1));
1265
uint64_t t_mark= (mytime-epoch).total_microseconds();
1069
type::Time::epoch_t t_mark;
1073
boost::posix_time::ptime mytime(boost::posix_time::microsec_clock::universal_time());
1074
t_mark= (mytime - _epoch).total_microseconds();
1078
t_mark= (_end_timer - _epoch).total_microseconds();
1269
inline uint64_t found_rows(void)
1084
// We may need to set user on this
1085
type::Time::epoch_t getCurrentTimestampEpoch() const
1087
if (not _user_time.is_not_a_date_time())
1088
return (_user_time - _epoch).total_seconds();
1090
return (_start_timer - _epoch).total_seconds();
1093
type::Time::epoch_t getCurrentTimestampEpoch(type::Time::usec_t &fraction_arg) const
1095
if (not _user_time.is_not_a_date_time())
1098
return (_user_time - _epoch).total_seconds();
1101
fraction_arg= _start_timer.time_of_day().fractional_seconds() % 1000000;
1102
return (_start_timer - _epoch).total_seconds();
1105
uint64_t found_rows(void) const
1271
1107
return limit_found_rows;
1273
1110
/** Returns whether the session is currently inside a transaction */
1274
inline bool inTransaction()
1111
bool inTransaction() const
1276
1113
return server_status & SERVER_STATUS_IN_TRANS;
1278
1116
LEX_STRING *make_lex_string(LEX_STRING *lex_str,
1279
1117
const char* str, uint32_t length,
1280
1118
bool allocate_lex_string);
1281
1120
LEX_STRING *make_lex_string(LEX_STRING *lex_str,
1282
1121
const std::string &str,
1283
1122
bool allocate_lex_string);
1285
1124
int send_explain_fields(select_result *result);
1287
1127
Clear the current error, if any.
1288
1128
We do not clear is_fatal_error or is_fatal_sub_stmt_error since we
1706
1554
Table *openTable(TableList *table_list, bool *refresh, uint32_t flags= 0);
1708
1556
void unlink_open_table(Table *find);
1709
void drop_open_table(Table *table, const TableIdentifier &identifier);
1557
void drop_open_table(Table *table, const identifier::Table &identifier);
1710
1558
void close_cached_table(Table *table);
1712
1560
/* Create a lock in the cache */
1713
table::Placeholder *table_cache_insert_placeholder(const TableIdentifier &identifier);
1714
bool lock_table_name_if_not_cached(const TableIdentifier &identifier, Table **table);
1716
typedef boost::unordered_map<std::string, message::Table, util::insensitive_hash, util::insensitive_equal_to> TableMessageCache;
1720
TableMessageCache table_message_cache;
1723
bool storeTableMessage(const TableIdentifier &identifier, message::Table &table_message);
1724
bool removeTableMessage(const TableIdentifier &identifier);
1725
bool getTableMessage(const TableIdentifier &identifier, message::Table &table_message);
1726
bool doesTableMessageExist(const TableIdentifier &identifier);
1727
bool renameTableMessage(const TableIdentifier &from, const TableIdentifier &to);
1561
table::Placeholder *table_cache_insert_placeholder(const identifier::Table &identifier);
1562
bool lock_table_name_if_not_cached(const identifier::Table &identifier, Table **table);
1731
TableMessages _table_message_cache;
1565
session::TableMessages _table_message_cache;
1734
TableMessages &getMessageCache()
1568
session::TableMessages &getMessageCache()
1736
1570
return _table_message_cache;
1739
1573
/* Reopen operations */
1740
bool reopen_tables(bool get_locks, bool mark_share_as_old);
1574
bool reopen_tables();
1741
1575
bool close_cached_tables(TableList *tables, bool wait_for_refresh, bool wait_for_placeholders);
1743
1577
void wait_for_condition(boost::mutex &mutex, boost::condition_variable_any &cond);
1637
catalog::Instance::const_reference catalog() const
1639
return *(_catalog.get());
1642
catalog::Instance::reference catalog()
1644
return *(_catalog.get());
1648
catalog::Instance::shared_ptr _catalog;
1803
1650
// This lives throughout the life of Session
1804
1651
bool use_usage;
1805
PropertyMap life_properties;
1806
std::vector<table::Instance *> temporary_shares;
1652
session::PropertyMap life_properties;
1653
std::vector<table::Singular *> temporary_shares;
1807
1654
struct rusage usage;
1812
1657
#define ESCAPE_CHARS "ntrb0ZN" // keep synchronous with READ_INFO::unescape
1814
} /* namespace drizzled */
1816
/** @TODO why is this in the middle of the file */
1817
#include <drizzled/select_to_file.h>
1818
#include <drizzled/select_export.h>
1819
#include <drizzled/select_dump.h>
1820
#include <drizzled/select_insert.h>
1821
#include <drizzled/select_create.h>
1822
#include <drizzled/tmp_table_param.h>
1823
#include <drizzled/select_union.h>
1824
#include <drizzled/select_subselect.h>
1825
#include <drizzled/select_singlerow_subselect.h>
1826
#include <drizzled/select_max_min_finder_subselect.h>
1827
#include <drizzled/select_exists_subselect.h>
1833
* A structure used to describe sort information
1834
* for a field or item used in ORDER BY.
1839
Field *field; /**< Field to sort */
1840
Item *item; /**< Item if not sorting fields */
1841
size_t length; /**< Length of sort field */
1842
uint32_t suffix_length; /**< Length suffix (0-4) */
1843
Item_result result_type; /**< Type of item */
1844
bool reverse; /**< if descending sort */
1845
bool need_strxnfrm; /**< If we have to use strxnfrm() */
1852
result_type(STRING_RESULT),
1859
} /* namespace drizzled */
1861
/** @TODO why is this in the middle of the file */
1863
#include <drizzled/table_ident.h>
1864
#include <drizzled/user_var_entry.h>
1865
#include <drizzled/unique.h>
1866
#include <drizzled/var.h>
1867
#include <drizzled/select_dumpvar.h>
1872
1659
/* Bits in sql_command_flags */
1874
1661
enum sql_command_flag_bits