17
17
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20
#ifndef DRIZZLED_SESSION_H
21
#define DRIZZLED_SESSION_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/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
#include "drizzled/select_result_interceptor.h"
37
#include "drizzled/sql_error.h"
38
#include "drizzled/sql_locale.h"
39
#include "drizzled/statistics_variables.h"
40
#include "drizzled/transaction_context.h"
41
#include "drizzled/util/storable.h"
42
#include "drizzled/xid.h"
47
#include <sys/resource.h>
22
49
#include <algorithm>
24
#include <boost/make_shared.hpp>
25
#include <boost/scoped_ptr.hpp>
26
#include <boost/thread/condition_variable.hpp>
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>
66
#include <boost/thread/thread.hpp>
27
67
#include <boost/thread/mutex.hpp>
28
68
#include <boost/thread/shared_mutex.hpp>
29
#include <boost/thread/thread.hpp>
33
#include <sys/resource.h>
36
#include <drizzled/charset.h>
37
#include <drizzled/base.h>
38
#include <drizzled/error.h>
39
#include <drizzled/lock.h>
40
#include <drizzled/pthread_globals.h>
41
#include <drizzled/sql_error.h>
42
#include <drizzled/sql_locale.h>
43
#include <drizzled/visibility.h>
44
#include <drizzled/util/find_ptr.h>
45
#include <drizzled/util/string.h>
46
#include <drizzled/type/time.h>
69
#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
#define MIN_HANDSHAKE_SIZE 6
86
class EventObserverList;
96
namespace internal { struct st_my_thread_var; }
98
namespace table { class Placeholder; }
100
class Lex_input_stream;
101
class user_var_entry;
105
class TableShareInstance;
50
107
extern char internal_table_name[2];
51
108
extern char empty_c_string[1];
52
109
extern const char **errmesg;
53
extern uint32_t server_id;
54
extern std::string server_uuid;
56
111
#define TC_HEURISTIC_RECOVER_COMMIT 1
57
112
#define TC_HEURISTIC_RECOVER_ROLLBACK 2
58
113
extern uint32_t tc_heuristic_recover;
118
#define Session_SENTRY_MAGIC 0xfeedd1ff
119
#define Session_SENTRY_GONE 0xdeadbeef
60
121
extern DRIZZLED_API struct drizzle_system_variables global_system_variables;
168
244
// requires under some setup non const, you must copy the QueryString in
169
245
// order to use it.
171
void resetQueryString();
172
const boost::shared_ptr<session::State>& state();
174
247
QueryString getQueryString() const
179
const char* getQueryStringCopy(size_t &length)
252
void resetQueryString()
259
We need to copy the lock on the string in order to make sure we have a stable string.
260
Once this is done we can use it to build a const char* which can be handed off for
261
a method to use (Innodb is currently the only engine using this).
263
const char *getQueryStringCopy(size_t &length)
181
265
QueryString tmp_string(getQueryString());
182
267
if (not tmp_string)
187
273
length= tmp_string->length();
188
return strmake(tmp_string->c_str(), tmp_string->length());
191
util::string::ptr schema() const;
274
char *to_return= strmake(tmp_string->c_str(), tmp_string->length());
279
session::State::shared_ptr _state;
283
session::State::const_shared_ptr state()
289
Name of the current (default) database.
291
If there is the current (default) database, "db" contains its name. If
292
there is no current (default) database, "db" is NULL and "db_length" is
293
0. In other words, "db", "db_length" must either be NULL, or contain a
296
@note this attribute is set and alloced by the slave SQL thread (for
297
the Session of that thread); that thread is (and must remain, for now) the
298
only responsible for freeing this member.
301
util::string::shared_ptr _schema;
305
util::string::const_shared_ptr schema() const
310
return util::string::const_shared_ptr(new std::string(""));
193
313
/* current cache key */
194
314
std::string query_cache_key;
258
405
scoreboard_index= in_scoreboard_index;
261
bool isOriginatingServerUUIDSet()
263
return originating_server_uuid_set;
266
void setOriginatingServerUUID(std::string in_originating_server_uuid)
268
originating_server_uuid= in_originating_server_uuid;
269
originating_server_uuid_set= true;
272
std::string &getOriginatingServerUUID()
274
return originating_server_uuid;
277
void setOriginatingCommitID(uint64_t in_originating_commit_id)
279
originating_commit_id= in_originating_commit_id;
282
uint64_t getOriginatingCommitID()
284
return originating_commit_id;
288
409
* Is this session viewable by the current user?
290
bool isViewable(const identifier::User&) const;
411
bool isViewable(identifier::User::const_reference) const;
347
469
* Type of current query: COM_STMT_PREPARE, COM_QUERY, etc. Set from
348
470
* first byte of the packet in executeStatement()
350
enum_server_command command;
472
enum enum_server_command command;
473
uint32_t file_id; /**< File ID for LOAD DATA INFILE */
474
/* @note the following three members should likely move to Client */
475
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;
352
502
thr_lock_type update_lock_default;
478
637
This, and some other variables like 'count_cuted_fields'
479
638
maybe should be statement/cursor local, that is, moved to Statement
480
639
class. With current implementation warnings produced in each prepared
481
640
statement/cursor settle here.
642
List<DRIZZLE_ERROR> warn_list;
483
643
uint32_t warn_count[(uint32_t) DRIZZLE_ERROR::WARN_LEVEL_END];
484
644
uint32_t total_warn_count;
645
Diagnostics_area main_da;
649
/* Statement id is thread-wide. This counter is used to generate ids */
650
uint32_t statement_id_counter;
651
uint32_t rand_saved_seed1;
652
uint32_t rand_saved_seed2;
487
654
Row counter, mainly for errors and warnings. Not increased in
488
655
create_sort_index(); may differ from examined_row_count.
490
657
uint32_t row_count;
659
uint32_t getRowCount() const
492
664
session_id_t thread_id;
493
665
uint32_t tmp_table;
494
666
enum global_read_lock_t
841
1053
const char* enter_cond(boost::condition_variable_any &cond, boost::mutex &mutex, const char* msg);
842
1054
void exit_cond(const char* old_msg);
844
uint64_t found_rows() const
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();
1090
* Returns the current micro-timestamp
1092
type::Time::epoch_t getCurrentTimestamp(bool actual= true) const
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();
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
846
1132
return limit_found_rows;
863
1149
int send_explain_fields(select_result *result);
865
void clear_error(bool full= false);
866
void clearDiagnostics();
867
bool is_error() const;
869
static const charset_info_st *charset() { return default_charset_info; }
1152
Clear the current error, if any.
1153
We do not clear is_fatal_error or is_fatal_sub_stmt_error since we
1154
assume this is never called if the fatal error is set.
1155
@todo: To silence an error, one should use Internal_error_handler
1156
mechanism. In future this function will be removed.
1158
inline void clear_error(bool full= false)
1160
if (main_da.is_error())
1161
main_da.reset_diagnostics_area();
1165
drizzle_reset_errors(this, true);
1169
void clearDiagnostics()
1171
main_da.reset_diagnostics_area();
1175
Mark the current error as fatal. Warning: this does not
1176
set any error, it sets a property of the error, so must be
1177
followed or prefixed with my_error().
1179
inline void fatal_error()
1181
assert(main_da.is_error());
1182
is_fatal_error= true;
1185
true if there is an error in the error stack.
1187
Please use this method instead of direct access to
1190
If true, the current (sub)-statement should be aborted.
1191
The main difference between this member and is_fatal_error
1192
is that a fatal error can not be handled by a stored
1193
procedure continue handler, whereas a normal error can.
1195
To raise this flag, use my_error().
1197
inline bool is_error() const { return main_da.is_error(); }
1198
inline const CHARSET_INFO *charset() { return default_charset_info; }
1200
void change_item_tree(Item **place, Item *new_value)
872
1205
Cleanup statement parse state (parse tree, lex) and execution
873
1206
state after execution of a non-prepared SQL statement.
958
1311
* @note Host, user and passwd may point to communication buffer.
959
1312
* Current implementation does not depend on that, but future changes
960
* should be done with this in mind;
1313
* should be done with this in mind;
962
1315
* @param passwd Scrambled password received from client
963
1316
* @param db Database name to connect to, may be NULL
965
1318
bool checkUser(const std::string &passwd, const std::string &db);
1321
* Returns the timestamp (in microseconds) of when the Session
1322
* connected to the server.
1324
uint64_t getConnectMicroseconds() const
1326
return (_connect_time - _epoch).total_microseconds();
1329
uint64_t getConnectSeconds() const
1331
return (_connect_time - _epoch).total_seconds();
968
1335
* Returns a pointer to the active Transaction message for this
1031
1398
void resetResultsetMessage()
1033
1400
resultset= NULL;
1036
plugin::EventObserverList *getSessionObservers()
1404
/** Pointers to memory managed by the ReplicationServices component */
1405
message::Transaction *transaction_message;
1406
message::Statement *statement_message;
1407
/* Pointer to the current resultset of Select query */
1408
message::Resultset *resultset;
1409
plugin::EventObserverList *session_event_observers;
1411
/* Schema observers are mapped to databases. */
1412
std::map<std::string, plugin::EventObserverList *> schema_event_observers;
1416
plugin::EventObserverList *getSessionObservers()
1038
1418
return session_event_observers;
1041
void setSessionObservers(plugin::EventObserverList *observers)
1421
void setSessionObservers(plugin::EventObserverList *observers)
1043
1423
session_event_observers= observers;
1046
plugin::EventObserverList* getSchemaObservers(const std::string& schema);
1047
plugin::EventObserverList* setSchemaObservers(const std::string& schema, plugin::EventObserverList*);
1426
/* For schema event observers there is one set of observers per database. */
1427
plugin::EventObserverList *getSchemaObservers(const std::string &db_name)
1429
std::map<std::string, plugin::EventObserverList *>::iterator it;
1431
it= schema_event_observers.find(db_name);
1432
if (it == schema_event_observers.end())
1438
void setSchemaObservers(const std::string &db_name, plugin::EventObserverList *observers)
1440
std::map<std::string, plugin::EventObserverList *>::iterator it;
1442
it= schema_event_observers.find(db_name);
1443
if (it != schema_event_observers.end())
1444
schema_event_observers.erase(it);;
1447
schema_event_observers[db_name] = observers;
1452
const char *proc_info;
1454
/** The current internal error handler for this thread, or NULL. */
1455
Internal_error_handler *m_internal_handler;
1457
The lex to hold the parsed tree of conventional (non-prepared) queries.
1458
Whereas for prepared and stored procedure statements we use an own lex
1459
instance for each new query, for conventional statements we reuse
1460
the same lex. (@see mysql_parse for details).
1464
This memory root is used for two purposes:
1465
- for conventional queries, to allocate structures stored in main_lex
1466
during parsing, and allocate runtime data (execution plan, etc.)
1468
- for prepared queries, only to allocate runtime data. The parsed
1469
tree itself is reused between executions and thus is stored elsewhere.
1471
memory::Root main_mem_root;
1474
* Marks all tables in the list which were used by current substatement
1475
* as free for reuse.
1477
* @param Head of the list of tables
1481
* The reason we reset query_id is that it's not enough to just test
1482
* if table->query_id != session->query_id to know if a table is in use.
1486
* SELECT f1_that_uses_t1() FROM t1;
1488
* In f1_that_uses_t1() we will see one instance of t1 where query_id is
1489
* set to query_id of original query.
1491
void mark_used_tables_as_free_for_reuse(Table *table);
1050
void my_ok(ha_rows affected_rows= 0, ha_rows found_rows_arg= 0, uint64_t passed_id= 0, const char *message= NULL);
1052
bool add_item_to_list(Item *item);
1053
bool add_value_to_list(Item *value);
1054
bool add_order_to_list(Item *item, bool asc);
1055
bool add_group_to_list(Item *item, bool asc);
1495
/** A short cut for session->main_da.set_ok_status(). */
1496
inline void my_ok(ha_rows affected_rows= 0, ha_rows found_rows_arg= 0,
1497
uint64_t passed_id= 0, const char *message= NULL)
1499
main_da.set_ok_status(this, affected_rows, found_rows_arg, passed_id, message);
1503
/** A short cut for session->main_da.set_eof_status(). */
1505
inline void my_eof()
1507
main_da.set_eof_status(this);
1510
/* Some inline functions for more speed */
1512
inline bool add_item_to_list(Item *item)
1514
return lex->current_select->add_item_to_list(this, item);
1517
inline bool add_value_to_list(Item *value)
1519
return lex->value_list.push_back(value);
1522
inline bool add_order_to_list(Item *item, bool asc)
1524
return lex->current_select->add_order_to_list(this, item, asc);
1527
inline bool add_group_to_list(Item *item, bool asc)
1529
return lex->current_select->add_group_to_list(this, item, asc);
1057
1531
void refresh_status();
1058
1532
user_var_entry *getVariable(LEX_STRING &name, bool create_if_not_exists);
1059
1533
user_var_entry *getVariable(const std::string &name, bool create_if_not_exists);
1060
1534
void setVariable(const std::string &name, const std::string &value);
1063
1537
* Closes all tables used by the current substatement, or all tables
1064
1538
* used by this thread if we are on the upper level.
1139
1625
pointer to plugin::StorageEngine
1141
plugin::StorageEngine *getDefaultStorageEngine();
1142
void get_xid(DrizzleXid *xid); // Innodb only
1144
table::Singular& getInstanceTable();
1145
table::Singular& getInstanceTable(std::list<CreateField>&);
1627
plugin::StorageEngine *getDefaultStorageEngine()
1629
if (variables.storage_engine)
1630
return variables.storage_engine;
1631
return global_system_variables.storage_engine;
1634
void get_xid(DRIZZLE_XID *xid); // Innodb only
1636
table::Singular *getInstanceTable();
1637
table::Singular *getInstanceTable(List<CreateField> &field_list);
1642
if (getrusage(RUSAGE_THREAD, &usage))
1147
1652
void setUsage(bool arg)
1149
1654
use_usage= arg;
1152
const rusage &getUsage()
1657
const struct rusage &getUsage()
1157
const catalog::Instance& catalog() const
1162
catalog::Instance& catalog()
1167
bool arg_of_last_insert_id_function; // Tells if LAST_INSERT_ID(#) was called for the current statement
1662
catalog::Instance::const_reference catalog() const
1664
return *(_catalog.get());
1667
catalog::Instance::reference catalog()
1669
return *(_catalog.get());
1169
drizzled::util::Storable* getProperty0(const std::string&);
1170
void setProperty0(const std::string&, drizzled::util::Storable*);
1174
return not getrusage(RUSAGE_THREAD, &usage);
1177
boost::shared_ptr<catalog::Instance> _catalog;
1179
/** Pointers to memory managed by the ReplicationServices component */
1180
message::Transaction *transaction_message;
1181
message::Statement *statement_message;
1182
/* Pointer to the current resultset of Select query */
1183
message::Resultset *resultset;
1184
plugin::EventObserverList *session_event_observers;
1187
const char *proc_info;
1188
bool abort_on_warning;
1189
bool concurrent_execute_allowed;
1190
bool tablespace_op; /**< This is true in DISCARD/IMPORT TABLESPACE */
1673
catalog::Instance::shared_ptr _catalog;
1675
// This lives throughout the life of Session
1191
1676
bool use_usage;
1193
identifier::user::mptr security_ctx;
1194
int32_t scoreboard_index;
1195
bool originating_server_uuid_set;
1196
std::string originating_server_uuid;
1197
uint64_t originating_commit_id;
1198
plugin::Client *client;
1677
session::PropertyMap life_properties;
1678
std::vector<table::Singular *> temporary_shares;
1679
struct rusage usage;
1201
1684
#define ESCAPE_CHARS "ntrb0ZN" // keep synchronous with READ_INFO::unescape
1686
} /* namespace drizzled */
1688
/** @TODO why is this in the middle of the file */
1689
#include <drizzled/select_to_file.h>
1690
#include <drizzled/select_export.h>
1691
#include <drizzled/select_dump.h>
1692
#include <drizzled/select_insert.h>
1693
#include <drizzled/select_create.h>
1694
#include <drizzled/tmp_table_param.h>
1695
#include <drizzled/select_union.h>
1696
#include <drizzled/select_subselect.h>
1697
#include <drizzled/select_singlerow_subselect.h>
1698
#include <drizzled/select_max_min_finder_subselect.h>
1699
#include <drizzled/select_exists_subselect.h>
1705
* A structure used to describe sort information
1706
* for a field or item used in ORDER BY.
1711
Field *field; /**< Field to sort */
1712
Item *item; /**< Item if not sorting fields */
1713
size_t length; /**< Length of sort field */
1714
uint32_t suffix_length; /**< Length suffix (0-4) */
1715
Item_result result_type; /**< Type of item */
1716
bool reverse; /**< if descending sort */
1717
bool need_strxnfrm; /**< If we have to use strxnfrm() */
1724
result_type(STRING_RESULT),
1731
} /* namespace drizzled */
1733
/** @TODO why is this in the middle of the file */
1735
#include <drizzled/table_ident.h>
1736
#include <drizzled/user_var_entry.h>
1737
#include <drizzled/unique.h>
1738
#include <drizzled/var.h>
1739
#include <drizzled/select_dumpvar.h>
1203
1744
/* Bits in sql_command_flags */
1205
enum sql_command_flag_bits
1746
enum sql_command_flag_bits
1207
1748
CF_BIT_CHANGES_DATA,
1208
1749
CF_BIT_HAS_ROW_COUNT,