/** * @file MySQL_Session.h * @brief Declaration of the MySQL_Session class and associated types and enums. */ #ifdef CLASS_BASE_SESSION_H #ifndef __CLASS_MYSQL_SESSION_H #define __CLASS_MYSQL_SESSION_H #include #include #include "proxysql.h" #include "cpp.h" #include "MySQL_Variables.h" #include "Base_Session.h" #ifndef PROXYJSON #define PROXYJSON #include "../deps/json/json_fwd.hpp" #endif // PROXYJSON extern class MySQL_Variables mysql_variables; /** * @enum proxysql_session_type * @brief Defines the types of ProxySQL sessions. */ /* enum proxysql_session_type { PROXYSQL_SESSION_MYSQL, PROXYSQL_SESSION_ADMIN, PROXYSQL_SESSION_STATS, PROXYSQL_SESSION_SQLITE, PROXYSQL_SESSION_CLICKHOUSE, PROXYSQL_SESSION_MYSQL_EMU, PROXYSQL_SESSION_NONE }; */ /** * @enum ps_type * @brief Defines types for prepared statement handling. */ enum ps_type : uint8_t { ps_type_not_set = 0x0, ps_type_prepare_stmt = 0x1, ps_type_execute_stmt = 0x2 }; /** * @enum SelectVersionForwardingMode * @brief Defines modes for handling SELECT VERSION() queries in ProxySQL. * * These modes control how ProxySQL responds to SELECT VERSION() queries: * - NEVER: Always return ProxySQL's own version * - ALWAYS: Always proxy the query to a backend server * - SMART_FALLBACK_INTERNAL: Try to get version from backend connection, fallback to ProxySQL version * - SMART_FALLBACK_PROXY: Try to get version from backend connection, fallback to proxying the query */ enum SelectVersionForwardingMode : uint8_t { SELECT_VERSION_NEVER = 0, SELECT_VERSION_ALWAYS = 1, SELECT_VERSION_SMART_FALLBACK_INTERNAL = 2, SELECT_VERSION_SMART_FALLBACK_PROXY = 3 }; //std::string proxysql_session_type_str(enum proxysql_session_type session_type); /** * @class Query_Info * @brief Holds information about a SQL query within a session. * * This class encapsulates various details about a query such as its text, * execution times, affected rows, and more, to facilitate query processing and logging. */ class Query_Info { public: SQP_par_t QueryParserArgs; MySQL_Session *sess; unsigned char *QueryPointer; unsigned long long start_time; unsigned long long end_time; MYSQL_STMT *mysql_stmt; stmt_execute_metadata_t *stmt_meta; uint64_t stmt_global_id; uint64_t stmt_client_id; MySQL_STMT_Global_info *stmt_info; int QueryLength; enum MYSQL_COM_QUERY_command MyComQueryCmd; bool bool_is_select_NOT_for_update; bool bool_is_select_NOT_for_update_computed; bool have_affected_rows; // if affected rows is set, last_insert_id is set too uint64_t affected_rows; uint64_t last_insert_id; uint64_t rows_sent; uint64_t waiting_since; std::string show_warnings_prev_query_digest; Query_Info(); ~Query_Info(); void init(unsigned char *_p, int len, bool mysql_header=false); void query_parser_init(); enum MYSQL_COM_QUERY_command query_parser_command_type(); void query_parser_free(); unsigned long long query_parser_update_counters(); void begin(unsigned char *_p, int len, bool mysql_header=false); void end(); char *get_digest_text(); bool is_select_NOT_for_update(); void set_end_time(unsigned long long time); }; /** * @brief Assigns query end time. * @details In addition to being a setter for end_time member variable, this * method ensures that end_time is always greater than or equal to start_time. * Refer https://github.com/sysown/proxysql/issues/4950 for more details. * @param time query end time */ inline void Query_Info::set_end_time(unsigned long long time) { end_time = time; #ifndef CLOCK_MONOTONIC_RAW if (start_time <= end_time) return; // If start_time is greater than end_time, assign current monotonic time end_time = monotonic_time(); if (start_time <= end_time) return; // If start_time is still greater than end_time, set the difference to 0 end_time = start_time; #endif // CLOCK_MONOTONIC_RAW } /** * @class MySQL_Session * @brief Manages a client session, including query parsing, backend connections, and state transitions. * * This class is central to ProxySQL's handling of client connections. It manages the lifecycle * of a session, processes queries, and communicates with backend MySQL servers. */ class MySQL_Session: public Base_Session { private: //int handler_ret; void handler___status_CONNECTING_CLIENT___STATE_SERVER_HANDSHAKE(PtrSize_t *, bool *); void handler___status_CONNECTING_CLIENT___STATE_SERVER_HANDSHAKE_WrongCredentials(PtrSize_t *, bool *); // void handler___status_CHANGING_USER_CLIENT___STATE_CLIENT_HANDSHAKE(PtrSize_t *, bool *); void handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_COM_FIELD_LIST(PtrSize_t *); void handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_COM_INIT_DB(PtrSize_t *); /** * @brief Handles 'COM_QUERIES' holding 'USE DB' statements. * * @param pkt The packet being processed. * @param query_digest The query digest returned by the 'QueryProcessor' * holding the 'USE' statement without the initial comment. * * @details NOTE: This function used to be called from 'handler_special_queries'. * But since it was change for handling 'USE' statements which are preceded by * comments, it's called after 'QueryProcessor' has processed the query. */ void handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_COM_QUERY_USE_DB(PtrSize_t *pkt); void handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_COM_PING(PtrSize_t *); void handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_COM_REFRESH(PtrSize_t *pkt); void handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_COM_CHANGE_USER(PtrSize_t *, bool *); /** * @brief Handles the command 'COM_RESET_CONNECTION'. * @param pkt Pointer to packet received holding the 'COM_RESET_CONNECTION'. * @details 'COM_RESET_CONNECTION' command is currently supported only for 'sesssion_types': * - 'PROXYSQL_SESSION_MYSQL'. * - 'PROXYSQL_SESSION_SQLITE'. * If the command is received for other sessions, the an error packet with error '1047' is sent to the * client. If the session is supported, it performs the following operations over the current session: * 1. Store the current relevent session variables to be recovered after the 'RESET'. * 2. Perform a reset and initialization of current session. * 3. Recover the relevant session variables and other initial state associated with the current session * user. * 4. Respond to client with 'OK' packet. */ void handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_COM_RESET_CONNECTION(PtrSize_t *pkt); void handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_COM_SET_OPTION(PtrSize_t *); void handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_COM_STATISTICS(PtrSize_t *); void handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_COM_PROCESS_KILL(PtrSize_t *); bool handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_COM_QUERY_qpo(PtrSize_t *, bool *lock_hostgroup, ps_type prepare_stmt_type=ps_type_not_set); void handler___client_DSS_QUERY_SENT___server_DSS_NOT_INITIALIZED__get_connection(); //void return_proxysql_internal(PtrSize_t *); bool handler_special_queries(PtrSize_t *); //bool handler_special_queries_STATUS(PtrSize_t *); /** * @brief Handles 'COMMIT|ROLLBACK' commands. * @details Forwarding the packet is required when there are active transactions. Since we are limited to * forwarding just one 'COMMIT|ROLLBACK', we work under the assumption that we only have one active * transaction. If more transactions are simultaneously open for the session, more 'COMMIT|ROLLBACK'. * commands are required to be issued by the client, so they could be forwarded to the corresponding * backend connections. * @param The received packet to be handled. * @return 'true' if the packet is intercepted and never forwarded to the client, 'false' otherwise. */ bool handler_CommitRollback(PtrSize_t *); bool handler_SetAutocommit(PtrSize_t *); /** * @brief Should execute most of the commands executed when a request is finalized. * @details Cleanup of current session state, and required operations to the supplied 'MySQL_Data_Stream' * for further queries processing. Takes care of the following actions: * - Update the status of the backend connection (if supplied), with previous query actions. * - Log the query for the required statuses. * - Cleanup the previous Query_Processor output. * - Free the resources of the backend connection (if supplied). * - Reset all the required session status flags. E.g: * + status * + client_myds::DSS * + started_sending_data_to_client * + previous_hostgroup * NOTE: Should become the place to hook other functions. * @param myds If not null, should point to a MySQL_Data_Stream (backend connection) which connection status * should be updated, and previous query resources cleanup. */ void RequestEnd(MySQL_Data_Stream * myds, const unsigned int myerrno = 0, const char * errmsg = nullptr); void LogQuery(MySQL_Data_Stream * myds, const unsigned int myerrno = 0, const char * errmsg = nullptr); void handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_COM_QUERY___create_mirror_session(); int handler_again___status_PINGING_SERVER(); int handler_again___status_RESETTING_CONNECTION(); bool handler_again___status_SHOW_WARNINGS(MySQL_Data_Stream *, bool); void handler_again___new_thread_to_kill_connection(); void handler_KillConnectionIfNeeded(); bool handler_again___verify_init_connect(); bool handler_again___verify_ldap_user_variable(); bool handler_again___verify_backend_autocommit(); bool handler_again___verify_backend_session_track_gtids(); bool handler_again___verify_backend_multi_statement(); bool handler_again___verify_backend_user_schema(); bool handler_again___verify_multiple_variables(MySQL_Connection *); bool handler_again___status_SETTING_INIT_CONNECT(int *); bool handler_again___status_SETTING_LDAP_USER_VARIABLE(int *); bool handler_again___status_SETTING_SQL_MODE(int *); bool handler_again___status_SETTING_SESSION_TRACK_GTIDS(int *); bool handler_again___status_CHANGING_CHARSET(int *_rc); bool handler_again___status_CHANGING_SCHEMA(int *); bool handler_again___status_CONNECTING_SERVER(int *); bool handler_again___status_CHANGING_USER_SERVER(int *); bool handler_again___status_CHANGING_AUTOCOMMIT(int *); bool handler_again___status_SETTING_MULTI_STMT(int *_rc); bool handler_again___multiple_statuses(int *rc); //void init(); void reset(); void add_ldap_comment_to_pkt(PtrSize_t *); #if 0 /** * @brief Performs the required housekeeping operations over the session and its connections before * performing any processing on received client packets. */ void housekeeping_before_pkts(); #endif // 0 int get_pkts_from_client(bool&, PtrSize_t&); // GPFC_ functions are subfunctions of get_pkts_from_client() int GPFC_Statuses2(bool&, PtrSize_t&); void GPFC_DetectedMultiPacket_SetDDS(); int GPFC_WaitingClientData_FastForwardSession(PtrSize_t&); void GPFC_PreparedStatements(PtrSize_t&, unsigned char); int GPFC_Replication_SwitchToFastForward(PtrSize_t&, unsigned char); bool GPFC_QueryUSE(PtrSize_t&, int&); void handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_COM_STMT_RESET(PtrSize_t&); void handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_COM_STMT_CLOSE(PtrSize_t&); void handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_COM_STMT_SEND_LONG_DATA(PtrSize_t&); void handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_COM_STMT_PREPARE(PtrSize_t& pkt); void handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_COM_STMT_EXECUTE(PtrSize_t& pkt); // these functions have code that used to be inline, and split into functions for readibility int handler_ProcessingQueryError_CheckBackendConnectionStatus(MySQL_Data_Stream *myds); void SetQueryTimeout(); bool handler_rc0_PROCESSING_STMT_PREPARE(enum session_status& st, MySQL_Data_Stream *myds, bool& prepared_stmt_with_no_params); void handler_rc0_PROCESSING_STMT_EXECUTE(MySQL_Data_Stream *myds); bool handler_minus1_ClientLibraryError(MySQL_Data_Stream *myds, int myerr, char **errmsg); void handler_minus1_LogErrorDuringQuery(MySQL_Connection *myconn, int myerr, char *errmsg); bool handler_minus1_HandleErrorCodes(MySQL_Data_Stream *myds, int myerr, char **errmsg, int& handler_ret); void handler_minus1_GenerateErrorMessage(MySQL_Data_Stream *myds, MySQL_Connection *myconn, bool& wrong_pass); void handler_minus1_HandleBackendConnection(MySQL_Data_Stream *myds, MySQL_Connection *myconn); int RunQuery(MySQL_Data_Stream *myds, MySQL_Connection *myconn); void handler___status_WAITING_CLIENT_DATA(); void handler_rc0_Process_GTID(MySQL_Connection *myconn); void handler_rc0_RefreshActiveTransactions(MySQL_Connection* myconn); void handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_COM_INIT_DB_replace_CLICKHOUSE(PtrSize_t& pkt); void handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_COM_QUERY___not_mysql(PtrSize_t& pkt); void handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_COM_QUERY___genai(const char* query, size_t query_len, PtrSize_t* pkt); void handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_COM_QUERY___llm(const char* query, size_t query_len, PtrSize_t* pkt); #ifdef epoll_create1 /** * @brief Handle GenAI response from socketpair * * Called when epoll notifies that a GenAI response is available on a client fd. * Reads the GenAI_ResponseHeader and JSON result, then sends the resultset * to the MySQL client. * * @param fd The socketpair fd (MySQL side) with data available to read * * @see handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___genai_send_async() * @see check_genai_events() */ void handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___handle_genai_response(int fd); /** * @brief Send GenAI request asynchronously via socketpair * * Creates a socketpair for async communication with the GenAI module: * 1. Creates socketpair(fds) * 2. Registers fds[1] with GenAI module * 3. Sends GenAI_RequestHeader + JSON query via fds[0] * 4. Adds fds[0] to session's epoll for response notification * 5. Returns immediately (MySQL thread is free to process other queries) * * The response will be handled by handle_genai_response() when ready. * * @param query The JSON query string (after "GENAI:" prefix) * @param query_len Length of the query string * @param pkt Original packet (stored for later cleanup) * @return true if request was sent successfully, false on error * * @see handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___handle_genai_response() */ bool handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___genai_send_async(const char* query, size_t query_len, PtrSize_t* pkt); /** * @brief Cleanup a GenAI pending request * * Removes the request from the pending map, closes the socketpair fd, * removes from epoll, and frees the original packet. Called after * the response is processed or on error. * * @param request_id The request ID to clean up * * @see handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___genai_send_async() */ void genai_cleanup_request(uint64_t request_id); /** * @brief Check for pending GenAI responses * * Performs a non-blocking epoll_wait on the session's GenAI epoll fd * to check if any responses are ready. If a response is found, it's * processed immediately by calling handle_genai_response(). * * This is called from the main handler() loop in the WAITING_CLIENT_DATA * case to ensure GenAI responses are processed promptly even when * there's no new client data. * * @return true if a response was processed, false if no responses were ready * * @see handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___handle_genai_response() */ bool check_genai_events(); #endif bool handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_COM_QUERY_detect_SQLi(); bool handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_COM_QUERY_detect_ai_anomaly(); bool handler___status_WAITING_CLIENT_DATA___STATE_SLEEP_MULTI_PACKET(PtrSize_t& pkt); bool handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_COM__various(PtrSize_t* pkt, bool* wrong_pass); void handler___status_WAITING_CLIENT_DATA___default(); void handler___status_NONE_or_default(PtrSize_t& pkt); void handler_WCD_SS_MCQ_qpo_QueryRewrite(PtrSize_t *pkt); void handler_WCD_SS_MCQ_qpo_OK_msg(PtrSize_t *pkt); void handler_WCD_SS_MCQ_qpo_error_msg(PtrSize_t *pkt); void handler_WCD_SS_MCQ_qpo_LargePacket(PtrSize_t *pkt); public: bool handler_again___status_SETTING_GENERIC_VARIABLE(int *_rc, const char *var_name, const char *var_value, bool no_quote=false, bool set_transaction=false); bool handler_again___status_SETTING_SQL_LOG_BIN(int *); std::stack previous_status; Query_Info CurrentQuery; PtrSize_t mirrorPkt; PtrSize_t pkt; #if 0 // uint64_t unsigned long long start_time; unsigned long long pause_until; unsigned long long idle_since; unsigned long long transaction_started_at; // pointers MySQL_Thread *thread; #endif // 0 MySQL_Query_Processor_Output *qpo; StatCounters *command_counters; #if 0 MySQL_Backend *mybe; PtrArray *mybes; MySQL_Data_Stream *client_myds; #endif // 0 MySQL_Data_Stream *server_myds; #if 0 /* * @brief Store the hostgroups that hold connections that have been flagged as 'expired' by the * maintenance thread. These values will be used to release the retained connections in the specific * hostgroups in housekeeping operations, before client packet processing. Currently 'housekeeping_before_pkts'. */ std::vector hgs_expired_conns {}; char * default_schema; char * user_attributes; //this pointer is always initialized inside handler(). // it is an attempt to start simplifying the complexing of handler() uint32_t thread_session_id; unsigned long long last_insert_id; int last_HG_affected_rows; enum session_status status; int healthy; int user_max_connections; int current_hostgroup; int default_hostgroup; int previous_hostgroup; /** * @brief Charset directly specified by the client. Supplied and updated via 'HandshakeResponse' * and 'COM_CHANGE_USER' packets. * @details Used when session needs to be restored via 'COM_RESET_CONNECTION'. */ int default_charset; int locked_on_hostgroup; int next_query_flagIN; int mirror_hostgroup; int mirror_flagOUT; unsigned int active_transactions; int transaction_persistent_hostgroup; int to_process; enum proxysql_session_type session_type; // bool bool autocommit; bool autocommit_handled; bool sending_set_autocommit; bool killed; bool locked_on_hostgroup_and_all_variables_set; //bool admin; bool max_connections_reached; bool client_authenticated; bool connections_handler; bool mirror; //bool stats; bool schema_locked; bool transaction_persistent; bool session_fast_forward; //bool started_sending_data_to_client; // this status variable tracks if some result set was sent to the client, or if proxysql is still buffering everything bool use_ssl; #endif // 0 int warning_in_hg; int autocommit_on_hostgroup; /** * @brief This status variable tracks whether the session is performing an * 'Auth Switch' due to a 'COM_CHANGE_USER' packet. * @details It becomes 'true' when the packet is detected and processed by: * - 'MySQL_Protocol::process_pkt_COM_CHANGE_USER' * It's reset before sending the final response for 'Auth Switch' to the client by: * - 'MySQL_Session::handler___status_CONNECTING_CLIENT___STATE_SERVER_HANDSHAKE' * This flag was introduced for issue #3504. */ bool change_user_auth_switch; bool with_gtid; char gtid_buf[128]; //uint64_t gtid_trxid; int gtid_hid; MySQL_STMTs_meta *sess_STMTs_meta; StmtLongDataHandler *SLDH; Session_Regex **match_regexes; ProxySQL_Node_Address * proxysql_node_address; // this is used ONLY for Admin, and only if the other party is another proxysql instance part of a cluster bool use_ldap_auth; // Fast forward grace close flags: track backend closure during fast forward mode // to allow pending client data to drain before closing the session. bool backend_closed_in_fast_forward; unsigned long long fast_forward_grace_start_time; // this variable is relevant only if status == SETTING_VARIABLE enum mysql_variable_name changing_variable_idx; MySQL_Session(); ~MySQL_Session(); //void set_unhealthy(); void set_status(enum session_status e); int handler(); void (*handler_function) (MySQL_Session* sess, void *, PtrSize_t *pkt); //MySQL_Backend * find_backend(int); //MySQL_Backend * create_backend(int, MySQL_Data_Stream *_myds=NULL); //MySQL_Backend * find_or_create_backend(int, MySQL_Data_Stream *_myds=NULL); void SQLite3_to_MySQL(SQLite3_result *, char *, int , MySQL_Protocol *, bool in_transaction=false, bool deprecate_eof_active=false) override; void MySQL_Result_to_MySQL_wire(MYSQL *mysql, MySQL_ResultSet *MyRS, unsigned int warning_count, MySQL_Data_Stream *_myds=NULL); void MySQL_Stmt_Result_to_MySQL_wire(MYSQL_STMT *stmt, MySQL_Connection *myconn); //unsigned int NumActiveTransactions(bool check_savpoint=false); //bool HasOfflineBackends(); //bool SetEventInOfflineBackends(); /** * @brief Finds one active transaction in the current backend connections. * @details Since only one connection is returned, if the session holds multiple backend connections with * potential transactions, the priority is: * 1. Connections flagged with 'SERVER_STATUS_IN_TRANS', or 'autocommit=0' in combination with * 'autocommit_false_is_transaction'. * 2. Connections with 'autocommit=0' holding a 'SAVEPOINT'. * 3. Connections with 'unknown transaction status', e.g: connections with errors. * @param check_savepoint Used to also check for connections holding savepoints. See MySQL bug * https://bugs.mysql.com/bug.php?id=107875. * @returns The hostgroup in which the connection was found, -1 in case no connection is found. */ //int FindOneActiveTransaction(bool check_savepoint=false); unsigned long long IdleTime(); //void reset_all_backends(); //void writeout(); void Memory_Stats(); void create_new_session_and_reset_connection(MySQL_Data_Stream *_myds) override; bool handle_command_query_kill(PtrSize_t *); //void update_expired_conns(const std::vector>&); /** * @brief Performs the final operations after current query has finished to be executed. It updates the session * 'transaction_persistent_hostgroup', and updates the 'MySQL_Data_Stream' and 'MySQL_Connection' before * returning the connection back to the connection pool. After this operation the session should be ready * for handling new client connections. * * @param myds The 'MySQL_Data_Stream' which status should be updated. * @param myconn The 'MySQL_Connection' which status should be updated, and which should be returned to * the connection pool. * @param prepared_stmt_with_no_params specifies if the processed query was a prepared statement with no * params. */ void finishQuery(MySQL_Data_Stream *myds, MySQL_Connection *myconn, bool); void generate_proxysql_internal_session_json(nlohmann::json &) override; bool known_query_for_locked_on_hostgroup(uint64_t); void unable_to_parse_set_statement(bool *); //bool has_any_backend(); void detected_broken_connection(const char *file, unsigned int line, const char *func, const char *action, MySQL_Connection *myconn, int myerr, const char *message, bool verbose=false); void generate_status_one_hostgroup(int hid, std::string& s); void reset_warning_hostgroup_flag_and_release_connection(); void set_previous_status_mode3(bool allow_execute=true); char* get_current_query(int max_length = -1); /** * @brief Attempts to get the server version string from a backend connection in the specified hostgroup. * @details This function iterates through servers in the hostgroup and checks for any available * free connections to extract the server version string. It does NOT remove the connection * from the pool - it only peeks at the version information. * * @param hostgroup_id The hostgroup ID to search for backend connections. * @return Pointer to the server version string if found, NULL otherwise. * Note: The returned pointer points to the connection's internal data and should * not be freed or modified. The pointer is only valid while the connection exists. */ char * get_backend_version_for_hostgroup(int hostgroup_id); friend void SQLite3_Server_session_handler(MySQL_Session*, void *_pa, PtrSize_t *pkt); #if defined(__clang__) template friend class Base_Session; #else friend class Base_Session; #endif }; #define KILL_QUERY 1 #define KILL_CONNECTION 2 class KillArgs { public: MySQL_Thread *mt; char *username; char *password; char *hostname; unsigned int port; unsigned long id; int kill_type; unsigned int hid; int use_ssl; KillArgs(char* u, char* p, char* h, unsigned int P, unsigned int _hid, unsigned long i, int kt, int _use_ssl, MySQL_Thread* _mt); KillArgs(char *u, char *p, char *h, unsigned int P, unsigned int _hid, unsigned long i, int kt, int _use_ssl, MySQL_Thread* _mt, char *ip); ~KillArgs(); const char* get_host_address() const; private: char* ip_addr; }; void * kill_query_thread(void *arg); #endif /* __CLASS_MYSQL_SESSION_ H */ #endif // CLASS_BASE_SESSION_H