#ifndef MYSQL_INCL_H #define MYSQL_INCL_H #ifndef HAVE_CONFIG_H #define HAVE_CONFIG_H #endif #define MYSQL_DYNAMIC_PLUGIN 1 #define MYSQL_SERVER 1 // Fix for VIO. We don't want to using method mapping as then a change in // the struct will cause the offsets compiled with to be wrong. // As is the case with ndb which uses a version of Vio with support for // ipv6 similar to 5.5 but different from 5.1 #define DONT_MAP_VIO #include #include // These two are not present in 5.7.9 #if MYSQL_VERSION_ID < 50709 #include #include #endif #include #if MYSQL_VERSION_ID >= 50600 // From 5.6 we use the audit plugin interface #include #endif #if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100307 // From MariaDB 10.3 we include macro definitions for items like MY_GNUC_PREREQ #include #include #endif #include #include #if !defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 80019 #include #include #include #endif #if !defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 80000 using my_bool = bool; #if MYSQL_VERSION_ID < 80012 #define PLUGIN_VAR_NOSYSVAR 0x0400 #endif #include #include #include #include #include #include #else #if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID < 100504 #include #endif typedef struct st_mysql_sys_var SYS_VAR; #endif #include #include #include #include #include // TODO: use mysql mutex instead of pthread /* #define pthread_mutex_lock mysql_mutex_lock #define pthread_mutex_unlock mysql_mutex_unlock #define pthread_mutex_init mysql_mutex_init #define pthread_mutex_destroy mysql_mutex_destroy #define pthread_mutex_t mysql_mutex_t */ #if MYSQL_VERSION_ID >= 50709 #include #if ! defined(MARIADB_BASE_VERSION) #include #include #endif #endif #include #include #include #include #include // 5.5 use my_free with a single param. 5.1 use with 2 params // based on: http://bazaar.launchpad.net/~mysql/myodbc/5.1/view/head:/util/stringutil.h #ifndef x_free # if MYSQL_VERSION_ID >= 50500 # define x_free(A) { void *tmp= (A); if (tmp) my_free((char *) tmp); } # else # define x_free(A) { void *tmp= (A); if (tmp) my_free((char *) tmp,MYF(0)); } # endif #endif #if defined(MARIADB_BASE_VERSION) // MariaDB has a kill service that overrides thd_killed as a macro. It also has thd_killed function defined for backwards compatibility, so we redefine it. #undef thd_killed extern "C" int thd_killed(const MYSQL_THD thd); // MariadDB 10.0.10 removed the include for thd_security_context #if MYSQL_VERSION_ID >= 100010 extern "C" char *thd_security_context(MYSQL_THD thd, char *buffer, unsigned int length, unsigned int max_query_len); #endif #endif //Define HAVE_SESS_CONNECT_ATTRS. We define it for mysql 5.6 and above and MariaDB 10.0 and above #if MYSQL_VERSION_ID >= 50600 #define HAVE_SESS_CONNECT_ATTRS 1 #endif #include #if defined(MARIADB_BASE_VERSION) || MYSQL_VERSION_ID < 80000 #include #endif namespace compat { /*************************/ /* my_getsystime */ /*************************/ #if defined(MARIADB_BASE_VERSION) // MariaDB doesn't have my_getsystime (returns 100 nano seconds) function. They replaced with my_hrtime_t my_hrtime() which returns microseconds static inline unsigned long long int my_getsystime() { return (my_hrtime()).val * 10; } #elif MYSQL_VERSION_ID < 80000 static inline unsigned long long int my_getsystime() { return ::my_getsystime(); } #else static inline unsigned long long int my_getsystime() { #ifdef HAVE_CLOCK_GETTIME // Performance regression testing showed this to be preferable struct timespec tp; clock_gettime(CLOCK_REALTIME, &tp); return (static_cast(tp.tv_sec) * 10000000 + static_cast(tp.tv_nsec) / 100); #else return std::chrono::duration_cast< std::chrono::duration>>( UTC_clock::now().time_since_epoch()) .count(); #endif /* HAVE_CLOCK_GETTIME */ } #endif /*********************************************/ /* vio_socket_connect */ /*********************************************/ #if MYSQL_VERSION_ID >= 50600 #ifndef MYSQL_VIO #define MYSQL_VIO Vio* #endif #if defined(MARIADB_BASE_VERSION) || MYSQL_VERSION_ID < 80000 static inline bool vio_socket_connect(MYSQL_VIO vio, struct sockaddr *addr, socklen_t len, int timeout) { return ::vio_socket_connect(vio, addr, len, timeout); } #else /*********************************************/ /* */ /* resolve the symbols manually to permit */ /* loading of the plugin in their absence */ /* */ /*********************************************/ extern bool (*_vio_socket_connect)(MYSQL_VIO vio, struct sockaddr *addr, socklen_t len, int timeout); extern bool (*_vio_socket_connect_80016)(MYSQL_VIO vio, struct sockaddr *addr, socklen_t len, bool nonblocking, int timeout); extern bool (*_vio_socket_connect_80020)(MYSQL_VIO vio, struct sockaddr *addr, socklen_t len, bool nonblocking, int timeout, bool *connect_done); static inline bool vio_socket_connect(MYSQL_VIO vio, struct sockaddr *addr, socklen_t len, int timeout) { if (_vio_socket_connect) return _vio_socket_connect(vio, addr, len, timeout); if (_vio_socket_connect_80016) return _vio_socket_connect_80016(vio, addr, len, false, timeout); if (_vio_socket_connect_80020) return _vio_socket_connect_80020(vio, addr, len, false, timeout, nullptr); return true; } static inline bool init_vio_socket_connect() { void* handle = dlopen(NULL, RTLD_LAZY); if (!handle) return false; _vio_socket_connect = (decltype(_vio_socket_connect))dlsym(handle, "_Z18vio_socket_connectP3VioP8sockaddrji"); _vio_socket_connect_80016 = (decltype(_vio_socket_connect_80016))dlsym(handle, "_Z18vio_socket_connectP3VioP8sockaddrjbi"); _vio_socket_connect_80020 = (decltype(_vio_socket_connect_80020))dlsym(handle, "_Z18vio_socket_connectP3VioP8sockaddrjbiPb"); dlclose(handle); return _vio_socket_connect || _vio_socket_connect_80016 || _vio_socket_connect_80020; } extern const std::string & (*_str_session_80026)(int cmd); extern const LEX_STRING *_command_name; static inline const char* str_session(int cmd) { if (_str_session_80026) return _str_session_80026(cmd).c_str(); if (_command_name) return _command_name[cmd].str; return ""; } static inline bool init_str_session() { void* handle = dlopen(NULL, RTLD_LAZY); if (!handle) return false; _command_name = (decltype(_command_name))dlsym(handle, "command_name"); _str_session_80026 = (decltype(_str_session_80026))dlsym(handle, "_ZN13Command_names11str_sessionE19enum_server_command"); dlclose(handle); return _command_name || _str_session_80026; } #endif #endif /*********************************************/ /* PFS_thread::get_current_thread */ /*********************************************/ #if defined(HAVE_SESS_CONNECT_ATTRS) && defined(MARIADB_BASE_VERSION) typedef const ::PFS_thread* (*pfs_thread_t)(); extern pfs_thread_t _pfs_thread_get_current_thread; extern PSI_v1* _psi_interface; namespace PFS_thread { static inline const ::PFS_thread* get_current_thread() { // Try PFS_thread and PSI_hook when MariaDB if (_pfs_thread_get_current_thread) return _pfs_thread_get_current_thread(); if (_psi_interface) return (::PFS_thread*)_psi_interface->get_thread(); return NULL; } } static inline bool init_PFS_thread_get_current_thread() { // obtain the PFS_thread::get_current_thread() address if it is exported void* handle = dlopen(NULL, RTLD_LAZY); if (handle) { _pfs_thread_get_current_thread = (pfs_thread_t)dlsym(handle, "_ZN10PFS_thread18get_current_threadEv"); dlclose(handle); } // obtain the PSI interface address if (PSI_hook) _psi_interface = (PSI_v1*)PSI_hook->get_interface(PSI_VERSION_1); if (!_pfs_thread_get_current_thread && !_psi_interface) sql_print_information("Failed to initialize Performance Schema. 'osuser' and 'appname' will not be avalilable."); return true; } #elif defined(HAVE_SESS_CONNECT_ATTRS) namespace PFS_thread { static inline const ::PFS_thread* get_current_thread() { // Use PFS_thread when MySQL return ::PFS_thread::get_current_thread(); } } #endif static inline bool init() { #if !defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 80000 return init_vio_socket_connect() && init_str_session(); #elif defined(HAVE_SESS_CONNECT_ATTRS) && defined(MARIADB_BASE_VERSION) return init_PFS_thread_get_current_thread(); #else return true; #endif } } #endif // MYSQL_INCL_H