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
22
#include <algorithm>
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>
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>
69
#define MIN_HANDSHAKE_SIZE 6
78
class EventObserverList;
88
namespace internal { struct st_my_thread_var; }
89
namespace table { class Placeholder; }
93
class Internal_error_handler;
94
class Lex_input_stream;
95
class TableShareInstance;
44
#include <drizzled/util/find_ptr.h>
45
#include <drizzled/util/string.h>
46
#include <drizzled/type/time.h>
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;
105
55
#define TC_HEURISTIC_RECOVER_COMMIT 1
106
56
#define TC_HEURISTIC_RECOVER_ROLLBACK 2
107
57
extern uint32_t tc_heuristic_recover;
109
#define Session_SENTRY_MAGIC 0xfeedd1ff
110
#define Session_SENTRY_GONE 0xdeadbeef
112
59
extern DRIZZLED_API struct drizzle_system_variables global_system_variables;
134
class DRIZZLED_API Session : public Open_tables_state
81
class DRIZZLED_API Session : private Open_tables_state
86
boost::scoped_ptr<impl_c> impl_;
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;
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)
146
92
assert(instance_arg);
147
93
return boost::make_shared<Session>(client, instance_arg);
204
147
void setXaId(uint64_t in_xa_id)
210
* Uniquely identifies each statement object in thread scope; change during
211
* statement lifetime.
213
* @todo should be const
217
LEX *lex; /**< parse tree descriptor */
225
enum_sql_command getSqlCommand() const
227
return lex->sql_command;
153
Diagnostics_area& main_da();
154
const LEX& lex() const;
156
enum_sql_command getSqlCommand() const;
230
158
/** query associated with this statement */
231
159
typedef boost::shared_ptr<const std::string> QueryString;
346
259
return user_vars;
349
drizzle_system_variables variables; /**< Mutable local variables local to the session */
351
enum_tx_isolation getTxIsolation()
353
return (enum_tx_isolation)variables.tx_isolation;
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;
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. */
365
274
char *thread_stack;
368
identifier::User::shared_ptr security_ctx;
370
int32_t scoreboard_index;
372
inline void checkSentry() const
374
assert(this->dbug_sentry == Session_SENTRY_MAGIC);
378
identifier::User::const_shared_ptr user() const
383
return identifier::User::const_shared_ptr();
386
void setUser(identifier::User::shared_ptr arg)
276
identifier::user::ptr user() const
278
return security_ctx ? security_ctx : identifier::user::ptr();
281
void setUser(identifier::user::mptr arg)
388
283
security_ctx= arg;
516
410
void **getEngineData(const plugin::MonitoredInTransaction *monitored);
517
ResourceContext *getResourceContext(const plugin::MonitoredInTransaction *monitored,
411
ResourceContext& getResourceContext(const plugin::MonitoredInTransaction&, size_t index= 0);
520
session::Transactions transaction;
413
session::Transactions& transaction;
414
Open_tables_state& open_tables;
522
416
Field *dup_field;
523
417
sigset_t signals;
525
420
// As of right now we do not allow a concurrent execute to launch itself
527
bool concurrent_execute_allowed;
531
421
void setConcurrentExecute(bool arg)
533
423
concurrent_execute_allowed= arg;
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.
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;
594
478
uint64_t limit_found_rows;
595
479
uint64_t options; /**< Bitmap of options */
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.
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;
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;
647
523
Row counter, mainly for errors and warnings. Not increased in
648
524
create_sort_index(); may differ from examined_row_count.
650
526
uint32_t row_count;
652
uint32_t getRowCount() const
657
528
session_id_t thread_id;
658
529
uint32_t tmp_table;
659
530
enum global_read_lock_t
770
640
bool substitute_null_with_insert_id;
771
641
bool cleanup_done;
774
bool abort_on_warning;
775
bool tablespace_op; /**< This is true in DISCARD/IMPORT TABLESPACE */
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;
783
bool doing_tablespace_operation(void)
649
bool doing_tablespace_operation()
785
651
return tablespace_op;
916
777
if (first_successful_insert_id_in_cur_stmt == 0)
917
778
first_successful_insert_id_in_cur_stmt= id_arg;
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()
921
782
return first_successful_insert_id_in_prev_stmt;
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
928
inline void force_one_auto_inc_interval(uint64_t next_id)
930
auto_inc_intervals_forced.empty(); // in case of multiple SET INSERT_ID
931
auto_inc_intervals_forced.append(next_id, UINT64_MAX, 0);
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();
939
790
* Cleans up after query.
1065
916
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();
918
utime_after_lock= (boost::posix_time::microsec_clock::universal_time() - _epoch).total_microseconds();
921
void set_end_timer();
1077
923
uint64_t getElapsedTime() const
1079
925
return (_end_timer - _start_timer).total_microseconds();
1083
929
* Returns the current micro-timestamp
1085
931
type::Time::epoch_t getCurrentTimestamp(bool actual= true) const
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();
933
return ((actual ? boost::posix_time::microsec_clock::universal_time() : _end_timer) - _epoch).total_microseconds();
1102
936
// We may need to set user on this
1103
937
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();
939
return ((_user_time.is_not_a_date_time() ? _start_timer : _user_time) - _epoch).total_seconds();
1111
942
type::Time::epoch_t getCurrentTimestampEpoch(type::Time::usec_t &fraction_arg) const
1113
944
if (not _user_time.is_not_a_date_time())
1115
946
fraction_arg= 0;
1142
973
int send_explain_fields(select_result *result);
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.
1151
inline void clear_error(bool full= false)
1153
if (main_da.is_error())
1154
main_da.reset_diagnostics_area();
1158
drizzle_reset_errors(this, true);
1162
void clearDiagnostics()
1164
main_da.reset_diagnostics_area();
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().
1172
inline void fatal_error()
1174
assert(main_da.is_error());
1175
is_fatal_error= true;
1178
true if there is an error in the error stack.
1180
Please use this method instead of direct access to
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.
1188
To raise this flag, use my_error().
1190
inline bool is_error() const { return main_da.is_error(); }
1191
inline const CHARSET_INFO *charset() { return default_charset_info; }
1193
void change_item_tree(Item **place, Item *new_value)
975
void clear_error(bool full= false);
976
void clearDiagnostics();
978
bool is_error() const;
980
inline const charset_info_st *charset() { return default_charset_info; }
1198
983
Cleanup statement parse state (parse tree, lex) and execution
1199
984
state after execution of a non-prepared SQL statement.
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;
1308
1093
* @param passwd Scrambled password received from client
1309
1094
* @param db Database name to connect to, may be NULL
1311
1096
bool checkUser(const std::string &passwd, const std::string &db);
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.
1317
1102
uint64_t getConnectMicroseconds() const
1391
1176
void resetResultsetMessage()
1393
1178
resultset= NULL;
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;
1404
/* Schema observers are mapped to databases. */
1405
std::map<std::string, plugin::EventObserverList *> schema_event_observers;
1409
plugin::EventObserverList *getSessionObservers()
1181
plugin::EventObserverList *getSessionObservers()
1411
1183
return session_event_observers;
1414
void setSessionObservers(plugin::EventObserverList *observers)
1186
void setSessionObservers(plugin::EventObserverList *observers)
1416
1188
session_event_observers= observers;
1419
/* For schema event observers there is one set of observers per database. */
1420
plugin::EventObserverList *getSchemaObservers(const std::string &db_name)
1422
std::map<std::string, plugin::EventObserverList *>::iterator it;
1424
it= schema_event_observers.find(db_name);
1425
if (it == schema_event_observers.end())
1431
void setSchemaObservers(const std::string &db_name, plugin::EventObserverList *observers)
1433
std::map<std::string, plugin::EventObserverList *>::iterator it;
1435
it= schema_event_observers.find(db_name);
1436
if (it != schema_event_observers.end())
1437
schema_event_observers.erase(it);;
1440
schema_event_observers[db_name] = observers;
1191
plugin::EventObserverList* getSchemaObservers(const std::string& schema);
1192
plugin::EventObserverList* setSchemaObservers(const std::string& schema, plugin::EventObserverList*);
1445
const char *proc_info;
1447
1196
/** The current internal error handler for this thread, or NULL. */
1448
1197
Internal_error_handler *m_internal_handler;
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).
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.
1479
1221
* SELECT f1_that_uses_t1() FROM t1;
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.
1484
1226
void mark_used_tables_as_free_for_reuse(Table *table);
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)
1492
main_da.set_ok_status(this, affected_rows, found_rows_arg, passed_id, message);
1496
/** A short cut for session->main_da.set_eof_status(). */
1498
inline void my_eof()
1500
main_da.set_eof_status(this);
1503
/* Some inline functions for more speed */
1505
inline bool add_item_to_list(Item *item)
1507
return lex->current_select->add_item_to_list(this, item);
1510
inline bool add_value_to_list(Item *value)
1512
return lex->value_list.push_back(value);
1515
inline bool add_order_to_list(Item *item, bool asc)
1517
return lex->current_select->add_order_to_list(this, item, asc);
1520
inline bool add_group_to_list(Item *item, bool asc)
1522
return lex->current_select->add_group_to_list(this, item, asc);
1229
void my_ok(ha_rows affected_rows= 0, ha_rows found_rows_arg= 0, uint64_t passed_id= 0, const char *message= NULL);
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);
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);
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.
1565
1272
* The lock will automaticaly be freed by close_thread_tables()
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);
1569
1281
int open_tables_from_list(TableList **start, uint32_t *counter, uint32_t flags= 0);
1596
1301
int setup_conds(TableList *leaves, COND **conds);
1597
1302
int lock_tables(TableList *tables, uint32_t count, bool *need_reopen);
1599
drizzled::util::Storable *getProperty(const std::string &arg)
1305
T* getProperty(const std::string& name)
1601
return life_properties.getProperty(arg);
1307
return static_cast<T*>(getProperty0(name));
1605
bool setProperty(const std::string &arg, T *value)
1311
T setProperty(const std::string& name, T value)
1607
life_properties.setProperty(arg, value);
1313
setProperty0(name, value);
1618
1323
pointer to plugin::StorageEngine
1620
plugin::StorageEngine *getDefaultStorageEngine()
1622
if (variables.storage_engine)
1623
return variables.storage_engine;
1624
return global_system_variables.storage_engine;
1325
plugin::StorageEngine *getDefaultStorageEngine();
1627
1326
void get_xid(DrizzleXid *xid); // Innodb only
1629
table::Singular *getInstanceTable();
1630
table::Singular *getInstanceTable(List<CreateField> &field_list);
1635
if (getrusage(RUSAGE_THREAD, &usage))
1328
table::Singular& getInstanceTable();
1329
table::Singular& getInstanceTable(std::list<CreateField>&);
1645
1331
void setUsage(bool arg)
1647
1333
use_usage= arg;
1650
const struct rusage &getUsage()
1336
const rusage &getUsage()
1655
catalog::Instance::const_reference catalog() const
1657
return *(_catalog.get());
1660
catalog::Instance::reference catalog()
1662
return *(_catalog.get());
1341
const catalog::Instance& catalog() const
1346
catalog::Instance& catalog()
1351
bool arg_of_last_insert_id_function; // Tells if LAST_INSERT_ID(#) was called for the current statement
1666
catalog::Instance::shared_ptr _catalog;
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*);
1362
return not getrusage(RUSAGE_THREAD, &usage);
1365
boost::shared_ptr<catalog::Instance> _catalog;
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;
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;
1381
identifier::user::mptr security_ctx;
1382
int32_t scoreboard_index;
1383
plugin::Client *client;
1384
util::string::shared_ptr _schema;
1675
1387
#define ESCAPE_CHARS "ntrb0ZN" // keep synchronous with READ_INFO::unescape
1677
1389
/* Bits in sql_command_flags */
1679
enum sql_command_flag_bits
1391
enum sql_command_flag_bits
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);
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);
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 */
1701
1413
} /* namespace drizzled */
1703
#endif /* DRIZZLED_SESSION_H */