00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #pragma once
00021
00022 #include <algorithm>
00023 #include <bitset>
00024 #include <boost/make_shared.hpp>
00025 #include <boost/scoped_ptr.hpp>
00026 #include <boost/thread/condition_variable.hpp>
00027 #include <boost/thread/mutex.hpp>
00028 #include <boost/thread/shared_mutex.hpp>
00029 #include <boost/thread/thread.hpp>
00030 #include <map>
00031 #include <netdb.h>
00032 #include <string>
00033 #include <sys/resource.h>
00034 #include <sys/time.h>
00035
00036 #include <drizzled/charset.h>
00037 #include <drizzled/base.h>
00038 #include <drizzled/error.h>
00039 #include <drizzled/lock.h>
00040 #include <drizzled/pthread_globals.h>
00041 #include <drizzled/sql_error.h>
00042 #include <drizzled/sql_locale.h>
00043 #include <drizzled/visibility.h>
00044 #include <drizzled/util/find_ptr.h>
00045 #include <drizzled/util/string.h>
00046 #include <drizzled/type/time.h>
00047
00048 namespace drizzled {
00049
00050 extern uint32_t server_id;
00051 extern std::string server_uuid;
00052
00053 #define TC_HEURISTIC_RECOVER_COMMIT 1
00054 #define TC_HEURISTIC_RECOVER_ROLLBACK 2
00055 extern uint32_t tc_heuristic_recover;
00056
00057 extern DRIZZLED_API struct drizzle_system_variables global_system_variables;
00058
00079 class Open_tables_state;
00080
00081 class DRIZZLED_API Session
00082 {
00083 private:
00084 class impl_c;
00085
00086 boost::scoped_ptr<impl_c> impl_;
00087 public:
00088 typedef boost::shared_ptr<Session> shared_ptr;
00089
00090 static shared_ptr make_shared(plugin::Client *client, boost::shared_ptr<catalog::Instance> instance_arg)
00091 {
00092 assert(instance_arg);
00093 return boost::make_shared<Session>(client, instance_arg);
00094 }
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107 enum_mark_columns mark_used_columns;
00108
00110 void free_items();
00111
00116 Item *free_list;
00117 memory::Root& mem;
00118 memory::Root* mem_root;
00120 uint64_t getXaId() const
00121 {
00122 return xa_id;
00123 }
00124
00125 void setXaId(uint64_t in_xa_id)
00126 {
00127 xa_id= in_xa_id;
00128 }
00129
00130 public:
00131 Diagnostics_area& main_da();
00132 const LEX& lex() const;
00133 LEX& lex();
00134 enum_sql_command getSqlCommand() const;
00135
00137 typedef boost::shared_ptr<const std::string> QueryString;
00138
00139 private:
00140 boost::shared_ptr<std::string> query;
00141
00142
00143
00144
00145 public:
00146 void resetQueryString();
00147 const boost::shared_ptr<session::State>& state();
00148
00149 QueryString getQueryString() const
00150 {
00151 return query;
00152 }
00153
00154 const char* getQueryStringCopy(size_t &length)
00155 {
00156 QueryString tmp_string(getQueryString());
00157 if (not tmp_string)
00158 {
00159 length= 0;
00160 return NULL;
00161 }
00162 length= tmp_string->length();
00163 return mem.strdup(*tmp_string);
00164 }
00165
00166 util::string::ptr schema() const;
00167
00174 static const char* const DEFAULT_WHERE;
00175
00176 memory::Root warn_root;
00177 public:
00178 void setClient(plugin::Client *client_arg);
00179
00180 plugin::Client *getClient() const
00181 {
00182 return client;
00183 }
00184
00185 plugin::Scheduler* scheduler;
00187 typedef boost::unordered_map<std::string, user_var_entry*, util::insensitive_hash, util::insensitive_equal_to> UserVars;
00188
00189 private:
00190 typedef std::pair< UserVars::iterator, UserVars::iterator > UserVarsRange;
00191 UserVars user_vars;
00193 public:
00194 const UserVars &getUserVariables() const
00195 {
00196 return user_vars;
00197 }
00198
00199 drizzle_system_variables& variables;
00200 enum_tx_isolation getTxIsolation() const;
00201 system_status_var& status_var;
00202
00203 THR_LOCK_INFO lock_info;
00204 THR_LOCK_OWNER main_lock_id;
00205 THR_LOCK_OWNER *lock_id;
00211 char *thread_stack;
00212
00213 identifier::user::ptr user() const
00214 {
00215 return security_ctx;
00216 }
00217
00218 void setUser(identifier::user::mptr arg)
00219 {
00220 security_ctx= arg;
00221 }
00222
00223 int32_t getScoreboardIndex() const
00224 {
00225 return scoreboard_index;
00226 }
00227
00228 void setScoreboardIndex(int32_t in_scoreboard_index)
00229 {
00230 scoreboard_index= in_scoreboard_index;
00231 }
00232
00233 bool isOriginatingServerUUIDSet() const
00234 {
00235 return originating_server_uuid_set;
00236 }
00237
00238 void setOriginatingServerUUID(std::string in_originating_server_uuid)
00239 {
00240 originating_server_uuid= in_originating_server_uuid;
00241 originating_server_uuid_set= true;
00242 }
00243
00244 const std::string &getOriginatingServerUUID() const
00245 {
00246 return originating_server_uuid;
00247 }
00248
00249 void setOriginatingCommitID(uint64_t in_originating_commit_id)
00250 {
00251 originating_commit_id= in_originating_commit_id;
00252 }
00253
00254 uint64_t getOriginatingCommitID() const
00255 {
00256 return originating_commit_id;
00257 }
00258
00262 bool isViewable(const identifier::User&) const;
00263
00264 private:
00270 const char *_where;
00271
00272 public:
00273 const char *where() const
00274 {
00275 return _where;
00276 }
00277
00278 void setWhere(const char *arg)
00279 {
00280 _where= arg;
00281 }
00282
00283
00284
00285
00286
00287
00288
00289 private:
00290 boost::thread::id boost_thread_id;
00291 thread_ptr _thread;
00292 boost::this_thread::disable_interruption *interrupt;
00293
00294 internal::st_my_thread_var *mysys_var;
00295
00296 public:
00297 thread_ptr &getThread()
00298 {
00299 return _thread;
00300 }
00301
00302 void pushInterrupt(boost::this_thread::disable_interruption *interrupt_arg)
00303 {
00304 interrupt= interrupt_arg;
00305 }
00306
00307 boost::this_thread::disable_interruption &getThreadInterupt()
00308 {
00309 assert(interrupt);
00310 return *interrupt;
00311 }
00312
00313 internal::st_my_thread_var *getThreadVar()
00314 {
00315 return mysys_var;
00316 }
00317
00322 enum_server_command command;
00323
00324 thr_lock_type update_lock_default;
00325
00326
00327
00328
00329
00330 private:
00331
00332 std::vector<Ha_data> ha_data;
00333
00334
00335
00336
00337
00338
00339
00340
00341 query_id_t query_id;
00342 query_id_t warn_query_id;
00343
00344 public:
00345 void **getEngineData(const plugin::MonitoredInTransaction *monitored);
00346 ResourceContext& getResourceContext(const plugin::MonitoredInTransaction&, size_t index= 0);
00347
00348 session::Transactions& transaction;
00349 Open_tables_state& open_tables;
00350 session::Times& times;
00351
00352 Field *dup_field;
00353 sigset_t signals;
00354
00355 public:
00356
00357 void setConcurrentExecute(bool arg)
00358 {
00359 concurrent_execute_allowed= arg;
00360 }
00361
00362 bool isConcurrentExecuteAllowed() const
00363 {
00364 return concurrent_execute_allowed;
00365 }
00366
00367
00368
00369
00370
00379 uint64_t first_successful_insert_id_in_prev_stmt;
00385 uint64_t first_successful_insert_id_in_cur_stmt;
00414 uint64_t limit_found_rows;
00415 uint64_t options;
00416 int64_t row_count_func;
00418 int64_t rowCount() const
00419 {
00420 return row_count_func;
00421 }
00422
00423 ha_rows cuted_fields;
00429 ha_rows sent_row_count;
00430
00434 ha_rows examined_row_count;
00435
00445 table_map used_tables;
00446
00455 uint32_t warn_count[(uint32_t) DRIZZLE_ERROR::WARN_LEVEL_END];
00456 uint32_t total_warn_count;
00457
00462 uint32_t row_count;
00463
00464 session_id_t thread_id;
00465 uint32_t tmp_table;
00466 enum global_read_lock_t
00467 {
00468 NONE= 0,
00469 GOT_GLOBAL_READ_LOCK= 1,
00470 MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT= 2
00471 };
00472 private:
00473 global_read_lock_t _global_read_lock;
00474
00475 public:
00476
00477 global_read_lock_t isGlobalReadLock() const
00478 {
00479 return _global_read_lock;
00480 }
00481
00482 void setGlobalReadLock(global_read_lock_t arg)
00483 {
00484 _global_read_lock= arg;
00485 }
00486
00487 DrizzleLock *lockTables(Table **tables, uint32_t count, uint32_t flags);
00488 bool lockGlobalReadLock();
00489 bool lock_table_names(TableList *table_list);
00490 bool lock_table_names_exclusively(TableList *table_list);
00491 bool makeGlobalReadLockBlockCommit();
00492 bool abortLockForThread(Table *table);
00493 bool wait_if_global_read_lock(bool abort_on_refresh, bool is_not_commit);
00494 int lock_table_name(TableList *table_list);
00495 void abortLock(Table *table);
00496 void removeLock(Table *table);
00497 void unlockReadTables(DrizzleLock *sql_lock);
00498 void unlockSomeTables(Table **table, uint32_t count);
00499 void unlockTables(DrizzleLock *sql_lock);
00500 void startWaitingGlobalReadLock();
00501 void unlockGlobalReadLock();
00502
00503 private:
00504 int unlock_external(Table **table, uint32_t count);
00505 int lock_external(Table **tables, uint32_t count);
00506 bool wait_for_locked_table_names(TableList *table_list);
00507 DrizzleLock *get_lock_data(Table **table_ptr, uint32_t count,
00508 bool should_lock, Table **write_lock_used);
00509 public:
00510
00511 uint32_t server_status;
00512 uint32_t open_options;
00513 uint32_t select_number;
00514
00515 enum_tx_isolation session_tx_isolation;
00516 enum_check_fields count_cuted_fields;
00517
00518 enum killed_state_t
00519 {
00520 NOT_KILLED,
00521 KILL_BAD_DATA,
00522 KILL_CONNECTION,
00523 KILL_QUERY,
00524 KILLED_NO_VALUE
00525 };
00526 private:
00527 killed_state_t volatile _killed;
00528
00529 public:
00530
00531 void setKilled(killed_state_t arg)
00532 {
00533 _killed= arg;
00534 }
00535
00536 killed_state_t getKilled() const
00537 {
00538 return _killed;
00539 }
00540
00541 volatile killed_state_t *getKilledPtr()
00542 {
00543 return &_killed;
00544 }
00545
00546 bool is_admin_connection;
00547 bool no_errors;
00555 bool is_fatal_error;
00561 bool transaction_rollback_request;
00573 bool is_fatal_sub_stmt_error;
00575 bool substitute_null_with_insert_id;
00576 bool cleanup_done;
00577
00578 public:
00579 bool got_warning;
00580 bool no_warnings_for_error;
00582 bool derived_tables_processing;
00583
00584 bool doing_tablespace_operation() const
00585 {
00586 return tablespace_op;
00587 }
00588
00589 void setDoingTablespaceOperation(bool doing)
00590 {
00591 tablespace_op= doing;
00592 }
00593
00594
00596 union
00597 {
00598 bool bool_value;
00599 uint32_t uint32_t_value;
00600 int32_t int32_t_value;
00601 uint64_t uint64_t_value;
00602 } sys_var_tmp;
00603
00611 Lex_input_stream *m_lip;
00612
00614 void *session_marker;
00615
00624 inline void set_proc_info(const char *info)
00625 {
00626 proc_info= info;
00627 }
00628 inline const char* get_proc_info() const
00629 {
00630 return proc_info;
00631 }
00632
00634 inline void setQueryId(query_id_t in_query_id)
00635 {
00636 query_id= in_query_id;
00637 }
00638
00640 query_id_t getQueryId() const
00641 {
00642 return query_id;
00643 }
00644
00645
00647 inline void setWarningQueryId(query_id_t in_query_id)
00648 {
00649 warn_query_id= in_query_id;
00650 }
00651
00653 inline query_id_t getWarningQueryId() const
00654 {
00655 return warn_query_id;
00656 }
00657
00659 inline session_id_t getSessionId() const
00660 {
00661 return thread_id;
00662 }
00663
00665 inline uint32_t getServerId() const
00666 {
00667
00668 return server_id;
00669 }
00670
00671 inline std::string &getServerUUID() const
00672 {
00673 return server_uuid;
00674 }
00675
00712 inline void record_first_successful_insert_id_in_cur_stmt(uint64_t id_arg)
00713 {
00714 if (first_successful_insert_id_in_cur_stmt == 0)
00715 first_successful_insert_id_in_cur_stmt= id_arg;
00716 }
00717 inline uint64_t read_first_successful_insert_id_in_prev_stmt() const
00718 {
00719 return first_successful_insert_id_in_prev_stmt;
00720 }
00721
00722 Session(plugin::Client*, boost::shared_ptr<catalog::Instance>);
00723 ~Session();
00724
00725 void cleanup();
00738 void cleanup_after_query();
00739 void storeGlobals();
00740 void awake(Session::killed_state_t state_to_set);
00741
00748 void prepareForQueries();
00749
00764 bool executeStatement();
00765
00782 void readAndStoreQuery(const char *in_packet, uint32_t in_packet_length);
00783
00792 bool endTransaction(enum enum_mysql_completiontype completion);
00793 bool endActiveTransaction();
00794 bool startTransaction(start_transaction_option_t opt= START_TRANS_NO_OPTIONS);
00795 void markTransactionForRollback(bool all);
00796
00802 bool authenticate();
00803 void run();
00804 static bool schedule(const Session::shared_ptr&);
00805 static void unlink(session_id_t&);
00806 static void unlink(const Session::shared_ptr&);
00807
00808
00809
00810
00811
00812
00813 const char* enter_cond(boost::condition_variable_any &cond, boost::mutex &mutex, const char* msg);
00814 void exit_cond(const char* old_msg);
00815
00816 uint64_t found_rows() const
00817 {
00818 return limit_found_rows;
00819 }
00820
00822 bool inTransaction() const
00823 {
00824 return server_status & SERVER_STATUS_IN_TRANS;
00825 }
00826
00827 lex_string_t* make_lex_string(lex_string_t*, str_ref);
00828
00829 void send_explain_fields(select_result*);
00830
00831 void clear_error(bool full= false);
00832 void clearDiagnostics();
00833 bool is_error() const;
00834
00835 static const charset_info_st *charset() { return default_charset_info; }
00836
00845 void end_statement();
00846 inline int killed_errno() const
00847 {
00848 killed_state_t killed_val;
00849 return (killed_val= _killed) != KILL_BAD_DATA ? killed_val : 0;
00850 }
00851 void send_kill_message() const;
00852
00853 inline bool abortOnWarning()
00854 {
00855 return abort_on_warning;
00856 }
00857
00858 inline void setAbortOnWarning(bool arg)
00859 {
00860 abort_on_warning= arg;
00861 }
00862
00863 void setAbort(bool arg);
00864 void lockOnSys();
00865 void set_status_var_init();
00883 void set_schema(const std::string&);
00884
00885
00886
00887
00888
00889
00890 str_ref copy_db_to() const;
00891
00892 public:
00893
00907 void reset_for_next_command();
00908
00917 void disconnect(enum error_t errcode= EE_OK);
00918
00931 bool checkUser(const std::string &passwd, const std::string &db);
00932
00938 message::Transaction *getTransactionMessage() const
00939 {
00940 return transaction_message;
00941 }
00942
00947 message::Statement *getStatementMessage() const
00948 {
00949 return statement_message;
00950 }
00951
00956 message::Resultset *getResultsetMessage() const
00957 {
00958 return resultset;
00959 }
00966 void setTransactionMessage(message::Transaction *in_message)
00967 {
00968 transaction_message= in_message;
00969 }
00970
00977 void setStatementMessage(message::Statement *in_message)
00978 {
00979 statement_message= in_message;
00980 }
00981
00988 void setResultsetMessage(message::Resultset *in_message)
00989 {
00990 resultset= in_message;
00991 }
00997 void resetResultsetMessage()
00998 {
00999 resultset= NULL;
01000 }
01001
01002 plugin::EventObserverList *getSessionObservers()
01003 {
01004 return session_event_observers;
01005 }
01006
01007 void setSessionObservers(plugin::EventObserverList *observers)
01008 {
01009 session_event_observers= observers;
01010 }
01011
01012 plugin::EventObserverList* getSchemaObservers(const std::string& schema);
01013 plugin::EventObserverList* setSchemaObservers(const std::string& schema, plugin::EventObserverList*);
01014
01015 public:
01016 void my_ok(ha_rows affected_rows= 0, ha_rows found_rows_arg= 0, uint64_t passed_id= 0, const char *message= NULL);
01017 void my_eof();
01018 void add_item_to_list(Item *item);
01019 void add_value_to_list(Item *value);
01020 void add_order_to_list(Item *item, bool asc);
01021 void add_group_to_list(Item *item, bool asc);
01022
01023 void refresh_status();
01024 user_var_entry* getVariable(str_ref name, bool create_if_not_exists);
01025 void setVariable(const std::string& name, const std::string& value);
01026
01031 void close_thread_tables();
01032 void close_old_data_files(bool morph_locks= false, bool send_refresh= false);
01033 void close_data_files_and_morph_locks(const identifier::Table&);
01034
01041 void close_tables_for_reopen(TableList **tables);
01042
01043
01058 bool openTablesLock(TableList*);
01059 Table *open_temporary_table(const identifier::Table &identifier, bool link_in_list= true);
01060
01061 int open_tables_from_list(TableList **start, uint32_t *counter, uint32_t flags= 0);
01062
01063 Table *openTableLock(TableList *table_list, thr_lock_type lock_type);
01064 Table *openTable(TableList *table_list, bool *refresh, uint32_t flags= 0);
01065
01066 void unlink_open_table(Table *find);
01067 void drop_open_table(Table *table, const identifier::Table &identifier);
01068 void close_cached_table(Table *table);
01069
01070
01071 table::Placeholder& table_cache_insert_placeholder(const identifier::Table&);
01072 Table* lock_table_name_if_not_cached(const identifier::Table&);
01073
01074 session::TableMessages &getMessageCache();
01075
01076
01077 bool reopen_tables();
01078 bool close_cached_tables(TableList *tables, bool wait_for_refresh, bool wait_for_placeholders);
01079
01080 void wait_for_condition(boost::mutex &mutex, boost::condition_variable_any &cond);
01081 int setup_conds(TableList *leaves, COND **conds);
01082 int lock_tables(TableList *tables, uint32_t count, bool *need_reopen);
01083
01084 template <class T>
01085 T* getProperty(const std::string& name)
01086 {
01087 return static_cast<T*>(getProperty0(name));
01088 }
01089
01090 template <class T>
01091 T setProperty(const std::string& name, T value)
01092 {
01093 setProperty0(name, value);
01094 return value;
01095 }
01096
01105 plugin::StorageEngine *getDefaultStorageEngine();
01106 void get_xid(DrizzleXid *xid) const;
01107
01108 table::Singular& getInstanceTable();
01109 table::Singular& getInstanceTable(std::list<CreateField>&);
01110
01111 void setUsage(bool arg)
01112 {
01113 use_usage= arg;
01114 }
01115
01116 const rusage &getUsage()
01117 {
01118 return usage;
01119 }
01120
01121 const catalog::Instance& catalog() const
01122 {
01123 return *_catalog;
01124 }
01125
01126 catalog::Instance& catalog()
01127 {
01128 return *_catalog;
01129 }
01130
01131 bool arg_of_last_insert_id_function;
01132 private:
01133 drizzled::util::Storable* getProperty0(const std::string&);
01134 void setProperty0(const std::string&, drizzled::util::Storable*);
01135
01136 bool resetUsage()
01137 {
01138 return not getrusage(RUSAGE_THREAD, &usage);
01139 }
01140
01141 boost::shared_ptr<catalog::Instance> _catalog;
01142
01144 message::Transaction *transaction_message;
01145 message::Statement *statement_message;
01146
01147 message::Resultset *resultset;
01148 plugin::EventObserverList *session_event_observers;
01149
01150 uint64_t xa_id;
01151 const char *proc_info;
01152 bool abort_on_warning;
01153 bool concurrent_execute_allowed;
01154 bool tablespace_op;
01155 bool use_usage;
01156 rusage usage;
01157 identifier::user::mptr security_ctx;
01158 int32_t scoreboard_index;
01159 bool originating_server_uuid_set;
01160 std::string originating_server_uuid;
01161 uint64_t originating_commit_id;
01162 plugin::Client *client;
01163 };
01164
01165 #define ESCAPE_CHARS "ntrb0ZN" // keep synchronous with READ_INFO::unescape
01166
01167
01168
01169 enum sql_command_flag_bits
01170 {
01171 CF_BIT_CHANGES_DATA,
01172 CF_BIT_HAS_ROW_COUNT,
01173 CF_BIT_STATUS_COMMAND,
01174 CF_BIT_SHOW_TABLE_COMMAND,
01175 CF_BIT_WRITE_LOGS_COMMAND,
01176 CF_BIT_SIZE
01177 };
01178
01179 static const std::bitset<CF_BIT_SIZE> CF_CHANGES_DATA(1 << CF_BIT_CHANGES_DATA);
01180 static const std::bitset<CF_BIT_SIZE> CF_HAS_ROW_COUNT(1 << CF_BIT_HAS_ROW_COUNT);
01181 static const std::bitset<CF_BIT_SIZE> CF_STATUS_COMMAND(1 << CF_BIT_STATUS_COMMAND);
01182 static const std::bitset<CF_BIT_SIZE> CF_SHOW_TABLE_COMMAND(1 << CF_BIT_SHOW_TABLE_COMMAND);
01183 static const std::bitset<CF_BIT_SIZE> CF_WRITE_LOGS_COMMAND(1 << CF_BIT_WRITE_LOGS_COMMAND);
01184
01185 namespace display
01186 {
01187 const std::string &type(Session::global_read_lock_t);
01188 size_t max_string_length(Session::global_read_lock_t);
01189 }
01190
01191 }
01192