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"
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"
25
#include <boost/make_shared.hpp>
26
#include <boost/thread/condition_variable.hpp>
46
#include "drizzled/internal/getrusage.h"
47
#include "drizzled/security_context.h"
48
#include "drizzled/open_tables_state.h"
49
#include "drizzled/internal_error_handler.h"
50
#include "drizzled/diagnostics_area.h"
51
#include "drizzled/plugin/authorization.h"
53
#include <boost/unordered_map.hpp>
27
54
#include <boost/thread/mutex.hpp>
28
55
#include <boost/thread/shared_mutex.hpp>
29
#include <boost/thread/thread.hpp>
33
#include <sys/resource.h>
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>
47
#include <drizzled/open_tables_state.h>
48
#include <drizzled/plugin.h>
49
#include <drizzled/plugin/authorization.h>
50
#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
#include <drizzled/sql_error.h>
58
#include <drizzled/sql_lex.h>
59
#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
#include <drizzled/visibility.h>
56
#include <boost/thread/condition_variable.hpp>
69
58
#define MIN_HANDSHAKE_SIZE 6
106
99
#define TC_HEURISTIC_RECOVER_ROLLBACK 2
107
100
extern uint32_t tc_heuristic_recover;
104
Local storage for proto that are tmp table. This should be enlarged
105
to hande the entire table-share for a local table. Once Hash is done,
106
we should consider exchanging the map for it.
108
typedef std::map <std::string, message::Table> ProtoCache;
111
The COPY_INFO structure is used by INSERT/REPLACE code.
112
The schema of the row counting by the INSERT/INSERT ... ON DUPLICATE KEY
114
If a row is inserted then the copied variable is incremented.
115
If a row is updated by the INSERT ... ON DUPLICATE KEY UPDATE and the
116
new data differs from the old one then the copied and the updated
117
variables are incremented.
118
The touched variable is incremented if a row was touched by the update part
119
of the INSERT ... ON DUPLICATE KEY UPDATE no matter whether the row
120
was actually changed or not.
125
ha_rows records; /**< Number of processed records */
126
ha_rows deleted; /**< Number of deleted records */
127
ha_rows updated; /**< Number of updated records */
128
ha_rows copied; /**< Number of copied records */
130
ha_rows touched; /* Number of touched records */
131
enum enum_duplicates handle_duplicates;
132
int escape_char, last_errno;
134
/* for INSERT ... UPDATE */
135
List<Item> *update_fields;
136
List<Item> *update_values;
137
/* for VIEW ... WITH CHECK OPTION */
155
} /* namespace drizzled */
157
/** @TODO why is this in the middle of the file */
158
#include <drizzled/lex_column.h>
109
166
#define Session_SENTRY_MAGIC 0xfeedd1ff
110
167
#define Session_SENTRY_GONE 0xdeadbeef
112
extern DRIZZLED_API struct drizzle_system_variables global_system_variables;
169
struct drizzle_system_variables
171
drizzle_system_variables()
174
How dynamically allocated system variables are handled:
176
The global_system_variables and max_system_variables are "authoritative"
177
They both should have the same 'version' and 'size'.
178
When attempting to access a dynamic variable, if the session version
179
is out of date, then the session version is updated and realloced if
180
neccessary and bytes copied from global to make up for missing data.
182
ulong dynamic_variables_version;
183
char * dynamic_variables_ptr;
184
uint32_t dynamic_variables_head; /* largest valid variable offset */
185
uint32_t dynamic_variables_size; /* how many bytes are in use */
187
uint64_t myisam_max_extra_sort_file_size;
188
uint64_t max_heap_table_size;
189
uint64_t tmp_table_size;
190
ha_rows select_limit;
191
ha_rows max_join_size;
192
uint64_t auto_increment_increment;
193
uint64_t auto_increment_offset;
194
uint64_t bulk_insert_buff_size;
195
uint64_t join_buff_size;
196
uint32_t max_allowed_packet;
197
uint64_t max_error_count;
198
uint64_t max_length_for_sort_data;
199
size_t max_sort_length;
200
uint64_t min_examined_row_limit;
201
bool optimizer_prune_level;
204
uint32_t optimizer_search_depth;
205
uint32_t div_precincrement;
206
uint64_t preload_buff_size;
207
uint32_t read_buff_size;
208
uint32_t read_rnd_buff_size;
209
bool replicate_query;
210
size_t sortbuff_size;
211
uint32_t thread_handling;
212
uint32_t tx_isolation;
213
size_t transaction_message_threshold;
214
uint32_t completion_type;
215
/* Determines which non-standard SQL behaviour should be enabled */
217
uint64_t max_seeks_for_key;
218
size_t range_alloc_block_size;
219
uint32_t query_alloc_block_size;
220
uint32_t query_prealloc_size;
221
uint64_t group_concat_max_len;
222
uint64_t pseudo_thread_id;
224
plugin::StorageEngine *storage_engine;
226
/* Only charset part of these variables is sensible */
227
const CHARSET_INFO *character_set_filesystem;
229
/* Both charset and collation parts of these variables are important */
230
const CHARSET_INFO *collation_server;
232
inline const CHARSET_INFO *getCollation(void)
234
return collation_server;
238
MY_LOCALE *lc_time_names;
240
Time_zone *time_zone;
243
extern struct drizzle_system_variables global_system_variables;
245
} /* namespace drizzled */
247
#include "drizzled/sql_lex.h"
252
void mark_transaction_to_rollback(Session *session, bool all);
255
Storage engine specific thread local data.
260
Storage engine specific thread local data.
261
Lifetime: one user connection.
265
* Resource contexts for both the "statement" and "normal"
268
* Resource context at index 0:
270
* Life time: one statement within a transaction. If @@autocommit is
271
* on, also represents the entire transaction.
273
* Resource context at index 1:
275
* Life time: one transaction within a connection.
279
* If the storage engine does not participate in a transaction,
280
* there will not be a resource context.
282
drizzled::ResourceContext resource_context[2];
284
Ha_data() :ha_ptr(NULL) {}
115
288
* Represents a client connection to the database server.
130
303
* all member variables that are not critical to non-internal operations of the
131
304
* session object.
306
typedef int64_t session_id_t;
134
class DRIZZLED_API Session : public Open_tables_state
308
class Session : public Open_tables_state
137
311
// Plugin storage in Session.
312
typedef boost::unordered_map<std::string, util::Storable *, util::insensitive_hash, util::insensitive_equal_to> PropertyMap;
313
typedef Session* Ptr;
138
314
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;
144
static shared_ptr make_shared(plugin::Client *client, catalog::Instance::shared_ptr instance_arg)
146
assert(instance_arg);
147
return boost::make_shared<Session>(client, instance_arg);
151
317
MARK_COLUMNS_NONE: Means mark_used_colums is not set and no indicator to
466
563
uint32_t file_id; /**< File ID for LOAD DATA INFILE */
467
564
/* @note the following three members should likely move to Client */
468
565
uint32_t max_client_packet_length; /**< Maximum number of bytes a client can send in a single packet */
471
boost::posix_time::ptime _epoch;
472
boost::posix_time::ptime _connect_time;
473
boost::posix_time::ptime _start_timer;
474
boost::posix_time::ptime _end_timer;
476
boost::posix_time::ptime _user_time;
478
uint64_t utime_after_lock; // This used by Innodb.
482
_user_time= boost::posix_time::not_a_date_time;
485
const boost::posix_time::ptime &start_timer() const
490
void getTimeDifference(boost::posix_time::time_duration &result_arg, const boost::posix_time::ptime &arg) const
492
result_arg= arg - _start_timer;
568
uint64_t thr_create_utime; /**< track down slow pthread_create */
569
uint64_t start_utime;
570
uint64_t utime_after_lock;
495
572
thr_lock_type update_lock_default;
512
589
query_id_t query_id;
513
590
query_id_t warn_query_id;
516
592
void **getEngineData(const plugin::MonitoredInTransaction *monitored);
517
593
ResourceContext *getResourceContext(const plugin::MonitoredInTransaction *monitored,
518
594
size_t index= 0);
520
session::Transactions transaction;
597
* Structure used to manage "statement transactions" and
598
* "normal transactions". In autocommit mode, the normal transaction is
599
* equivalent to the statement transaction.
601
* Storage engines will be registered here when they participate in
602
* a transaction. No engine is registered more than once.
604
struct st_transactions {
605
std::deque<NamedSavepoint> savepoints;
608
* The normal transaction (since BEGIN WORK).
610
* Contains a list of all engines that have participated in any of the
611
* statement transactions started within the context of the normal
614
* @note In autocommit mode, this is empty.
616
TransactionContext all;
619
* The statment transaction.
621
* Contains a list of all engines participating in the given statement.
623
* @note In autocommit mode, this will be used to commit/rollback the
624
* normal transaction.
626
TransactionContext stmt;
522
642
Field *dup_field;
523
643
sigset_t signals;
1046
1136
const char* enter_cond(boost::condition_variable_any &cond, boost::mutex &mutex, const char* msg);
1047
1137
void exit_cond(const char* old_msg);
1049
type::Time::epoch_t query_start()
1051
return getCurrentTimestampEpoch();
1056
_end_timer= _start_timer= boost::posix_time::microsec_clock::universal_time();
1057
utime_after_lock= (_start_timer - _epoch).total_microseconds();
1060
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
1062
_user_time= boost::posix_time::from_time_t(t);
1065
void set_time_after_lock()
1067
boost::posix_time::ptime mytime(boost::posix_time::microsec_clock::universal_time());
1068
utime_after_lock= (mytime - _epoch).total_microseconds();
1071
void set_end_timer()
1073
_end_timer= boost::posix_time::microsec_clock::universal_time();
1074
status_var.execution_time_nsec+=(_end_timer - _start_timer).total_microseconds();
1077
uint64_t getElapsedTime() const
1079
return (_end_timer - _start_timer).total_microseconds();
1139
inline time_t query_start() { return start_time; }
1140
inline void set_time()
1142
boost::posix_time::ptime mytime(boost::posix_time::microsec_clock::local_time());
1143
boost::posix_time::ptime epoch(boost::gregorian::date(1970,1,1));
1144
start_utime= utime_after_lock= (mytime-epoch).total_microseconds();
1148
start_time= user_time;
1149
connect_microseconds= start_utime;
1152
start_time= (mytime-epoch).total_seconds();
1154
inline void set_current_time() { start_time= time(NULL); }
1155
inline void set_time(time_t t)
1157
start_time= user_time= t;
1158
boost::posix_time::ptime mytime(boost::posix_time::microsec_clock::local_time());
1159
boost::posix_time::ptime epoch(boost::gregorian::date(1970,1,1));
1160
uint64_t t_mark= (mytime-epoch).total_microseconds();
1162
start_utime= utime_after_lock= t_mark;
1164
void set_time_after_lock() {
1165
boost::posix_time::ptime mytime(boost::posix_time::microsec_clock::local_time());
1166
boost::posix_time::ptime epoch(boost::gregorian::date(1970,1,1));
1167
utime_after_lock= (mytime-epoch).total_microseconds();
1083
1170
* Returns the current micro-timestamp
1085
type::Time::epoch_t getCurrentTimestamp(bool actual= true) const
1172
inline uint64_t getCurrentTimestamp()
1087
type::Time::epoch_t t_mark;
1091
boost::posix_time::ptime mytime(boost::posix_time::microsec_clock::universal_time());
1092
t_mark= (mytime - _epoch).total_microseconds();
1096
t_mark= (_end_timer - _epoch).total_microseconds();
1174
boost::posix_time::ptime mytime(boost::posix_time::microsec_clock::local_time());
1175
boost::posix_time::ptime epoch(boost::gregorian::date(1970,1,1));
1176
uint64_t t_mark= (mytime-epoch).total_microseconds();
1102
// We may need to set user on this
1103
type::Time::epoch_t getCurrentTimestampEpoch() const
1105
if (not _user_time.is_not_a_date_time())
1106
return (_user_time - _epoch).total_seconds();
1108
return (_start_timer - _epoch).total_seconds();
1111
type::Time::epoch_t getCurrentTimestampEpoch(type::Time::usec_t &fraction_arg) const
1113
if (not _user_time.is_not_a_date_time())
1116
return (_user_time - _epoch).total_seconds();
1119
fraction_arg= _start_timer.time_of_day().fractional_seconds() % 1000000;
1120
return (_start_timer - _epoch).total_seconds();
1123
uint64_t found_rows(void) const
1180
inline uint64_t found_rows(void)
1125
1182
return limit_found_rows;
1128
1184
/** Returns whether the session is currently inside a transaction */
1129
bool inTransaction() const
1185
inline bool inTransaction()
1131
1187
return server_status & SERVER_STATUS_IN_TRANS;
1134
1189
LEX_STRING *make_lex_string(LEX_STRING *lex_str,
1135
1190
const char* str, uint32_t length,
1136
1191
bool allocate_lex_string);
1138
1192
LEX_STRING *make_lex_string(LEX_STRING *lex_str,
1139
1193
const std::string &str,
1140
1194
bool allocate_lex_string);
1142
1196
int send_explain_fields(select_result *result);
1145
1198
Clear the current error, if any.
1146
1199
We do not clear is_fatal_error or is_fatal_sub_stmt_error since we
1572
1621
Table *openTable(TableList *table_list, bool *refresh, uint32_t flags= 0);
1574
1623
void unlink_open_table(Table *find);
1575
void drop_open_table(Table *table, const identifier::Table &identifier);
1624
void drop_open_table(Table *table, TableIdentifier &identifier);
1576
1625
void close_cached_table(Table *table);
1578
1627
/* Create a lock in the cache */
1579
table::Placeholder *table_cache_insert_placeholder(const identifier::Table &identifier);
1580
bool lock_table_name_if_not_cached(const identifier::Table &identifier, Table **table);
1628
table::Placeholder *table_cache_insert_placeholder(const TableIdentifier &identifier);
1629
bool lock_table_name_if_not_cached(TableIdentifier &identifier, Table **table);
1631
typedef boost::unordered_map<std::string, message::Table, util::insensitive_hash, util::insensitive_equal_to> TableMessageCache;
1635
TableMessageCache table_message_cache;
1638
bool storeTableMessage(const TableIdentifier &identifier, message::Table &table_message);
1639
bool removeTableMessage(const TableIdentifier &identifier);
1640
bool getTableMessage(const TableIdentifier &identifier, message::Table &table_message);
1641
bool doesTableMessageExist(const TableIdentifier &identifier);
1642
bool renameTableMessage(const TableIdentifier &from, const TableIdentifier &to);
1583
session::TableMessages _table_message_cache;
1646
TableMessages _table_message_cache;
1586
session::TableMessages &getMessageCache()
1649
TableMessages &getMessageCache()
1588
1651
return _table_message_cache;
1591
1654
/* Reopen operations */
1592
bool reopen_tables();
1655
bool reopen_tables(bool get_locks, bool mark_share_as_old);
1593
1656
bool close_cached_tables(TableList *tables, bool wait_for_refresh, bool wait_for_placeholders);
1595
1658
void wait_for_condition(boost::mutex &mutex, boost::condition_variable_any &cond);
1655
catalog::Instance::const_reference catalog() const
1657
return *(_catalog.get());
1660
catalog::Instance::reference catalog()
1662
return *(_catalog.get());
1666
catalog::Instance::shared_ptr _catalog;
1668
1718
// This lives throughout the life of Session
1669
1719
bool use_usage;
1670
session::PropertyMap life_properties;
1671
std::vector<table::Singular *> temporary_shares;
1720
PropertyMap life_properties;
1721
std::vector<table::Instance *> temporary_shares;
1672
1722
struct rusage usage;
1675
1727
#define ESCAPE_CHARS "ntrb0ZN" // keep synchronous with READ_INFO::unescape
1729
} /* namespace drizzled */
1731
/** @TODO why is this in the middle of the file */
1732
#include <drizzled/select_to_file.h>
1733
#include <drizzled/select_export.h>
1734
#include <drizzled/select_dump.h>
1735
#include <drizzled/select_insert.h>
1736
#include <drizzled/select_create.h>
1737
#include <drizzled/tmp_table_param.h>
1738
#include <drizzled/select_union.h>
1739
#include <drizzled/select_subselect.h>
1740
#include <drizzled/select_singlerow_subselect.h>
1741
#include <drizzled/select_max_min_finder_subselect.h>
1742
#include <drizzled/select_exists_subselect.h>
1748
* A structure used to describe sort information
1749
* for a field or item used in ORDER BY.
1754
Field *field; /**< Field to sort */
1755
Item *item; /**< Item if not sorting fields */
1756
size_t length; /**< Length of sort field */
1757
uint32_t suffix_length; /**< Length suffix (0-4) */
1758
Item_result result_type; /**< Type of item */
1759
bool reverse; /**< if descending sort */
1760
bool need_strxnfrm; /**< If we have to use strxnfrm() */
1767
result_type(STRING_RESULT),
1774
} /* namespace drizzled */
1776
/** @TODO why is this in the middle of the file */
1778
#include <drizzled/table_ident.h>
1779
#include <drizzled/user_var_entry.h>
1780
#include <drizzled/unique.h>
1781
#include <drizzled/var.h>
1782
#include <drizzled/select_dumpvar.h>
1677
1787
/* Bits in sql_command_flags */
1679
1789
enum sql_command_flag_bits