summaryrefslogtreecommitdiffstats
path: root/include/mysql
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-04 18:07:14 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-04 18:07:14 +0000
commita175314c3e5827eb193872241446f2f8f5c9d33c (patch)
treecd3d60ca99ae00829c52a6ca79150a5b6e62528b /include/mysql
parentInitial commit. (diff)
downloadmariadb-10.5-a175314c3e5827eb193872241446f2f8f5c9d33c.tar.xz
mariadb-10.5-a175314c3e5827eb193872241446f2f8f5c9d33c.zip
Adding upstream version 1:10.5.12.upstream/1%10.5.12upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'include/mysql')
-rw-r--r--include/mysql/auth_dialog_client.h56
-rw-r--r--include/mysql/client_plugin.h188
-rw-r--r--include/mysql/client_plugin.h.pp41
-rw-r--r--include/mysql/plugin.h778
-rw-r--r--include/mysql/plugin_audit.h180
-rw-r--r--include/mysql/plugin_audit.h.pp687
-rw-r--r--include/mysql/plugin_auth.h182
-rw-r--r--include/mysql/plugin_auth.h.pp664
-rw-r--r--include/mysql/plugin_auth_common.h131
-rw-r--r--include/mysql/plugin_data_type.h49
-rw-r--r--include/mysql/plugin_data_type.h.pp629
-rw-r--r--include/mysql/plugin_encryption.h126
-rw-r--r--include/mysql/plugin_encryption.h.pp642
-rw-r--r--include/mysql/plugin_ftparser.h222
-rw-r--r--include/mysql/plugin_ftparser.h.pp624
-rw-r--r--include/mysql/plugin_function.h54
-rw-r--r--include/mysql/plugin_function.h.pp638
-rw-r--r--include/mysql/plugin_password_validation.h54
-rw-r--r--include/mysql/plugin_password_validation.h.pp632
-rw-r--r--include/mysql/psi/mysql_file.h1454
-rw-r--r--include/mysql/psi/mysql_idle.h104
-rw-r--r--include/mysql/psi/mysql_mdl.h143
-rw-r--r--include/mysql/psi/mysql_memory.h79
-rw-r--r--include/mysql/psi/mysql_ps.h108
-rw-r--r--include/mysql/psi/mysql_socket.h1295
-rw-r--r--include/mysql/psi/mysql_sp.h104
-rw-r--r--include/mysql/psi/mysql_stage.h205
-rw-r--r--include/mysql/psi/mysql_statement.h243
-rw-r--r--include/mysql/psi/mysql_table.h172
-rw-r--r--include/mysql/psi/mysql_thread.h1349
-rw-r--r--include/mysql/psi/mysql_transaction.h220
-rw-r--r--include/mysql/psi/psi.h3028
-rw-r--r--include/mysql/psi/psi_abi_v0.h31
-rw-r--r--include/mysql/psi/psi_abi_v0.h.pp100
-rw-r--r--include/mysql/psi/psi_abi_v1.h33
-rw-r--r--include/mysql/psi/psi_abi_v1.h.pp854
-rw-r--r--include/mysql/psi/psi_abi_v2.h33
-rw-r--r--include/mysql/psi/psi_abi_v2.h.pp279
-rw-r--r--include/mysql/psi/psi_base.h172
-rw-r--r--include/mysql/psi/psi_memory.h171
-rw-r--r--include/mysql/service_base64.h82
-rw-r--r--include/mysql/service_debug_sync.h361
-rw-r--r--include/mysql/service_encryption.h131
-rw-r--r--include/mysql/service_encryption_scheme.h133
-rw-r--r--include/mysql/service_json.h119
-rw-r--r--include/mysql/service_kill_statement.h71
-rw-r--r--include/mysql/service_logger.h105
-rw-r--r--include/mysql/service_md5.h69
-rw-r--r--include/mysql/service_my_crypt.h120
-rw-r--r--include/mysql/service_my_print_error.h64
-rw-r--r--include/mysql/service_my_snprintf.h110
-rw-r--r--include/mysql/service_progress_report.h82
-rw-r--r--include/mysql/service_sha1.h69
-rw-r--r--include/mysql/service_sha2.h130
-rw-r--r--include/mysql/service_thd_alloc.h139
-rw-r--r--include/mysql/service_thd_autoinc.h53
-rw-r--r--include/mysql/service_thd_error_context.h93
-rw-r--r--include/mysql/service_thd_mdl.h46
-rw-r--r--include/mysql/service_thd_rnd.h62
-rw-r--r--include/mysql/service_thd_specifics.h110
-rw-r--r--include/mysql/service_thd_timezone.h73
-rw-r--r--include/mysql/service_thd_wait.h104
-rw-r--r--include/mysql/service_wsrep.h242
-rw-r--r--include/mysql/services.h51
64 files changed, 19373 insertions, 0 deletions
diff --git a/include/mysql/auth_dialog_client.h b/include/mysql/auth_dialog_client.h
new file mode 100644
index 00000000..f1ad3e69
--- /dev/null
+++ b/include/mysql/auth_dialog_client.h
@@ -0,0 +1,56 @@
+#ifndef MYSQL_AUTH_DIALOG_CLIENT_INCLUDED
+/* Copyright (C) 2010 Sergei Golubchik and Monty Program Ab
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */
+
+/**
+ @file
+
+ Definitions needed to use Dialog client authentication plugin
+*/
+
+struct st_mysql;
+
+#define MYSQL_AUTH_DIALOG_CLIENT_INCLUDED
+
+/**
+ type of the mysql_authentication_dialog_ask function
+
+ @param mysql mysql
+ @param type type of the input
+ 1 - ordinary string input
+ 2 - password string
+ @param prompt prompt
+ @param buf a buffer to store the use input
+ @param buf_len the length of the buffer
+
+ @retval a pointer to the user input string.
+ It may be equal to 'buf' or to 'mysql->password'.
+ In all other cases it is assumed to be an allocated
+ string, and the "dialog" plugin will free() it.
+*/
+typedef char *(*mysql_authentication_dialog_ask_t)(struct st_mysql *mysql,
+ int type, const char *prompt, char *buf, int buf_len);
+
+/**
+ first byte of the question string is the question "type".
+ It can be an "ordinary" or a "password" question.
+ The last bit set marks a last question in the authentication exchange.
+*/
+#define ORDINARY_QUESTION "\2"
+#define LAST_QUESTION "\3"
+#define PASSWORD_QUESTION "\4"
+#define LAST_PASSWORD "\5"
+
+#endif
diff --git a/include/mysql/client_plugin.h b/include/mysql/client_plugin.h
new file mode 100644
index 00000000..990cecc9
--- /dev/null
+++ b/include/mysql/client_plugin.h
@@ -0,0 +1,188 @@
+#ifndef MYSQL_CLIENT_PLUGIN_INCLUDED
+/* Copyright (C) 2010 Sergei Golubchik and Monty Program Ab
+ Copyright (c) 2010, 2011, Oracle and/or its affiliates.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */
+
+/**
+ @file
+
+ MySQL Client Plugin API
+
+ This file defines the API for plugins that work on the client side
+*/
+#define MYSQL_CLIENT_PLUGIN_INCLUDED
+
+/*
+ On Windows, exports from DLL need to be declared
+ Also, plugin needs to be declared as extern "C" because MSVC
+ unlike other compilers, uses C++ mangling for variables not only
+ for functions.
+*/
+#undef MYSQL_PLUGIN_EXPORT
+#if defined(_MSC_VER)
+ #define MYSQL_PLUGIN_EXPORT_C __declspec(dllexport)
+#else /*_MSC_VER */
+ #define MYSQL_PLUGIN_EXPORT_C
+#endif
+#ifdef __cplusplus
+#define MYSQL_PLUGIN_EXPORT extern "C" MYSQL_PLUGIN_EXPORT_C
+#define C_MODE_START extern "C" {
+#define C_MODE_END }
+#else
+#define MYSQL_PLUGIN_EXPORT MYSQL_PLUGIN_EXPORT_C
+#define C_MODE_START
+#define C_MODE_END
+#endif
+
+#ifndef MYSQL_ABI_CHECK
+#include <stdarg.h>
+#include <stdlib.h>
+#endif
+
+/* known plugin types */
+#define MYSQL_CLIENT_reserved1 0
+#define MYSQL_CLIENT_reserved2 1
+#define MYSQL_CLIENT_AUTHENTICATION_PLUGIN 2
+
+#define MYSQL_CLIENT_AUTHENTICATION_PLUGIN_INTERFACE_VERSION 0x0100
+
+#define MYSQL_CLIENT_MAX_PLUGINS 3
+
+#define mysql_declare_client_plugin(X) \
+ C_MODE_START MYSQL_PLUGIN_EXPORT_C \
+ struct st_mysql_client_plugin_ ## X \
+ _mysql_client_plugin_declaration_ = { \
+ MYSQL_CLIENT_ ## X ## _PLUGIN, \
+ MYSQL_CLIENT_ ## X ## _PLUGIN_INTERFACE_VERSION,
+#define mysql_end_client_plugin }; C_MODE_END
+
+/* generic plugin header structure */
+#define MYSQL_CLIENT_PLUGIN_HEADER \
+ int type; \
+ unsigned int interface_version; \
+ const char *name; \
+ const char *author; \
+ const char *desc; \
+ unsigned int version[3]; \
+ const char *license; \
+ void *mysql_api; \
+ int (*init)(char *, size_t, int, va_list); \
+ int (*deinit)(); \
+ int (*options)(const char *option, const void *);
+
+struct st_mysql_client_plugin
+{
+ MYSQL_CLIENT_PLUGIN_HEADER
+};
+
+struct st_mysql;
+
+/******** authentication plugin specific declarations *********/
+#include <mysql/plugin_auth_common.h>
+
+struct st_mysql_client_plugin_AUTHENTICATION
+{
+ MYSQL_CLIENT_PLUGIN_HEADER
+ int (*authenticate_user)(MYSQL_PLUGIN_VIO *vio, struct st_mysql *mysql);
+};
+
+#include <mysql/auth_dialog_client.h>
+
+/******** using plugins ************/
+
+/**
+ loads a plugin and initializes it
+
+ @param mysql MYSQL structure.
+ @param name a name of the plugin to load
+ @param type type of plugin that should be loaded, -1 to disable type check
+ @param argc number of arguments to pass to the plugin initialization
+ function
+ @param ... arguments for the plugin initialization function
+
+ @retval
+ a pointer to the loaded plugin, or NULL in case of a failure
+*/
+struct st_mysql_client_plugin *
+mysql_load_plugin(struct st_mysql *mysql, const char *name, int type,
+ int argc, ...);
+
+/**
+ loads a plugin and initializes it, taking va_list as an argument
+
+ This is the same as mysql_load_plugin, but take va_list instead of
+ a list of arguments.
+
+ @param mysql MYSQL structure.
+ @param name a name of the plugin to load
+ @param type type of plugin that should be loaded, -1 to disable type check
+ @param argc number of arguments to pass to the plugin initialization
+ function
+ @param args arguments for the plugin initialization function
+
+ @retval
+ a pointer to the loaded plugin, or NULL in case of a failure
+*/
+struct st_mysql_client_plugin *
+mysql_load_plugin_v(struct st_mysql *mysql, const char *name, int type,
+ int argc, va_list args);
+
+/**
+ finds an already loaded plugin by name, or loads it, if necessary
+
+ @param mysql MYSQL structure.
+ @param name a name of the plugin to load
+ @param type type of plugin that should be loaded
+
+ @retval
+ a pointer to the plugin, or NULL in case of a failure
+*/
+struct st_mysql_client_plugin *
+mysql_client_find_plugin(struct st_mysql *mysql, const char *name, int type);
+
+/**
+ adds a plugin structure to the list of loaded plugins
+
+ This is useful if an application has the necessary functionality
+ (for example, a special load data handler) statically linked into
+ the application binary. It can use this function to register the plugin
+ directly, avoiding the need to factor it out into a shared object.
+
+ @param mysql MYSQL structure. It is only used for error reporting
+ @param plugin an st_mysql_client_plugin structure to register
+
+ @retval
+ a pointer to the plugin, or NULL in case of a failure
+*/
+struct st_mysql_client_plugin *
+mysql_client_register_plugin(struct st_mysql *mysql,
+ struct st_mysql_client_plugin *plugin);
+
+/**
+ set plugin options
+
+ Can be used to set extra options and affect behavior for a plugin.
+ This function may be called multiple times to set several options
+
+ @param plugin an st_mysql_client_plugin structure
+ @param option a string which specifies the option to set
+ @param value value for the option.
+
+ @retval 0 on success, 1 in case of failure
+**/
+int mysql_plugin_options(struct st_mysql_client_plugin *plugin,
+ const char *option, const void *value);
+#endif
+
diff --git a/include/mysql/client_plugin.h.pp b/include/mysql/client_plugin.h.pp
new file mode 100644
index 00000000..b6ba9cf0
--- /dev/null
+++ b/include/mysql/client_plugin.h.pp
@@ -0,0 +1,41 @@
+struct st_mysql_client_plugin
+{
+ int type; unsigned int interface_version; const char *name; const char *author; const char *desc; unsigned int version[3]; const char *license; void *mysql_api; int (*init)(char *, size_t, int, va_list); int (*deinit)(); int (*options)(const char *option, const void *);
+};
+struct st_mysql;
+typedef struct st_plugin_vio_info
+{
+ enum { MYSQL_VIO_INVALID, MYSQL_VIO_TCP, MYSQL_VIO_SOCKET,
+ MYSQL_VIO_PIPE, MYSQL_VIO_MEMORY } protocol;
+ int socket;
+} MYSQL_PLUGIN_VIO_INFO;
+typedef struct st_plugin_vio
+{
+ int (*read_packet)(struct st_plugin_vio *vio,
+ unsigned char **buf);
+ int (*write_packet)(struct st_plugin_vio *vio,
+ const unsigned char *packet,
+ int packet_len);
+ void (*info)(struct st_plugin_vio *vio, struct st_plugin_vio_info *info);
+} MYSQL_PLUGIN_VIO;
+struct st_mysql_client_plugin_AUTHENTICATION
+{
+ int type; unsigned int interface_version; const char *name; const char *author; const char *desc; unsigned int version[3]; const char *license; void *mysql_api; int (*init)(char *, size_t, int, va_list); int (*deinit)(); int (*options)(const char *option, const void *);
+ int (*authenticate_user)(MYSQL_PLUGIN_VIO *vio, struct st_mysql *mysql);
+};
+struct st_mysql;
+typedef char *(*mysql_authentication_dialog_ask_t)(struct st_mysql *mysql,
+ int type, const char *prompt, char *buf, int buf_len);
+struct st_mysql_client_plugin *
+mysql_load_plugin(struct st_mysql *mysql, const char *name, int type,
+ int argc, ...);
+struct st_mysql_client_plugin *
+mysql_load_plugin_v(struct st_mysql *mysql, const char *name, int type,
+ int argc, va_list args);
+struct st_mysql_client_plugin *
+mysql_client_find_plugin(struct st_mysql *mysql, const char *name, int type);
+struct st_mysql_client_plugin *
+mysql_client_register_plugin(struct st_mysql *mysql,
+ struct st_mysql_client_plugin *plugin);
+int mysql_plugin_options(struct st_mysql_client_plugin *plugin,
+ const char *option, const void *value);
diff --git a/include/mysql/plugin.h b/include/mysql/plugin.h
new file mode 100644
index 00000000..738ffc6c
--- /dev/null
+++ b/include/mysql/plugin.h
@@ -0,0 +1,778 @@
+/* Copyright (c) 2005, 2013, Oracle and/or its affiliates
+ Copyright (C) 2009, 2017, MariaDB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */
+
+#ifndef MYSQL_PLUGIN_INCLUDED
+#define MYSQL_PLUGIN_INCLUDED
+
+/*
+ On Windows, exports from DLL need to be declared
+ Also, plugin needs to be declared as extern "C" because MSVC
+ unlike other compilers, uses C++ mangling for variables not only
+ for functions.
+*/
+#ifdef MYSQL_DYNAMIC_PLUGIN
+ #ifdef _MSC_VER
+ #define MYSQL_DLLEXPORT _declspec(dllexport)
+ #else
+ #define MYSQL_DLLEXPORT
+ #endif
+#else
+ #define MYSQL_DLLEXPORT
+#endif
+
+#ifdef __cplusplus
+ #define MYSQL_PLUGIN_EXPORT extern "C" MYSQL_DLLEXPORT
+#else
+ #define MYSQL_PLUGIN_EXPORT MYSQL_DLLEXPORT
+#endif
+
+#ifdef __cplusplus
+class THD;
+class Item;
+#define MYSQL_THD THD*
+#else
+#define MYSQL_THD void*
+#endif
+
+typedef char my_bool;
+typedef void * MYSQL_PLUGIN;
+
+#include <mysql/services.h>
+
+#define MYSQL_XIDDATASIZE 128
+/**
+ struct st_mysql_xid is binary compatible with the XID structure as
+ in the X/Open CAE Specification, Distributed Transaction Processing:
+ The XA Specification, X/Open Company Ltd., 1991.
+ http://www.opengroup.org/bookstore/catalog/c193.htm
+
+ @see XID in sql/handler.h
+*/
+struct st_mysql_xid {
+ long formatID;
+ long gtrid_length;
+ long bqual_length;
+ char data[MYSQL_XIDDATASIZE]; /* Not \0-terminated */
+};
+typedef struct st_mysql_xid MYSQL_XID;
+
+/*************************************************************************
+ Plugin API. Common for all plugin types.
+*/
+
+/* MySQL plugin interface version */
+#define MYSQL_PLUGIN_INTERFACE_VERSION 0x0104
+
+/* MariaDB plugin interface version */
+#define MARIA_PLUGIN_INTERFACE_VERSION 0x010e
+
+/*
+ The allowable types of plugins
+*/
+#define MYSQL_UDF_PLUGIN 0 /* not implemented */
+#define MYSQL_STORAGE_ENGINE_PLUGIN 1
+#define MYSQL_FTPARSER_PLUGIN 2 /* Full-text parser plugin */
+#define MYSQL_DAEMON_PLUGIN 3
+#define MYSQL_INFORMATION_SCHEMA_PLUGIN 4
+#define MYSQL_AUDIT_PLUGIN 5
+#define MYSQL_REPLICATION_PLUGIN 6
+#define MYSQL_AUTHENTICATION_PLUGIN 7
+#define MYSQL_MAX_PLUGIN_TYPE_NUM 12 /* The number of plugin types */
+
+/* MariaDB plugin types */
+#define MariaDB_PASSWORD_VALIDATION_PLUGIN 8
+#define MariaDB_ENCRYPTION_PLUGIN 9
+#define MariaDB_DATA_TYPE_PLUGIN 10
+#define MariaDB_FUNCTION_PLUGIN 11
+
+/* We use the following strings to define licenses for plugins */
+#define PLUGIN_LICENSE_PROPRIETARY 0
+#define PLUGIN_LICENSE_GPL 1
+#define PLUGIN_LICENSE_BSD 2
+
+#define PLUGIN_LICENSE_PROPRIETARY_STRING "PROPRIETARY"
+#define PLUGIN_LICENSE_GPL_STRING "GPL"
+#define PLUGIN_LICENSE_BSD_STRING "BSD"
+
+/* definitions of code maturity for plugins */
+#define MariaDB_PLUGIN_MATURITY_UNKNOWN 0
+#define MariaDB_PLUGIN_MATURITY_EXPERIMENTAL 1
+#define MariaDB_PLUGIN_MATURITY_ALPHA 2
+#define MariaDB_PLUGIN_MATURITY_BETA 3
+#define MariaDB_PLUGIN_MATURITY_GAMMA 4
+#define MariaDB_PLUGIN_MATURITY_STABLE 5
+
+/*
+ Macros for beginning and ending plugin declarations. Between
+ mysql_declare_plugin and mysql_declare_plugin_end there should
+ be a st_mysql_plugin struct for each plugin to be declared.
+*/
+
+
+#ifndef MYSQL_DYNAMIC_PLUGIN
+#define __MYSQL_DECLARE_PLUGIN(NAME, VERSION, PSIZE, DECLS) \
+int VERSION= MYSQL_PLUGIN_INTERFACE_VERSION; \
+int PSIZE= sizeof(struct st_mysql_plugin); \
+struct st_mysql_plugin DECLS[]= {
+
+#define MARIA_DECLARE_PLUGIN__(NAME, VERSION, PSIZE, DECLS) \
+MYSQL_PLUGIN_EXPORT int VERSION; \
+int VERSION= MARIA_PLUGIN_INTERFACE_VERSION; \
+MYSQL_PLUGIN_EXPORT int PSIZE; \
+int PSIZE= sizeof(struct st_maria_plugin); \
+MYSQL_PLUGIN_EXPORT struct st_maria_plugin DECLS[]; \
+struct st_maria_plugin DECLS[]= {
+#else
+
+#define __MYSQL_DECLARE_PLUGIN(NAME, VERSION, PSIZE, DECLS) \
+MYSQL_PLUGIN_EXPORT int _mysql_plugin_interface_version_; \
+int _mysql_plugin_interface_version_= MYSQL_PLUGIN_INTERFACE_VERSION; \
+MYSQL_PLUGIN_EXPORT int _mysql_sizeof_struct_st_plugin_; \
+int _mysql_sizeof_struct_st_plugin_= sizeof(struct st_mysql_plugin); \
+MYSQL_PLUGIN_EXPORT struct st_mysql_plugin _mysql_plugin_declarations_[]; \
+struct st_mysql_plugin _mysql_plugin_declarations_[]= {
+
+#define MARIA_DECLARE_PLUGIN__(NAME, VERSION, PSIZE, DECLS) \
+MYSQL_PLUGIN_EXPORT int _maria_plugin_interface_version_; \
+int _maria_plugin_interface_version_= MARIA_PLUGIN_INTERFACE_VERSION; \
+MYSQL_PLUGIN_EXPORT int _maria_sizeof_struct_st_plugin_; \
+int _maria_sizeof_struct_st_plugin_= sizeof(struct st_maria_plugin); \
+MYSQL_PLUGIN_EXPORT struct st_maria_plugin _maria_plugin_declarations_[]; \
+struct st_maria_plugin _maria_plugin_declarations_[]= {
+
+#endif
+
+#define mysql_declare_plugin(NAME) \
+__MYSQL_DECLARE_PLUGIN(NAME, \
+ builtin_ ## NAME ## _plugin_interface_version, \
+ builtin_ ## NAME ## _sizeof_struct_st_plugin, \
+ builtin_ ## NAME ## _plugin)
+
+#define maria_declare_plugin(NAME) \
+MARIA_DECLARE_PLUGIN__(NAME, \
+ builtin_maria_ ## NAME ## _plugin_interface_version, \
+ builtin_maria_ ## NAME ## _sizeof_struct_st_plugin, \
+ builtin_maria_ ## NAME ## _plugin)
+
+#define mysql_declare_plugin_end ,{0,0,0,0,0,0,0,0,0,0,0,0,0}}
+#define maria_declare_plugin_end ,{0,0,0,0,0,0,0,0,0,0,0,0,0}}
+
+/*
+ declarations for SHOW STATUS support in plugins
+*/
+enum enum_mysql_show_type
+{
+ SHOW_UNDEF, SHOW_BOOL, SHOW_UINT, SHOW_ULONG,
+ SHOW_ULONGLONG, SHOW_CHAR, SHOW_CHAR_PTR,
+ SHOW_ARRAY, SHOW_FUNC, SHOW_DOUBLE,
+ SHOW_SINT, SHOW_SLONG, SHOW_SLONGLONG, SHOW_SIMPLE_FUNC,
+ SHOW_SIZE_T, SHOW_always_last
+};
+
+/* backward compatibility mapping. */
+#define SHOW_INT SHOW_UINT
+#define SHOW_LONG SHOW_ULONG
+#define SHOW_LONGLONG SHOW_ULONGLONG
+
+enum enum_var_type
+{
+ SHOW_OPT_DEFAULT= 0, SHOW_OPT_SESSION, SHOW_OPT_GLOBAL
+};
+
+struct st_mysql_show_var {
+ const char *name;
+ void *value;
+ enum enum_mysql_show_type type;
+};
+
+struct system_status_var;
+
+#define SHOW_VAR_FUNC_BUFF_SIZE (256 * sizeof(void*))
+typedef int (*mysql_show_var_func)(MYSQL_THD, struct st_mysql_show_var*, void *, struct system_status_var *status_var, enum enum_var_type);
+
+
+/*
+ Constants for plugin flags.
+ */
+
+#define PLUGIN_OPT_NO_INSTALL 1UL /* Not dynamically loadable */
+#define PLUGIN_OPT_NO_UNINSTALL 2UL /* Not dynamically unloadable */
+
+
+/*
+ declarations for server variables and command line options
+*/
+
+
+#define PLUGIN_VAR_BOOL 0x0001
+#define PLUGIN_VAR_INT 0x0002
+#define PLUGIN_VAR_LONG 0x0003
+#define PLUGIN_VAR_LONGLONG 0x0004
+#define PLUGIN_VAR_STR 0x0005
+#define PLUGIN_VAR_ENUM 0x0006
+#define PLUGIN_VAR_SET 0x0007
+#define PLUGIN_VAR_DOUBLE 0x0008
+#define PLUGIN_VAR_UNSIGNED 0x0080
+#define PLUGIN_VAR_THDLOCAL 0x0100 /* Variable is per-connection */
+#define PLUGIN_VAR_READONLY 0x0200 /* Server variable is read only */
+#define PLUGIN_VAR_NOSYSVAR 0x0400 /* Not a server variable */
+#define PLUGIN_VAR_NOCMDOPT 0x0800 /* Not a command line option */
+#define PLUGIN_VAR_NOCMDARG 0x1000 /* No argument for cmd line */
+#define PLUGIN_VAR_RQCMDARG 0x0000 /* Argument required for cmd line */
+#define PLUGIN_VAR_OPCMDARG 0x2000 /* Argument optional for cmd line */
+#define PLUGIN_VAR_MEMALLOC 0x8000 /* String needs memory allocated */
+
+struct st_mysql_sys_var;
+struct st_mysql_value;
+
+/*
+ SYNOPSIS
+ (*mysql_var_check_func)()
+ thd thread handle
+ var dynamic variable being altered
+ save pointer to temporary storage
+ value user provided value
+ RETURN
+ 0 user provided value is OK and the update func may be called.
+ any other value indicates error.
+
+ This function should parse the user provided value and store in the
+ provided temporary storage any data as required by the update func.
+ There is sufficient space in the temporary storage to store a double.
+ Note that the update func may not be called if any other error occurs
+ so any memory allocated should be thread-local so that it may be freed
+ automatically at the end of the statement.
+*/
+
+typedef int (*mysql_var_check_func)(MYSQL_THD thd,
+ struct st_mysql_sys_var *var,
+ void *save, struct st_mysql_value *value);
+
+/*
+ SYNOPSIS
+ (*mysql_var_update_func)()
+ thd thread handle
+ var dynamic variable being altered
+ var_ptr pointer to dynamic variable
+ save pointer to temporary storage
+ RETURN
+ NONE
+
+ This function should use the validated value stored in the temporary store
+ and persist it in the provided pointer to the dynamic variable.
+ For example, strings may require memory to be allocated.
+*/
+typedef void (*mysql_var_update_func)(MYSQL_THD thd,
+ struct st_mysql_sys_var *var,
+ void *var_ptr, const void *save);
+
+
+/* the following declarations are for internal use only */
+
+
+#define PLUGIN_VAR_MASK \
+ (PLUGIN_VAR_READONLY | PLUGIN_VAR_NOSYSVAR | \
+ PLUGIN_VAR_NOCMDOPT | PLUGIN_VAR_NOCMDARG | \
+ PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_MEMALLOC)
+
+#define MYSQL_PLUGIN_VAR_HEADER \
+ int flags; \
+ const char *name; \
+ const char *comment; \
+ mysql_var_check_func check; \
+ mysql_var_update_func update
+
+#define MYSQL_SYSVAR_NAME(name) mysql_sysvar_ ## name
+#define MYSQL_SYSVAR(name) \
+ ((struct st_mysql_sys_var *)&(MYSQL_SYSVAR_NAME(name)))
+
+/*
+ for global variables, the value pointer is the first
+ element after the header, the default value is the second.
+ for thread variables, the value offset is the first
+ element after the header, the default value is the second.
+*/
+
+
+#define DECLARE_MYSQL_SYSVAR_BASIC(name, type) struct { \
+ MYSQL_PLUGIN_VAR_HEADER; \
+ type *value; \
+ const type def_val; \
+} MYSQL_SYSVAR_NAME(name)
+
+#define DECLARE_MYSQL_SYSVAR_CONST_BASIC(name, type) struct { \
+ MYSQL_PLUGIN_VAR_HEADER; \
+ const type *value; \
+ const type def_val; \
+} MYSQL_SYSVAR_NAME(name)
+
+#define DECLARE_MYSQL_SYSVAR_SIMPLE(name, type) struct { \
+ MYSQL_PLUGIN_VAR_HEADER; \
+ type *value; type def_val; \
+ type min_val; type max_val; \
+ type blk_sz; \
+} MYSQL_SYSVAR_NAME(name)
+
+#define DECLARE_MYSQL_SYSVAR_TYPELIB(name, type) struct { \
+ MYSQL_PLUGIN_VAR_HEADER; \
+ type *value; type def_val; \
+ TYPELIB *typelib; \
+} MYSQL_SYSVAR_NAME(name)
+
+#define DECLARE_THDVAR_FUNC(type) \
+ type *(*resolve)(MYSQL_THD thd, int offset)
+
+#define DECLARE_MYSQL_THDVAR_BASIC(name, type) struct { \
+ MYSQL_PLUGIN_VAR_HEADER; \
+ int offset; \
+ const type def_val; \
+ DECLARE_THDVAR_FUNC(type); \
+} MYSQL_SYSVAR_NAME(name)
+
+#define DECLARE_MYSQL_THDVAR_SIMPLE(name, type) struct { \
+ MYSQL_PLUGIN_VAR_HEADER; \
+ int offset; \
+ type def_val; type min_val; \
+ type max_val; type blk_sz; \
+ DECLARE_THDVAR_FUNC(type); \
+} MYSQL_SYSVAR_NAME(name)
+
+#define DECLARE_MYSQL_THDVAR_TYPELIB(name, type) struct { \
+ MYSQL_PLUGIN_VAR_HEADER; \
+ int offset; \
+ const type def_val; \
+ DECLARE_THDVAR_FUNC(type); \
+ TYPELIB *typelib; \
+} MYSQL_SYSVAR_NAME(name)
+
+
+/*
+ the following declarations are for use by plugin implementors
+*/
+
+#define MYSQL_SYSVAR_BOOL(name, varname, opt, comment, check, update, def) \
+DECLARE_MYSQL_SYSVAR_BASIC(name, char) = { \
+ PLUGIN_VAR_BOOL | ((opt) & PLUGIN_VAR_MASK), \
+ #name, comment, check, update, &varname, def}
+
+#define MYSQL_SYSVAR_STR(name, varname, opt, comment, check, update, def) \
+DECLARE_MYSQL_SYSVAR_BASIC(name, char *) = { \
+ PLUGIN_VAR_STR | ((opt) & PLUGIN_VAR_MASK), \
+ #name, comment, check, update, &varname, def}
+
+#define MYSQL_SYSVAR_CONST_STR(name, varname, opt, comment, check, update, def) \
+DECLARE_MYSQL_SYSVAR_CONST_BASIC(name, char *) = { \
+ PLUGIN_VAR_STR | ((opt) & PLUGIN_VAR_MASK), \
+ #name, comment, check, update, &varname, def}
+
+#define MYSQL_SYSVAR_INT(name, varname, opt, comment, check, update, def, min, max, blk) \
+DECLARE_MYSQL_SYSVAR_SIMPLE(name, int) = { \
+ PLUGIN_VAR_INT | ((opt) & PLUGIN_VAR_MASK), \
+ #name, comment, check, update, &varname, def, min, max, blk }
+
+#define MYSQL_SYSVAR_UINT(name, varname, opt, comment, check, update, def, min, max, blk) \
+DECLARE_MYSQL_SYSVAR_SIMPLE(name, unsigned int) = { \
+ PLUGIN_VAR_INT | PLUGIN_VAR_UNSIGNED | ((opt) & PLUGIN_VAR_MASK), \
+ #name, comment, check, update, &varname, def, min, max, blk }
+
+#define MYSQL_SYSVAR_LONG(name, varname, opt, comment, check, update, def, min, max, blk) \
+DECLARE_MYSQL_SYSVAR_SIMPLE(name, long) = { \
+ PLUGIN_VAR_LONG | ((opt) & PLUGIN_VAR_MASK), \
+ #name, comment, check, update, &varname, def, min, max, blk }
+
+#define MYSQL_SYSVAR_ULONG(name, varname, opt, comment, check, update, def, min, max, blk) \
+DECLARE_MYSQL_SYSVAR_SIMPLE(name, unsigned long) = { \
+ PLUGIN_VAR_LONG | PLUGIN_VAR_UNSIGNED | ((opt) & PLUGIN_VAR_MASK), \
+ #name, comment, check, update, &varname, def, min, max, blk }
+
+#define MYSQL_SYSVAR_LONGLONG(name, varname, opt, comment, check, update, def, min, max, blk) \
+DECLARE_MYSQL_SYSVAR_SIMPLE(name, long long) = { \
+ PLUGIN_VAR_LONGLONG | ((opt) & PLUGIN_VAR_MASK), \
+ #name, comment, check, update, &varname, def, min, max, blk }
+
+#define MYSQL_SYSVAR_ULONGLONG(name, varname, opt, comment, check, update, def, min, max, blk) \
+DECLARE_MYSQL_SYSVAR_SIMPLE(name, unsigned long long) = { \
+ PLUGIN_VAR_LONGLONG | PLUGIN_VAR_UNSIGNED | ((opt) & PLUGIN_VAR_MASK), \
+ #name, comment, check, update, &varname, def, min, max, blk }
+
+#define MYSQL_SYSVAR_UINT64_T(name, varname, opt, comment, check, update, def, min, max, blk) \
+DECLARE_MYSQL_SYSVAR_SIMPLE(name, uint64_t) = { \
+ PLUGIN_VAR_LONGLONG | PLUGIN_VAR_UNSIGNED | ((opt) & PLUGIN_VAR_MASK), \
+ #name, comment, check, update, &varname, def, min, max, blk }
+
+#ifdef _WIN64
+#define MYSQL_SYSVAR_SIZE_T(name, varname, opt, comment, check, update, def, min, max, blk) \
+DECLARE_MYSQL_SYSVAR_SIMPLE(name, size_t) = { \
+ PLUGIN_VAR_LONGLONG | PLUGIN_VAR_UNSIGNED | ((opt) & PLUGIN_VAR_MASK), \
+ #name, comment, check, update, &varname, def, min, max, blk }
+#else
+#define MYSQL_SYSVAR_SIZE_T(name, varname, opt, comment, check, update, def, min, max, blk) \
+DECLARE_MYSQL_SYSVAR_SIMPLE(name, size_t) = { \
+ PLUGIN_VAR_LONG | PLUGIN_VAR_UNSIGNED | ((opt) & PLUGIN_VAR_MASK), \
+ #name, comment, check, update, &varname, def, min, max, blk }
+#endif
+
+#define MYSQL_SYSVAR_ENUM(name, varname, opt, comment, check, update, def, typelib) \
+DECLARE_MYSQL_SYSVAR_TYPELIB(name, unsigned long) = { \
+ PLUGIN_VAR_ENUM | ((opt) & PLUGIN_VAR_MASK), \
+ #name, comment, check, update, &varname, def, typelib }
+
+#define MYSQL_SYSVAR_SET(name, varname, opt, comment, check, update, def, typelib) \
+DECLARE_MYSQL_SYSVAR_TYPELIB(name, unsigned long long) = { \
+ PLUGIN_VAR_SET | ((opt) & PLUGIN_VAR_MASK), \
+ #name, comment, check, update, &varname, def, typelib }
+
+#define MYSQL_SYSVAR_DOUBLE(name, varname, opt, comment, check, update, def, min, max, blk) \
+DECLARE_MYSQL_SYSVAR_SIMPLE(name, double) = { \
+ PLUGIN_VAR_DOUBLE | ((opt) & PLUGIN_VAR_MASK), \
+ #name, comment, check, update, &varname, def, min, max, blk }
+
+#define MYSQL_THDVAR_BOOL(name, opt, comment, check, update, def) \
+DECLARE_MYSQL_THDVAR_BASIC(name, char) = { \
+ PLUGIN_VAR_BOOL | PLUGIN_VAR_THDLOCAL | ((opt) & PLUGIN_VAR_MASK), \
+ #name, comment, check, update, -1, def, NULL}
+
+#define MYSQL_THDVAR_STR(name, opt, comment, check, update, def) \
+DECLARE_MYSQL_THDVAR_BASIC(name, char *) = { \
+ PLUGIN_VAR_STR | PLUGIN_VAR_THDLOCAL | ((opt) & PLUGIN_VAR_MASK), \
+ #name, comment, check, update, -1, def, NULL}
+
+#define MYSQL_THDVAR_INT(name, opt, comment, check, update, def, min, max, blk) \
+DECLARE_MYSQL_THDVAR_SIMPLE(name, int) = { \
+ PLUGIN_VAR_INT | PLUGIN_VAR_THDLOCAL | ((opt) & PLUGIN_VAR_MASK), \
+ #name, comment, check, update, -1, def, min, max, blk, NULL }
+
+#define MYSQL_THDVAR_UINT(name, opt, comment, check, update, def, min, max, blk) \
+DECLARE_MYSQL_THDVAR_SIMPLE(name, unsigned int) = { \
+ PLUGIN_VAR_INT | PLUGIN_VAR_THDLOCAL | PLUGIN_VAR_UNSIGNED | ((opt) & PLUGIN_VAR_MASK), \
+ #name, comment, check, update, -1, def, min, max, blk, NULL }
+
+#define MYSQL_THDVAR_LONG(name, opt, comment, check, update, def, min, max, blk) \
+DECLARE_MYSQL_THDVAR_SIMPLE(name, long) = { \
+ PLUGIN_VAR_LONG | PLUGIN_VAR_THDLOCAL | ((opt) & PLUGIN_VAR_MASK), \
+ #name, comment, check, update, -1, def, min, max, blk, NULL }
+
+#define MYSQL_THDVAR_ULONG(name, opt, comment, check, update, def, min, max, blk) \
+DECLARE_MYSQL_THDVAR_SIMPLE(name, unsigned long) = { \
+ PLUGIN_VAR_LONG | PLUGIN_VAR_THDLOCAL | PLUGIN_VAR_UNSIGNED | ((opt) & PLUGIN_VAR_MASK), \
+ #name, comment, check, update, -1, def, min, max, blk, NULL }
+
+#define MYSQL_THDVAR_LONGLONG(name, opt, comment, check, update, def, min, max, blk) \
+DECLARE_MYSQL_THDVAR_SIMPLE(name, long long) = { \
+ PLUGIN_VAR_LONGLONG | PLUGIN_VAR_THDLOCAL | ((opt) & PLUGIN_VAR_MASK), \
+ #name, comment, check, update, -1, def, min, max, blk, NULL }
+
+#define MYSQL_THDVAR_ULONGLONG(name, opt, comment, check, update, def, min, max, blk) \
+DECLARE_MYSQL_THDVAR_SIMPLE(name, unsigned long long) = { \
+ PLUGIN_VAR_LONGLONG | PLUGIN_VAR_THDLOCAL | PLUGIN_VAR_UNSIGNED | ((opt) & PLUGIN_VAR_MASK), \
+ #name, comment, check, update, -1, def, min, max, blk, NULL }
+
+#define MYSQL_THDVAR_ENUM(name, opt, comment, check, update, def, typelib) \
+DECLARE_MYSQL_THDVAR_TYPELIB(name, unsigned long) = { \
+ PLUGIN_VAR_ENUM | PLUGIN_VAR_THDLOCAL | ((opt) & PLUGIN_VAR_MASK), \
+ #name, comment, check, update, -1, def, NULL, typelib }
+
+#define MYSQL_THDVAR_SET(name, opt, comment, check, update, def, typelib) \
+DECLARE_MYSQL_THDVAR_TYPELIB(name, unsigned long long) = { \
+ PLUGIN_VAR_SET | PLUGIN_VAR_THDLOCAL | ((opt) & PLUGIN_VAR_MASK), \
+ #name, comment, check, update, -1, def, NULL, typelib }
+
+#define MYSQL_THDVAR_DOUBLE(name, opt, comment, check, update, def, min, max, blk) \
+DECLARE_MYSQL_THDVAR_SIMPLE(name, double) = { \
+ PLUGIN_VAR_DOUBLE | PLUGIN_VAR_THDLOCAL | ((opt) & PLUGIN_VAR_MASK), \
+ #name, comment, check, update, -1, def, min, max, blk, NULL }
+
+/* accessor macros */
+
+#define SYSVAR(name) \
+ (*(MYSQL_SYSVAR_NAME(name).value))
+
+/* when thd == null, result points to global value */
+#define THDVAR(thd, name) \
+ (*(MYSQL_SYSVAR_NAME(name).resolve(thd, MYSQL_SYSVAR_NAME(name).offset)))
+
+
+/*
+ Plugin description structure.
+*/
+
+struct st_mysql_plugin
+{
+ int type; /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ void *info; /* pointer to type-specific plugin descriptor */
+ const char *name; /* plugin name */
+ const char *author; /* plugin author (for I_S.PLUGINS) */
+ const char *descr; /* general descriptive text (for I_S.PLUGINS) */
+ int license; /* the plugin license (PLUGIN_LICENSE_XXX) */
+ int (*init)(void *); /* the function to invoke when plugin is loaded */
+ int (*deinit)(void *);/* the function to invoke when plugin is unloaded */
+ unsigned int version; /* plugin version (for I_S.PLUGINS) */
+ struct st_mysql_show_var *status_vars;
+ struct st_mysql_sys_var **system_vars;
+ void * __reserved1; /* reserved for dependency checking */
+ unsigned long flags; /* flags for plugin */
+};
+
+/*
+ MariaDB extension for plugins declaration structure.
+
+ It also copy current MySQL plugin fields to have more independency
+ in plugins extension
+*/
+
+struct st_maria_plugin
+{
+ int type; /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ void *info; /* pointer to type-specific plugin descriptor */
+ const char *name; /* plugin name */
+ const char *author; /* plugin author (for SHOW PLUGINS) */
+ const char *descr; /* general descriptive text (for SHOW PLUGINS ) */
+ int license; /* the plugin license (PLUGIN_LICENSE_XXX) */
+ int (*init)(void *); /* the function to invoke when plugin is loaded */
+ int (*deinit)(void *);/* the function to invoke when plugin is unloaded */
+ unsigned int version; /* plugin version (for SHOW PLUGINS) */
+ struct st_mysql_show_var *status_vars;
+ struct st_mysql_sys_var **system_vars;
+ const char *version_info; /* plugin version string */
+ unsigned int maturity; /* MariaDB_PLUGIN_MATURITY_XXX */
+};
+
+/*************************************************************************
+ API for Full-text parser plugin. (MYSQL_FTPARSER_PLUGIN)
+*/
+#include "plugin_ftparser.h"
+
+/*************************************************************************
+ API for Storage Engine plugin. (MYSQL_DAEMON_PLUGIN)
+*/
+
+/* handlertons of different MySQL releases are incompatible */
+#define MYSQL_DAEMON_INTERFACE_VERSION (MYSQL_VERSION_ID << 8)
+
+/*
+ Here we define only the descriptor structure, that is referred from
+ st_mysql_plugin.
+*/
+
+struct st_mysql_daemon
+{
+ int interface_version;
+};
+
+
+/*************************************************************************
+ API for I_S plugin. (MYSQL_INFORMATION_SCHEMA_PLUGIN)
+*/
+
+/* handlertons of different MySQL releases are incompatible */
+#define MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION (MYSQL_VERSION_ID << 8)
+
+/*
+ Here we define only the descriptor structure, that is referred from
+ st_mysql_plugin.
+*/
+
+struct st_mysql_information_schema
+{
+ int interface_version;
+};
+
+
+/*************************************************************************
+ API for Storage Engine plugin. (MYSQL_STORAGE_ENGINE_PLUGIN)
+*/
+
+/* handlertons of different MySQL releases are incompatible */
+#define MYSQL_HANDLERTON_INTERFACE_VERSION (MYSQL_VERSION_ID << 8)
+
+/*
+ The real API is in the sql/handler.h
+ Here we define only the descriptor structure, that is referred from
+ st_mysql_plugin.
+*/
+
+struct st_mysql_storage_engine
+{
+ int interface_version;
+};
+
+struct handlerton;
+
+
+/*
+ API for Replication plugin. (MYSQL_REPLICATION_PLUGIN)
+*/
+ #define MYSQL_REPLICATION_INTERFACE_VERSION 0x0200
+
+ /**
+ Replication plugin descriptor
+ */
+ struct Mysql_replication {
+ int interface_version;
+ };
+
+/*************************************************************************
+ st_mysql_value struct for reading values from mysqld.
+ Used by server variables framework to parse user-provided values.
+ Will be used for arguments when implementing UDFs.
+
+ Note that val_str() returns a string in temporary memory
+ that will be freed at the end of statement. Copy the string
+ if you need it to persist.
+*/
+
+#define MYSQL_VALUE_TYPE_STRING 0
+#define MYSQL_VALUE_TYPE_REAL 1
+#define MYSQL_VALUE_TYPE_INT 2
+
+struct st_mysql_value
+{
+ int (*value_type)(struct st_mysql_value *);
+ const char *(*val_str)(struct st_mysql_value *, char *buffer, int *length);
+ int (*val_real)(struct st_mysql_value *, double *realbuf);
+ int (*val_int)(struct st_mysql_value *, long long *intbuf);
+ int (*is_unsigned)(struct st_mysql_value *);
+};
+
+
+/*************************************************************************
+ Miscellaneous functions for plugin implementors
+*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int thd_in_lock_tables(const MYSQL_THD thd);
+int thd_tablespace_op(const MYSQL_THD thd);
+long long thd_test_options(const MYSQL_THD thd, long long test_options);
+int thd_sql_command(const MYSQL_THD thd);
+void thd_storage_lock_wait(MYSQL_THD thd, long long value);
+int thd_tx_isolation(const MYSQL_THD thd);
+int thd_tx_is_read_only(const MYSQL_THD thd);
+/**
+ Create a temporary file.
+
+ @details
+ The temporary file is created in a location specified by the mysql
+ server configuration (--tmpdir option). The caller does not need to
+ delete the file, it will be deleted automatically.
+
+ @param prefix prefix for temporary file name
+ @retval -1 error
+ @retval >= 0 a file handle that can be passed to dup or my_close
+*/
+int mysql_tmpfile(const char *prefix);
+
+/**
+ Return the thread id of a user thread
+
+ @param thd user thread connection handle
+ @return thread id
+*/
+unsigned long thd_get_thread_id(const MYSQL_THD thd);
+
+/**
+ Get the XID for this connection's transaction
+
+ @param thd user thread connection handle
+ @param xid location where identifier is stored
+*/
+void thd_get_xid(const MYSQL_THD thd, MYSQL_XID *xid);
+
+/**
+ Invalidate the query cache for a given table.
+
+ @param thd user thread connection handle
+ @param key databasename\\0tablename\\0
+ @param key_length length of key in bytes, including the NUL bytes
+ @param using_trx flag: TRUE if using transactions, FALSE otherwise
+*/
+void mysql_query_cache_invalidate4(MYSQL_THD thd,
+ const char *key, unsigned int key_length,
+ int using_trx);
+
+
+/**
+ Provide a handler data getter to simplify coding
+*/
+void *thd_get_ha_data(const MYSQL_THD thd, const struct handlerton *hton);
+
+
+/**
+ Provide a handler data setter to simplify coding
+
+ @details
+ Set ha_data pointer (storage engine per-connection information).
+
+ To avoid unclean deactivation (uninstall) of storage engine plugin
+ in the middle of transaction, additional storage engine plugin
+ lock is acquired.
+
+ If ha_data is not null and storage engine plugin was not locked
+ by thd_set_ha_data() in this connection before, storage engine
+ plugin gets locked.
+
+ If ha_data is null and storage engine plugin was locked by
+ thd_set_ha_data() in this connection before, storage engine
+ plugin lock gets released.
+
+ If handlerton::close_connection() didn't reset ha_data, server does
+ it immediately after calling handlerton::close_connection().
+*/
+void thd_set_ha_data(MYSQL_THD thd, const struct handlerton *hton,
+ const void *ha_data);
+
+
+/**
+ Signal that the first part of handler commit is finished, and that the
+ committed transaction is now visible and has fixed commit ordering with
+ respect to other transactions. The commit need _not_ be durable yet, and
+ typically will not be when this call makes sense.
+
+ This call is optional, if the storage engine does not call it the upper
+ layer will after the handler commit() method is done. However, the storage
+ engine may choose to call it itself to increase the possibility for group
+ commit.
+
+ In-order parallel replication uses this to apply different transaction in
+ parallel, but delay the commits of later transactions until earlier
+ transactions have committed first, thus achieving increased performance on
+ multi-core systems while still preserving full transaction consistency.
+
+ The storage engine can call this from within the commit() method, typically
+ after the commit record has been written to the transaction log, but before
+ the log has been fsync()'ed. This will allow the next replicated transaction
+ to proceed to commit before the first one has done fsync() or similar. Thus,
+ it becomes possible for multiple sequential replicated transactions to share
+ a single fsync() inside the engine in group commit.
+
+ Note that this method should _not_ be called from within the commit_ordered()
+ method, or any other place in the storage engine. When commit_ordered() is
+ used (typically when binlog is enabled), the transaction coordinator takes
+ care of this and makes group commit in the storage engine possible without
+ any other action needed on the part of the storage engine. This function
+ thd_wakeup_subsequent_commits() is only needed when no transaction
+ coordinator is used, meaning a single storage engine and no binary log.
+*/
+void thd_wakeup_subsequent_commits(MYSQL_THD thd, int wakeup_error);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/include/mysql/plugin_audit.h b/include/mysql/plugin_audit.h
new file mode 100644
index 00000000..e99c0137
--- /dev/null
+++ b/include/mysql/plugin_audit.h
@@ -0,0 +1,180 @@
+/* Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; version 2 of
+ the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */
+
+#ifndef _my_audit_h
+#define _my_audit_h
+
+/*************************************************************************
+ API for Audit plugin. (MYSQL_AUDIT_PLUGIN)
+*/
+
+#include "plugin.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define MYSQL_AUDIT_CLASS_MASK_SIZE 1
+
+#define MYSQL_AUDIT_INTERFACE_VERSION 0x0302
+
+
+/*************************************************************************
+ AUDIT CLASS : GENERAL
+
+ LOG events occurs before emitting to the general query log.
+ ERROR events occur before transmitting errors to the user.
+ RESULT events occur after transmitting a resultset to the user.
+ STATUS events occur after transmitting a resultset or errors
+ to the user.
+*/
+
+#define MYSQL_AUDIT_GENERAL_CLASS 0
+#define MYSQL_AUDIT_GENERAL_CLASSMASK (1 << MYSQL_AUDIT_GENERAL_CLASS)
+#define MYSQL_AUDIT_GENERAL_LOG 0
+#define MYSQL_AUDIT_GENERAL_ERROR 1
+#define MYSQL_AUDIT_GENERAL_RESULT 2
+#define MYSQL_AUDIT_GENERAL_STATUS 3
+
+struct mysql_event_general
+{
+ unsigned int event_subclass;
+ int general_error_code;
+ unsigned long general_thread_id;
+ const char *general_user;
+ unsigned int general_user_length;
+ const char *general_command;
+ unsigned int general_command_length;
+ const char *general_query;
+ unsigned int general_query_length;
+ const struct charset_info_st *general_charset;
+ unsigned long long general_time;
+ unsigned long long general_rows;
+ /* Added in version 0x302 */
+ unsigned long long query_id;
+ MYSQL_CONST_LEX_STRING database;
+};
+
+
+/*
+ AUDIT CLASS : CONNECTION
+
+ CONNECT occurs after authentication phase is completed.
+ DISCONNECT occurs after connection is terminated.
+ CHANGE_USER occurs after COM_CHANGE_USER RPC is completed.
+*/
+
+#define MYSQL_AUDIT_CONNECTION_CLASS 1
+#define MYSQL_AUDIT_CONNECTION_CLASSMASK (1 << MYSQL_AUDIT_CONNECTION_CLASS)
+#define MYSQL_AUDIT_CONNECTION_CONNECT 0
+#define MYSQL_AUDIT_CONNECTION_DISCONNECT 1
+#define MYSQL_AUDIT_CONNECTION_CHANGE_USER 2
+
+struct mysql_event_connection
+{
+ unsigned int event_subclass;
+ int status;
+ unsigned long thread_id;
+ const char *user;
+ unsigned int user_length;
+ const char *priv_user;
+ unsigned int priv_user_length;
+ const char *external_user;
+ unsigned int external_user_length;
+ const char *proxy_user;
+ unsigned int proxy_user_length;
+ const char *host;
+ unsigned int host_length;
+ const char *ip;
+ unsigned int ip_length;
+ MYSQL_CONST_LEX_STRING database;
+};
+
+/*
+ AUDIT CLASS : TABLE
+
+ LOCK occurs when a connection "locks" (this does not necessarily mean a table
+ lock and also happens for row-locking engines) the table at the beginning of
+ a statement. This event is generated at the beginning of every statement for
+ every affected table, unless there's a LOCK TABLES statement in effect (in
+ which case it is generated once for LOCK TABLES and then is suppressed until
+ the tables are unlocked).
+
+ CREATE/DROP/RENAME occur when a table is created, dropped, or renamed.
+*/
+
+#define MYSQL_AUDIT_TABLE_CLASS 15
+#define MYSQL_AUDIT_TABLE_CLASSMASK (1 << MYSQL_AUDIT_TABLE_CLASS)
+#define MYSQL_AUDIT_TABLE_LOCK 0
+#define MYSQL_AUDIT_TABLE_CREATE 1
+#define MYSQL_AUDIT_TABLE_DROP 2
+#define MYSQL_AUDIT_TABLE_RENAME 3
+#define MYSQL_AUDIT_TABLE_ALTER 4
+
+struct mysql_event_table
+{
+ unsigned int event_subclass;
+ unsigned long thread_id;
+ const char *user;
+ const char *priv_user;
+ const char *priv_host;
+ const char *external_user;
+ const char *proxy_user;
+ const char *host;
+ const char *ip;
+ MYSQL_CONST_LEX_STRING database;
+ MYSQL_CONST_LEX_STRING table;
+ /* for MYSQL_AUDIT_TABLE_RENAME */
+ MYSQL_CONST_LEX_STRING new_database;
+ MYSQL_CONST_LEX_STRING new_table;
+ /* for MYSQL_AUDIT_TABLE_LOCK, true if read-only, false if read/write */
+ int read_only;
+ /* Added in version 0x302 */
+ unsigned long long query_id;
+};
+
+/*************************************************************************
+ Here we define the descriptor structure, that is referred from
+ st_mysql_plugin.
+
+ release_thd() event occurs when the event class consumer is to be
+ disassociated from the specified THD. This would typically occur
+ before some operation which may require sleeping - such as when
+ waiting for the next query from the client.
+
+ event_notify() is invoked whenever an event occurs which is of any
+ class for which the plugin has interest. The second argument
+ indicates the specific event class and the third argument is data
+ as required for that class.
+
+ class_mask is an array of bits used to indicate what event classes
+ that this plugin wants to receive.
+*/
+
+struct st_mysql_audit
+{
+ int interface_version;
+ void (*release_thd)(MYSQL_THD);
+ void (*event_notify)(MYSQL_THD, unsigned int, const void *);
+ unsigned long class_mask[MYSQL_AUDIT_CLASS_MASK_SIZE];
+};
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/mysql/plugin_audit.h.pp b/include/mysql/plugin_audit.h.pp
new file mode 100644
index 00000000..07fe16ea
--- /dev/null
+++ b/include/mysql/plugin_audit.h.pp
@@ -0,0 +1,687 @@
+class THD;
+class Item;
+typedef char my_bool;
+typedef void * MYSQL_PLUGIN;
+extern "C" {
+extern "C" {
+extern struct base64_service_st {
+ int (*base64_needed_encoded_length_ptr)(int length_of_data);
+ int (*base64_encode_max_arg_length_ptr)(void);
+ int (*base64_needed_decoded_length_ptr)(int length_of_encoded_data);
+ int (*base64_decode_max_arg_length_ptr)();
+ int (*base64_encode_ptr)(const void *src, size_t src_len, char *dst);
+ int (*base64_decode_ptr)(const char *src, size_t src_len,
+ void *dst, const char **end_ptr, int flags);
+} *base64_service;
+int my_base64_needed_encoded_length(int length_of_data);
+int my_base64_encode_max_arg_length(void);
+int my_base64_needed_decoded_length(int length_of_encoded_data);
+int my_base64_decode_max_arg_length();
+int my_base64_encode(const void *src, size_t src_len, char *dst);
+int my_base64_decode(const char *src, size_t src_len,
+ void *dst, const char **end_ptr, int flags);
+}
+extern "C" {
+extern void (*debug_sync_C_callback_ptr)(THD*, const char *, size_t);
+}
+extern "C" {
+struct encryption_service_st {
+ unsigned int (*encryption_key_get_latest_version_func)(unsigned int key_id);
+ unsigned int (*encryption_key_get_func)(unsigned int key_id, unsigned int key_version,
+ unsigned char* buffer, unsigned int* length);
+ unsigned int (*encryption_ctx_size_func)(unsigned int key_id, unsigned int key_version);
+ int (*encryption_ctx_init_func)(void *ctx, const unsigned char* key, unsigned int klen,
+ const unsigned char* iv, unsigned int ivlen,
+ int flags, unsigned int key_id,
+ unsigned int key_version);
+ int (*encryption_ctx_update_func)(void *ctx, const unsigned char* src, unsigned int slen,
+ unsigned char* dst, unsigned int* dlen);
+ int (*encryption_ctx_finish_func)(void *ctx, unsigned char* dst, unsigned int* dlen);
+ unsigned int (*encryption_encrypted_length_func)(unsigned int slen, unsigned int key_id, unsigned int key_version);
+};
+extern struct encryption_service_st encryption_handler;
+static inline unsigned int encryption_key_id_exists(unsigned int id)
+{
+ return encryption_handler.encryption_key_get_latest_version_func(id) != (~(unsigned int)0);
+}
+static inline unsigned int encryption_key_version_exists(unsigned int id, unsigned int version)
+{
+ unsigned int unused;
+ return encryption_handler.encryption_key_get_func((id),(version),(NULL),(&unused)) != (~(unsigned int)0);
+}
+static inline int encryption_crypt(const unsigned char* src, unsigned int slen,
+ unsigned char* dst, unsigned int* dlen,
+ const unsigned char* key, unsigned int klen,
+ const unsigned char* iv, unsigned int ivlen,
+ int flags, unsigned int key_id, unsigned int key_version)
+{
+ void *ctx= alloca(encryption_handler.encryption_ctx_size_func((key_id),(key_version)));
+ int res1, res2;
+ unsigned int d1, d2;
+ if ((res1= encryption_handler.encryption_ctx_init_func((ctx),(key),(klen),(iv),(ivlen),(flags),(key_id),(key_version))))
+ return res1;
+ res1= encryption_handler.encryption_ctx_update_func((ctx),(src),(slen),(dst),(&d1));
+ res2= encryption_handler.encryption_ctx_finish_func((ctx),(dst + d1),(&d2));
+ *dlen= d1 + d2;
+ return res1 ? res1 : res2;
+}
+}
+extern "C" {
+struct st_encryption_scheme_key {
+ unsigned int version;
+ unsigned char key[16];
+};
+struct st_encryption_scheme {
+ unsigned char iv[16];
+ struct st_encryption_scheme_key key[3];
+ unsigned int keyserver_requests;
+ unsigned int key_id;
+ unsigned int type;
+ void (*locker)(struct st_encryption_scheme *self, int release);
+};
+extern struct encryption_scheme_service_st {
+ int (*encryption_scheme_encrypt_func)
+ (const unsigned char* src, unsigned int slen,
+ unsigned char* dst, unsigned int* dlen,
+ struct st_encryption_scheme *scheme,
+ unsigned int key_version, unsigned int i32_1,
+ unsigned int i32_2, unsigned long long i64);
+ int (*encryption_scheme_decrypt_func)
+ (const unsigned char* src, unsigned int slen,
+ unsigned char* dst, unsigned int* dlen,
+ struct st_encryption_scheme *scheme,
+ unsigned int key_version, unsigned int i32_1,
+ unsigned int i32_2, unsigned long long i64);
+} *encryption_scheme_service;
+int encryption_scheme_encrypt(const unsigned char* src, unsigned int slen,
+ unsigned char* dst, unsigned int* dlen,
+ struct st_encryption_scheme *scheme,
+ unsigned int key_version, unsigned int i32_1,
+ unsigned int i32_2, unsigned long long i64);
+int encryption_scheme_decrypt(const unsigned char* src, unsigned int slen,
+ unsigned char* dst, unsigned int* dlen,
+ struct st_encryption_scheme *scheme,
+ unsigned int key_version, unsigned int i32_1,
+ unsigned int i32_2, unsigned long long i64);
+}
+extern "C" {
+enum thd_kill_levels {
+ THD_IS_NOT_KILLED=0,
+ THD_ABORT_SOFTLY=50,
+ THD_ABORT_ASAP=100,
+};
+extern struct kill_statement_service_st {
+ enum thd_kill_levels (*thd_kill_level_func)(const THD*);
+} *thd_kill_statement_service;
+enum thd_kill_levels thd_kill_level(const THD*);
+}
+extern "C" {
+typedef struct logger_handle_st LOGGER_HANDLE;
+extern struct logger_service_st {
+ void (*logger_init_mutexes)();
+ LOGGER_HANDLE* (*open)(const char *path,
+ unsigned long long size_limit,
+ unsigned int rotations);
+ int (*close)(LOGGER_HANDLE *log);
+ int (*vprintf)(LOGGER_HANDLE *log, const char *fmt, va_list argptr);
+ int (*printf)(LOGGER_HANDLE *log, const char *fmt, ...);
+ int (*write)(LOGGER_HANDLE *log, const char *buffer, size_t size);
+ int (*rotate)(LOGGER_HANDLE *log);
+} *logger_service;
+ void logger_init_mutexes();
+ LOGGER_HANDLE *logger_open(const char *path,
+ unsigned long long size_limit,
+ unsigned int rotations);
+ int logger_close(LOGGER_HANDLE *log);
+ int logger_vprintf(LOGGER_HANDLE *log, const char *fmt, va_list argptr);
+ int logger_printf(LOGGER_HANDLE *log, const char *fmt, ...);
+ int logger_write(LOGGER_HANDLE *log, const char *buffer, size_t size);
+ int logger_rotate(LOGGER_HANDLE *log);
+}
+extern "C" {
+extern struct my_md5_service_st {
+ void (*my_md5_type)(unsigned char*, const char*, size_t);
+ void (*my_md5_multi_type)(unsigned char*, ...);
+ size_t (*my_md5_context_size_type)();
+ void (*my_md5_init_type)(void *);
+ void (*my_md5_input_type)(void *, const unsigned char *, size_t);
+ void (*my_md5_result_type)(void *, unsigned char *);
+} *my_md5_service;
+void my_md5(unsigned char*, const char*, size_t);
+void my_md5_multi(unsigned char*, ...);
+size_t my_md5_context_size();
+void my_md5_init(void *context);
+void my_md5_input(void *context, const unsigned char *buf, size_t len);
+void my_md5_result(void *context, unsigned char *digest);
+}
+extern "C" {
+enum my_aes_mode {
+ MY_AES_ECB, MY_AES_CBC
+};
+extern struct my_crypt_service_st {
+ int (*my_aes_crypt_init)(void *ctx, enum my_aes_mode mode, int flags,
+ const unsigned char* key, unsigned int klen,
+ const unsigned char* iv, unsigned int ivlen);
+ int (*my_aes_crypt_update)(void *ctx, const unsigned char *src, unsigned int slen,
+ unsigned char *dst, unsigned int *dlen);
+ int (*my_aes_crypt_finish)(void *ctx, unsigned char *dst, unsigned int *dlen);
+ int (*my_aes_crypt)(enum my_aes_mode mode, int flags,
+ const unsigned char *src, unsigned int slen, unsigned char *dst, unsigned int *dlen,
+ const unsigned char *key, unsigned int klen, const unsigned char *iv, unsigned int ivlen);
+ unsigned int (*my_aes_get_size)(enum my_aes_mode mode, unsigned int source_length);
+ unsigned int (*my_aes_ctx_size)(enum my_aes_mode mode);
+ int (*my_random_bytes)(unsigned char* buf, int num);
+} *my_crypt_service;
+int my_aes_crypt_init(void *ctx, enum my_aes_mode mode, int flags,
+ const unsigned char* key, unsigned int klen,
+ const unsigned char* iv, unsigned int ivlen);
+int my_aes_crypt_update(void *ctx, const unsigned char *src, unsigned int slen,
+ unsigned char *dst, unsigned int *dlen);
+int my_aes_crypt_finish(void *ctx, unsigned char *dst, unsigned int *dlen);
+int my_aes_crypt(enum my_aes_mode mode, int flags,
+ const unsigned char *src, unsigned int slen, unsigned char *dst, unsigned int *dlen,
+ const unsigned char *key, unsigned int klen, const unsigned char *iv, unsigned int ivlen);
+int my_random_bytes(unsigned char* buf, int num);
+unsigned int my_aes_get_size(enum my_aes_mode mode, unsigned int source_length);
+unsigned int my_aes_ctx_size(enum my_aes_mode mode);
+}
+extern "C" {
+extern struct my_print_error_service_st {
+ void (*my_error_func)(unsigned int nr, unsigned long MyFlags, ...);
+ void (*my_printf_error_func)(unsigned int nr, const char *fmt, unsigned long MyFlags,...);
+ void (*my_printv_error_func)(unsigned int error, const char *format, unsigned long MyFlags, va_list ap);
+} *my_print_error_service;
+extern void my_error(unsigned int nr, unsigned long MyFlags, ...);
+extern void my_printf_error(unsigned int my_err, const char *format, unsigned long MyFlags, ...);
+extern void my_printv_error(unsigned int error, const char *format, unsigned long MyFlags,va_list ap);
+}
+extern "C" {
+extern struct my_snprintf_service_st {
+ size_t (*my_snprintf_type)(char*, size_t, const char*, ...);
+ size_t (*my_vsnprintf_type)(char *, size_t, const char*, va_list);
+} *my_snprintf_service;
+size_t my_snprintf(char* to, size_t n, const char* fmt, ...);
+size_t my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap);
+}
+extern "C" {
+extern struct progress_report_service_st {
+ void (*thd_progress_init_func)(THD* thd, unsigned int max_stage);
+ void (*thd_progress_report_func)(THD* thd,
+ unsigned long long progress,
+ unsigned long long max_progress);
+ void (*thd_progress_next_stage_func)(THD* thd);
+ void (*thd_progress_end_func)(THD* thd);
+ const char *(*set_thd_proc_info_func)(THD*, const char *info,
+ const char *func,
+ const char *file,
+ unsigned int line);
+} *progress_report_service;
+void thd_progress_init(THD* thd, unsigned int max_stage);
+void thd_progress_report(THD* thd,
+ unsigned long long progress,
+ unsigned long long max_progress);
+void thd_progress_next_stage(THD* thd);
+void thd_progress_end(THD* thd);
+const char *set_thd_proc_info(THD*, const char * info, const char *func,
+ const char *file, unsigned int line);
+}
+extern "C" {
+extern struct my_sha1_service_st {
+ void (*my_sha1_type)(unsigned char*, const char*, size_t);
+ void (*my_sha1_multi_type)(unsigned char*, ...);
+ size_t (*my_sha1_context_size_type)();
+ void (*my_sha1_init_type)(void *);
+ void (*my_sha1_input_type)(void *, const unsigned char *, size_t);
+ void (*my_sha1_result_type)(void *, unsigned char *);
+} *my_sha1_service;
+void my_sha1(unsigned char*, const char*, size_t);
+void my_sha1_multi(unsigned char*, ...);
+size_t my_sha1_context_size();
+void my_sha1_init(void *context);
+void my_sha1_input(void *context, const unsigned char *buf, size_t len);
+void my_sha1_result(void *context, unsigned char *digest);
+}
+extern "C" {
+extern struct my_sha2_service_st {
+ void (*my_sha224_type)(unsigned char*, const char*, size_t);
+ void (*my_sha224_multi_type)(unsigned char*, ...);
+ size_t (*my_sha224_context_size_type)();
+ void (*my_sha224_init_type)(void *);
+ void (*my_sha224_input_type)(void *, const unsigned char *, size_t);
+ void (*my_sha224_result_type)(void *, unsigned char *);
+ void (*my_sha256_type)(unsigned char*, const char*, size_t);
+ void (*my_sha256_multi_type)(unsigned char*, ...);
+ size_t (*my_sha256_context_size_type)();
+ void (*my_sha256_init_type)(void *);
+ void (*my_sha256_input_type)(void *, const unsigned char *, size_t);
+ void (*my_sha256_result_type)(void *, unsigned char *);
+ void (*my_sha384_type)(unsigned char*, const char*, size_t);
+ void (*my_sha384_multi_type)(unsigned char*, ...);
+ size_t (*my_sha384_context_size_type)();
+ void (*my_sha384_init_type)(void *);
+ void (*my_sha384_input_type)(void *, const unsigned char *, size_t);
+ void (*my_sha384_result_type)(void *, unsigned char *);
+ void (*my_sha512_type)(unsigned char*, const char*, size_t);
+ void (*my_sha512_multi_type)(unsigned char*, ...);
+ size_t (*my_sha512_context_size_type)();
+ void (*my_sha512_init_type)(void *);
+ void (*my_sha512_input_type)(void *, const unsigned char *, size_t);
+ void (*my_sha512_result_type)(void *, unsigned char *);
+} *my_sha2_service;
+void my_sha224(unsigned char*, const char*, size_t);
+void my_sha224_multi(unsigned char*, ...);
+size_t my_sha224_context_size();
+void my_sha224_init(void *context);
+void my_sha224_input(void *context, const unsigned char *buf, size_t len);
+void my_sha224_result(void *context, unsigned char *digest);
+void my_sha256(unsigned char*, const char*, size_t);
+void my_sha256_multi(unsigned char*, ...);
+size_t my_sha256_context_size();
+void my_sha256_init(void *context);
+void my_sha256_input(void *context, const unsigned char *buf, size_t len);
+void my_sha256_result(void *context, unsigned char *digest);
+void my_sha384(unsigned char*, const char*, size_t);
+void my_sha384_multi(unsigned char*, ...);
+size_t my_sha384_context_size();
+void my_sha384_init(void *context);
+void my_sha384_input(void *context, const unsigned char *buf, size_t len);
+void my_sha384_result(void *context, unsigned char *digest);
+void my_sha512(unsigned char*, const char*, size_t);
+void my_sha512_multi(unsigned char*, ...);
+size_t my_sha512_context_size();
+void my_sha512_init(void *context);
+void my_sha512_input(void *context, const unsigned char *buf, size_t len);
+void my_sha512_result(void *context, unsigned char *digest);
+}
+extern "C" {
+struct st_mysql_lex_string
+{
+ char *str;
+ size_t length;
+};
+typedef struct st_mysql_lex_string MYSQL_LEX_STRING;
+struct st_mysql_const_lex_string
+{
+ const char *str;
+ size_t length;
+};
+typedef struct st_mysql_const_lex_string MYSQL_CONST_LEX_STRING;
+extern struct thd_alloc_service_st {
+ void *(*thd_alloc_func)(THD*, size_t);
+ void *(*thd_calloc_func)(THD*, size_t);
+ char *(*thd_strdup_func)(THD*, const char *);
+ char *(*thd_strmake_func)(THD*, const char *, size_t);
+ void *(*thd_memdup_func)(THD*, const void*, size_t);
+ MYSQL_CONST_LEX_STRING *(*thd_make_lex_string_func)(THD*,
+ MYSQL_CONST_LEX_STRING *,
+ const char *, size_t, int);
+} *thd_alloc_service;
+void *thd_alloc(THD* thd, size_t size);
+void *thd_calloc(THD* thd, size_t size);
+char *thd_strdup(THD* thd, const char *str);
+char *thd_strmake(THD* thd, const char *str, size_t size);
+void *thd_memdup(THD* thd, const void* str, size_t size);
+MYSQL_CONST_LEX_STRING
+*thd_make_lex_string(THD* thd, MYSQL_CONST_LEX_STRING *lex_str,
+ const char *str, size_t size,
+ int allocate_lex_string);
+}
+extern "C" {
+extern struct thd_autoinc_service_st {
+ void (*thd_get_autoinc_func)(const THD* thd,
+ unsigned long* off, unsigned long* inc);
+} *thd_autoinc_service;
+void thd_get_autoinc(const THD* thd,
+ unsigned long* off, unsigned long* inc);
+}
+extern "C" {
+extern struct thd_error_context_service_st {
+ const char *(*thd_get_error_message_func)(const THD* thd);
+ unsigned int (*thd_get_error_number_func)(const THD* thd);
+ unsigned long (*thd_get_error_row_func)(const THD* thd);
+ void (*thd_inc_error_row_func)(THD* thd);
+ char *(*thd_get_error_context_description_func)(THD* thd,
+ char *buffer,
+ unsigned int length,
+ unsigned int max_query_length);
+} *thd_error_context_service;
+const char *thd_get_error_message(const THD* thd);
+unsigned int thd_get_error_number(const THD* thd);
+unsigned long thd_get_error_row(const THD* thd);
+void thd_inc_error_row(THD* thd);
+char *thd_get_error_context_description(THD* thd,
+ char *buffer, unsigned int length,
+ unsigned int max_query_length);
+}
+extern "C" {
+extern struct thd_rnd_service_st {
+ double (*thd_rnd_ptr)(THD* thd);
+ void (*thd_c_r_p_ptr)(THD* thd, char *to, size_t length);
+} *thd_rnd_service;
+double thd_rnd(THD* thd);
+void thd_create_random_password(THD* thd, char *to, size_t length);
+}
+extern "C" {
+typedef int MYSQL_THD_KEY_T;
+extern struct thd_specifics_service_st {
+ int (*thd_key_create_func)(MYSQL_THD_KEY_T *key);
+ void (*thd_key_delete_func)(MYSQL_THD_KEY_T *key);
+ void *(*thd_getspecific_func)(THD* thd, MYSQL_THD_KEY_T key);
+ int (*thd_setspecific_func)(THD* thd, MYSQL_THD_KEY_T key, void *value);
+} *thd_specifics_service;
+int thd_key_create(MYSQL_THD_KEY_T *key);
+void thd_key_delete(MYSQL_THD_KEY_T *key);
+void* thd_getspecific(THD* thd, MYSQL_THD_KEY_T key);
+int thd_setspecific(THD* thd, MYSQL_THD_KEY_T key, void *value);
+}
+typedef long my_time_t;
+enum enum_mysql_timestamp_type
+{
+ MYSQL_TIMESTAMP_NONE= -2, MYSQL_TIMESTAMP_ERROR= -1,
+ MYSQL_TIMESTAMP_DATE= 0, MYSQL_TIMESTAMP_DATETIME= 1, MYSQL_TIMESTAMP_TIME= 2
+};
+typedef struct st_mysql_time
+{
+ unsigned int year, month, day, hour, minute, second;
+ unsigned long second_part;
+ my_bool neg;
+ enum enum_mysql_timestamp_type time_type;
+} MYSQL_TIME;
+extern "C" {
+extern struct thd_timezone_service_st {
+ my_time_t (*thd_TIME_to_gmt_sec)(THD* thd, const MYSQL_TIME *ltime, unsigned int *errcode);
+ void (*thd_gmt_sec_to_TIME)(THD* thd, MYSQL_TIME *ltime, my_time_t t);
+} *thd_timezone_service;
+my_time_t thd_TIME_to_gmt_sec(THD* thd, const MYSQL_TIME *ltime, unsigned int *errcode);
+void thd_gmt_sec_to_TIME(THD* thd, MYSQL_TIME *ltime, my_time_t t);
+}
+extern "C" {
+typedef enum _thd_wait_type_e {
+ THD_WAIT_SLEEP= 1,
+ THD_WAIT_DISKIO= 2,
+ THD_WAIT_ROW_LOCK= 3,
+ THD_WAIT_GLOBAL_LOCK= 4,
+ THD_WAIT_META_DATA_LOCK= 5,
+ THD_WAIT_TABLE_LOCK= 6,
+ THD_WAIT_USER_LOCK= 7,
+ THD_WAIT_BINLOG= 8,
+ THD_WAIT_GROUP_COMMIT= 9,
+ THD_WAIT_SYNC= 10,
+ THD_WAIT_NET= 11,
+ THD_WAIT_LAST= 12
+} thd_wait_type;
+extern struct thd_wait_service_st {
+ void (*thd_wait_begin_func)(THD*, int);
+ void (*thd_wait_end_func)(THD*);
+} *thd_wait_service;
+void thd_wait_begin(THD* thd, int wait_type);
+void thd_wait_end(THD* thd);
+}
+extern "C" {
+enum json_types
+{
+ JSV_BAD_JSON=-1,
+ JSV_NOTHING=0,
+ JSV_OBJECT=1,
+ JSV_ARRAY=2,
+ JSV_STRING=3,
+ JSV_NUMBER=4,
+ JSV_TRUE=5,
+ JSV_FALSE=6,
+ JSV_NULL=7
+};
+extern struct json_service_st {
+ enum json_types (*json_type)(const char *js, const char *js_end,
+ const char **value, int *value_len);
+ enum json_types (*json_get_array_item)(const char *js, const char *js_end,
+ int n_item,
+ const char **value, int *value_len);
+ enum json_types (*json_get_object_key)(const char *js, const char *js_end,
+ const char *key,
+ const char **value, int *value_len);
+ enum json_types (*json_get_object_nkey)(const char *js,const char *js_end,
+ int nkey,
+ const char **keyname, const char **keyname_end,
+ const char **value, int *value_len);
+ int (*json_escape_string)(const char *str,const char *str_end,
+ char *json, char *json_end);
+ int (*json_unescape_json)(const char *json_str, const char *json_end,
+ char *res, char *res_end);
+} *json_service;
+enum json_types json_type(const char *js, const char *js_end,
+ const char **value, int *value_len);
+enum json_types json_get_array_item(const char *js, const char *js_end,
+ int n_item,
+ const char **value, int *value_len);
+enum json_types json_get_object_key(const char *js, const char *js_end,
+ const char *key,
+ const char **value, int *value_len);
+enum json_types json_get_object_nkey(const char *js,const char *js_end, int nkey,
+ const char **keyname, const char **keyname_end,
+ const char **value, int *value_len);
+int json_escape_string(const char *str,const char *str_end,
+ char *json, char *json_end);
+int json_unescape_json(const char *json_str, const char *json_end,
+ char *res, char *res_end);
+}
+}
+struct st_mysql_xid {
+ long formatID;
+ long gtrid_length;
+ long bqual_length;
+ char data[128];
+};
+typedef struct st_mysql_xid MYSQL_XID;
+enum enum_mysql_show_type
+{
+ SHOW_UNDEF, SHOW_BOOL, SHOW_UINT, SHOW_ULONG,
+ SHOW_ULONGLONG, SHOW_CHAR, SHOW_CHAR_PTR,
+ SHOW_ARRAY, SHOW_FUNC, SHOW_DOUBLE,
+ SHOW_SINT, SHOW_SLONG, SHOW_SLONGLONG, SHOW_SIMPLE_FUNC,
+ SHOW_SIZE_T, SHOW_always_last
+};
+enum enum_var_type
+{
+ SHOW_OPT_DEFAULT= 0, SHOW_OPT_SESSION, SHOW_OPT_GLOBAL
+};
+struct st_mysql_show_var {
+ const char *name;
+ void *value;
+ enum enum_mysql_show_type type;
+};
+struct system_status_var;
+typedef int (*mysql_show_var_func)(THD*, struct st_mysql_show_var*, void *, struct system_status_var *status_var, enum enum_var_type);
+struct st_mysql_sys_var;
+struct st_mysql_value;
+typedef int (*mysql_var_check_func)(THD* thd,
+ struct st_mysql_sys_var *var,
+ void *save, struct st_mysql_value *value);
+typedef void (*mysql_var_update_func)(THD* thd,
+ struct st_mysql_sys_var *var,
+ void *var_ptr, const void *save);
+struct st_mysql_plugin
+{
+ int type;
+ void *info;
+ const char *name;
+ const char *author;
+ const char *descr;
+ int license;
+ int (*init)(void *);
+ int (*deinit)(void *);
+ unsigned int version;
+ struct st_mysql_show_var *status_vars;
+ struct st_mysql_sys_var **system_vars;
+ void * __reserved1;
+ unsigned long flags;
+};
+struct st_maria_plugin
+{
+ int type;
+ void *info;
+ const char *name;
+ const char *author;
+ const char *descr;
+ int license;
+ int (*init)(void *);
+ int (*deinit)(void *);
+ unsigned int version;
+ struct st_mysql_show_var *status_vars;
+ struct st_mysql_sys_var **system_vars;
+ const char *version_info;
+ unsigned int maturity;
+};
+extern "C" {
+enum enum_ftparser_mode
+{
+ MYSQL_FTPARSER_SIMPLE_MODE= 0,
+ MYSQL_FTPARSER_WITH_STOPWORDS= 1,
+ MYSQL_FTPARSER_FULL_BOOLEAN_INFO= 2
+};
+enum enum_ft_token_type
+{
+ FT_TOKEN_EOF= 0,
+ FT_TOKEN_WORD= 1,
+ FT_TOKEN_LEFT_PAREN= 2,
+ FT_TOKEN_RIGHT_PAREN= 3,
+ FT_TOKEN_STOPWORD= 4
+};
+typedef struct st_mysql_ftparser_boolean_info
+{
+ enum enum_ft_token_type type;
+ int yesno;
+ int weight_adjust;
+ char wasign;
+ char trunc;
+ char prev;
+ char *quot;
+} MYSQL_FTPARSER_BOOLEAN_INFO;
+typedef struct st_mysql_ftparser_param
+{
+ int (*mysql_parse)(struct st_mysql_ftparser_param *,
+ const char *doc, int doc_len);
+ int (*mysql_add_word)(struct st_mysql_ftparser_param *,
+ const char *word, int word_len,
+ MYSQL_FTPARSER_BOOLEAN_INFO *boolean_info);
+ void *ftparser_state;
+ void *mysql_ftparam;
+ const struct charset_info_st *cs;
+ const char *doc;
+ int length;
+ unsigned int flags;
+ enum enum_ftparser_mode mode;
+} MYSQL_FTPARSER_PARAM;
+struct st_mysql_ftparser
+{
+ int interface_version;
+ int (*parse)(MYSQL_FTPARSER_PARAM *param);
+ int (*init)(MYSQL_FTPARSER_PARAM *param);
+ int (*deinit)(MYSQL_FTPARSER_PARAM *param);
+};
+}
+struct st_mysql_daemon
+{
+ int interface_version;
+};
+struct st_mysql_information_schema
+{
+ int interface_version;
+};
+struct st_mysql_storage_engine
+{
+ int interface_version;
+};
+struct handlerton;
+ struct Mysql_replication {
+ int interface_version;
+ };
+struct st_mysql_value
+{
+ int (*value_type)(struct st_mysql_value *);
+ const char *(*val_str)(struct st_mysql_value *, char *buffer, int *length);
+ int (*val_real)(struct st_mysql_value *, double *realbuf);
+ int (*val_int)(struct st_mysql_value *, long long *intbuf);
+ int (*is_unsigned)(struct st_mysql_value *);
+};
+extern "C" {
+int thd_in_lock_tables(const THD* thd);
+int thd_tablespace_op(const THD* thd);
+long long thd_test_options(const THD* thd, long long test_options);
+int thd_sql_command(const THD* thd);
+void thd_storage_lock_wait(THD* thd, long long value);
+int thd_tx_isolation(const THD* thd);
+int thd_tx_is_read_only(const THD* thd);
+int mysql_tmpfile(const char *prefix);
+unsigned long thd_get_thread_id(const THD* thd);
+void thd_get_xid(const THD* thd, MYSQL_XID *xid);
+void mysql_query_cache_invalidate4(THD* thd,
+ const char *key, unsigned int key_length,
+ int using_trx);
+void *thd_get_ha_data(const THD* thd, const struct handlerton *hton);
+void thd_set_ha_data(THD* thd, const struct handlerton *hton,
+ const void *ha_data);
+void thd_wakeup_subsequent_commits(THD* thd, int wakeup_error);
+}
+extern "C" {
+struct mysql_event_general
+{
+ unsigned int event_subclass;
+ int general_error_code;
+ unsigned long general_thread_id;
+ const char *general_user;
+ unsigned int general_user_length;
+ const char *general_command;
+ unsigned int general_command_length;
+ const char *general_query;
+ unsigned int general_query_length;
+ const struct charset_info_st *general_charset;
+ unsigned long long general_time;
+ unsigned long long general_rows;
+ unsigned long long query_id;
+ MYSQL_CONST_LEX_STRING database;
+};
+struct mysql_event_connection
+{
+ unsigned int event_subclass;
+ int status;
+ unsigned long thread_id;
+ const char *user;
+ unsigned int user_length;
+ const char *priv_user;
+ unsigned int priv_user_length;
+ const char *external_user;
+ unsigned int external_user_length;
+ const char *proxy_user;
+ unsigned int proxy_user_length;
+ const char *host;
+ unsigned int host_length;
+ const char *ip;
+ unsigned int ip_length;
+ MYSQL_CONST_LEX_STRING database;
+};
+struct mysql_event_table
+{
+ unsigned int event_subclass;
+ unsigned long thread_id;
+ const char *user;
+ const char *priv_user;
+ const char *priv_host;
+ const char *external_user;
+ const char *proxy_user;
+ const char *host;
+ const char *ip;
+ MYSQL_CONST_LEX_STRING database;
+ MYSQL_CONST_LEX_STRING table;
+ MYSQL_CONST_LEX_STRING new_database;
+ MYSQL_CONST_LEX_STRING new_table;
+ int read_only;
+ unsigned long long query_id;
+};
+struct st_mysql_audit
+{
+ int interface_version;
+ void (*release_thd)(THD*);
+ void (*event_notify)(THD*, unsigned int, const void *);
+ unsigned long class_mask[1];
+};
+}
diff --git a/include/mysql/plugin_auth.h b/include/mysql/plugin_auth.h
new file mode 100644
index 00000000..ae9c9368
--- /dev/null
+++ b/include/mysql/plugin_auth.h
@@ -0,0 +1,182 @@
+#ifndef MYSQL_PLUGIN_AUTH_INCLUDED
+/* Copyright (C) 2010 Sergei Golubchik and Monty Program Ab
+ Copyright (c) 2010, Oracle and/or its affiliates.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */
+
+/**
+ @file
+
+ Authentication Plugin API.
+
+ This file defines the API for server authentication plugins.
+*/
+
+#define MYSQL_PLUGIN_AUTH_INCLUDED
+
+#include <mysql/plugin.h>
+
+#define MYSQL_AUTHENTICATION_INTERFACE_VERSION 0x0202
+
+#include <mysql/plugin_auth_common.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* defines for MYSQL_SERVER_AUTH_INFO.password_used */
+
+#define PASSWORD_USED_NO 0
+#define PASSWORD_USED_YES 1
+#define PASSWORD_USED_NO_MENTION 2
+
+
+/**
+ Provides server plugin access to authentication information
+*/
+typedef struct st_mysql_server_auth_info
+{
+ /**
+ User name as sent by the client and shown in USER().
+ NULL if the client packet with the user name was not received yet.
+ */
+ const char *user_name;
+
+ /**
+ Length of user_name
+ */
+ unsigned int user_name_length;
+
+ /**
+ A corresponding column value from the mysql.user table for the
+ matching account name or the preprocessed value, if preprocess_hash
+ method is not NULL
+ */
+ const char *auth_string;
+
+ /**
+ Length of auth_string
+ */
+ unsigned long auth_string_length;
+
+ /**
+ Matching account name as found in the mysql.user table.
+ A plugin can override it with another name that will be
+ used by MySQL for authorization, and shown in CURRENT_USER()
+ */
+ char authenticated_as[MYSQL_USERNAME_LENGTH+1];
+
+
+ /**
+ The unique user name that was used by the plugin to authenticate.
+ Not used by the server.
+ Available through the @@EXTERNAL_USER variable.
+ */
+ char external_user[MYSQL_USERNAME_LENGTH+1];
+
+ /**
+ This only affects the "Authentication failed. Password used: %s"
+ error message. has the following values :
+ 0 : %s will be NO.
+ 1 : %s will be YES.
+ 2 : there will be no %s.
+ Set it as appropriate or ignore at will.
+ */
+ int password_used;
+
+ /**
+ Set to the name of the connected client host, if it can be resolved,
+ or to its IP address otherwise.
+ */
+ const char *host_or_ip;
+
+ /**
+ Length of host_or_ip
+ */
+ unsigned int host_or_ip_length;
+
+ /**
+ Current THD pointer (to use with various services)
+ */
+ MYSQL_THD thd;
+
+} MYSQL_SERVER_AUTH_INFO;
+
+/**
+ Server authentication plugin descriptor
+*/
+struct st_mysql_auth
+{
+ int interface_version; /**< version plugin uses */
+ /**
+ A plugin that a client must use for authentication with this server
+ plugin. Can be NULL to mean "any plugin".
+ */
+ const char *client_auth_plugin;
+ /**
+ Function provided by the plugin which should perform authentication (using
+ the vio functions if necessary) and return 0 if successful. The plugin can
+ also fill the info.authenticated_as field if a different username should be
+ used for authorization.
+ */
+ int (*authenticate_user)(MYSQL_PLUGIN_VIO *vio, MYSQL_SERVER_AUTH_INFO *info);
+ /**
+ Create a password hash (or digest) out of a plain-text password
+
+ Used in SET PASSWORD, GRANT, and CREATE USER to convert user specified
+ plain-text password into a value that will be stored in mysql.user table.
+
+ @see preprocess_hash
+
+ @param password plain-text password
+ @param password_length plain-text password length
+ @param hash the digest will be stored there
+ @param hash_length in: hash buffer size
+ out: the actual length of the hash
+
+ @return 0 for ok, 1 for error
+
+ Can be NULL.
+ */
+ int (*hash_password)(const char *password, size_t password_length,
+ char *hash, size_t *hash_length);
+
+ /**
+ Prepare the password hash for authentication.
+
+ Password hash is stored in the authentication_string column of the
+ mysql.user table in a text form. If a plugin needs to preprocess the
+ value somehow before the authentication (e.g. convert from hex or base64
+ to binary), it can do it in this method. This way the conversion
+ will happen only once, not for every authentication attempt.
+
+ The value written to the out buffer will be cached and later made
+ available to the authenticate_user() method in the
+ MYSQL_SERVER_AUTH_INFO::auth_string[] buffer.
+
+ @return 0 for ok, 1 for error
+
+ Can be NULL, in this case the mysql.user.authentication_string value will
+ be given to the authenticate_user() method as is, unconverted.
+ */
+ int (*preprocess_hash)(const char *hash, size_t hash_length,
+ unsigned char *out, size_t *out_length);
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/include/mysql/plugin_auth.h.pp b/include/mysql/plugin_auth.h.pp
new file mode 100644
index 00000000..18eebd5e
--- /dev/null
+++ b/include/mysql/plugin_auth.h.pp
@@ -0,0 +1,664 @@
+class THD;
+class Item;
+typedef char my_bool;
+typedef void * MYSQL_PLUGIN;
+extern "C" {
+extern "C" {
+extern struct base64_service_st {
+ int (*base64_needed_encoded_length_ptr)(int length_of_data);
+ int (*base64_encode_max_arg_length_ptr)(void);
+ int (*base64_needed_decoded_length_ptr)(int length_of_encoded_data);
+ int (*base64_decode_max_arg_length_ptr)();
+ int (*base64_encode_ptr)(const void *src, size_t src_len, char *dst);
+ int (*base64_decode_ptr)(const char *src, size_t src_len,
+ void *dst, const char **end_ptr, int flags);
+} *base64_service;
+int my_base64_needed_encoded_length(int length_of_data);
+int my_base64_encode_max_arg_length(void);
+int my_base64_needed_decoded_length(int length_of_encoded_data);
+int my_base64_decode_max_arg_length();
+int my_base64_encode(const void *src, size_t src_len, char *dst);
+int my_base64_decode(const char *src, size_t src_len,
+ void *dst, const char **end_ptr, int flags);
+}
+extern "C" {
+extern void (*debug_sync_C_callback_ptr)(THD*, const char *, size_t);
+}
+extern "C" {
+struct encryption_service_st {
+ unsigned int (*encryption_key_get_latest_version_func)(unsigned int key_id);
+ unsigned int (*encryption_key_get_func)(unsigned int key_id, unsigned int key_version,
+ unsigned char* buffer, unsigned int* length);
+ unsigned int (*encryption_ctx_size_func)(unsigned int key_id, unsigned int key_version);
+ int (*encryption_ctx_init_func)(void *ctx, const unsigned char* key, unsigned int klen,
+ const unsigned char* iv, unsigned int ivlen,
+ int flags, unsigned int key_id,
+ unsigned int key_version);
+ int (*encryption_ctx_update_func)(void *ctx, const unsigned char* src, unsigned int slen,
+ unsigned char* dst, unsigned int* dlen);
+ int (*encryption_ctx_finish_func)(void *ctx, unsigned char* dst, unsigned int* dlen);
+ unsigned int (*encryption_encrypted_length_func)(unsigned int slen, unsigned int key_id, unsigned int key_version);
+};
+extern struct encryption_service_st encryption_handler;
+static inline unsigned int encryption_key_id_exists(unsigned int id)
+{
+ return encryption_handler.encryption_key_get_latest_version_func(id) != (~(unsigned int)0);
+}
+static inline unsigned int encryption_key_version_exists(unsigned int id, unsigned int version)
+{
+ unsigned int unused;
+ return encryption_handler.encryption_key_get_func((id),(version),(NULL),(&unused)) != (~(unsigned int)0);
+}
+static inline int encryption_crypt(const unsigned char* src, unsigned int slen,
+ unsigned char* dst, unsigned int* dlen,
+ const unsigned char* key, unsigned int klen,
+ const unsigned char* iv, unsigned int ivlen,
+ int flags, unsigned int key_id, unsigned int key_version)
+{
+ void *ctx= alloca(encryption_handler.encryption_ctx_size_func((key_id),(key_version)));
+ int res1, res2;
+ unsigned int d1, d2;
+ if ((res1= encryption_handler.encryption_ctx_init_func((ctx),(key),(klen),(iv),(ivlen),(flags),(key_id),(key_version))))
+ return res1;
+ res1= encryption_handler.encryption_ctx_update_func((ctx),(src),(slen),(dst),(&d1));
+ res2= encryption_handler.encryption_ctx_finish_func((ctx),(dst + d1),(&d2));
+ *dlen= d1 + d2;
+ return res1 ? res1 : res2;
+}
+}
+extern "C" {
+struct st_encryption_scheme_key {
+ unsigned int version;
+ unsigned char key[16];
+};
+struct st_encryption_scheme {
+ unsigned char iv[16];
+ struct st_encryption_scheme_key key[3];
+ unsigned int keyserver_requests;
+ unsigned int key_id;
+ unsigned int type;
+ void (*locker)(struct st_encryption_scheme *self, int release);
+};
+extern struct encryption_scheme_service_st {
+ int (*encryption_scheme_encrypt_func)
+ (const unsigned char* src, unsigned int slen,
+ unsigned char* dst, unsigned int* dlen,
+ struct st_encryption_scheme *scheme,
+ unsigned int key_version, unsigned int i32_1,
+ unsigned int i32_2, unsigned long long i64);
+ int (*encryption_scheme_decrypt_func)
+ (const unsigned char* src, unsigned int slen,
+ unsigned char* dst, unsigned int* dlen,
+ struct st_encryption_scheme *scheme,
+ unsigned int key_version, unsigned int i32_1,
+ unsigned int i32_2, unsigned long long i64);
+} *encryption_scheme_service;
+int encryption_scheme_encrypt(const unsigned char* src, unsigned int slen,
+ unsigned char* dst, unsigned int* dlen,
+ struct st_encryption_scheme *scheme,
+ unsigned int key_version, unsigned int i32_1,
+ unsigned int i32_2, unsigned long long i64);
+int encryption_scheme_decrypt(const unsigned char* src, unsigned int slen,
+ unsigned char* dst, unsigned int* dlen,
+ struct st_encryption_scheme *scheme,
+ unsigned int key_version, unsigned int i32_1,
+ unsigned int i32_2, unsigned long long i64);
+}
+extern "C" {
+enum thd_kill_levels {
+ THD_IS_NOT_KILLED=0,
+ THD_ABORT_SOFTLY=50,
+ THD_ABORT_ASAP=100,
+};
+extern struct kill_statement_service_st {
+ enum thd_kill_levels (*thd_kill_level_func)(const THD*);
+} *thd_kill_statement_service;
+enum thd_kill_levels thd_kill_level(const THD*);
+}
+extern "C" {
+typedef struct logger_handle_st LOGGER_HANDLE;
+extern struct logger_service_st {
+ void (*logger_init_mutexes)();
+ LOGGER_HANDLE* (*open)(const char *path,
+ unsigned long long size_limit,
+ unsigned int rotations);
+ int (*close)(LOGGER_HANDLE *log);
+ int (*vprintf)(LOGGER_HANDLE *log, const char *fmt, va_list argptr);
+ int (*printf)(LOGGER_HANDLE *log, const char *fmt, ...);
+ int (*write)(LOGGER_HANDLE *log, const char *buffer, size_t size);
+ int (*rotate)(LOGGER_HANDLE *log);
+} *logger_service;
+ void logger_init_mutexes();
+ LOGGER_HANDLE *logger_open(const char *path,
+ unsigned long long size_limit,
+ unsigned int rotations);
+ int logger_close(LOGGER_HANDLE *log);
+ int logger_vprintf(LOGGER_HANDLE *log, const char *fmt, va_list argptr);
+ int logger_printf(LOGGER_HANDLE *log, const char *fmt, ...);
+ int logger_write(LOGGER_HANDLE *log, const char *buffer, size_t size);
+ int logger_rotate(LOGGER_HANDLE *log);
+}
+extern "C" {
+extern struct my_md5_service_st {
+ void (*my_md5_type)(unsigned char*, const char*, size_t);
+ void (*my_md5_multi_type)(unsigned char*, ...);
+ size_t (*my_md5_context_size_type)();
+ void (*my_md5_init_type)(void *);
+ void (*my_md5_input_type)(void *, const unsigned char *, size_t);
+ void (*my_md5_result_type)(void *, unsigned char *);
+} *my_md5_service;
+void my_md5(unsigned char*, const char*, size_t);
+void my_md5_multi(unsigned char*, ...);
+size_t my_md5_context_size();
+void my_md5_init(void *context);
+void my_md5_input(void *context, const unsigned char *buf, size_t len);
+void my_md5_result(void *context, unsigned char *digest);
+}
+extern "C" {
+enum my_aes_mode {
+ MY_AES_ECB, MY_AES_CBC
+};
+extern struct my_crypt_service_st {
+ int (*my_aes_crypt_init)(void *ctx, enum my_aes_mode mode, int flags,
+ const unsigned char* key, unsigned int klen,
+ const unsigned char* iv, unsigned int ivlen);
+ int (*my_aes_crypt_update)(void *ctx, const unsigned char *src, unsigned int slen,
+ unsigned char *dst, unsigned int *dlen);
+ int (*my_aes_crypt_finish)(void *ctx, unsigned char *dst, unsigned int *dlen);
+ int (*my_aes_crypt)(enum my_aes_mode mode, int flags,
+ const unsigned char *src, unsigned int slen, unsigned char *dst, unsigned int *dlen,
+ const unsigned char *key, unsigned int klen, const unsigned char *iv, unsigned int ivlen);
+ unsigned int (*my_aes_get_size)(enum my_aes_mode mode, unsigned int source_length);
+ unsigned int (*my_aes_ctx_size)(enum my_aes_mode mode);
+ int (*my_random_bytes)(unsigned char* buf, int num);
+} *my_crypt_service;
+int my_aes_crypt_init(void *ctx, enum my_aes_mode mode, int flags,
+ const unsigned char* key, unsigned int klen,
+ const unsigned char* iv, unsigned int ivlen);
+int my_aes_crypt_update(void *ctx, const unsigned char *src, unsigned int slen,
+ unsigned char *dst, unsigned int *dlen);
+int my_aes_crypt_finish(void *ctx, unsigned char *dst, unsigned int *dlen);
+int my_aes_crypt(enum my_aes_mode mode, int flags,
+ const unsigned char *src, unsigned int slen, unsigned char *dst, unsigned int *dlen,
+ const unsigned char *key, unsigned int klen, const unsigned char *iv, unsigned int ivlen);
+int my_random_bytes(unsigned char* buf, int num);
+unsigned int my_aes_get_size(enum my_aes_mode mode, unsigned int source_length);
+unsigned int my_aes_ctx_size(enum my_aes_mode mode);
+}
+extern "C" {
+extern struct my_print_error_service_st {
+ void (*my_error_func)(unsigned int nr, unsigned long MyFlags, ...);
+ void (*my_printf_error_func)(unsigned int nr, const char *fmt, unsigned long MyFlags,...);
+ void (*my_printv_error_func)(unsigned int error, const char *format, unsigned long MyFlags, va_list ap);
+} *my_print_error_service;
+extern void my_error(unsigned int nr, unsigned long MyFlags, ...);
+extern void my_printf_error(unsigned int my_err, const char *format, unsigned long MyFlags, ...);
+extern void my_printv_error(unsigned int error, const char *format, unsigned long MyFlags,va_list ap);
+}
+extern "C" {
+extern struct my_snprintf_service_st {
+ size_t (*my_snprintf_type)(char*, size_t, const char*, ...);
+ size_t (*my_vsnprintf_type)(char *, size_t, const char*, va_list);
+} *my_snprintf_service;
+size_t my_snprintf(char* to, size_t n, const char* fmt, ...);
+size_t my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap);
+}
+extern "C" {
+extern struct progress_report_service_st {
+ void (*thd_progress_init_func)(THD* thd, unsigned int max_stage);
+ void (*thd_progress_report_func)(THD* thd,
+ unsigned long long progress,
+ unsigned long long max_progress);
+ void (*thd_progress_next_stage_func)(THD* thd);
+ void (*thd_progress_end_func)(THD* thd);
+ const char *(*set_thd_proc_info_func)(THD*, const char *info,
+ const char *func,
+ const char *file,
+ unsigned int line);
+} *progress_report_service;
+void thd_progress_init(THD* thd, unsigned int max_stage);
+void thd_progress_report(THD* thd,
+ unsigned long long progress,
+ unsigned long long max_progress);
+void thd_progress_next_stage(THD* thd);
+void thd_progress_end(THD* thd);
+const char *set_thd_proc_info(THD*, const char * info, const char *func,
+ const char *file, unsigned int line);
+}
+extern "C" {
+extern struct my_sha1_service_st {
+ void (*my_sha1_type)(unsigned char*, const char*, size_t);
+ void (*my_sha1_multi_type)(unsigned char*, ...);
+ size_t (*my_sha1_context_size_type)();
+ void (*my_sha1_init_type)(void *);
+ void (*my_sha1_input_type)(void *, const unsigned char *, size_t);
+ void (*my_sha1_result_type)(void *, unsigned char *);
+} *my_sha1_service;
+void my_sha1(unsigned char*, const char*, size_t);
+void my_sha1_multi(unsigned char*, ...);
+size_t my_sha1_context_size();
+void my_sha1_init(void *context);
+void my_sha1_input(void *context, const unsigned char *buf, size_t len);
+void my_sha1_result(void *context, unsigned char *digest);
+}
+extern "C" {
+extern struct my_sha2_service_st {
+ void (*my_sha224_type)(unsigned char*, const char*, size_t);
+ void (*my_sha224_multi_type)(unsigned char*, ...);
+ size_t (*my_sha224_context_size_type)();
+ void (*my_sha224_init_type)(void *);
+ void (*my_sha224_input_type)(void *, const unsigned char *, size_t);
+ void (*my_sha224_result_type)(void *, unsigned char *);
+ void (*my_sha256_type)(unsigned char*, const char*, size_t);
+ void (*my_sha256_multi_type)(unsigned char*, ...);
+ size_t (*my_sha256_context_size_type)();
+ void (*my_sha256_init_type)(void *);
+ void (*my_sha256_input_type)(void *, const unsigned char *, size_t);
+ void (*my_sha256_result_type)(void *, unsigned char *);
+ void (*my_sha384_type)(unsigned char*, const char*, size_t);
+ void (*my_sha384_multi_type)(unsigned char*, ...);
+ size_t (*my_sha384_context_size_type)();
+ void (*my_sha384_init_type)(void *);
+ void (*my_sha384_input_type)(void *, const unsigned char *, size_t);
+ void (*my_sha384_result_type)(void *, unsigned char *);
+ void (*my_sha512_type)(unsigned char*, const char*, size_t);
+ void (*my_sha512_multi_type)(unsigned char*, ...);
+ size_t (*my_sha512_context_size_type)();
+ void (*my_sha512_init_type)(void *);
+ void (*my_sha512_input_type)(void *, const unsigned char *, size_t);
+ void (*my_sha512_result_type)(void *, unsigned char *);
+} *my_sha2_service;
+void my_sha224(unsigned char*, const char*, size_t);
+void my_sha224_multi(unsigned char*, ...);
+size_t my_sha224_context_size();
+void my_sha224_init(void *context);
+void my_sha224_input(void *context, const unsigned char *buf, size_t len);
+void my_sha224_result(void *context, unsigned char *digest);
+void my_sha256(unsigned char*, const char*, size_t);
+void my_sha256_multi(unsigned char*, ...);
+size_t my_sha256_context_size();
+void my_sha256_init(void *context);
+void my_sha256_input(void *context, const unsigned char *buf, size_t len);
+void my_sha256_result(void *context, unsigned char *digest);
+void my_sha384(unsigned char*, const char*, size_t);
+void my_sha384_multi(unsigned char*, ...);
+size_t my_sha384_context_size();
+void my_sha384_init(void *context);
+void my_sha384_input(void *context, const unsigned char *buf, size_t len);
+void my_sha384_result(void *context, unsigned char *digest);
+void my_sha512(unsigned char*, const char*, size_t);
+void my_sha512_multi(unsigned char*, ...);
+size_t my_sha512_context_size();
+void my_sha512_init(void *context);
+void my_sha512_input(void *context, const unsigned char *buf, size_t len);
+void my_sha512_result(void *context, unsigned char *digest);
+}
+extern "C" {
+struct st_mysql_lex_string
+{
+ char *str;
+ size_t length;
+};
+typedef struct st_mysql_lex_string MYSQL_LEX_STRING;
+struct st_mysql_const_lex_string
+{
+ const char *str;
+ size_t length;
+};
+typedef struct st_mysql_const_lex_string MYSQL_CONST_LEX_STRING;
+extern struct thd_alloc_service_st {
+ void *(*thd_alloc_func)(THD*, size_t);
+ void *(*thd_calloc_func)(THD*, size_t);
+ char *(*thd_strdup_func)(THD*, const char *);
+ char *(*thd_strmake_func)(THD*, const char *, size_t);
+ void *(*thd_memdup_func)(THD*, const void*, size_t);
+ MYSQL_CONST_LEX_STRING *(*thd_make_lex_string_func)(THD*,
+ MYSQL_CONST_LEX_STRING *,
+ const char *, size_t, int);
+} *thd_alloc_service;
+void *thd_alloc(THD* thd, size_t size);
+void *thd_calloc(THD* thd, size_t size);
+char *thd_strdup(THD* thd, const char *str);
+char *thd_strmake(THD* thd, const char *str, size_t size);
+void *thd_memdup(THD* thd, const void* str, size_t size);
+MYSQL_CONST_LEX_STRING
+*thd_make_lex_string(THD* thd, MYSQL_CONST_LEX_STRING *lex_str,
+ const char *str, size_t size,
+ int allocate_lex_string);
+}
+extern "C" {
+extern struct thd_autoinc_service_st {
+ void (*thd_get_autoinc_func)(const THD* thd,
+ unsigned long* off, unsigned long* inc);
+} *thd_autoinc_service;
+void thd_get_autoinc(const THD* thd,
+ unsigned long* off, unsigned long* inc);
+}
+extern "C" {
+extern struct thd_error_context_service_st {
+ const char *(*thd_get_error_message_func)(const THD* thd);
+ unsigned int (*thd_get_error_number_func)(const THD* thd);
+ unsigned long (*thd_get_error_row_func)(const THD* thd);
+ void (*thd_inc_error_row_func)(THD* thd);
+ char *(*thd_get_error_context_description_func)(THD* thd,
+ char *buffer,
+ unsigned int length,
+ unsigned int max_query_length);
+} *thd_error_context_service;
+const char *thd_get_error_message(const THD* thd);
+unsigned int thd_get_error_number(const THD* thd);
+unsigned long thd_get_error_row(const THD* thd);
+void thd_inc_error_row(THD* thd);
+char *thd_get_error_context_description(THD* thd,
+ char *buffer, unsigned int length,
+ unsigned int max_query_length);
+}
+extern "C" {
+extern struct thd_rnd_service_st {
+ double (*thd_rnd_ptr)(THD* thd);
+ void (*thd_c_r_p_ptr)(THD* thd, char *to, size_t length);
+} *thd_rnd_service;
+double thd_rnd(THD* thd);
+void thd_create_random_password(THD* thd, char *to, size_t length);
+}
+extern "C" {
+typedef int MYSQL_THD_KEY_T;
+extern struct thd_specifics_service_st {
+ int (*thd_key_create_func)(MYSQL_THD_KEY_T *key);
+ void (*thd_key_delete_func)(MYSQL_THD_KEY_T *key);
+ void *(*thd_getspecific_func)(THD* thd, MYSQL_THD_KEY_T key);
+ int (*thd_setspecific_func)(THD* thd, MYSQL_THD_KEY_T key, void *value);
+} *thd_specifics_service;
+int thd_key_create(MYSQL_THD_KEY_T *key);
+void thd_key_delete(MYSQL_THD_KEY_T *key);
+void* thd_getspecific(THD* thd, MYSQL_THD_KEY_T key);
+int thd_setspecific(THD* thd, MYSQL_THD_KEY_T key, void *value);
+}
+typedef long my_time_t;
+enum enum_mysql_timestamp_type
+{
+ MYSQL_TIMESTAMP_NONE= -2, MYSQL_TIMESTAMP_ERROR= -1,
+ MYSQL_TIMESTAMP_DATE= 0, MYSQL_TIMESTAMP_DATETIME= 1, MYSQL_TIMESTAMP_TIME= 2
+};
+typedef struct st_mysql_time
+{
+ unsigned int year, month, day, hour, minute, second;
+ unsigned long second_part;
+ my_bool neg;
+ enum enum_mysql_timestamp_type time_type;
+} MYSQL_TIME;
+extern "C" {
+extern struct thd_timezone_service_st {
+ my_time_t (*thd_TIME_to_gmt_sec)(THD* thd, const MYSQL_TIME *ltime, unsigned int *errcode);
+ void (*thd_gmt_sec_to_TIME)(THD* thd, MYSQL_TIME *ltime, my_time_t t);
+} *thd_timezone_service;
+my_time_t thd_TIME_to_gmt_sec(THD* thd, const MYSQL_TIME *ltime, unsigned int *errcode);
+void thd_gmt_sec_to_TIME(THD* thd, MYSQL_TIME *ltime, my_time_t t);
+}
+extern "C" {
+typedef enum _thd_wait_type_e {
+ THD_WAIT_SLEEP= 1,
+ THD_WAIT_DISKIO= 2,
+ THD_WAIT_ROW_LOCK= 3,
+ THD_WAIT_GLOBAL_LOCK= 4,
+ THD_WAIT_META_DATA_LOCK= 5,
+ THD_WAIT_TABLE_LOCK= 6,
+ THD_WAIT_USER_LOCK= 7,
+ THD_WAIT_BINLOG= 8,
+ THD_WAIT_GROUP_COMMIT= 9,
+ THD_WAIT_SYNC= 10,
+ THD_WAIT_NET= 11,
+ THD_WAIT_LAST= 12
+} thd_wait_type;
+extern struct thd_wait_service_st {
+ void (*thd_wait_begin_func)(THD*, int);
+ void (*thd_wait_end_func)(THD*);
+} *thd_wait_service;
+void thd_wait_begin(THD* thd, int wait_type);
+void thd_wait_end(THD* thd);
+}
+extern "C" {
+enum json_types
+{
+ JSV_BAD_JSON=-1,
+ JSV_NOTHING=0,
+ JSV_OBJECT=1,
+ JSV_ARRAY=2,
+ JSV_STRING=3,
+ JSV_NUMBER=4,
+ JSV_TRUE=5,
+ JSV_FALSE=6,
+ JSV_NULL=7
+};
+extern struct json_service_st {
+ enum json_types (*json_type)(const char *js, const char *js_end,
+ const char **value, int *value_len);
+ enum json_types (*json_get_array_item)(const char *js, const char *js_end,
+ int n_item,
+ const char **value, int *value_len);
+ enum json_types (*json_get_object_key)(const char *js, const char *js_end,
+ const char *key,
+ const char **value, int *value_len);
+ enum json_types (*json_get_object_nkey)(const char *js,const char *js_end,
+ int nkey,
+ const char **keyname, const char **keyname_end,
+ const char **value, int *value_len);
+ int (*json_escape_string)(const char *str,const char *str_end,
+ char *json, char *json_end);
+ int (*json_unescape_json)(const char *json_str, const char *json_end,
+ char *res, char *res_end);
+} *json_service;
+enum json_types json_type(const char *js, const char *js_end,
+ const char **value, int *value_len);
+enum json_types json_get_array_item(const char *js, const char *js_end,
+ int n_item,
+ const char **value, int *value_len);
+enum json_types json_get_object_key(const char *js, const char *js_end,
+ const char *key,
+ const char **value, int *value_len);
+enum json_types json_get_object_nkey(const char *js,const char *js_end, int nkey,
+ const char **keyname, const char **keyname_end,
+ const char **value, int *value_len);
+int json_escape_string(const char *str,const char *str_end,
+ char *json, char *json_end);
+int json_unescape_json(const char *json_str, const char *json_end,
+ char *res, char *res_end);
+}
+}
+struct st_mysql_xid {
+ long formatID;
+ long gtrid_length;
+ long bqual_length;
+ char data[128];
+};
+typedef struct st_mysql_xid MYSQL_XID;
+enum enum_mysql_show_type
+{
+ SHOW_UNDEF, SHOW_BOOL, SHOW_UINT, SHOW_ULONG,
+ SHOW_ULONGLONG, SHOW_CHAR, SHOW_CHAR_PTR,
+ SHOW_ARRAY, SHOW_FUNC, SHOW_DOUBLE,
+ SHOW_SINT, SHOW_SLONG, SHOW_SLONGLONG, SHOW_SIMPLE_FUNC,
+ SHOW_SIZE_T, SHOW_always_last
+};
+enum enum_var_type
+{
+ SHOW_OPT_DEFAULT= 0, SHOW_OPT_SESSION, SHOW_OPT_GLOBAL
+};
+struct st_mysql_show_var {
+ const char *name;
+ void *value;
+ enum enum_mysql_show_type type;
+};
+struct system_status_var;
+typedef int (*mysql_show_var_func)(THD*, struct st_mysql_show_var*, void *, struct system_status_var *status_var, enum enum_var_type);
+struct st_mysql_sys_var;
+struct st_mysql_value;
+typedef int (*mysql_var_check_func)(THD* thd,
+ struct st_mysql_sys_var *var,
+ void *save, struct st_mysql_value *value);
+typedef void (*mysql_var_update_func)(THD* thd,
+ struct st_mysql_sys_var *var,
+ void *var_ptr, const void *save);
+struct st_mysql_plugin
+{
+ int type;
+ void *info;
+ const char *name;
+ const char *author;
+ const char *descr;
+ int license;
+ int (*init)(void *);
+ int (*deinit)(void *);
+ unsigned int version;
+ struct st_mysql_show_var *status_vars;
+ struct st_mysql_sys_var **system_vars;
+ void * __reserved1;
+ unsigned long flags;
+};
+struct st_maria_plugin
+{
+ int type;
+ void *info;
+ const char *name;
+ const char *author;
+ const char *descr;
+ int license;
+ int (*init)(void *);
+ int (*deinit)(void *);
+ unsigned int version;
+ struct st_mysql_show_var *status_vars;
+ struct st_mysql_sys_var **system_vars;
+ const char *version_info;
+ unsigned int maturity;
+};
+extern "C" {
+enum enum_ftparser_mode
+{
+ MYSQL_FTPARSER_SIMPLE_MODE= 0,
+ MYSQL_FTPARSER_WITH_STOPWORDS= 1,
+ MYSQL_FTPARSER_FULL_BOOLEAN_INFO= 2
+};
+enum enum_ft_token_type
+{
+ FT_TOKEN_EOF= 0,
+ FT_TOKEN_WORD= 1,
+ FT_TOKEN_LEFT_PAREN= 2,
+ FT_TOKEN_RIGHT_PAREN= 3,
+ FT_TOKEN_STOPWORD= 4
+};
+typedef struct st_mysql_ftparser_boolean_info
+{
+ enum enum_ft_token_type type;
+ int yesno;
+ int weight_adjust;
+ char wasign;
+ char trunc;
+ char prev;
+ char *quot;
+} MYSQL_FTPARSER_BOOLEAN_INFO;
+typedef struct st_mysql_ftparser_param
+{
+ int (*mysql_parse)(struct st_mysql_ftparser_param *,
+ const char *doc, int doc_len);
+ int (*mysql_add_word)(struct st_mysql_ftparser_param *,
+ const char *word, int word_len,
+ MYSQL_FTPARSER_BOOLEAN_INFO *boolean_info);
+ void *ftparser_state;
+ void *mysql_ftparam;
+ const struct charset_info_st *cs;
+ const char *doc;
+ int length;
+ unsigned int flags;
+ enum enum_ftparser_mode mode;
+} MYSQL_FTPARSER_PARAM;
+struct st_mysql_ftparser
+{
+ int interface_version;
+ int (*parse)(MYSQL_FTPARSER_PARAM *param);
+ int (*init)(MYSQL_FTPARSER_PARAM *param);
+ int (*deinit)(MYSQL_FTPARSER_PARAM *param);
+};
+}
+struct st_mysql_daemon
+{
+ int interface_version;
+};
+struct st_mysql_information_schema
+{
+ int interface_version;
+};
+struct st_mysql_storage_engine
+{
+ int interface_version;
+};
+struct handlerton;
+ struct Mysql_replication {
+ int interface_version;
+ };
+struct st_mysql_value
+{
+ int (*value_type)(struct st_mysql_value *);
+ const char *(*val_str)(struct st_mysql_value *, char *buffer, int *length);
+ int (*val_real)(struct st_mysql_value *, double *realbuf);
+ int (*val_int)(struct st_mysql_value *, long long *intbuf);
+ int (*is_unsigned)(struct st_mysql_value *);
+};
+extern "C" {
+int thd_in_lock_tables(const THD* thd);
+int thd_tablespace_op(const THD* thd);
+long long thd_test_options(const THD* thd, long long test_options);
+int thd_sql_command(const THD* thd);
+void thd_storage_lock_wait(THD* thd, long long value);
+int thd_tx_isolation(const THD* thd);
+int thd_tx_is_read_only(const THD* thd);
+int mysql_tmpfile(const char *prefix);
+unsigned long thd_get_thread_id(const THD* thd);
+void thd_get_xid(const THD* thd, MYSQL_XID *xid);
+void mysql_query_cache_invalidate4(THD* thd,
+ const char *key, unsigned int key_length,
+ int using_trx);
+void *thd_get_ha_data(const THD* thd, const struct handlerton *hton);
+void thd_set_ha_data(THD* thd, const struct handlerton *hton,
+ const void *ha_data);
+void thd_wakeup_subsequent_commits(THD* thd, int wakeup_error);
+}
+typedef struct st_plugin_vio_info
+{
+ enum { MYSQL_VIO_INVALID, MYSQL_VIO_TCP, MYSQL_VIO_SOCKET,
+ MYSQL_VIO_PIPE, MYSQL_VIO_MEMORY } protocol;
+ int socket;
+} MYSQL_PLUGIN_VIO_INFO;
+typedef struct st_plugin_vio
+{
+ int (*read_packet)(struct st_plugin_vio *vio,
+ unsigned char **buf);
+ int (*write_packet)(struct st_plugin_vio *vio,
+ const unsigned char *packet,
+ int packet_len);
+ void (*info)(struct st_plugin_vio *vio, struct st_plugin_vio_info *info);
+} MYSQL_PLUGIN_VIO;
+extern "C" {
+typedef struct st_mysql_server_auth_info
+{
+ const char *user_name;
+ unsigned int user_name_length;
+ const char *auth_string;
+ unsigned long auth_string_length;
+ char authenticated_as[512 +1];
+ char external_user[512 +1];
+ int password_used;
+ const char *host_or_ip;
+ unsigned int host_or_ip_length;
+ THD* thd;
+} MYSQL_SERVER_AUTH_INFO;
+struct st_mysql_auth
+{
+ int interface_version;
+ const char *client_auth_plugin;
+ int (*authenticate_user)(MYSQL_PLUGIN_VIO *vio, MYSQL_SERVER_AUTH_INFO *info);
+ int (*hash_password)(const char *password, size_t password_length,
+ char *hash, size_t *hash_length);
+ int (*preprocess_hash)(const char *hash, size_t hash_length,
+ unsigned char *out, size_t *out_length);
+};
+}
diff --git a/include/mysql/plugin_auth_common.h b/include/mysql/plugin_auth_common.h
new file mode 100644
index 00000000..8edd7128
--- /dev/null
+++ b/include/mysql/plugin_auth_common.h
@@ -0,0 +1,131 @@
+#ifndef MYSQL_PLUGIN_AUTH_COMMON_INCLUDED
+/* Copyright (C) 2010 Sergei Golubchik and Monty Program Ab
+ Copyright (c) 2010, Oracle and/or its affiliates.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */
+
+#ifdef _WIN32
+#include <windows.h>
+#endif
+
+/**
+ @file
+
+ This file defines constants and data structures that are the same for
+ both client- and server-side authentication plugins.
+*/
+#define MYSQL_PLUGIN_AUTH_COMMON_INCLUDED
+
+/** the max allowed length for a user name */
+#define MYSQL_USERNAME_LENGTH 512
+
+/**
+ return values of the plugin authenticate_user() method.
+*/
+
+ /**
+ Authentication failed, plugin internal error.
+ An error occurred in the authentication plugin itself.
+ These errors are reported in table performance_schema.host_cache,
+ column COUNT_AUTH_PLUGIN_ERRORS.
+*/
+#define CR_AUTH_PLUGIN_ERROR 3
+/**
+ Authentication failed, client server handshake.
+ An error occurred during the client server handshake.
+ These errors are reported in table performance_schema.host_cache,
+ column COUNT_HANDSHAKE_ERRORS.
+*/
+#define CR_AUTH_HANDSHAKE 2
+/**
+ Authentication failed, user credentials.
+ For example, wrong passwords.
+ These errors are reported in table performance_schema.host_cache,
+ column COUNT_AUTHENTICATION_ERRORS.
+*/
+#define CR_AUTH_USER_CREDENTIALS 1
+/**
+ Authentication failed. Additionally, all other CR_xxx values
+ (libmysql error code) can be used too.
+
+ The client plugin may set the error code and the error message directly
+ in the MYSQL structure and return CR_ERROR. If a CR_xxx specific error
+ code was returned, an error message in the MYSQL structure will be
+ overwritten. If CR_ERROR is returned without setting the error in MYSQL,
+ CR_UNKNOWN_ERROR will be user.
+*/
+#define CR_ERROR 0
+/**
+ Authentication (client part) was successful. It does not mean that the
+ authentication as a whole was successful, usually it only means
+ that the client was able to send the user name and the password to the
+ server. If CR_OK is returned, the libmysql reads the next packet expecting
+ it to be one of OK, ERROR, or CHANGE_PLUGIN packets.
+*/
+#define CR_OK -1
+/**
+ Authentication was successful.
+ It means that the client has done its part successfully and also that
+ a plugin has read the last packet (one of OK, ERROR, CHANGE_PLUGIN).
+ In this case, libmysql will not read a packet from the server,
+ but it will use the data at mysql->net.read_pos.
+
+ A plugin may return this value if the number of roundtrips in the
+ authentication protocol is not known in advance, and the client plugin
+ needs to read one packet more to determine if the authentication is finished
+ or not.
+*/
+#define CR_OK_HANDSHAKE_COMPLETE -2
+
+typedef struct st_plugin_vio_info
+{
+ enum { MYSQL_VIO_INVALID, MYSQL_VIO_TCP, MYSQL_VIO_SOCKET,
+ MYSQL_VIO_PIPE, MYSQL_VIO_MEMORY } protocol;
+ int socket; /**< it's set, if the protocol is SOCKET or TCP */
+#ifdef _WIN32
+ HANDLE handle; /**< it's set, if the protocol is PIPE or MEMORY */
+#endif
+} MYSQL_PLUGIN_VIO_INFO;
+
+/**
+ Provides plugin access to communication channel
+*/
+typedef struct st_plugin_vio
+{
+ /**
+ Plugin provides a pointer reference and this function sets it to the
+ contents of any incoming packet. Returns the packet length, or -1 if
+ the plugin should terminate.
+ */
+ int (*read_packet)(struct st_plugin_vio *vio,
+ unsigned char **buf);
+
+ /**
+ Plugin provides a buffer with data and the length and this
+ function sends it as a packet. Returns 0 on success, 1 on failure.
+ */
+ int (*write_packet)(struct st_plugin_vio *vio,
+ const unsigned char *packet,
+ int packet_len);
+
+ /**
+ Fills in a st_plugin_vio_info structure, providing the information
+ about the connection.
+ */
+ void (*info)(struct st_plugin_vio *vio, struct st_plugin_vio_info *info);
+
+} MYSQL_PLUGIN_VIO;
+
+#endif
+
diff --git a/include/mysql/plugin_data_type.h b/include/mysql/plugin_data_type.h
new file mode 100644
index 00000000..77aa9fb2
--- /dev/null
+++ b/include/mysql/plugin_data_type.h
@@ -0,0 +1,49 @@
+#ifndef MARIADB_PLUGIN_DATA_TYPE_INCLUDED
+#define MARIADB_PLUGIN_DATA_TYPE_INCLUDED
+/* Copyright (C) 2019, Alexander Barkov and MariaDB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */
+
+/**
+ @file
+
+ Data Type Plugin API.
+
+ This file defines the API for server plugins that manage data types.
+*/
+
+#ifdef __cplusplus
+
+#include <mysql/plugin.h>
+
+/*
+ API for data type plugins. (MariaDB_DATA_TYPE_PLUGIN)
+*/
+#define MariaDB_DATA_TYPE_INTERFACE_VERSION (MYSQL_VERSION_ID << 8)
+
+
+struct st_mariadb_data_type
+{
+ int interface_version;
+ class Type_handler *type_handler;
+};
+
+
+/**
+ Data type plugin descriptor
+*/
+
+#endif /* __cplusplus */
+
+#endif /* MARIADB_PLUGIN_DATA_TYPE_INCLUDED */
diff --git a/include/mysql/plugin_data_type.h.pp b/include/mysql/plugin_data_type.h.pp
new file mode 100644
index 00000000..3db2fdd0
--- /dev/null
+++ b/include/mysql/plugin_data_type.h.pp
@@ -0,0 +1,629 @@
+class THD;
+class Item;
+typedef char my_bool;
+typedef void * MYSQL_PLUGIN;
+extern "C" {
+extern "C" {
+extern struct base64_service_st {
+ int (*base64_needed_encoded_length_ptr)(int length_of_data);
+ int (*base64_encode_max_arg_length_ptr)(void);
+ int (*base64_needed_decoded_length_ptr)(int length_of_encoded_data);
+ int (*base64_decode_max_arg_length_ptr)();
+ int (*base64_encode_ptr)(const void *src, size_t src_len, char *dst);
+ int (*base64_decode_ptr)(const char *src, size_t src_len,
+ void *dst, const char **end_ptr, int flags);
+} *base64_service;
+int my_base64_needed_encoded_length(int length_of_data);
+int my_base64_encode_max_arg_length(void);
+int my_base64_needed_decoded_length(int length_of_encoded_data);
+int my_base64_decode_max_arg_length();
+int my_base64_encode(const void *src, size_t src_len, char *dst);
+int my_base64_decode(const char *src, size_t src_len,
+ void *dst, const char **end_ptr, int flags);
+}
+extern "C" {
+extern void (*debug_sync_C_callback_ptr)(THD*, const char *, size_t);
+}
+extern "C" {
+struct encryption_service_st {
+ unsigned int (*encryption_key_get_latest_version_func)(unsigned int key_id);
+ unsigned int (*encryption_key_get_func)(unsigned int key_id, unsigned int key_version,
+ unsigned char* buffer, unsigned int* length);
+ unsigned int (*encryption_ctx_size_func)(unsigned int key_id, unsigned int key_version);
+ int (*encryption_ctx_init_func)(void *ctx, const unsigned char* key, unsigned int klen,
+ const unsigned char* iv, unsigned int ivlen,
+ int flags, unsigned int key_id,
+ unsigned int key_version);
+ int (*encryption_ctx_update_func)(void *ctx, const unsigned char* src, unsigned int slen,
+ unsigned char* dst, unsigned int* dlen);
+ int (*encryption_ctx_finish_func)(void *ctx, unsigned char* dst, unsigned int* dlen);
+ unsigned int (*encryption_encrypted_length_func)(unsigned int slen, unsigned int key_id, unsigned int key_version);
+};
+extern struct encryption_service_st encryption_handler;
+static inline unsigned int encryption_key_id_exists(unsigned int id)
+{
+ return encryption_handler.encryption_key_get_latest_version_func(id) != (~(unsigned int)0);
+}
+static inline unsigned int encryption_key_version_exists(unsigned int id, unsigned int version)
+{
+ unsigned int unused;
+ return encryption_handler.encryption_key_get_func((id),(version),(NULL),(&unused)) != (~(unsigned int)0);
+}
+static inline int encryption_crypt(const unsigned char* src, unsigned int slen,
+ unsigned char* dst, unsigned int* dlen,
+ const unsigned char* key, unsigned int klen,
+ const unsigned char* iv, unsigned int ivlen,
+ int flags, unsigned int key_id, unsigned int key_version)
+{
+ void *ctx= alloca(encryption_handler.encryption_ctx_size_func((key_id),(key_version)));
+ int res1, res2;
+ unsigned int d1, d2;
+ if ((res1= encryption_handler.encryption_ctx_init_func((ctx),(key),(klen),(iv),(ivlen),(flags),(key_id),(key_version))))
+ return res1;
+ res1= encryption_handler.encryption_ctx_update_func((ctx),(src),(slen),(dst),(&d1));
+ res2= encryption_handler.encryption_ctx_finish_func((ctx),(dst + d1),(&d2));
+ *dlen= d1 + d2;
+ return res1 ? res1 : res2;
+}
+}
+extern "C" {
+struct st_encryption_scheme_key {
+ unsigned int version;
+ unsigned char key[16];
+};
+struct st_encryption_scheme {
+ unsigned char iv[16];
+ struct st_encryption_scheme_key key[3];
+ unsigned int keyserver_requests;
+ unsigned int key_id;
+ unsigned int type;
+ void (*locker)(struct st_encryption_scheme *self, int release);
+};
+extern struct encryption_scheme_service_st {
+ int (*encryption_scheme_encrypt_func)
+ (const unsigned char* src, unsigned int slen,
+ unsigned char* dst, unsigned int* dlen,
+ struct st_encryption_scheme *scheme,
+ unsigned int key_version, unsigned int i32_1,
+ unsigned int i32_2, unsigned long long i64);
+ int (*encryption_scheme_decrypt_func)
+ (const unsigned char* src, unsigned int slen,
+ unsigned char* dst, unsigned int* dlen,
+ struct st_encryption_scheme *scheme,
+ unsigned int key_version, unsigned int i32_1,
+ unsigned int i32_2, unsigned long long i64);
+} *encryption_scheme_service;
+int encryption_scheme_encrypt(const unsigned char* src, unsigned int slen,
+ unsigned char* dst, unsigned int* dlen,
+ struct st_encryption_scheme *scheme,
+ unsigned int key_version, unsigned int i32_1,
+ unsigned int i32_2, unsigned long long i64);
+int encryption_scheme_decrypt(const unsigned char* src, unsigned int slen,
+ unsigned char* dst, unsigned int* dlen,
+ struct st_encryption_scheme *scheme,
+ unsigned int key_version, unsigned int i32_1,
+ unsigned int i32_2, unsigned long long i64);
+}
+extern "C" {
+enum thd_kill_levels {
+ THD_IS_NOT_KILLED=0,
+ THD_ABORT_SOFTLY=50,
+ THD_ABORT_ASAP=100,
+};
+extern struct kill_statement_service_st {
+ enum thd_kill_levels (*thd_kill_level_func)(const THD*);
+} *thd_kill_statement_service;
+enum thd_kill_levels thd_kill_level(const THD*);
+}
+extern "C" {
+typedef struct logger_handle_st LOGGER_HANDLE;
+extern struct logger_service_st {
+ void (*logger_init_mutexes)();
+ LOGGER_HANDLE* (*open)(const char *path,
+ unsigned long long size_limit,
+ unsigned int rotations);
+ int (*close)(LOGGER_HANDLE *log);
+ int (*vprintf)(LOGGER_HANDLE *log, const char *fmt, va_list argptr);
+ int (*printf)(LOGGER_HANDLE *log, const char *fmt, ...);
+ int (*write)(LOGGER_HANDLE *log, const char *buffer, size_t size);
+ int (*rotate)(LOGGER_HANDLE *log);
+} *logger_service;
+ void logger_init_mutexes();
+ LOGGER_HANDLE *logger_open(const char *path,
+ unsigned long long size_limit,
+ unsigned int rotations);
+ int logger_close(LOGGER_HANDLE *log);
+ int logger_vprintf(LOGGER_HANDLE *log, const char *fmt, va_list argptr);
+ int logger_printf(LOGGER_HANDLE *log, const char *fmt, ...);
+ int logger_write(LOGGER_HANDLE *log, const char *buffer, size_t size);
+ int logger_rotate(LOGGER_HANDLE *log);
+}
+extern "C" {
+extern struct my_md5_service_st {
+ void (*my_md5_type)(unsigned char*, const char*, size_t);
+ void (*my_md5_multi_type)(unsigned char*, ...);
+ size_t (*my_md5_context_size_type)();
+ void (*my_md5_init_type)(void *);
+ void (*my_md5_input_type)(void *, const unsigned char *, size_t);
+ void (*my_md5_result_type)(void *, unsigned char *);
+} *my_md5_service;
+void my_md5(unsigned char*, const char*, size_t);
+void my_md5_multi(unsigned char*, ...);
+size_t my_md5_context_size();
+void my_md5_init(void *context);
+void my_md5_input(void *context, const unsigned char *buf, size_t len);
+void my_md5_result(void *context, unsigned char *digest);
+}
+extern "C" {
+enum my_aes_mode {
+ MY_AES_ECB, MY_AES_CBC
+};
+extern struct my_crypt_service_st {
+ int (*my_aes_crypt_init)(void *ctx, enum my_aes_mode mode, int flags,
+ const unsigned char* key, unsigned int klen,
+ const unsigned char* iv, unsigned int ivlen);
+ int (*my_aes_crypt_update)(void *ctx, const unsigned char *src, unsigned int slen,
+ unsigned char *dst, unsigned int *dlen);
+ int (*my_aes_crypt_finish)(void *ctx, unsigned char *dst, unsigned int *dlen);
+ int (*my_aes_crypt)(enum my_aes_mode mode, int flags,
+ const unsigned char *src, unsigned int slen, unsigned char *dst, unsigned int *dlen,
+ const unsigned char *key, unsigned int klen, const unsigned char *iv, unsigned int ivlen);
+ unsigned int (*my_aes_get_size)(enum my_aes_mode mode, unsigned int source_length);
+ unsigned int (*my_aes_ctx_size)(enum my_aes_mode mode);
+ int (*my_random_bytes)(unsigned char* buf, int num);
+} *my_crypt_service;
+int my_aes_crypt_init(void *ctx, enum my_aes_mode mode, int flags,
+ const unsigned char* key, unsigned int klen,
+ const unsigned char* iv, unsigned int ivlen);
+int my_aes_crypt_update(void *ctx, const unsigned char *src, unsigned int slen,
+ unsigned char *dst, unsigned int *dlen);
+int my_aes_crypt_finish(void *ctx, unsigned char *dst, unsigned int *dlen);
+int my_aes_crypt(enum my_aes_mode mode, int flags,
+ const unsigned char *src, unsigned int slen, unsigned char *dst, unsigned int *dlen,
+ const unsigned char *key, unsigned int klen, const unsigned char *iv, unsigned int ivlen);
+int my_random_bytes(unsigned char* buf, int num);
+unsigned int my_aes_get_size(enum my_aes_mode mode, unsigned int source_length);
+unsigned int my_aes_ctx_size(enum my_aes_mode mode);
+}
+extern "C" {
+extern struct my_print_error_service_st {
+ void (*my_error_func)(unsigned int nr, unsigned long MyFlags, ...);
+ void (*my_printf_error_func)(unsigned int nr, const char *fmt, unsigned long MyFlags,...);
+ void (*my_printv_error_func)(unsigned int error, const char *format, unsigned long MyFlags, va_list ap);
+} *my_print_error_service;
+extern void my_error(unsigned int nr, unsigned long MyFlags, ...);
+extern void my_printf_error(unsigned int my_err, const char *format, unsigned long MyFlags, ...);
+extern void my_printv_error(unsigned int error, const char *format, unsigned long MyFlags,va_list ap);
+}
+extern "C" {
+extern struct my_snprintf_service_st {
+ size_t (*my_snprintf_type)(char*, size_t, const char*, ...);
+ size_t (*my_vsnprintf_type)(char *, size_t, const char*, va_list);
+} *my_snprintf_service;
+size_t my_snprintf(char* to, size_t n, const char* fmt, ...);
+size_t my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap);
+}
+extern "C" {
+extern struct progress_report_service_st {
+ void (*thd_progress_init_func)(THD* thd, unsigned int max_stage);
+ void (*thd_progress_report_func)(THD* thd,
+ unsigned long long progress,
+ unsigned long long max_progress);
+ void (*thd_progress_next_stage_func)(THD* thd);
+ void (*thd_progress_end_func)(THD* thd);
+ const char *(*set_thd_proc_info_func)(THD*, const char *info,
+ const char *func,
+ const char *file,
+ unsigned int line);
+} *progress_report_service;
+void thd_progress_init(THD* thd, unsigned int max_stage);
+void thd_progress_report(THD* thd,
+ unsigned long long progress,
+ unsigned long long max_progress);
+void thd_progress_next_stage(THD* thd);
+void thd_progress_end(THD* thd);
+const char *set_thd_proc_info(THD*, const char * info, const char *func,
+ const char *file, unsigned int line);
+}
+extern "C" {
+extern struct my_sha1_service_st {
+ void (*my_sha1_type)(unsigned char*, const char*, size_t);
+ void (*my_sha1_multi_type)(unsigned char*, ...);
+ size_t (*my_sha1_context_size_type)();
+ void (*my_sha1_init_type)(void *);
+ void (*my_sha1_input_type)(void *, const unsigned char *, size_t);
+ void (*my_sha1_result_type)(void *, unsigned char *);
+} *my_sha1_service;
+void my_sha1(unsigned char*, const char*, size_t);
+void my_sha1_multi(unsigned char*, ...);
+size_t my_sha1_context_size();
+void my_sha1_init(void *context);
+void my_sha1_input(void *context, const unsigned char *buf, size_t len);
+void my_sha1_result(void *context, unsigned char *digest);
+}
+extern "C" {
+extern struct my_sha2_service_st {
+ void (*my_sha224_type)(unsigned char*, const char*, size_t);
+ void (*my_sha224_multi_type)(unsigned char*, ...);
+ size_t (*my_sha224_context_size_type)();
+ void (*my_sha224_init_type)(void *);
+ void (*my_sha224_input_type)(void *, const unsigned char *, size_t);
+ void (*my_sha224_result_type)(void *, unsigned char *);
+ void (*my_sha256_type)(unsigned char*, const char*, size_t);
+ void (*my_sha256_multi_type)(unsigned char*, ...);
+ size_t (*my_sha256_context_size_type)();
+ void (*my_sha256_init_type)(void *);
+ void (*my_sha256_input_type)(void *, const unsigned char *, size_t);
+ void (*my_sha256_result_type)(void *, unsigned char *);
+ void (*my_sha384_type)(unsigned char*, const char*, size_t);
+ void (*my_sha384_multi_type)(unsigned char*, ...);
+ size_t (*my_sha384_context_size_type)();
+ void (*my_sha384_init_type)(void *);
+ void (*my_sha384_input_type)(void *, const unsigned char *, size_t);
+ void (*my_sha384_result_type)(void *, unsigned char *);
+ void (*my_sha512_type)(unsigned char*, const char*, size_t);
+ void (*my_sha512_multi_type)(unsigned char*, ...);
+ size_t (*my_sha512_context_size_type)();
+ void (*my_sha512_init_type)(void *);
+ void (*my_sha512_input_type)(void *, const unsigned char *, size_t);
+ void (*my_sha512_result_type)(void *, unsigned char *);
+} *my_sha2_service;
+void my_sha224(unsigned char*, const char*, size_t);
+void my_sha224_multi(unsigned char*, ...);
+size_t my_sha224_context_size();
+void my_sha224_init(void *context);
+void my_sha224_input(void *context, const unsigned char *buf, size_t len);
+void my_sha224_result(void *context, unsigned char *digest);
+void my_sha256(unsigned char*, const char*, size_t);
+void my_sha256_multi(unsigned char*, ...);
+size_t my_sha256_context_size();
+void my_sha256_init(void *context);
+void my_sha256_input(void *context, const unsigned char *buf, size_t len);
+void my_sha256_result(void *context, unsigned char *digest);
+void my_sha384(unsigned char*, const char*, size_t);
+void my_sha384_multi(unsigned char*, ...);
+size_t my_sha384_context_size();
+void my_sha384_init(void *context);
+void my_sha384_input(void *context, const unsigned char *buf, size_t len);
+void my_sha384_result(void *context, unsigned char *digest);
+void my_sha512(unsigned char*, const char*, size_t);
+void my_sha512_multi(unsigned char*, ...);
+size_t my_sha512_context_size();
+void my_sha512_init(void *context);
+void my_sha512_input(void *context, const unsigned char *buf, size_t len);
+void my_sha512_result(void *context, unsigned char *digest);
+}
+extern "C" {
+struct st_mysql_lex_string
+{
+ char *str;
+ size_t length;
+};
+typedef struct st_mysql_lex_string MYSQL_LEX_STRING;
+struct st_mysql_const_lex_string
+{
+ const char *str;
+ size_t length;
+};
+typedef struct st_mysql_const_lex_string MYSQL_CONST_LEX_STRING;
+extern struct thd_alloc_service_st {
+ void *(*thd_alloc_func)(THD*, size_t);
+ void *(*thd_calloc_func)(THD*, size_t);
+ char *(*thd_strdup_func)(THD*, const char *);
+ char *(*thd_strmake_func)(THD*, const char *, size_t);
+ void *(*thd_memdup_func)(THD*, const void*, size_t);
+ MYSQL_CONST_LEX_STRING *(*thd_make_lex_string_func)(THD*,
+ MYSQL_CONST_LEX_STRING *,
+ const char *, size_t, int);
+} *thd_alloc_service;
+void *thd_alloc(THD* thd, size_t size);
+void *thd_calloc(THD* thd, size_t size);
+char *thd_strdup(THD* thd, const char *str);
+char *thd_strmake(THD* thd, const char *str, size_t size);
+void *thd_memdup(THD* thd, const void* str, size_t size);
+MYSQL_CONST_LEX_STRING
+*thd_make_lex_string(THD* thd, MYSQL_CONST_LEX_STRING *lex_str,
+ const char *str, size_t size,
+ int allocate_lex_string);
+}
+extern "C" {
+extern struct thd_autoinc_service_st {
+ void (*thd_get_autoinc_func)(const THD* thd,
+ unsigned long* off, unsigned long* inc);
+} *thd_autoinc_service;
+void thd_get_autoinc(const THD* thd,
+ unsigned long* off, unsigned long* inc);
+}
+extern "C" {
+extern struct thd_error_context_service_st {
+ const char *(*thd_get_error_message_func)(const THD* thd);
+ unsigned int (*thd_get_error_number_func)(const THD* thd);
+ unsigned long (*thd_get_error_row_func)(const THD* thd);
+ void (*thd_inc_error_row_func)(THD* thd);
+ char *(*thd_get_error_context_description_func)(THD* thd,
+ char *buffer,
+ unsigned int length,
+ unsigned int max_query_length);
+} *thd_error_context_service;
+const char *thd_get_error_message(const THD* thd);
+unsigned int thd_get_error_number(const THD* thd);
+unsigned long thd_get_error_row(const THD* thd);
+void thd_inc_error_row(THD* thd);
+char *thd_get_error_context_description(THD* thd,
+ char *buffer, unsigned int length,
+ unsigned int max_query_length);
+}
+extern "C" {
+extern struct thd_rnd_service_st {
+ double (*thd_rnd_ptr)(THD* thd);
+ void (*thd_c_r_p_ptr)(THD* thd, char *to, size_t length);
+} *thd_rnd_service;
+double thd_rnd(THD* thd);
+void thd_create_random_password(THD* thd, char *to, size_t length);
+}
+extern "C" {
+typedef int MYSQL_THD_KEY_T;
+extern struct thd_specifics_service_st {
+ int (*thd_key_create_func)(MYSQL_THD_KEY_T *key);
+ void (*thd_key_delete_func)(MYSQL_THD_KEY_T *key);
+ void *(*thd_getspecific_func)(THD* thd, MYSQL_THD_KEY_T key);
+ int (*thd_setspecific_func)(THD* thd, MYSQL_THD_KEY_T key, void *value);
+} *thd_specifics_service;
+int thd_key_create(MYSQL_THD_KEY_T *key);
+void thd_key_delete(MYSQL_THD_KEY_T *key);
+void* thd_getspecific(THD* thd, MYSQL_THD_KEY_T key);
+int thd_setspecific(THD* thd, MYSQL_THD_KEY_T key, void *value);
+}
+typedef long my_time_t;
+enum enum_mysql_timestamp_type
+{
+ MYSQL_TIMESTAMP_NONE= -2, MYSQL_TIMESTAMP_ERROR= -1,
+ MYSQL_TIMESTAMP_DATE= 0, MYSQL_TIMESTAMP_DATETIME= 1, MYSQL_TIMESTAMP_TIME= 2
+};
+typedef struct st_mysql_time
+{
+ unsigned int year, month, day, hour, minute, second;
+ unsigned long second_part;
+ my_bool neg;
+ enum enum_mysql_timestamp_type time_type;
+} MYSQL_TIME;
+extern "C" {
+extern struct thd_timezone_service_st {
+ my_time_t (*thd_TIME_to_gmt_sec)(THD* thd, const MYSQL_TIME *ltime, unsigned int *errcode);
+ void (*thd_gmt_sec_to_TIME)(THD* thd, MYSQL_TIME *ltime, my_time_t t);
+} *thd_timezone_service;
+my_time_t thd_TIME_to_gmt_sec(THD* thd, const MYSQL_TIME *ltime, unsigned int *errcode);
+void thd_gmt_sec_to_TIME(THD* thd, MYSQL_TIME *ltime, my_time_t t);
+}
+extern "C" {
+typedef enum _thd_wait_type_e {
+ THD_WAIT_SLEEP= 1,
+ THD_WAIT_DISKIO= 2,
+ THD_WAIT_ROW_LOCK= 3,
+ THD_WAIT_GLOBAL_LOCK= 4,
+ THD_WAIT_META_DATA_LOCK= 5,
+ THD_WAIT_TABLE_LOCK= 6,
+ THD_WAIT_USER_LOCK= 7,
+ THD_WAIT_BINLOG= 8,
+ THD_WAIT_GROUP_COMMIT= 9,
+ THD_WAIT_SYNC= 10,
+ THD_WAIT_NET= 11,
+ THD_WAIT_LAST= 12
+} thd_wait_type;
+extern struct thd_wait_service_st {
+ void (*thd_wait_begin_func)(THD*, int);
+ void (*thd_wait_end_func)(THD*);
+} *thd_wait_service;
+void thd_wait_begin(THD* thd, int wait_type);
+void thd_wait_end(THD* thd);
+}
+extern "C" {
+enum json_types
+{
+ JSV_BAD_JSON=-1,
+ JSV_NOTHING=0,
+ JSV_OBJECT=1,
+ JSV_ARRAY=2,
+ JSV_STRING=3,
+ JSV_NUMBER=4,
+ JSV_TRUE=5,
+ JSV_FALSE=6,
+ JSV_NULL=7
+};
+extern struct json_service_st {
+ enum json_types (*json_type)(const char *js, const char *js_end,
+ const char **value, int *value_len);
+ enum json_types (*json_get_array_item)(const char *js, const char *js_end,
+ int n_item,
+ const char **value, int *value_len);
+ enum json_types (*json_get_object_key)(const char *js, const char *js_end,
+ const char *key,
+ const char **value, int *value_len);
+ enum json_types (*json_get_object_nkey)(const char *js,const char *js_end,
+ int nkey,
+ const char **keyname, const char **keyname_end,
+ const char **value, int *value_len);
+ int (*json_escape_string)(const char *str,const char *str_end,
+ char *json, char *json_end);
+ int (*json_unescape_json)(const char *json_str, const char *json_end,
+ char *res, char *res_end);
+} *json_service;
+enum json_types json_type(const char *js, const char *js_end,
+ const char **value, int *value_len);
+enum json_types json_get_array_item(const char *js, const char *js_end,
+ int n_item,
+ const char **value, int *value_len);
+enum json_types json_get_object_key(const char *js, const char *js_end,
+ const char *key,
+ const char **value, int *value_len);
+enum json_types json_get_object_nkey(const char *js,const char *js_end, int nkey,
+ const char **keyname, const char **keyname_end,
+ const char **value, int *value_len);
+int json_escape_string(const char *str,const char *str_end,
+ char *json, char *json_end);
+int json_unescape_json(const char *json_str, const char *json_end,
+ char *res, char *res_end);
+}
+}
+struct st_mysql_xid {
+ long formatID;
+ long gtrid_length;
+ long bqual_length;
+ char data[128];
+};
+typedef struct st_mysql_xid MYSQL_XID;
+enum enum_mysql_show_type
+{
+ SHOW_UNDEF, SHOW_BOOL, SHOW_UINT, SHOW_ULONG,
+ SHOW_ULONGLONG, SHOW_CHAR, SHOW_CHAR_PTR,
+ SHOW_ARRAY, SHOW_FUNC, SHOW_DOUBLE,
+ SHOW_SINT, SHOW_SLONG, SHOW_SLONGLONG, SHOW_SIMPLE_FUNC,
+ SHOW_SIZE_T, SHOW_always_last
+};
+enum enum_var_type
+{
+ SHOW_OPT_DEFAULT= 0, SHOW_OPT_SESSION, SHOW_OPT_GLOBAL
+};
+struct st_mysql_show_var {
+ const char *name;
+ void *value;
+ enum enum_mysql_show_type type;
+};
+struct system_status_var;
+typedef int (*mysql_show_var_func)(THD*, struct st_mysql_show_var*, void *, struct system_status_var *status_var, enum enum_var_type);
+struct st_mysql_sys_var;
+struct st_mysql_value;
+typedef int (*mysql_var_check_func)(THD* thd,
+ struct st_mysql_sys_var *var,
+ void *save, struct st_mysql_value *value);
+typedef void (*mysql_var_update_func)(THD* thd,
+ struct st_mysql_sys_var *var,
+ void *var_ptr, const void *save);
+struct st_mysql_plugin
+{
+ int type;
+ void *info;
+ const char *name;
+ const char *author;
+ const char *descr;
+ int license;
+ int (*init)(void *);
+ int (*deinit)(void *);
+ unsigned int version;
+ struct st_mysql_show_var *status_vars;
+ struct st_mysql_sys_var **system_vars;
+ void * __reserved1;
+ unsigned long flags;
+};
+struct st_maria_plugin
+{
+ int type;
+ void *info;
+ const char *name;
+ const char *author;
+ const char *descr;
+ int license;
+ int (*init)(void *);
+ int (*deinit)(void *);
+ unsigned int version;
+ struct st_mysql_show_var *status_vars;
+ struct st_mysql_sys_var **system_vars;
+ const char *version_info;
+ unsigned int maturity;
+};
+extern "C" {
+enum enum_ftparser_mode
+{
+ MYSQL_FTPARSER_SIMPLE_MODE= 0,
+ MYSQL_FTPARSER_WITH_STOPWORDS= 1,
+ MYSQL_FTPARSER_FULL_BOOLEAN_INFO= 2
+};
+enum enum_ft_token_type
+{
+ FT_TOKEN_EOF= 0,
+ FT_TOKEN_WORD= 1,
+ FT_TOKEN_LEFT_PAREN= 2,
+ FT_TOKEN_RIGHT_PAREN= 3,
+ FT_TOKEN_STOPWORD= 4
+};
+typedef struct st_mysql_ftparser_boolean_info
+{
+ enum enum_ft_token_type type;
+ int yesno;
+ int weight_adjust;
+ char wasign;
+ char trunc;
+ char prev;
+ char *quot;
+} MYSQL_FTPARSER_BOOLEAN_INFO;
+typedef struct st_mysql_ftparser_param
+{
+ int (*mysql_parse)(struct st_mysql_ftparser_param *,
+ const char *doc, int doc_len);
+ int (*mysql_add_word)(struct st_mysql_ftparser_param *,
+ const char *word, int word_len,
+ MYSQL_FTPARSER_BOOLEAN_INFO *boolean_info);
+ void *ftparser_state;
+ void *mysql_ftparam;
+ const struct charset_info_st *cs;
+ const char *doc;
+ int length;
+ unsigned int flags;
+ enum enum_ftparser_mode mode;
+} MYSQL_FTPARSER_PARAM;
+struct st_mysql_ftparser
+{
+ int interface_version;
+ int (*parse)(MYSQL_FTPARSER_PARAM *param);
+ int (*init)(MYSQL_FTPARSER_PARAM *param);
+ int (*deinit)(MYSQL_FTPARSER_PARAM *param);
+};
+}
+struct st_mysql_daemon
+{
+ int interface_version;
+};
+struct st_mysql_information_schema
+{
+ int interface_version;
+};
+struct st_mysql_storage_engine
+{
+ int interface_version;
+};
+struct handlerton;
+ struct Mysql_replication {
+ int interface_version;
+ };
+struct st_mysql_value
+{
+ int (*value_type)(struct st_mysql_value *);
+ const char *(*val_str)(struct st_mysql_value *, char *buffer, int *length);
+ int (*val_real)(struct st_mysql_value *, double *realbuf);
+ int (*val_int)(struct st_mysql_value *, long long *intbuf);
+ int (*is_unsigned)(struct st_mysql_value *);
+};
+extern "C" {
+int thd_in_lock_tables(const THD* thd);
+int thd_tablespace_op(const THD* thd);
+long long thd_test_options(const THD* thd, long long test_options);
+int thd_sql_command(const THD* thd);
+void thd_storage_lock_wait(THD* thd, long long value);
+int thd_tx_isolation(const THD* thd);
+int thd_tx_is_read_only(const THD* thd);
+int mysql_tmpfile(const char *prefix);
+unsigned long thd_get_thread_id(const THD* thd);
+void thd_get_xid(const THD* thd, MYSQL_XID *xid);
+void mysql_query_cache_invalidate4(THD* thd,
+ const char *key, unsigned int key_length,
+ int using_trx);
+void *thd_get_ha_data(const THD* thd, const struct handlerton *hton);
+void thd_set_ha_data(THD* thd, const struct handlerton *hton,
+ const void *ha_data);
+void thd_wakeup_subsequent_commits(THD* thd, int wakeup_error);
+}
+struct st_mariadb_data_type
+{
+ int interface_version;
+ class Type_handler *type_handler;
+};
diff --git a/include/mysql/plugin_encryption.h b/include/mysql/plugin_encryption.h
new file mode 100644
index 00000000..3c574aa4
--- /dev/null
+++ b/include/mysql/plugin_encryption.h
@@ -0,0 +1,126 @@
+#ifndef MYSQL_PLUGIN_ENCRYPTION_INCLUDED
+/* Copyright (C) 2014, 2015 Sergei Golubchik and MariaDB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */
+
+/**
+ @file
+
+ Encryption Plugin API.
+
+ This file defines the API for server plugins that manage encryption
+ keys for MariaDB on-disk data encryption.
+*/
+
+#define MYSQL_PLUGIN_ENCRYPTION_INCLUDED
+
+#include <mysql/plugin.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define MariaDB_ENCRYPTION_INTERFACE_VERSION 0x0300
+
+/**
+ Encryption plugin descriptor
+*/
+struct st_mariadb_encryption
+{
+ int interface_version; /**< version plugin uses */
+
+ /*********** KEY MANAGEMENT ********************************************/
+
+ /**
+ function returning latest key version for a given key id
+
+ @return a version or ENCRYPTION_KEY_VERSION_INVALID to indicate an error.
+ */
+ unsigned int (*get_latest_key_version)(unsigned int key_id);
+
+ /**
+ function returning a key for a key version
+
+ @param version the requested key version
+ @param key the key will be stored there. Can be NULL -
+ in which case no key will be returned
+ @param key_length in: key buffer size
+ out: the actual length of the key
+
+ This method can be used to query the key length - the required
+ buffer size - by passing key==NULL.
+
+ If the buffer size is less than the key length the content of the
+ key buffer is undefined (the plugin is free to partially fill it with
+ the key data or leave it untouched).
+
+ @return 0 on success, or
+ ENCRYPTION_KEY_VERSION_INVALID, ENCRYPTION_KEY_BUFFER_TOO_SMALL
+ or any other non-zero number for errors
+ */
+ unsigned int (*get_key)(unsigned int key_id, unsigned int version,
+ unsigned char *key, unsigned int *key_length);
+
+ /*********** ENCRYPTION ************************************************/
+ /*
+ the caller uses encryption as follows:
+ 1. create the encryption context object of the crypt_ctx_size() bytes.
+ 2. initialize it with crypt_ctx_init().
+ 3. repeat crypt_ctx_update() until there are no more data to encrypt.
+ 4. write the remaining output bytes and destroy the context object
+ with crypt_ctx_finish().
+ */
+
+ /**
+ returns the size of the encryption context object in bytes
+ */
+ unsigned int (*crypt_ctx_size)(unsigned int key_id, unsigned int key_version);
+ /**
+ initializes the encryption context object.
+ */
+ int (*crypt_ctx_init)(void *ctx, const unsigned char* key, unsigned int klen,
+ const unsigned char* iv, unsigned int ivlen,
+ int flags, unsigned int key_id,
+ unsigned int key_version);
+ /**
+ processes (encrypts or decrypts) a chunk of data
+
+ writes the output to th dst buffer. note that it might write
+ more bytes that were in the input. or less. or none at all.
+ */
+ int (*crypt_ctx_update)(void *ctx, const unsigned char* src, unsigned int slen,
+ unsigned char* dst, unsigned int* dlen);
+ /**
+ writes the remaining output bytes and destroys the encryption context
+
+ crypt_ctx_update might've cached part of the output in the context,
+ this method will flush these data out.
+ */
+ int (*crypt_ctx_finish)(void *ctx, unsigned char* dst, unsigned int* dlen);
+ /**
+ returns the length of the encrypted data
+
+ it returns the exact length, given only the source length.
+ which means, this API only supports encryption algorithms where
+ the length of the encrypted data only depends on the length of the
+ input (a.k.a. compression is not supported).
+ */
+ unsigned int (*encrypted_length)(unsigned int slen, unsigned int key_id, unsigned int key_version);
+};
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+
diff --git a/include/mysql/plugin_encryption.h.pp b/include/mysql/plugin_encryption.h.pp
new file mode 100644
index 00000000..ff436bb2
--- /dev/null
+++ b/include/mysql/plugin_encryption.h.pp
@@ -0,0 +1,642 @@
+class THD;
+class Item;
+typedef char my_bool;
+typedef void * MYSQL_PLUGIN;
+extern "C" {
+extern "C" {
+extern struct base64_service_st {
+ int (*base64_needed_encoded_length_ptr)(int length_of_data);
+ int (*base64_encode_max_arg_length_ptr)(void);
+ int (*base64_needed_decoded_length_ptr)(int length_of_encoded_data);
+ int (*base64_decode_max_arg_length_ptr)();
+ int (*base64_encode_ptr)(const void *src, size_t src_len, char *dst);
+ int (*base64_decode_ptr)(const char *src, size_t src_len,
+ void *dst, const char **end_ptr, int flags);
+} *base64_service;
+int my_base64_needed_encoded_length(int length_of_data);
+int my_base64_encode_max_arg_length(void);
+int my_base64_needed_decoded_length(int length_of_encoded_data);
+int my_base64_decode_max_arg_length();
+int my_base64_encode(const void *src, size_t src_len, char *dst);
+int my_base64_decode(const char *src, size_t src_len,
+ void *dst, const char **end_ptr, int flags);
+}
+extern "C" {
+extern void (*debug_sync_C_callback_ptr)(THD*, const char *, size_t);
+}
+extern "C" {
+struct encryption_service_st {
+ unsigned int (*encryption_key_get_latest_version_func)(unsigned int key_id);
+ unsigned int (*encryption_key_get_func)(unsigned int key_id, unsigned int key_version,
+ unsigned char* buffer, unsigned int* length);
+ unsigned int (*encryption_ctx_size_func)(unsigned int key_id, unsigned int key_version);
+ int (*encryption_ctx_init_func)(void *ctx, const unsigned char* key, unsigned int klen,
+ const unsigned char* iv, unsigned int ivlen,
+ int flags, unsigned int key_id,
+ unsigned int key_version);
+ int (*encryption_ctx_update_func)(void *ctx, const unsigned char* src, unsigned int slen,
+ unsigned char* dst, unsigned int* dlen);
+ int (*encryption_ctx_finish_func)(void *ctx, unsigned char* dst, unsigned int* dlen);
+ unsigned int (*encryption_encrypted_length_func)(unsigned int slen, unsigned int key_id, unsigned int key_version);
+};
+extern struct encryption_service_st encryption_handler;
+static inline unsigned int encryption_key_id_exists(unsigned int id)
+{
+ return encryption_handler.encryption_key_get_latest_version_func(id) != (~(unsigned int)0);
+}
+static inline unsigned int encryption_key_version_exists(unsigned int id, unsigned int version)
+{
+ unsigned int unused;
+ return encryption_handler.encryption_key_get_func((id),(version),(NULL),(&unused)) != (~(unsigned int)0);
+}
+static inline int encryption_crypt(const unsigned char* src, unsigned int slen,
+ unsigned char* dst, unsigned int* dlen,
+ const unsigned char* key, unsigned int klen,
+ const unsigned char* iv, unsigned int ivlen,
+ int flags, unsigned int key_id, unsigned int key_version)
+{
+ void *ctx= alloca(encryption_handler.encryption_ctx_size_func((key_id),(key_version)));
+ int res1, res2;
+ unsigned int d1, d2;
+ if ((res1= encryption_handler.encryption_ctx_init_func((ctx),(key),(klen),(iv),(ivlen),(flags),(key_id),(key_version))))
+ return res1;
+ res1= encryption_handler.encryption_ctx_update_func((ctx),(src),(slen),(dst),(&d1));
+ res2= encryption_handler.encryption_ctx_finish_func((ctx),(dst + d1),(&d2));
+ *dlen= d1 + d2;
+ return res1 ? res1 : res2;
+}
+}
+extern "C" {
+struct st_encryption_scheme_key {
+ unsigned int version;
+ unsigned char key[16];
+};
+struct st_encryption_scheme {
+ unsigned char iv[16];
+ struct st_encryption_scheme_key key[3];
+ unsigned int keyserver_requests;
+ unsigned int key_id;
+ unsigned int type;
+ void (*locker)(struct st_encryption_scheme *self, int release);
+};
+extern struct encryption_scheme_service_st {
+ int (*encryption_scheme_encrypt_func)
+ (const unsigned char* src, unsigned int slen,
+ unsigned char* dst, unsigned int* dlen,
+ struct st_encryption_scheme *scheme,
+ unsigned int key_version, unsigned int i32_1,
+ unsigned int i32_2, unsigned long long i64);
+ int (*encryption_scheme_decrypt_func)
+ (const unsigned char* src, unsigned int slen,
+ unsigned char* dst, unsigned int* dlen,
+ struct st_encryption_scheme *scheme,
+ unsigned int key_version, unsigned int i32_1,
+ unsigned int i32_2, unsigned long long i64);
+} *encryption_scheme_service;
+int encryption_scheme_encrypt(const unsigned char* src, unsigned int slen,
+ unsigned char* dst, unsigned int* dlen,
+ struct st_encryption_scheme *scheme,
+ unsigned int key_version, unsigned int i32_1,
+ unsigned int i32_2, unsigned long long i64);
+int encryption_scheme_decrypt(const unsigned char* src, unsigned int slen,
+ unsigned char* dst, unsigned int* dlen,
+ struct st_encryption_scheme *scheme,
+ unsigned int key_version, unsigned int i32_1,
+ unsigned int i32_2, unsigned long long i64);
+}
+extern "C" {
+enum thd_kill_levels {
+ THD_IS_NOT_KILLED=0,
+ THD_ABORT_SOFTLY=50,
+ THD_ABORT_ASAP=100,
+};
+extern struct kill_statement_service_st {
+ enum thd_kill_levels (*thd_kill_level_func)(const THD*);
+} *thd_kill_statement_service;
+enum thd_kill_levels thd_kill_level(const THD*);
+}
+extern "C" {
+typedef struct logger_handle_st LOGGER_HANDLE;
+extern struct logger_service_st {
+ void (*logger_init_mutexes)();
+ LOGGER_HANDLE* (*open)(const char *path,
+ unsigned long long size_limit,
+ unsigned int rotations);
+ int (*close)(LOGGER_HANDLE *log);
+ int (*vprintf)(LOGGER_HANDLE *log, const char *fmt, va_list argptr);
+ int (*printf)(LOGGER_HANDLE *log, const char *fmt, ...);
+ int (*write)(LOGGER_HANDLE *log, const char *buffer, size_t size);
+ int (*rotate)(LOGGER_HANDLE *log);
+} *logger_service;
+ void logger_init_mutexes();
+ LOGGER_HANDLE *logger_open(const char *path,
+ unsigned long long size_limit,
+ unsigned int rotations);
+ int logger_close(LOGGER_HANDLE *log);
+ int logger_vprintf(LOGGER_HANDLE *log, const char *fmt, va_list argptr);
+ int logger_printf(LOGGER_HANDLE *log, const char *fmt, ...);
+ int logger_write(LOGGER_HANDLE *log, const char *buffer, size_t size);
+ int logger_rotate(LOGGER_HANDLE *log);
+}
+extern "C" {
+extern struct my_md5_service_st {
+ void (*my_md5_type)(unsigned char*, const char*, size_t);
+ void (*my_md5_multi_type)(unsigned char*, ...);
+ size_t (*my_md5_context_size_type)();
+ void (*my_md5_init_type)(void *);
+ void (*my_md5_input_type)(void *, const unsigned char *, size_t);
+ void (*my_md5_result_type)(void *, unsigned char *);
+} *my_md5_service;
+void my_md5(unsigned char*, const char*, size_t);
+void my_md5_multi(unsigned char*, ...);
+size_t my_md5_context_size();
+void my_md5_init(void *context);
+void my_md5_input(void *context, const unsigned char *buf, size_t len);
+void my_md5_result(void *context, unsigned char *digest);
+}
+extern "C" {
+enum my_aes_mode {
+ MY_AES_ECB, MY_AES_CBC
+};
+extern struct my_crypt_service_st {
+ int (*my_aes_crypt_init)(void *ctx, enum my_aes_mode mode, int flags,
+ const unsigned char* key, unsigned int klen,
+ const unsigned char* iv, unsigned int ivlen);
+ int (*my_aes_crypt_update)(void *ctx, const unsigned char *src, unsigned int slen,
+ unsigned char *dst, unsigned int *dlen);
+ int (*my_aes_crypt_finish)(void *ctx, unsigned char *dst, unsigned int *dlen);
+ int (*my_aes_crypt)(enum my_aes_mode mode, int flags,
+ const unsigned char *src, unsigned int slen, unsigned char *dst, unsigned int *dlen,
+ const unsigned char *key, unsigned int klen, const unsigned char *iv, unsigned int ivlen);
+ unsigned int (*my_aes_get_size)(enum my_aes_mode mode, unsigned int source_length);
+ unsigned int (*my_aes_ctx_size)(enum my_aes_mode mode);
+ int (*my_random_bytes)(unsigned char* buf, int num);
+} *my_crypt_service;
+int my_aes_crypt_init(void *ctx, enum my_aes_mode mode, int flags,
+ const unsigned char* key, unsigned int klen,
+ const unsigned char* iv, unsigned int ivlen);
+int my_aes_crypt_update(void *ctx, const unsigned char *src, unsigned int slen,
+ unsigned char *dst, unsigned int *dlen);
+int my_aes_crypt_finish(void *ctx, unsigned char *dst, unsigned int *dlen);
+int my_aes_crypt(enum my_aes_mode mode, int flags,
+ const unsigned char *src, unsigned int slen, unsigned char *dst, unsigned int *dlen,
+ const unsigned char *key, unsigned int klen, const unsigned char *iv, unsigned int ivlen);
+int my_random_bytes(unsigned char* buf, int num);
+unsigned int my_aes_get_size(enum my_aes_mode mode, unsigned int source_length);
+unsigned int my_aes_ctx_size(enum my_aes_mode mode);
+}
+extern "C" {
+extern struct my_print_error_service_st {
+ void (*my_error_func)(unsigned int nr, unsigned long MyFlags, ...);
+ void (*my_printf_error_func)(unsigned int nr, const char *fmt, unsigned long MyFlags,...);
+ void (*my_printv_error_func)(unsigned int error, const char *format, unsigned long MyFlags, va_list ap);
+} *my_print_error_service;
+extern void my_error(unsigned int nr, unsigned long MyFlags, ...);
+extern void my_printf_error(unsigned int my_err, const char *format, unsigned long MyFlags, ...);
+extern void my_printv_error(unsigned int error, const char *format, unsigned long MyFlags,va_list ap);
+}
+extern "C" {
+extern struct my_snprintf_service_st {
+ size_t (*my_snprintf_type)(char*, size_t, const char*, ...);
+ size_t (*my_vsnprintf_type)(char *, size_t, const char*, va_list);
+} *my_snprintf_service;
+size_t my_snprintf(char* to, size_t n, const char* fmt, ...);
+size_t my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap);
+}
+extern "C" {
+extern struct progress_report_service_st {
+ void (*thd_progress_init_func)(THD* thd, unsigned int max_stage);
+ void (*thd_progress_report_func)(THD* thd,
+ unsigned long long progress,
+ unsigned long long max_progress);
+ void (*thd_progress_next_stage_func)(THD* thd);
+ void (*thd_progress_end_func)(THD* thd);
+ const char *(*set_thd_proc_info_func)(THD*, const char *info,
+ const char *func,
+ const char *file,
+ unsigned int line);
+} *progress_report_service;
+void thd_progress_init(THD* thd, unsigned int max_stage);
+void thd_progress_report(THD* thd,
+ unsigned long long progress,
+ unsigned long long max_progress);
+void thd_progress_next_stage(THD* thd);
+void thd_progress_end(THD* thd);
+const char *set_thd_proc_info(THD*, const char * info, const char *func,
+ const char *file, unsigned int line);
+}
+extern "C" {
+extern struct my_sha1_service_st {
+ void (*my_sha1_type)(unsigned char*, const char*, size_t);
+ void (*my_sha1_multi_type)(unsigned char*, ...);
+ size_t (*my_sha1_context_size_type)();
+ void (*my_sha1_init_type)(void *);
+ void (*my_sha1_input_type)(void *, const unsigned char *, size_t);
+ void (*my_sha1_result_type)(void *, unsigned char *);
+} *my_sha1_service;
+void my_sha1(unsigned char*, const char*, size_t);
+void my_sha1_multi(unsigned char*, ...);
+size_t my_sha1_context_size();
+void my_sha1_init(void *context);
+void my_sha1_input(void *context, const unsigned char *buf, size_t len);
+void my_sha1_result(void *context, unsigned char *digest);
+}
+extern "C" {
+extern struct my_sha2_service_st {
+ void (*my_sha224_type)(unsigned char*, const char*, size_t);
+ void (*my_sha224_multi_type)(unsigned char*, ...);
+ size_t (*my_sha224_context_size_type)();
+ void (*my_sha224_init_type)(void *);
+ void (*my_sha224_input_type)(void *, const unsigned char *, size_t);
+ void (*my_sha224_result_type)(void *, unsigned char *);
+ void (*my_sha256_type)(unsigned char*, const char*, size_t);
+ void (*my_sha256_multi_type)(unsigned char*, ...);
+ size_t (*my_sha256_context_size_type)();
+ void (*my_sha256_init_type)(void *);
+ void (*my_sha256_input_type)(void *, const unsigned char *, size_t);
+ void (*my_sha256_result_type)(void *, unsigned char *);
+ void (*my_sha384_type)(unsigned char*, const char*, size_t);
+ void (*my_sha384_multi_type)(unsigned char*, ...);
+ size_t (*my_sha384_context_size_type)();
+ void (*my_sha384_init_type)(void *);
+ void (*my_sha384_input_type)(void *, const unsigned char *, size_t);
+ void (*my_sha384_result_type)(void *, unsigned char *);
+ void (*my_sha512_type)(unsigned char*, const char*, size_t);
+ void (*my_sha512_multi_type)(unsigned char*, ...);
+ size_t (*my_sha512_context_size_type)();
+ void (*my_sha512_init_type)(void *);
+ void (*my_sha512_input_type)(void *, const unsigned char *, size_t);
+ void (*my_sha512_result_type)(void *, unsigned char *);
+} *my_sha2_service;
+void my_sha224(unsigned char*, const char*, size_t);
+void my_sha224_multi(unsigned char*, ...);
+size_t my_sha224_context_size();
+void my_sha224_init(void *context);
+void my_sha224_input(void *context, const unsigned char *buf, size_t len);
+void my_sha224_result(void *context, unsigned char *digest);
+void my_sha256(unsigned char*, const char*, size_t);
+void my_sha256_multi(unsigned char*, ...);
+size_t my_sha256_context_size();
+void my_sha256_init(void *context);
+void my_sha256_input(void *context, const unsigned char *buf, size_t len);
+void my_sha256_result(void *context, unsigned char *digest);
+void my_sha384(unsigned char*, const char*, size_t);
+void my_sha384_multi(unsigned char*, ...);
+size_t my_sha384_context_size();
+void my_sha384_init(void *context);
+void my_sha384_input(void *context, const unsigned char *buf, size_t len);
+void my_sha384_result(void *context, unsigned char *digest);
+void my_sha512(unsigned char*, const char*, size_t);
+void my_sha512_multi(unsigned char*, ...);
+size_t my_sha512_context_size();
+void my_sha512_init(void *context);
+void my_sha512_input(void *context, const unsigned char *buf, size_t len);
+void my_sha512_result(void *context, unsigned char *digest);
+}
+extern "C" {
+struct st_mysql_lex_string
+{
+ char *str;
+ size_t length;
+};
+typedef struct st_mysql_lex_string MYSQL_LEX_STRING;
+struct st_mysql_const_lex_string
+{
+ const char *str;
+ size_t length;
+};
+typedef struct st_mysql_const_lex_string MYSQL_CONST_LEX_STRING;
+extern struct thd_alloc_service_st {
+ void *(*thd_alloc_func)(THD*, size_t);
+ void *(*thd_calloc_func)(THD*, size_t);
+ char *(*thd_strdup_func)(THD*, const char *);
+ char *(*thd_strmake_func)(THD*, const char *, size_t);
+ void *(*thd_memdup_func)(THD*, const void*, size_t);
+ MYSQL_CONST_LEX_STRING *(*thd_make_lex_string_func)(THD*,
+ MYSQL_CONST_LEX_STRING *,
+ const char *, size_t, int);
+} *thd_alloc_service;
+void *thd_alloc(THD* thd, size_t size);
+void *thd_calloc(THD* thd, size_t size);
+char *thd_strdup(THD* thd, const char *str);
+char *thd_strmake(THD* thd, const char *str, size_t size);
+void *thd_memdup(THD* thd, const void* str, size_t size);
+MYSQL_CONST_LEX_STRING
+*thd_make_lex_string(THD* thd, MYSQL_CONST_LEX_STRING *lex_str,
+ const char *str, size_t size,
+ int allocate_lex_string);
+}
+extern "C" {
+extern struct thd_autoinc_service_st {
+ void (*thd_get_autoinc_func)(const THD* thd,
+ unsigned long* off, unsigned long* inc);
+} *thd_autoinc_service;
+void thd_get_autoinc(const THD* thd,
+ unsigned long* off, unsigned long* inc);
+}
+extern "C" {
+extern struct thd_error_context_service_st {
+ const char *(*thd_get_error_message_func)(const THD* thd);
+ unsigned int (*thd_get_error_number_func)(const THD* thd);
+ unsigned long (*thd_get_error_row_func)(const THD* thd);
+ void (*thd_inc_error_row_func)(THD* thd);
+ char *(*thd_get_error_context_description_func)(THD* thd,
+ char *buffer,
+ unsigned int length,
+ unsigned int max_query_length);
+} *thd_error_context_service;
+const char *thd_get_error_message(const THD* thd);
+unsigned int thd_get_error_number(const THD* thd);
+unsigned long thd_get_error_row(const THD* thd);
+void thd_inc_error_row(THD* thd);
+char *thd_get_error_context_description(THD* thd,
+ char *buffer, unsigned int length,
+ unsigned int max_query_length);
+}
+extern "C" {
+extern struct thd_rnd_service_st {
+ double (*thd_rnd_ptr)(THD* thd);
+ void (*thd_c_r_p_ptr)(THD* thd, char *to, size_t length);
+} *thd_rnd_service;
+double thd_rnd(THD* thd);
+void thd_create_random_password(THD* thd, char *to, size_t length);
+}
+extern "C" {
+typedef int MYSQL_THD_KEY_T;
+extern struct thd_specifics_service_st {
+ int (*thd_key_create_func)(MYSQL_THD_KEY_T *key);
+ void (*thd_key_delete_func)(MYSQL_THD_KEY_T *key);
+ void *(*thd_getspecific_func)(THD* thd, MYSQL_THD_KEY_T key);
+ int (*thd_setspecific_func)(THD* thd, MYSQL_THD_KEY_T key, void *value);
+} *thd_specifics_service;
+int thd_key_create(MYSQL_THD_KEY_T *key);
+void thd_key_delete(MYSQL_THD_KEY_T *key);
+void* thd_getspecific(THD* thd, MYSQL_THD_KEY_T key);
+int thd_setspecific(THD* thd, MYSQL_THD_KEY_T key, void *value);
+}
+typedef long my_time_t;
+enum enum_mysql_timestamp_type
+{
+ MYSQL_TIMESTAMP_NONE= -2, MYSQL_TIMESTAMP_ERROR= -1,
+ MYSQL_TIMESTAMP_DATE= 0, MYSQL_TIMESTAMP_DATETIME= 1, MYSQL_TIMESTAMP_TIME= 2
+};
+typedef struct st_mysql_time
+{
+ unsigned int year, month, day, hour, minute, second;
+ unsigned long second_part;
+ my_bool neg;
+ enum enum_mysql_timestamp_type time_type;
+} MYSQL_TIME;
+extern "C" {
+extern struct thd_timezone_service_st {
+ my_time_t (*thd_TIME_to_gmt_sec)(THD* thd, const MYSQL_TIME *ltime, unsigned int *errcode);
+ void (*thd_gmt_sec_to_TIME)(THD* thd, MYSQL_TIME *ltime, my_time_t t);
+} *thd_timezone_service;
+my_time_t thd_TIME_to_gmt_sec(THD* thd, const MYSQL_TIME *ltime, unsigned int *errcode);
+void thd_gmt_sec_to_TIME(THD* thd, MYSQL_TIME *ltime, my_time_t t);
+}
+extern "C" {
+typedef enum _thd_wait_type_e {
+ THD_WAIT_SLEEP= 1,
+ THD_WAIT_DISKIO= 2,
+ THD_WAIT_ROW_LOCK= 3,
+ THD_WAIT_GLOBAL_LOCK= 4,
+ THD_WAIT_META_DATA_LOCK= 5,
+ THD_WAIT_TABLE_LOCK= 6,
+ THD_WAIT_USER_LOCK= 7,
+ THD_WAIT_BINLOG= 8,
+ THD_WAIT_GROUP_COMMIT= 9,
+ THD_WAIT_SYNC= 10,
+ THD_WAIT_NET= 11,
+ THD_WAIT_LAST= 12
+} thd_wait_type;
+extern struct thd_wait_service_st {
+ void (*thd_wait_begin_func)(THD*, int);
+ void (*thd_wait_end_func)(THD*);
+} *thd_wait_service;
+void thd_wait_begin(THD* thd, int wait_type);
+void thd_wait_end(THD* thd);
+}
+extern "C" {
+enum json_types
+{
+ JSV_BAD_JSON=-1,
+ JSV_NOTHING=0,
+ JSV_OBJECT=1,
+ JSV_ARRAY=2,
+ JSV_STRING=3,
+ JSV_NUMBER=4,
+ JSV_TRUE=5,
+ JSV_FALSE=6,
+ JSV_NULL=7
+};
+extern struct json_service_st {
+ enum json_types (*json_type)(const char *js, const char *js_end,
+ const char **value, int *value_len);
+ enum json_types (*json_get_array_item)(const char *js, const char *js_end,
+ int n_item,
+ const char **value, int *value_len);
+ enum json_types (*json_get_object_key)(const char *js, const char *js_end,
+ const char *key,
+ const char **value, int *value_len);
+ enum json_types (*json_get_object_nkey)(const char *js,const char *js_end,
+ int nkey,
+ const char **keyname, const char **keyname_end,
+ const char **value, int *value_len);
+ int (*json_escape_string)(const char *str,const char *str_end,
+ char *json, char *json_end);
+ int (*json_unescape_json)(const char *json_str, const char *json_end,
+ char *res, char *res_end);
+} *json_service;
+enum json_types json_type(const char *js, const char *js_end,
+ const char **value, int *value_len);
+enum json_types json_get_array_item(const char *js, const char *js_end,
+ int n_item,
+ const char **value, int *value_len);
+enum json_types json_get_object_key(const char *js, const char *js_end,
+ const char *key,
+ const char **value, int *value_len);
+enum json_types json_get_object_nkey(const char *js,const char *js_end, int nkey,
+ const char **keyname, const char **keyname_end,
+ const char **value, int *value_len);
+int json_escape_string(const char *str,const char *str_end,
+ char *json, char *json_end);
+int json_unescape_json(const char *json_str, const char *json_end,
+ char *res, char *res_end);
+}
+}
+struct st_mysql_xid {
+ long formatID;
+ long gtrid_length;
+ long bqual_length;
+ char data[128];
+};
+typedef struct st_mysql_xid MYSQL_XID;
+enum enum_mysql_show_type
+{
+ SHOW_UNDEF, SHOW_BOOL, SHOW_UINT, SHOW_ULONG,
+ SHOW_ULONGLONG, SHOW_CHAR, SHOW_CHAR_PTR,
+ SHOW_ARRAY, SHOW_FUNC, SHOW_DOUBLE,
+ SHOW_SINT, SHOW_SLONG, SHOW_SLONGLONG, SHOW_SIMPLE_FUNC,
+ SHOW_SIZE_T, SHOW_always_last
+};
+enum enum_var_type
+{
+ SHOW_OPT_DEFAULT= 0, SHOW_OPT_SESSION, SHOW_OPT_GLOBAL
+};
+struct st_mysql_show_var {
+ const char *name;
+ void *value;
+ enum enum_mysql_show_type type;
+};
+struct system_status_var;
+typedef int (*mysql_show_var_func)(THD*, struct st_mysql_show_var*, void *, struct system_status_var *status_var, enum enum_var_type);
+struct st_mysql_sys_var;
+struct st_mysql_value;
+typedef int (*mysql_var_check_func)(THD* thd,
+ struct st_mysql_sys_var *var,
+ void *save, struct st_mysql_value *value);
+typedef void (*mysql_var_update_func)(THD* thd,
+ struct st_mysql_sys_var *var,
+ void *var_ptr, const void *save);
+struct st_mysql_plugin
+{
+ int type;
+ void *info;
+ const char *name;
+ const char *author;
+ const char *descr;
+ int license;
+ int (*init)(void *);
+ int (*deinit)(void *);
+ unsigned int version;
+ struct st_mysql_show_var *status_vars;
+ struct st_mysql_sys_var **system_vars;
+ void * __reserved1;
+ unsigned long flags;
+};
+struct st_maria_plugin
+{
+ int type;
+ void *info;
+ const char *name;
+ const char *author;
+ const char *descr;
+ int license;
+ int (*init)(void *);
+ int (*deinit)(void *);
+ unsigned int version;
+ struct st_mysql_show_var *status_vars;
+ struct st_mysql_sys_var **system_vars;
+ const char *version_info;
+ unsigned int maturity;
+};
+extern "C" {
+enum enum_ftparser_mode
+{
+ MYSQL_FTPARSER_SIMPLE_MODE= 0,
+ MYSQL_FTPARSER_WITH_STOPWORDS= 1,
+ MYSQL_FTPARSER_FULL_BOOLEAN_INFO= 2
+};
+enum enum_ft_token_type
+{
+ FT_TOKEN_EOF= 0,
+ FT_TOKEN_WORD= 1,
+ FT_TOKEN_LEFT_PAREN= 2,
+ FT_TOKEN_RIGHT_PAREN= 3,
+ FT_TOKEN_STOPWORD= 4
+};
+typedef struct st_mysql_ftparser_boolean_info
+{
+ enum enum_ft_token_type type;
+ int yesno;
+ int weight_adjust;
+ char wasign;
+ char trunc;
+ char prev;
+ char *quot;
+} MYSQL_FTPARSER_BOOLEAN_INFO;
+typedef struct st_mysql_ftparser_param
+{
+ int (*mysql_parse)(struct st_mysql_ftparser_param *,
+ const char *doc, int doc_len);
+ int (*mysql_add_word)(struct st_mysql_ftparser_param *,
+ const char *word, int word_len,
+ MYSQL_FTPARSER_BOOLEAN_INFO *boolean_info);
+ void *ftparser_state;
+ void *mysql_ftparam;
+ const struct charset_info_st *cs;
+ const char *doc;
+ int length;
+ unsigned int flags;
+ enum enum_ftparser_mode mode;
+} MYSQL_FTPARSER_PARAM;
+struct st_mysql_ftparser
+{
+ int interface_version;
+ int (*parse)(MYSQL_FTPARSER_PARAM *param);
+ int (*init)(MYSQL_FTPARSER_PARAM *param);
+ int (*deinit)(MYSQL_FTPARSER_PARAM *param);
+};
+}
+struct st_mysql_daemon
+{
+ int interface_version;
+};
+struct st_mysql_information_schema
+{
+ int interface_version;
+};
+struct st_mysql_storage_engine
+{
+ int interface_version;
+};
+struct handlerton;
+ struct Mysql_replication {
+ int interface_version;
+ };
+struct st_mysql_value
+{
+ int (*value_type)(struct st_mysql_value *);
+ const char *(*val_str)(struct st_mysql_value *, char *buffer, int *length);
+ int (*val_real)(struct st_mysql_value *, double *realbuf);
+ int (*val_int)(struct st_mysql_value *, long long *intbuf);
+ int (*is_unsigned)(struct st_mysql_value *);
+};
+extern "C" {
+int thd_in_lock_tables(const THD* thd);
+int thd_tablespace_op(const THD* thd);
+long long thd_test_options(const THD* thd, long long test_options);
+int thd_sql_command(const THD* thd);
+void thd_storage_lock_wait(THD* thd, long long value);
+int thd_tx_isolation(const THD* thd);
+int thd_tx_is_read_only(const THD* thd);
+int mysql_tmpfile(const char *prefix);
+unsigned long thd_get_thread_id(const THD* thd);
+void thd_get_xid(const THD* thd, MYSQL_XID *xid);
+void mysql_query_cache_invalidate4(THD* thd,
+ const char *key, unsigned int key_length,
+ int using_trx);
+void *thd_get_ha_data(const THD* thd, const struct handlerton *hton);
+void thd_set_ha_data(THD* thd, const struct handlerton *hton,
+ const void *ha_data);
+void thd_wakeup_subsequent_commits(THD* thd, int wakeup_error);
+}
+extern "C" {
+struct st_mariadb_encryption
+{
+ int interface_version;
+ unsigned int (*get_latest_key_version)(unsigned int key_id);
+ unsigned int (*get_key)(unsigned int key_id, unsigned int version,
+ unsigned char *key, unsigned int *key_length);
+ unsigned int (*crypt_ctx_size)(unsigned int key_id, unsigned int key_version);
+ int (*crypt_ctx_init)(void *ctx, const unsigned char* key, unsigned int klen,
+ const unsigned char* iv, unsigned int ivlen,
+ int flags, unsigned int key_id,
+ unsigned int key_version);
+ int (*crypt_ctx_update)(void *ctx, const unsigned char* src, unsigned int slen,
+ unsigned char* dst, unsigned int* dlen);
+ int (*crypt_ctx_finish)(void *ctx, unsigned char* dst, unsigned int* dlen);
+ unsigned int (*encrypted_length)(unsigned int slen, unsigned int key_id, unsigned int key_version);
+};
+}
diff --git a/include/mysql/plugin_ftparser.h b/include/mysql/plugin_ftparser.h
new file mode 100644
index 00000000..8db87129
--- /dev/null
+++ b/include/mysql/plugin_ftparser.h
@@ -0,0 +1,222 @@
+/* Copyright (c) 2005 MySQL AB, 2009 Sun Microsystems, Inc.
+ Use is subject to license terms.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */
+
+#ifndef _my_plugin_ftparser_h
+#define _my_plugin_ftparser_h
+#include "plugin.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*************************************************************************
+ API for Full-text parser plugin. (MYSQL_FTPARSER_PLUGIN)
+*/
+
+#define MYSQL_FTPARSER_INTERFACE_VERSION 0x0100
+
+/* Parsing modes. Set in MYSQL_FTPARSER_PARAM::mode */
+enum enum_ftparser_mode
+{
+/*
+ Fast and simple mode. This mode is used for indexing, and natural
+ language queries.
+
+ The parser is expected to return only those words that go into the
+ index. Stopwords or too short/long words should not be returned. The
+ 'boolean_info' argument of mysql_add_word() does not have to be set.
+*/
+ MYSQL_FTPARSER_SIMPLE_MODE= 0,
+
+/*
+ Parse with stopwords mode. This mode is used in boolean searches for
+ "phrase matching."
+
+ The parser is not allowed to ignore words in this mode. Every word
+ should be returned, including stopwords and words that are too short
+ or long. The 'boolean_info' argument of mysql_add_word() does not
+ have to be set.
+*/
+ MYSQL_FTPARSER_WITH_STOPWORDS= 1,
+
+/*
+ Parse in boolean mode. This mode is used to parse a boolean query string.
+
+ The parser should provide a valid MYSQL_FTPARSER_BOOLEAN_INFO
+ structure in the 'boolean_info' argument to mysql_add_word().
+ Usually that means that the parser should recognize boolean operators
+ in the parsing stream and set appropriate fields in
+ MYSQL_FTPARSER_BOOLEAN_INFO structure accordingly. As for
+ MYSQL_FTPARSER_WITH_STOPWORDS mode, no word should be ignored.
+ Instead, use FT_TOKEN_STOPWORD for the token type of such a word.
+*/
+ MYSQL_FTPARSER_FULL_BOOLEAN_INFO= 2
+};
+
+/*
+ Token types for boolean mode searching (used for the type member of
+ MYSQL_FTPARSER_BOOLEAN_INFO struct)
+
+ FT_TOKEN_EOF: End of data.
+ FT_TOKEN_WORD: Regular word.
+ FT_TOKEN_LEFT_PAREN: Left parenthesis (start of group/sub-expression).
+ FT_TOKEN_RIGHT_PAREN: Right parenthesis (end of group/sub-expression).
+ FT_TOKEN_STOPWORD: Stopword.
+*/
+
+enum enum_ft_token_type
+{
+ FT_TOKEN_EOF= 0,
+ FT_TOKEN_WORD= 1,
+ FT_TOKEN_LEFT_PAREN= 2,
+ FT_TOKEN_RIGHT_PAREN= 3,
+ FT_TOKEN_STOPWORD= 4
+};
+
+/*
+ This structure is used in boolean search mode only. It conveys
+ boolean-mode metadata to the MySQL search engine for every word in
+ the search query. A valid instance of this structure must be filled
+ in by the plugin parser and passed as an argument in the call to
+ mysql_add_word (the callback function in the MYSQL_FTPARSER_PARAM
+ structure) when a query is parsed in boolean mode.
+
+ type: The token type. Should be one of the enum_ft_token_type values.
+
+ yesno: Whether the word must be present for a match to occur:
+ >0 Must be present
+ <0 Must not be present
+ 0 Neither; the word is optional but its presence increases the relevance
+ With the default settings of the ft_boolean_syntax system variable,
+ >0 corresponds to the '+' operator, <0 corrresponds to the '-' operator,
+ and 0 means neither operator was used.
+
+ weight_adjust: A weighting factor that determines how much a match
+ for the word counts. Positive values increase, negative - decrease the
+ relative word's importance in the query.
+
+ wasign: The sign of the word's weight in the query. If it's non-negative
+ the match for the word will increase document relevance, if it's
+ negative - decrease (the word becomes a "noise word", the less of it the
+ better).
+
+ trunc: Corresponds to the '*' operator in the default setting of the
+ ft_boolean_syntax system variable.
+*/
+
+typedef struct st_mysql_ftparser_boolean_info
+{
+ enum enum_ft_token_type type;
+ int yesno;
+ int weight_adjust;
+ char wasign;
+ char trunc;
+ /* These are parser state and must be removed. */
+ char prev;
+ char *quot;
+} MYSQL_FTPARSER_BOOLEAN_INFO;
+
+/*
+ The following flag means that buffer with a string (document, word)
+ may be overwritten by the caller before the end of the parsing (that is
+ before st_mysql_ftparser::deinit() call). If one needs the string
+ to survive between two successive calls of the parsing function, she
+ needs to save a copy of it. The flag may be set by MySQL before calling
+ st_mysql_ftparser::parse(), or it may be set by a plugin before calling
+ st_mysql_ftparser_param::mysql_parse() or
+ st_mysql_ftparser_param::mysql_add_word().
+*/
+#define MYSQL_FTFLAGS_NEED_COPY 1
+
+/*
+ An argument of the full-text parser plugin. This structure is
+ filled in by MySQL server and passed to the parsing function of the
+ plugin as an in/out parameter.
+
+ mysql_parse: A pointer to the built-in parser implementation of the
+ server. It's set by the server and can be used by the parser plugin
+ to invoke the MySQL default parser. If plugin's role is to extract
+ textual data from .doc, .pdf or .xml content, it might extract
+ plaintext from the content, and then pass the text to the default
+ MySQL parser to be parsed.
+
+ mysql_add_word: A server callback to add a new word. When parsing
+ a document, the server sets this to point at a function that adds
+ the word to MySQL full-text index. When parsing a search query,
+ this function will add the new word to the list of words to search
+ for. The boolean_info argument can be NULL for all cases except
+ when mode is MYSQL_FTPARSER_FULL_BOOLEAN_INFO. A plugin can replace this
+ callback to post-process every parsed word before passing it to the original
+ mysql_add_word function.
+
+ ftparser_state: A generic pointer. The plugin can set it to point
+ to information to be used internally for its own purposes.
+
+ mysql_ftparam: This is set by the server. It is used by MySQL functions
+ called via mysql_parse() and mysql_add_word() callback. The plugin
+ should not modify it.
+
+ cs: Information about the character set of the document or query string.
+
+ doc: A pointer to the document or query string to be parsed.
+
+ length: Length of the document or query string, in bytes.
+
+ flags: See MYSQL_FTFLAGS_* constants above.
+
+ mode: The parsing mode. With boolean operators, with stopwords, or
+ nothing. See enum_ftparser_mode above.
+*/
+
+typedef struct st_mysql_ftparser_param
+{
+ int (*mysql_parse)(struct st_mysql_ftparser_param *,
+ const char *doc, int doc_len);
+ int (*mysql_add_word)(struct st_mysql_ftparser_param *,
+ const char *word, int word_len,
+ MYSQL_FTPARSER_BOOLEAN_INFO *boolean_info);
+ void *ftparser_state;
+ void *mysql_ftparam;
+ const struct charset_info_st *cs;
+ const char *doc;
+ int length;
+ unsigned int flags;
+ enum enum_ftparser_mode mode;
+} MYSQL_FTPARSER_PARAM;
+
+/*
+ Full-text parser descriptor.
+
+ interface_version is, e.g., MYSQL_FTPARSER_INTERFACE_VERSION.
+ The parsing, initialization, and deinitialization functions are
+ invoked per SQL statement for which the parser is used.
+*/
+
+struct st_mysql_ftparser
+{
+ int interface_version;
+ int (*parse)(MYSQL_FTPARSER_PARAM *param);
+ int (*init)(MYSQL_FTPARSER_PARAM *param);
+ int (*deinit)(MYSQL_FTPARSER_PARAM *param);
+};
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/include/mysql/plugin_ftparser.h.pp b/include/mysql/plugin_ftparser.h.pp
new file mode 100644
index 00000000..daefd6b2
--- /dev/null
+++ b/include/mysql/plugin_ftparser.h.pp
@@ -0,0 +1,624 @@
+class THD;
+class Item;
+typedef char my_bool;
+typedef void * MYSQL_PLUGIN;
+extern "C" {
+extern "C" {
+extern struct base64_service_st {
+ int (*base64_needed_encoded_length_ptr)(int length_of_data);
+ int (*base64_encode_max_arg_length_ptr)(void);
+ int (*base64_needed_decoded_length_ptr)(int length_of_encoded_data);
+ int (*base64_decode_max_arg_length_ptr)();
+ int (*base64_encode_ptr)(const void *src, size_t src_len, char *dst);
+ int (*base64_decode_ptr)(const char *src, size_t src_len,
+ void *dst, const char **end_ptr, int flags);
+} *base64_service;
+int my_base64_needed_encoded_length(int length_of_data);
+int my_base64_encode_max_arg_length(void);
+int my_base64_needed_decoded_length(int length_of_encoded_data);
+int my_base64_decode_max_arg_length();
+int my_base64_encode(const void *src, size_t src_len, char *dst);
+int my_base64_decode(const char *src, size_t src_len,
+ void *dst, const char **end_ptr, int flags);
+}
+extern "C" {
+extern void (*debug_sync_C_callback_ptr)(THD*, const char *, size_t);
+}
+extern "C" {
+struct encryption_service_st {
+ unsigned int (*encryption_key_get_latest_version_func)(unsigned int key_id);
+ unsigned int (*encryption_key_get_func)(unsigned int key_id, unsigned int key_version,
+ unsigned char* buffer, unsigned int* length);
+ unsigned int (*encryption_ctx_size_func)(unsigned int key_id, unsigned int key_version);
+ int (*encryption_ctx_init_func)(void *ctx, const unsigned char* key, unsigned int klen,
+ const unsigned char* iv, unsigned int ivlen,
+ int flags, unsigned int key_id,
+ unsigned int key_version);
+ int (*encryption_ctx_update_func)(void *ctx, const unsigned char* src, unsigned int slen,
+ unsigned char* dst, unsigned int* dlen);
+ int (*encryption_ctx_finish_func)(void *ctx, unsigned char* dst, unsigned int* dlen);
+ unsigned int (*encryption_encrypted_length_func)(unsigned int slen, unsigned int key_id, unsigned int key_version);
+};
+extern struct encryption_service_st encryption_handler;
+static inline unsigned int encryption_key_id_exists(unsigned int id)
+{
+ return encryption_handler.encryption_key_get_latest_version_func(id) != (~(unsigned int)0);
+}
+static inline unsigned int encryption_key_version_exists(unsigned int id, unsigned int version)
+{
+ unsigned int unused;
+ return encryption_handler.encryption_key_get_func((id),(version),(NULL),(&unused)) != (~(unsigned int)0);
+}
+static inline int encryption_crypt(const unsigned char* src, unsigned int slen,
+ unsigned char* dst, unsigned int* dlen,
+ const unsigned char* key, unsigned int klen,
+ const unsigned char* iv, unsigned int ivlen,
+ int flags, unsigned int key_id, unsigned int key_version)
+{
+ void *ctx= alloca(encryption_handler.encryption_ctx_size_func((key_id),(key_version)));
+ int res1, res2;
+ unsigned int d1, d2;
+ if ((res1= encryption_handler.encryption_ctx_init_func((ctx),(key),(klen),(iv),(ivlen),(flags),(key_id),(key_version))))
+ return res1;
+ res1= encryption_handler.encryption_ctx_update_func((ctx),(src),(slen),(dst),(&d1));
+ res2= encryption_handler.encryption_ctx_finish_func((ctx),(dst + d1),(&d2));
+ *dlen= d1 + d2;
+ return res1 ? res1 : res2;
+}
+}
+extern "C" {
+struct st_encryption_scheme_key {
+ unsigned int version;
+ unsigned char key[16];
+};
+struct st_encryption_scheme {
+ unsigned char iv[16];
+ struct st_encryption_scheme_key key[3];
+ unsigned int keyserver_requests;
+ unsigned int key_id;
+ unsigned int type;
+ void (*locker)(struct st_encryption_scheme *self, int release);
+};
+extern struct encryption_scheme_service_st {
+ int (*encryption_scheme_encrypt_func)
+ (const unsigned char* src, unsigned int slen,
+ unsigned char* dst, unsigned int* dlen,
+ struct st_encryption_scheme *scheme,
+ unsigned int key_version, unsigned int i32_1,
+ unsigned int i32_2, unsigned long long i64);
+ int (*encryption_scheme_decrypt_func)
+ (const unsigned char* src, unsigned int slen,
+ unsigned char* dst, unsigned int* dlen,
+ struct st_encryption_scheme *scheme,
+ unsigned int key_version, unsigned int i32_1,
+ unsigned int i32_2, unsigned long long i64);
+} *encryption_scheme_service;
+int encryption_scheme_encrypt(const unsigned char* src, unsigned int slen,
+ unsigned char* dst, unsigned int* dlen,
+ struct st_encryption_scheme *scheme,
+ unsigned int key_version, unsigned int i32_1,
+ unsigned int i32_2, unsigned long long i64);
+int encryption_scheme_decrypt(const unsigned char* src, unsigned int slen,
+ unsigned char* dst, unsigned int* dlen,
+ struct st_encryption_scheme *scheme,
+ unsigned int key_version, unsigned int i32_1,
+ unsigned int i32_2, unsigned long long i64);
+}
+extern "C" {
+enum thd_kill_levels {
+ THD_IS_NOT_KILLED=0,
+ THD_ABORT_SOFTLY=50,
+ THD_ABORT_ASAP=100,
+};
+extern struct kill_statement_service_st {
+ enum thd_kill_levels (*thd_kill_level_func)(const THD*);
+} *thd_kill_statement_service;
+enum thd_kill_levels thd_kill_level(const THD*);
+}
+extern "C" {
+typedef struct logger_handle_st LOGGER_HANDLE;
+extern struct logger_service_st {
+ void (*logger_init_mutexes)();
+ LOGGER_HANDLE* (*open)(const char *path,
+ unsigned long long size_limit,
+ unsigned int rotations);
+ int (*close)(LOGGER_HANDLE *log);
+ int (*vprintf)(LOGGER_HANDLE *log, const char *fmt, va_list argptr);
+ int (*printf)(LOGGER_HANDLE *log, const char *fmt, ...);
+ int (*write)(LOGGER_HANDLE *log, const char *buffer, size_t size);
+ int (*rotate)(LOGGER_HANDLE *log);
+} *logger_service;
+ void logger_init_mutexes();
+ LOGGER_HANDLE *logger_open(const char *path,
+ unsigned long long size_limit,
+ unsigned int rotations);
+ int logger_close(LOGGER_HANDLE *log);
+ int logger_vprintf(LOGGER_HANDLE *log, const char *fmt, va_list argptr);
+ int logger_printf(LOGGER_HANDLE *log, const char *fmt, ...);
+ int logger_write(LOGGER_HANDLE *log, const char *buffer, size_t size);
+ int logger_rotate(LOGGER_HANDLE *log);
+}
+extern "C" {
+extern struct my_md5_service_st {
+ void (*my_md5_type)(unsigned char*, const char*, size_t);
+ void (*my_md5_multi_type)(unsigned char*, ...);
+ size_t (*my_md5_context_size_type)();
+ void (*my_md5_init_type)(void *);
+ void (*my_md5_input_type)(void *, const unsigned char *, size_t);
+ void (*my_md5_result_type)(void *, unsigned char *);
+} *my_md5_service;
+void my_md5(unsigned char*, const char*, size_t);
+void my_md5_multi(unsigned char*, ...);
+size_t my_md5_context_size();
+void my_md5_init(void *context);
+void my_md5_input(void *context, const unsigned char *buf, size_t len);
+void my_md5_result(void *context, unsigned char *digest);
+}
+extern "C" {
+enum my_aes_mode {
+ MY_AES_ECB, MY_AES_CBC
+};
+extern struct my_crypt_service_st {
+ int (*my_aes_crypt_init)(void *ctx, enum my_aes_mode mode, int flags,
+ const unsigned char* key, unsigned int klen,
+ const unsigned char* iv, unsigned int ivlen);
+ int (*my_aes_crypt_update)(void *ctx, const unsigned char *src, unsigned int slen,
+ unsigned char *dst, unsigned int *dlen);
+ int (*my_aes_crypt_finish)(void *ctx, unsigned char *dst, unsigned int *dlen);
+ int (*my_aes_crypt)(enum my_aes_mode mode, int flags,
+ const unsigned char *src, unsigned int slen, unsigned char *dst, unsigned int *dlen,
+ const unsigned char *key, unsigned int klen, const unsigned char *iv, unsigned int ivlen);
+ unsigned int (*my_aes_get_size)(enum my_aes_mode mode, unsigned int source_length);
+ unsigned int (*my_aes_ctx_size)(enum my_aes_mode mode);
+ int (*my_random_bytes)(unsigned char* buf, int num);
+} *my_crypt_service;
+int my_aes_crypt_init(void *ctx, enum my_aes_mode mode, int flags,
+ const unsigned char* key, unsigned int klen,
+ const unsigned char* iv, unsigned int ivlen);
+int my_aes_crypt_update(void *ctx, const unsigned char *src, unsigned int slen,
+ unsigned char *dst, unsigned int *dlen);
+int my_aes_crypt_finish(void *ctx, unsigned char *dst, unsigned int *dlen);
+int my_aes_crypt(enum my_aes_mode mode, int flags,
+ const unsigned char *src, unsigned int slen, unsigned char *dst, unsigned int *dlen,
+ const unsigned char *key, unsigned int klen, const unsigned char *iv, unsigned int ivlen);
+int my_random_bytes(unsigned char* buf, int num);
+unsigned int my_aes_get_size(enum my_aes_mode mode, unsigned int source_length);
+unsigned int my_aes_ctx_size(enum my_aes_mode mode);
+}
+extern "C" {
+extern struct my_print_error_service_st {
+ void (*my_error_func)(unsigned int nr, unsigned long MyFlags, ...);
+ void (*my_printf_error_func)(unsigned int nr, const char *fmt, unsigned long MyFlags,...);
+ void (*my_printv_error_func)(unsigned int error, const char *format, unsigned long MyFlags, va_list ap);
+} *my_print_error_service;
+extern void my_error(unsigned int nr, unsigned long MyFlags, ...);
+extern void my_printf_error(unsigned int my_err, const char *format, unsigned long MyFlags, ...);
+extern void my_printv_error(unsigned int error, const char *format, unsigned long MyFlags,va_list ap);
+}
+extern "C" {
+extern struct my_snprintf_service_st {
+ size_t (*my_snprintf_type)(char*, size_t, const char*, ...);
+ size_t (*my_vsnprintf_type)(char *, size_t, const char*, va_list);
+} *my_snprintf_service;
+size_t my_snprintf(char* to, size_t n, const char* fmt, ...);
+size_t my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap);
+}
+extern "C" {
+extern struct progress_report_service_st {
+ void (*thd_progress_init_func)(THD* thd, unsigned int max_stage);
+ void (*thd_progress_report_func)(THD* thd,
+ unsigned long long progress,
+ unsigned long long max_progress);
+ void (*thd_progress_next_stage_func)(THD* thd);
+ void (*thd_progress_end_func)(THD* thd);
+ const char *(*set_thd_proc_info_func)(THD*, const char *info,
+ const char *func,
+ const char *file,
+ unsigned int line);
+} *progress_report_service;
+void thd_progress_init(THD* thd, unsigned int max_stage);
+void thd_progress_report(THD* thd,
+ unsigned long long progress,
+ unsigned long long max_progress);
+void thd_progress_next_stage(THD* thd);
+void thd_progress_end(THD* thd);
+const char *set_thd_proc_info(THD*, const char * info, const char *func,
+ const char *file, unsigned int line);
+}
+extern "C" {
+extern struct my_sha1_service_st {
+ void (*my_sha1_type)(unsigned char*, const char*, size_t);
+ void (*my_sha1_multi_type)(unsigned char*, ...);
+ size_t (*my_sha1_context_size_type)();
+ void (*my_sha1_init_type)(void *);
+ void (*my_sha1_input_type)(void *, const unsigned char *, size_t);
+ void (*my_sha1_result_type)(void *, unsigned char *);
+} *my_sha1_service;
+void my_sha1(unsigned char*, const char*, size_t);
+void my_sha1_multi(unsigned char*, ...);
+size_t my_sha1_context_size();
+void my_sha1_init(void *context);
+void my_sha1_input(void *context, const unsigned char *buf, size_t len);
+void my_sha1_result(void *context, unsigned char *digest);
+}
+extern "C" {
+extern struct my_sha2_service_st {
+ void (*my_sha224_type)(unsigned char*, const char*, size_t);
+ void (*my_sha224_multi_type)(unsigned char*, ...);
+ size_t (*my_sha224_context_size_type)();
+ void (*my_sha224_init_type)(void *);
+ void (*my_sha224_input_type)(void *, const unsigned char *, size_t);
+ void (*my_sha224_result_type)(void *, unsigned char *);
+ void (*my_sha256_type)(unsigned char*, const char*, size_t);
+ void (*my_sha256_multi_type)(unsigned char*, ...);
+ size_t (*my_sha256_context_size_type)();
+ void (*my_sha256_init_type)(void *);
+ void (*my_sha256_input_type)(void *, const unsigned char *, size_t);
+ void (*my_sha256_result_type)(void *, unsigned char *);
+ void (*my_sha384_type)(unsigned char*, const char*, size_t);
+ void (*my_sha384_multi_type)(unsigned char*, ...);
+ size_t (*my_sha384_context_size_type)();
+ void (*my_sha384_init_type)(void *);
+ void (*my_sha384_input_type)(void *, const unsigned char *, size_t);
+ void (*my_sha384_result_type)(void *, unsigned char *);
+ void (*my_sha512_type)(unsigned char*, const char*, size_t);
+ void (*my_sha512_multi_type)(unsigned char*, ...);
+ size_t (*my_sha512_context_size_type)();
+ void (*my_sha512_init_type)(void *);
+ void (*my_sha512_input_type)(void *, const unsigned char *, size_t);
+ void (*my_sha512_result_type)(void *, unsigned char *);
+} *my_sha2_service;
+void my_sha224(unsigned char*, const char*, size_t);
+void my_sha224_multi(unsigned char*, ...);
+size_t my_sha224_context_size();
+void my_sha224_init(void *context);
+void my_sha224_input(void *context, const unsigned char *buf, size_t len);
+void my_sha224_result(void *context, unsigned char *digest);
+void my_sha256(unsigned char*, const char*, size_t);
+void my_sha256_multi(unsigned char*, ...);
+size_t my_sha256_context_size();
+void my_sha256_init(void *context);
+void my_sha256_input(void *context, const unsigned char *buf, size_t len);
+void my_sha256_result(void *context, unsigned char *digest);
+void my_sha384(unsigned char*, const char*, size_t);
+void my_sha384_multi(unsigned char*, ...);
+size_t my_sha384_context_size();
+void my_sha384_init(void *context);
+void my_sha384_input(void *context, const unsigned char *buf, size_t len);
+void my_sha384_result(void *context, unsigned char *digest);
+void my_sha512(unsigned char*, const char*, size_t);
+void my_sha512_multi(unsigned char*, ...);
+size_t my_sha512_context_size();
+void my_sha512_init(void *context);
+void my_sha512_input(void *context, const unsigned char *buf, size_t len);
+void my_sha512_result(void *context, unsigned char *digest);
+}
+extern "C" {
+struct st_mysql_lex_string
+{
+ char *str;
+ size_t length;
+};
+typedef struct st_mysql_lex_string MYSQL_LEX_STRING;
+struct st_mysql_const_lex_string
+{
+ const char *str;
+ size_t length;
+};
+typedef struct st_mysql_const_lex_string MYSQL_CONST_LEX_STRING;
+extern struct thd_alloc_service_st {
+ void *(*thd_alloc_func)(THD*, size_t);
+ void *(*thd_calloc_func)(THD*, size_t);
+ char *(*thd_strdup_func)(THD*, const char *);
+ char *(*thd_strmake_func)(THD*, const char *, size_t);
+ void *(*thd_memdup_func)(THD*, const void*, size_t);
+ MYSQL_CONST_LEX_STRING *(*thd_make_lex_string_func)(THD*,
+ MYSQL_CONST_LEX_STRING *,
+ const char *, size_t, int);
+} *thd_alloc_service;
+void *thd_alloc(THD* thd, size_t size);
+void *thd_calloc(THD* thd, size_t size);
+char *thd_strdup(THD* thd, const char *str);
+char *thd_strmake(THD* thd, const char *str, size_t size);
+void *thd_memdup(THD* thd, const void* str, size_t size);
+MYSQL_CONST_LEX_STRING
+*thd_make_lex_string(THD* thd, MYSQL_CONST_LEX_STRING *lex_str,
+ const char *str, size_t size,
+ int allocate_lex_string);
+}
+extern "C" {
+extern struct thd_autoinc_service_st {
+ void (*thd_get_autoinc_func)(const THD* thd,
+ unsigned long* off, unsigned long* inc);
+} *thd_autoinc_service;
+void thd_get_autoinc(const THD* thd,
+ unsigned long* off, unsigned long* inc);
+}
+extern "C" {
+extern struct thd_error_context_service_st {
+ const char *(*thd_get_error_message_func)(const THD* thd);
+ unsigned int (*thd_get_error_number_func)(const THD* thd);
+ unsigned long (*thd_get_error_row_func)(const THD* thd);
+ void (*thd_inc_error_row_func)(THD* thd);
+ char *(*thd_get_error_context_description_func)(THD* thd,
+ char *buffer,
+ unsigned int length,
+ unsigned int max_query_length);
+} *thd_error_context_service;
+const char *thd_get_error_message(const THD* thd);
+unsigned int thd_get_error_number(const THD* thd);
+unsigned long thd_get_error_row(const THD* thd);
+void thd_inc_error_row(THD* thd);
+char *thd_get_error_context_description(THD* thd,
+ char *buffer, unsigned int length,
+ unsigned int max_query_length);
+}
+extern "C" {
+extern struct thd_rnd_service_st {
+ double (*thd_rnd_ptr)(THD* thd);
+ void (*thd_c_r_p_ptr)(THD* thd, char *to, size_t length);
+} *thd_rnd_service;
+double thd_rnd(THD* thd);
+void thd_create_random_password(THD* thd, char *to, size_t length);
+}
+extern "C" {
+typedef int MYSQL_THD_KEY_T;
+extern struct thd_specifics_service_st {
+ int (*thd_key_create_func)(MYSQL_THD_KEY_T *key);
+ void (*thd_key_delete_func)(MYSQL_THD_KEY_T *key);
+ void *(*thd_getspecific_func)(THD* thd, MYSQL_THD_KEY_T key);
+ int (*thd_setspecific_func)(THD* thd, MYSQL_THD_KEY_T key, void *value);
+} *thd_specifics_service;
+int thd_key_create(MYSQL_THD_KEY_T *key);
+void thd_key_delete(MYSQL_THD_KEY_T *key);
+void* thd_getspecific(THD* thd, MYSQL_THD_KEY_T key);
+int thd_setspecific(THD* thd, MYSQL_THD_KEY_T key, void *value);
+}
+typedef long my_time_t;
+enum enum_mysql_timestamp_type
+{
+ MYSQL_TIMESTAMP_NONE= -2, MYSQL_TIMESTAMP_ERROR= -1,
+ MYSQL_TIMESTAMP_DATE= 0, MYSQL_TIMESTAMP_DATETIME= 1, MYSQL_TIMESTAMP_TIME= 2
+};
+typedef struct st_mysql_time
+{
+ unsigned int year, month, day, hour, minute, second;
+ unsigned long second_part;
+ my_bool neg;
+ enum enum_mysql_timestamp_type time_type;
+} MYSQL_TIME;
+extern "C" {
+extern struct thd_timezone_service_st {
+ my_time_t (*thd_TIME_to_gmt_sec)(THD* thd, const MYSQL_TIME *ltime, unsigned int *errcode);
+ void (*thd_gmt_sec_to_TIME)(THD* thd, MYSQL_TIME *ltime, my_time_t t);
+} *thd_timezone_service;
+my_time_t thd_TIME_to_gmt_sec(THD* thd, const MYSQL_TIME *ltime, unsigned int *errcode);
+void thd_gmt_sec_to_TIME(THD* thd, MYSQL_TIME *ltime, my_time_t t);
+}
+extern "C" {
+typedef enum _thd_wait_type_e {
+ THD_WAIT_SLEEP= 1,
+ THD_WAIT_DISKIO= 2,
+ THD_WAIT_ROW_LOCK= 3,
+ THD_WAIT_GLOBAL_LOCK= 4,
+ THD_WAIT_META_DATA_LOCK= 5,
+ THD_WAIT_TABLE_LOCK= 6,
+ THD_WAIT_USER_LOCK= 7,
+ THD_WAIT_BINLOG= 8,
+ THD_WAIT_GROUP_COMMIT= 9,
+ THD_WAIT_SYNC= 10,
+ THD_WAIT_NET= 11,
+ THD_WAIT_LAST= 12
+} thd_wait_type;
+extern struct thd_wait_service_st {
+ void (*thd_wait_begin_func)(THD*, int);
+ void (*thd_wait_end_func)(THD*);
+} *thd_wait_service;
+void thd_wait_begin(THD* thd, int wait_type);
+void thd_wait_end(THD* thd);
+}
+extern "C" {
+enum json_types
+{
+ JSV_BAD_JSON=-1,
+ JSV_NOTHING=0,
+ JSV_OBJECT=1,
+ JSV_ARRAY=2,
+ JSV_STRING=3,
+ JSV_NUMBER=4,
+ JSV_TRUE=5,
+ JSV_FALSE=6,
+ JSV_NULL=7
+};
+extern struct json_service_st {
+ enum json_types (*json_type)(const char *js, const char *js_end,
+ const char **value, int *value_len);
+ enum json_types (*json_get_array_item)(const char *js, const char *js_end,
+ int n_item,
+ const char **value, int *value_len);
+ enum json_types (*json_get_object_key)(const char *js, const char *js_end,
+ const char *key,
+ const char **value, int *value_len);
+ enum json_types (*json_get_object_nkey)(const char *js,const char *js_end,
+ int nkey,
+ const char **keyname, const char **keyname_end,
+ const char **value, int *value_len);
+ int (*json_escape_string)(const char *str,const char *str_end,
+ char *json, char *json_end);
+ int (*json_unescape_json)(const char *json_str, const char *json_end,
+ char *res, char *res_end);
+} *json_service;
+enum json_types json_type(const char *js, const char *js_end,
+ const char **value, int *value_len);
+enum json_types json_get_array_item(const char *js, const char *js_end,
+ int n_item,
+ const char **value, int *value_len);
+enum json_types json_get_object_key(const char *js, const char *js_end,
+ const char *key,
+ const char **value, int *value_len);
+enum json_types json_get_object_nkey(const char *js,const char *js_end, int nkey,
+ const char **keyname, const char **keyname_end,
+ const char **value, int *value_len);
+int json_escape_string(const char *str,const char *str_end,
+ char *json, char *json_end);
+int json_unescape_json(const char *json_str, const char *json_end,
+ char *res, char *res_end);
+}
+}
+struct st_mysql_xid {
+ long formatID;
+ long gtrid_length;
+ long bqual_length;
+ char data[128];
+};
+typedef struct st_mysql_xid MYSQL_XID;
+enum enum_mysql_show_type
+{
+ SHOW_UNDEF, SHOW_BOOL, SHOW_UINT, SHOW_ULONG,
+ SHOW_ULONGLONG, SHOW_CHAR, SHOW_CHAR_PTR,
+ SHOW_ARRAY, SHOW_FUNC, SHOW_DOUBLE,
+ SHOW_SINT, SHOW_SLONG, SHOW_SLONGLONG, SHOW_SIMPLE_FUNC,
+ SHOW_SIZE_T, SHOW_always_last
+};
+enum enum_var_type
+{
+ SHOW_OPT_DEFAULT= 0, SHOW_OPT_SESSION, SHOW_OPT_GLOBAL
+};
+struct st_mysql_show_var {
+ const char *name;
+ void *value;
+ enum enum_mysql_show_type type;
+};
+struct system_status_var;
+typedef int (*mysql_show_var_func)(THD*, struct st_mysql_show_var*, void *, struct system_status_var *status_var, enum enum_var_type);
+struct st_mysql_sys_var;
+struct st_mysql_value;
+typedef int (*mysql_var_check_func)(THD* thd,
+ struct st_mysql_sys_var *var,
+ void *save, struct st_mysql_value *value);
+typedef void (*mysql_var_update_func)(THD* thd,
+ struct st_mysql_sys_var *var,
+ void *var_ptr, const void *save);
+struct st_mysql_plugin
+{
+ int type;
+ void *info;
+ const char *name;
+ const char *author;
+ const char *descr;
+ int license;
+ int (*init)(void *);
+ int (*deinit)(void *);
+ unsigned int version;
+ struct st_mysql_show_var *status_vars;
+ struct st_mysql_sys_var **system_vars;
+ void * __reserved1;
+ unsigned long flags;
+};
+struct st_maria_plugin
+{
+ int type;
+ void *info;
+ const char *name;
+ const char *author;
+ const char *descr;
+ int license;
+ int (*init)(void *);
+ int (*deinit)(void *);
+ unsigned int version;
+ struct st_mysql_show_var *status_vars;
+ struct st_mysql_sys_var **system_vars;
+ const char *version_info;
+ unsigned int maturity;
+};
+struct st_mysql_daemon
+{
+ int interface_version;
+};
+struct st_mysql_information_schema
+{
+ int interface_version;
+};
+struct st_mysql_storage_engine
+{
+ int interface_version;
+};
+struct handlerton;
+ struct Mysql_replication {
+ int interface_version;
+ };
+struct st_mysql_value
+{
+ int (*value_type)(struct st_mysql_value *);
+ const char *(*val_str)(struct st_mysql_value *, char *buffer, int *length);
+ int (*val_real)(struct st_mysql_value *, double *realbuf);
+ int (*val_int)(struct st_mysql_value *, long long *intbuf);
+ int (*is_unsigned)(struct st_mysql_value *);
+};
+extern "C" {
+int thd_in_lock_tables(const THD* thd);
+int thd_tablespace_op(const THD* thd);
+long long thd_test_options(const THD* thd, long long test_options);
+int thd_sql_command(const THD* thd);
+void thd_storage_lock_wait(THD* thd, long long value);
+int thd_tx_isolation(const THD* thd);
+int thd_tx_is_read_only(const THD* thd);
+int mysql_tmpfile(const char *prefix);
+unsigned long thd_get_thread_id(const THD* thd);
+void thd_get_xid(const THD* thd, MYSQL_XID *xid);
+void mysql_query_cache_invalidate4(THD* thd,
+ const char *key, unsigned int key_length,
+ int using_trx);
+void *thd_get_ha_data(const THD* thd, const struct handlerton *hton);
+void thd_set_ha_data(THD* thd, const struct handlerton *hton,
+ const void *ha_data);
+void thd_wakeup_subsequent_commits(THD* thd, int wakeup_error);
+}
+extern "C" {
+enum enum_ftparser_mode
+{
+ MYSQL_FTPARSER_SIMPLE_MODE= 0,
+ MYSQL_FTPARSER_WITH_STOPWORDS= 1,
+ MYSQL_FTPARSER_FULL_BOOLEAN_INFO= 2
+};
+enum enum_ft_token_type
+{
+ FT_TOKEN_EOF= 0,
+ FT_TOKEN_WORD= 1,
+ FT_TOKEN_LEFT_PAREN= 2,
+ FT_TOKEN_RIGHT_PAREN= 3,
+ FT_TOKEN_STOPWORD= 4
+};
+typedef struct st_mysql_ftparser_boolean_info
+{
+ enum enum_ft_token_type type;
+ int yesno;
+ int weight_adjust;
+ char wasign;
+ char trunc;
+ char prev;
+ char *quot;
+} MYSQL_FTPARSER_BOOLEAN_INFO;
+typedef struct st_mysql_ftparser_param
+{
+ int (*mysql_parse)(struct st_mysql_ftparser_param *,
+ const char *doc, int doc_len);
+ int (*mysql_add_word)(struct st_mysql_ftparser_param *,
+ const char *word, int word_len,
+ MYSQL_FTPARSER_BOOLEAN_INFO *boolean_info);
+ void *ftparser_state;
+ void *mysql_ftparam;
+ const struct charset_info_st *cs;
+ const char *doc;
+ int length;
+ unsigned int flags;
+ enum enum_ftparser_mode mode;
+} MYSQL_FTPARSER_PARAM;
+struct st_mysql_ftparser
+{
+ int interface_version;
+ int (*parse)(MYSQL_FTPARSER_PARAM *param);
+ int (*init)(MYSQL_FTPARSER_PARAM *param);
+ int (*deinit)(MYSQL_FTPARSER_PARAM *param);
+};
+}
diff --git a/include/mysql/plugin_function.h b/include/mysql/plugin_function.h
new file mode 100644
index 00000000..117acd43
--- /dev/null
+++ b/include/mysql/plugin_function.h
@@ -0,0 +1,54 @@
+#ifndef MARIADB_PLUGIN_FUNCTION_INCLUDED
+#define MARIADB_PLUGIN_FUNCTION_INCLUDED
+/* Copyright (C) 2019, Alexander Barkov and MariaDB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */
+
+/**
+ @file
+
+ Function Plugin API.
+
+ This file defines the API for server plugins that manage functions.
+*/
+
+#ifdef __cplusplus
+
+#include <mysql/plugin.h>
+
+/*
+ API for function plugins. (MariaDB_FUNCTION_PLUGIN)
+*/
+#define MariaDB_FUNCTION_INTERFACE_VERSION (MYSQL_VERSION_ID << 8)
+
+
+class Plugin_function
+{
+ int m_interface_version;
+ Create_func *m_builder;
+public:
+ Plugin_function(Create_func *builder)
+ :m_interface_version(MariaDB_FUNCTION_INTERFACE_VERSION),
+ m_builder(builder)
+ { }
+ Create_func *create_func()
+ {
+ return m_builder;
+ }
+};
+
+
+#endif /* __cplusplus */
+
+#endif /* MARIADB_PLUGIN_FUNCTION_INCLUDED */
diff --git a/include/mysql/plugin_function.h.pp b/include/mysql/plugin_function.h.pp
new file mode 100644
index 00000000..0f915c84
--- /dev/null
+++ b/include/mysql/plugin_function.h.pp
@@ -0,0 +1,638 @@
+class THD;
+class Item;
+typedef char my_bool;
+typedef void * MYSQL_PLUGIN;
+extern "C" {
+extern "C" {
+extern struct base64_service_st {
+ int (*base64_needed_encoded_length_ptr)(int length_of_data);
+ int (*base64_encode_max_arg_length_ptr)(void);
+ int (*base64_needed_decoded_length_ptr)(int length_of_encoded_data);
+ int (*base64_decode_max_arg_length_ptr)();
+ int (*base64_encode_ptr)(const void *src, size_t src_len, char *dst);
+ int (*base64_decode_ptr)(const char *src, size_t src_len,
+ void *dst, const char **end_ptr, int flags);
+} *base64_service;
+int my_base64_needed_encoded_length(int length_of_data);
+int my_base64_encode_max_arg_length(void);
+int my_base64_needed_decoded_length(int length_of_encoded_data);
+int my_base64_decode_max_arg_length();
+int my_base64_encode(const void *src, size_t src_len, char *dst);
+int my_base64_decode(const char *src, size_t src_len,
+ void *dst, const char **end_ptr, int flags);
+}
+extern "C" {
+extern void (*debug_sync_C_callback_ptr)(THD*, const char *, size_t);
+}
+extern "C" {
+struct encryption_service_st {
+ unsigned int (*encryption_key_get_latest_version_func)(unsigned int key_id);
+ unsigned int (*encryption_key_get_func)(unsigned int key_id, unsigned int key_version,
+ unsigned char* buffer, unsigned int* length);
+ unsigned int (*encryption_ctx_size_func)(unsigned int key_id, unsigned int key_version);
+ int (*encryption_ctx_init_func)(void *ctx, const unsigned char* key, unsigned int klen,
+ const unsigned char* iv, unsigned int ivlen,
+ int flags, unsigned int key_id,
+ unsigned int key_version);
+ int (*encryption_ctx_update_func)(void *ctx, const unsigned char* src, unsigned int slen,
+ unsigned char* dst, unsigned int* dlen);
+ int (*encryption_ctx_finish_func)(void *ctx, unsigned char* dst, unsigned int* dlen);
+ unsigned int (*encryption_encrypted_length_func)(unsigned int slen, unsigned int key_id, unsigned int key_version);
+};
+extern struct encryption_service_st encryption_handler;
+static inline unsigned int encryption_key_id_exists(unsigned int id)
+{
+ return encryption_handler.encryption_key_get_latest_version_func(id) != (~(unsigned int)0);
+}
+static inline unsigned int encryption_key_version_exists(unsigned int id, unsigned int version)
+{
+ unsigned int unused;
+ return encryption_handler.encryption_key_get_func((id),(version),(NULL),(&unused)) != (~(unsigned int)0);
+}
+static inline int encryption_crypt(const unsigned char* src, unsigned int slen,
+ unsigned char* dst, unsigned int* dlen,
+ const unsigned char* key, unsigned int klen,
+ const unsigned char* iv, unsigned int ivlen,
+ int flags, unsigned int key_id, unsigned int key_version)
+{
+ void *ctx= alloca(encryption_handler.encryption_ctx_size_func((key_id),(key_version)));
+ int res1, res2;
+ unsigned int d1, d2;
+ if ((res1= encryption_handler.encryption_ctx_init_func((ctx),(key),(klen),(iv),(ivlen),(flags),(key_id),(key_version))))
+ return res1;
+ res1= encryption_handler.encryption_ctx_update_func((ctx),(src),(slen),(dst),(&d1));
+ res2= encryption_handler.encryption_ctx_finish_func((ctx),(dst + d1),(&d2));
+ *dlen= d1 + d2;
+ return res1 ? res1 : res2;
+}
+}
+extern "C" {
+struct st_encryption_scheme_key {
+ unsigned int version;
+ unsigned char key[16];
+};
+struct st_encryption_scheme {
+ unsigned char iv[16];
+ struct st_encryption_scheme_key key[3];
+ unsigned int keyserver_requests;
+ unsigned int key_id;
+ unsigned int type;
+ void (*locker)(struct st_encryption_scheme *self, int release);
+};
+extern struct encryption_scheme_service_st {
+ int (*encryption_scheme_encrypt_func)
+ (const unsigned char* src, unsigned int slen,
+ unsigned char* dst, unsigned int* dlen,
+ struct st_encryption_scheme *scheme,
+ unsigned int key_version, unsigned int i32_1,
+ unsigned int i32_2, unsigned long long i64);
+ int (*encryption_scheme_decrypt_func)
+ (const unsigned char* src, unsigned int slen,
+ unsigned char* dst, unsigned int* dlen,
+ struct st_encryption_scheme *scheme,
+ unsigned int key_version, unsigned int i32_1,
+ unsigned int i32_2, unsigned long long i64);
+} *encryption_scheme_service;
+int encryption_scheme_encrypt(const unsigned char* src, unsigned int slen,
+ unsigned char* dst, unsigned int* dlen,
+ struct st_encryption_scheme *scheme,
+ unsigned int key_version, unsigned int i32_1,
+ unsigned int i32_2, unsigned long long i64);
+int encryption_scheme_decrypt(const unsigned char* src, unsigned int slen,
+ unsigned char* dst, unsigned int* dlen,
+ struct st_encryption_scheme *scheme,
+ unsigned int key_version, unsigned int i32_1,
+ unsigned int i32_2, unsigned long long i64);
+}
+extern "C" {
+enum thd_kill_levels {
+ THD_IS_NOT_KILLED=0,
+ THD_ABORT_SOFTLY=50,
+ THD_ABORT_ASAP=100,
+};
+extern struct kill_statement_service_st {
+ enum thd_kill_levels (*thd_kill_level_func)(const THD*);
+} *thd_kill_statement_service;
+enum thd_kill_levels thd_kill_level(const THD*);
+}
+extern "C" {
+typedef struct logger_handle_st LOGGER_HANDLE;
+extern struct logger_service_st {
+ void (*logger_init_mutexes)();
+ LOGGER_HANDLE* (*open)(const char *path,
+ unsigned long long size_limit,
+ unsigned int rotations);
+ int (*close)(LOGGER_HANDLE *log);
+ int (*vprintf)(LOGGER_HANDLE *log, const char *fmt, va_list argptr);
+ int (*printf)(LOGGER_HANDLE *log, const char *fmt, ...);
+ int (*write)(LOGGER_HANDLE *log, const char *buffer, size_t size);
+ int (*rotate)(LOGGER_HANDLE *log);
+} *logger_service;
+ void logger_init_mutexes();
+ LOGGER_HANDLE *logger_open(const char *path,
+ unsigned long long size_limit,
+ unsigned int rotations);
+ int logger_close(LOGGER_HANDLE *log);
+ int logger_vprintf(LOGGER_HANDLE *log, const char *fmt, va_list argptr);
+ int logger_printf(LOGGER_HANDLE *log, const char *fmt, ...);
+ int logger_write(LOGGER_HANDLE *log, const char *buffer, size_t size);
+ int logger_rotate(LOGGER_HANDLE *log);
+}
+extern "C" {
+extern struct my_md5_service_st {
+ void (*my_md5_type)(unsigned char*, const char*, size_t);
+ void (*my_md5_multi_type)(unsigned char*, ...);
+ size_t (*my_md5_context_size_type)();
+ void (*my_md5_init_type)(void *);
+ void (*my_md5_input_type)(void *, const unsigned char *, size_t);
+ void (*my_md5_result_type)(void *, unsigned char *);
+} *my_md5_service;
+void my_md5(unsigned char*, const char*, size_t);
+void my_md5_multi(unsigned char*, ...);
+size_t my_md5_context_size();
+void my_md5_init(void *context);
+void my_md5_input(void *context, const unsigned char *buf, size_t len);
+void my_md5_result(void *context, unsigned char *digest);
+}
+extern "C" {
+enum my_aes_mode {
+ MY_AES_ECB, MY_AES_CBC
+};
+extern struct my_crypt_service_st {
+ int (*my_aes_crypt_init)(void *ctx, enum my_aes_mode mode, int flags,
+ const unsigned char* key, unsigned int klen,
+ const unsigned char* iv, unsigned int ivlen);
+ int (*my_aes_crypt_update)(void *ctx, const unsigned char *src, unsigned int slen,
+ unsigned char *dst, unsigned int *dlen);
+ int (*my_aes_crypt_finish)(void *ctx, unsigned char *dst, unsigned int *dlen);
+ int (*my_aes_crypt)(enum my_aes_mode mode, int flags,
+ const unsigned char *src, unsigned int slen, unsigned char *dst, unsigned int *dlen,
+ const unsigned char *key, unsigned int klen, const unsigned char *iv, unsigned int ivlen);
+ unsigned int (*my_aes_get_size)(enum my_aes_mode mode, unsigned int source_length);
+ unsigned int (*my_aes_ctx_size)(enum my_aes_mode mode);
+ int (*my_random_bytes)(unsigned char* buf, int num);
+} *my_crypt_service;
+int my_aes_crypt_init(void *ctx, enum my_aes_mode mode, int flags,
+ const unsigned char* key, unsigned int klen,
+ const unsigned char* iv, unsigned int ivlen);
+int my_aes_crypt_update(void *ctx, const unsigned char *src, unsigned int slen,
+ unsigned char *dst, unsigned int *dlen);
+int my_aes_crypt_finish(void *ctx, unsigned char *dst, unsigned int *dlen);
+int my_aes_crypt(enum my_aes_mode mode, int flags,
+ const unsigned char *src, unsigned int slen, unsigned char *dst, unsigned int *dlen,
+ const unsigned char *key, unsigned int klen, const unsigned char *iv, unsigned int ivlen);
+int my_random_bytes(unsigned char* buf, int num);
+unsigned int my_aes_get_size(enum my_aes_mode mode, unsigned int source_length);
+unsigned int my_aes_ctx_size(enum my_aes_mode mode);
+}
+extern "C" {
+extern struct my_print_error_service_st {
+ void (*my_error_func)(unsigned int nr, unsigned long MyFlags, ...);
+ void (*my_printf_error_func)(unsigned int nr, const char *fmt, unsigned long MyFlags,...);
+ void (*my_printv_error_func)(unsigned int error, const char *format, unsigned long MyFlags, va_list ap);
+} *my_print_error_service;
+extern void my_error(unsigned int nr, unsigned long MyFlags, ...);
+extern void my_printf_error(unsigned int my_err, const char *format, unsigned long MyFlags, ...);
+extern void my_printv_error(unsigned int error, const char *format, unsigned long MyFlags,va_list ap);
+}
+extern "C" {
+extern struct my_snprintf_service_st {
+ size_t (*my_snprintf_type)(char*, size_t, const char*, ...);
+ size_t (*my_vsnprintf_type)(char *, size_t, const char*, va_list);
+} *my_snprintf_service;
+size_t my_snprintf(char* to, size_t n, const char* fmt, ...);
+size_t my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap);
+}
+extern "C" {
+extern struct progress_report_service_st {
+ void (*thd_progress_init_func)(THD* thd, unsigned int max_stage);
+ void (*thd_progress_report_func)(THD* thd,
+ unsigned long long progress,
+ unsigned long long max_progress);
+ void (*thd_progress_next_stage_func)(THD* thd);
+ void (*thd_progress_end_func)(THD* thd);
+ const char *(*set_thd_proc_info_func)(THD*, const char *info,
+ const char *func,
+ const char *file,
+ unsigned int line);
+} *progress_report_service;
+void thd_progress_init(THD* thd, unsigned int max_stage);
+void thd_progress_report(THD* thd,
+ unsigned long long progress,
+ unsigned long long max_progress);
+void thd_progress_next_stage(THD* thd);
+void thd_progress_end(THD* thd);
+const char *set_thd_proc_info(THD*, const char * info, const char *func,
+ const char *file, unsigned int line);
+}
+extern "C" {
+extern struct my_sha1_service_st {
+ void (*my_sha1_type)(unsigned char*, const char*, size_t);
+ void (*my_sha1_multi_type)(unsigned char*, ...);
+ size_t (*my_sha1_context_size_type)();
+ void (*my_sha1_init_type)(void *);
+ void (*my_sha1_input_type)(void *, const unsigned char *, size_t);
+ void (*my_sha1_result_type)(void *, unsigned char *);
+} *my_sha1_service;
+void my_sha1(unsigned char*, const char*, size_t);
+void my_sha1_multi(unsigned char*, ...);
+size_t my_sha1_context_size();
+void my_sha1_init(void *context);
+void my_sha1_input(void *context, const unsigned char *buf, size_t len);
+void my_sha1_result(void *context, unsigned char *digest);
+}
+extern "C" {
+extern struct my_sha2_service_st {
+ void (*my_sha224_type)(unsigned char*, const char*, size_t);
+ void (*my_sha224_multi_type)(unsigned char*, ...);
+ size_t (*my_sha224_context_size_type)();
+ void (*my_sha224_init_type)(void *);
+ void (*my_sha224_input_type)(void *, const unsigned char *, size_t);
+ void (*my_sha224_result_type)(void *, unsigned char *);
+ void (*my_sha256_type)(unsigned char*, const char*, size_t);
+ void (*my_sha256_multi_type)(unsigned char*, ...);
+ size_t (*my_sha256_context_size_type)();
+ void (*my_sha256_init_type)(void *);
+ void (*my_sha256_input_type)(void *, const unsigned char *, size_t);
+ void (*my_sha256_result_type)(void *, unsigned char *);
+ void (*my_sha384_type)(unsigned char*, const char*, size_t);
+ void (*my_sha384_multi_type)(unsigned char*, ...);
+ size_t (*my_sha384_context_size_type)();
+ void (*my_sha384_init_type)(void *);
+ void (*my_sha384_input_type)(void *, const unsigned char *, size_t);
+ void (*my_sha384_result_type)(void *, unsigned char *);
+ void (*my_sha512_type)(unsigned char*, const char*, size_t);
+ void (*my_sha512_multi_type)(unsigned char*, ...);
+ size_t (*my_sha512_context_size_type)();
+ void (*my_sha512_init_type)(void *);
+ void (*my_sha512_input_type)(void *, const unsigned char *, size_t);
+ void (*my_sha512_result_type)(void *, unsigned char *);
+} *my_sha2_service;
+void my_sha224(unsigned char*, const char*, size_t);
+void my_sha224_multi(unsigned char*, ...);
+size_t my_sha224_context_size();
+void my_sha224_init(void *context);
+void my_sha224_input(void *context, const unsigned char *buf, size_t len);
+void my_sha224_result(void *context, unsigned char *digest);
+void my_sha256(unsigned char*, const char*, size_t);
+void my_sha256_multi(unsigned char*, ...);
+size_t my_sha256_context_size();
+void my_sha256_init(void *context);
+void my_sha256_input(void *context, const unsigned char *buf, size_t len);
+void my_sha256_result(void *context, unsigned char *digest);
+void my_sha384(unsigned char*, const char*, size_t);
+void my_sha384_multi(unsigned char*, ...);
+size_t my_sha384_context_size();
+void my_sha384_init(void *context);
+void my_sha384_input(void *context, const unsigned char *buf, size_t len);
+void my_sha384_result(void *context, unsigned char *digest);
+void my_sha512(unsigned char*, const char*, size_t);
+void my_sha512_multi(unsigned char*, ...);
+size_t my_sha512_context_size();
+void my_sha512_init(void *context);
+void my_sha512_input(void *context, const unsigned char *buf, size_t len);
+void my_sha512_result(void *context, unsigned char *digest);
+}
+extern "C" {
+struct st_mysql_lex_string
+{
+ char *str;
+ size_t length;
+};
+typedef struct st_mysql_lex_string MYSQL_LEX_STRING;
+struct st_mysql_const_lex_string
+{
+ const char *str;
+ size_t length;
+};
+typedef struct st_mysql_const_lex_string MYSQL_CONST_LEX_STRING;
+extern struct thd_alloc_service_st {
+ void *(*thd_alloc_func)(THD*, size_t);
+ void *(*thd_calloc_func)(THD*, size_t);
+ char *(*thd_strdup_func)(THD*, const char *);
+ char *(*thd_strmake_func)(THD*, const char *, size_t);
+ void *(*thd_memdup_func)(THD*, const void*, size_t);
+ MYSQL_CONST_LEX_STRING *(*thd_make_lex_string_func)(THD*,
+ MYSQL_CONST_LEX_STRING *,
+ const char *, size_t, int);
+} *thd_alloc_service;
+void *thd_alloc(THD* thd, size_t size);
+void *thd_calloc(THD* thd, size_t size);
+char *thd_strdup(THD* thd, const char *str);
+char *thd_strmake(THD* thd, const char *str, size_t size);
+void *thd_memdup(THD* thd, const void* str, size_t size);
+MYSQL_CONST_LEX_STRING
+*thd_make_lex_string(THD* thd, MYSQL_CONST_LEX_STRING *lex_str,
+ const char *str, size_t size,
+ int allocate_lex_string);
+}
+extern "C" {
+extern struct thd_autoinc_service_st {
+ void (*thd_get_autoinc_func)(const THD* thd,
+ unsigned long* off, unsigned long* inc);
+} *thd_autoinc_service;
+void thd_get_autoinc(const THD* thd,
+ unsigned long* off, unsigned long* inc);
+}
+extern "C" {
+extern struct thd_error_context_service_st {
+ const char *(*thd_get_error_message_func)(const THD* thd);
+ unsigned int (*thd_get_error_number_func)(const THD* thd);
+ unsigned long (*thd_get_error_row_func)(const THD* thd);
+ void (*thd_inc_error_row_func)(THD* thd);
+ char *(*thd_get_error_context_description_func)(THD* thd,
+ char *buffer,
+ unsigned int length,
+ unsigned int max_query_length);
+} *thd_error_context_service;
+const char *thd_get_error_message(const THD* thd);
+unsigned int thd_get_error_number(const THD* thd);
+unsigned long thd_get_error_row(const THD* thd);
+void thd_inc_error_row(THD* thd);
+char *thd_get_error_context_description(THD* thd,
+ char *buffer, unsigned int length,
+ unsigned int max_query_length);
+}
+extern "C" {
+extern struct thd_rnd_service_st {
+ double (*thd_rnd_ptr)(THD* thd);
+ void (*thd_c_r_p_ptr)(THD* thd, char *to, size_t length);
+} *thd_rnd_service;
+double thd_rnd(THD* thd);
+void thd_create_random_password(THD* thd, char *to, size_t length);
+}
+extern "C" {
+typedef int MYSQL_THD_KEY_T;
+extern struct thd_specifics_service_st {
+ int (*thd_key_create_func)(MYSQL_THD_KEY_T *key);
+ void (*thd_key_delete_func)(MYSQL_THD_KEY_T *key);
+ void *(*thd_getspecific_func)(THD* thd, MYSQL_THD_KEY_T key);
+ int (*thd_setspecific_func)(THD* thd, MYSQL_THD_KEY_T key, void *value);
+} *thd_specifics_service;
+int thd_key_create(MYSQL_THD_KEY_T *key);
+void thd_key_delete(MYSQL_THD_KEY_T *key);
+void* thd_getspecific(THD* thd, MYSQL_THD_KEY_T key);
+int thd_setspecific(THD* thd, MYSQL_THD_KEY_T key, void *value);
+}
+typedef long my_time_t;
+enum enum_mysql_timestamp_type
+{
+ MYSQL_TIMESTAMP_NONE= -2, MYSQL_TIMESTAMP_ERROR= -1,
+ MYSQL_TIMESTAMP_DATE= 0, MYSQL_TIMESTAMP_DATETIME= 1, MYSQL_TIMESTAMP_TIME= 2
+};
+typedef struct st_mysql_time
+{
+ unsigned int year, month, day, hour, minute, second;
+ unsigned long second_part;
+ my_bool neg;
+ enum enum_mysql_timestamp_type time_type;
+} MYSQL_TIME;
+extern "C" {
+extern struct thd_timezone_service_st {
+ my_time_t (*thd_TIME_to_gmt_sec)(THD* thd, const MYSQL_TIME *ltime, unsigned int *errcode);
+ void (*thd_gmt_sec_to_TIME)(THD* thd, MYSQL_TIME *ltime, my_time_t t);
+} *thd_timezone_service;
+my_time_t thd_TIME_to_gmt_sec(THD* thd, const MYSQL_TIME *ltime, unsigned int *errcode);
+void thd_gmt_sec_to_TIME(THD* thd, MYSQL_TIME *ltime, my_time_t t);
+}
+extern "C" {
+typedef enum _thd_wait_type_e {
+ THD_WAIT_SLEEP= 1,
+ THD_WAIT_DISKIO= 2,
+ THD_WAIT_ROW_LOCK= 3,
+ THD_WAIT_GLOBAL_LOCK= 4,
+ THD_WAIT_META_DATA_LOCK= 5,
+ THD_WAIT_TABLE_LOCK= 6,
+ THD_WAIT_USER_LOCK= 7,
+ THD_WAIT_BINLOG= 8,
+ THD_WAIT_GROUP_COMMIT= 9,
+ THD_WAIT_SYNC= 10,
+ THD_WAIT_NET= 11,
+ THD_WAIT_LAST= 12
+} thd_wait_type;
+extern struct thd_wait_service_st {
+ void (*thd_wait_begin_func)(THD*, int);
+ void (*thd_wait_end_func)(THD*);
+} *thd_wait_service;
+void thd_wait_begin(THD* thd, int wait_type);
+void thd_wait_end(THD* thd);
+}
+extern "C" {
+enum json_types
+{
+ JSV_BAD_JSON=-1,
+ JSV_NOTHING=0,
+ JSV_OBJECT=1,
+ JSV_ARRAY=2,
+ JSV_STRING=3,
+ JSV_NUMBER=4,
+ JSV_TRUE=5,
+ JSV_FALSE=6,
+ JSV_NULL=7
+};
+extern struct json_service_st {
+ enum json_types (*json_type)(const char *js, const char *js_end,
+ const char **value, int *value_len);
+ enum json_types (*json_get_array_item)(const char *js, const char *js_end,
+ int n_item,
+ const char **value, int *value_len);
+ enum json_types (*json_get_object_key)(const char *js, const char *js_end,
+ const char *key,
+ const char **value, int *value_len);
+ enum json_types (*json_get_object_nkey)(const char *js,const char *js_end,
+ int nkey,
+ const char **keyname, const char **keyname_end,
+ const char **value, int *value_len);
+ int (*json_escape_string)(const char *str,const char *str_end,
+ char *json, char *json_end);
+ int (*json_unescape_json)(const char *json_str, const char *json_end,
+ char *res, char *res_end);
+} *json_service;
+enum json_types json_type(const char *js, const char *js_end,
+ const char **value, int *value_len);
+enum json_types json_get_array_item(const char *js, const char *js_end,
+ int n_item,
+ const char **value, int *value_len);
+enum json_types json_get_object_key(const char *js, const char *js_end,
+ const char *key,
+ const char **value, int *value_len);
+enum json_types json_get_object_nkey(const char *js,const char *js_end, int nkey,
+ const char **keyname, const char **keyname_end,
+ const char **value, int *value_len);
+int json_escape_string(const char *str,const char *str_end,
+ char *json, char *json_end);
+int json_unescape_json(const char *json_str, const char *json_end,
+ char *res, char *res_end);
+}
+}
+struct st_mysql_xid {
+ long formatID;
+ long gtrid_length;
+ long bqual_length;
+ char data[128];
+};
+typedef struct st_mysql_xid MYSQL_XID;
+enum enum_mysql_show_type
+{
+ SHOW_UNDEF, SHOW_BOOL, SHOW_UINT, SHOW_ULONG,
+ SHOW_ULONGLONG, SHOW_CHAR, SHOW_CHAR_PTR,
+ SHOW_ARRAY, SHOW_FUNC, SHOW_DOUBLE,
+ SHOW_SINT, SHOW_SLONG, SHOW_SLONGLONG, SHOW_SIMPLE_FUNC,
+ SHOW_SIZE_T, SHOW_always_last
+};
+enum enum_var_type
+{
+ SHOW_OPT_DEFAULT= 0, SHOW_OPT_SESSION, SHOW_OPT_GLOBAL
+};
+struct st_mysql_show_var {
+ const char *name;
+ void *value;
+ enum enum_mysql_show_type type;
+};
+struct system_status_var;
+typedef int (*mysql_show_var_func)(THD*, struct st_mysql_show_var*, void *, struct system_status_var *status_var, enum enum_var_type);
+struct st_mysql_sys_var;
+struct st_mysql_value;
+typedef int (*mysql_var_check_func)(THD* thd,
+ struct st_mysql_sys_var *var,
+ void *save, struct st_mysql_value *value);
+typedef void (*mysql_var_update_func)(THD* thd,
+ struct st_mysql_sys_var *var,
+ void *var_ptr, const void *save);
+struct st_mysql_plugin
+{
+ int type;
+ void *info;
+ const char *name;
+ const char *author;
+ const char *descr;
+ int license;
+ int (*init)(void *);
+ int (*deinit)(void *);
+ unsigned int version;
+ struct st_mysql_show_var *status_vars;
+ struct st_mysql_sys_var **system_vars;
+ void * __reserved1;
+ unsigned long flags;
+};
+struct st_maria_plugin
+{
+ int type;
+ void *info;
+ const char *name;
+ const char *author;
+ const char *descr;
+ int license;
+ int (*init)(void *);
+ int (*deinit)(void *);
+ unsigned int version;
+ struct st_mysql_show_var *status_vars;
+ struct st_mysql_sys_var **system_vars;
+ const char *version_info;
+ unsigned int maturity;
+};
+extern "C" {
+enum enum_ftparser_mode
+{
+ MYSQL_FTPARSER_SIMPLE_MODE= 0,
+ MYSQL_FTPARSER_WITH_STOPWORDS= 1,
+ MYSQL_FTPARSER_FULL_BOOLEAN_INFO= 2
+};
+enum enum_ft_token_type
+{
+ FT_TOKEN_EOF= 0,
+ FT_TOKEN_WORD= 1,
+ FT_TOKEN_LEFT_PAREN= 2,
+ FT_TOKEN_RIGHT_PAREN= 3,
+ FT_TOKEN_STOPWORD= 4
+};
+typedef struct st_mysql_ftparser_boolean_info
+{
+ enum enum_ft_token_type type;
+ int yesno;
+ int weight_adjust;
+ char wasign;
+ char trunc;
+ char prev;
+ char *quot;
+} MYSQL_FTPARSER_BOOLEAN_INFO;
+typedef struct st_mysql_ftparser_param
+{
+ int (*mysql_parse)(struct st_mysql_ftparser_param *,
+ const char *doc, int doc_len);
+ int (*mysql_add_word)(struct st_mysql_ftparser_param *,
+ const char *word, int word_len,
+ MYSQL_FTPARSER_BOOLEAN_INFO *boolean_info);
+ void *ftparser_state;
+ void *mysql_ftparam;
+ const struct charset_info_st *cs;
+ const char *doc;
+ int length;
+ unsigned int flags;
+ enum enum_ftparser_mode mode;
+} MYSQL_FTPARSER_PARAM;
+struct st_mysql_ftparser
+{
+ int interface_version;
+ int (*parse)(MYSQL_FTPARSER_PARAM *param);
+ int (*init)(MYSQL_FTPARSER_PARAM *param);
+ int (*deinit)(MYSQL_FTPARSER_PARAM *param);
+};
+}
+struct st_mysql_daemon
+{
+ int interface_version;
+};
+struct st_mysql_information_schema
+{
+ int interface_version;
+};
+struct st_mysql_storage_engine
+{
+ int interface_version;
+};
+struct handlerton;
+ struct Mysql_replication {
+ int interface_version;
+ };
+struct st_mysql_value
+{
+ int (*value_type)(struct st_mysql_value *);
+ const char *(*val_str)(struct st_mysql_value *, char *buffer, int *length);
+ int (*val_real)(struct st_mysql_value *, double *realbuf);
+ int (*val_int)(struct st_mysql_value *, long long *intbuf);
+ int (*is_unsigned)(struct st_mysql_value *);
+};
+extern "C" {
+int thd_in_lock_tables(const THD* thd);
+int thd_tablespace_op(const THD* thd);
+long long thd_test_options(const THD* thd, long long test_options);
+int thd_sql_command(const THD* thd);
+void thd_storage_lock_wait(THD* thd, long long value);
+int thd_tx_isolation(const THD* thd);
+int thd_tx_is_read_only(const THD* thd);
+int mysql_tmpfile(const char *prefix);
+unsigned long thd_get_thread_id(const THD* thd);
+void thd_get_xid(const THD* thd, MYSQL_XID *xid);
+void mysql_query_cache_invalidate4(THD* thd,
+ const char *key, unsigned int key_length,
+ int using_trx);
+void *thd_get_ha_data(const THD* thd, const struct handlerton *hton);
+void thd_set_ha_data(THD* thd, const struct handlerton *hton,
+ const void *ha_data);
+void thd_wakeup_subsequent_commits(THD* thd, int wakeup_error);
+}
+class Plugin_function
+{
+ int m_interface_version;
+ Create_func *m_builder;
+public:
+ Plugin_function(Create_func *builder)
+ :m_interface_version((MYSQL_VERSION_ID << 8)),
+ m_builder(builder)
+ { }
+ Create_func *create_func()
+ {
+ return m_builder;
+ }
+};
diff --git a/include/mysql/plugin_password_validation.h b/include/mysql/plugin_password_validation.h
new file mode 100644
index 00000000..23d2c884
--- /dev/null
+++ b/include/mysql/plugin_password_validation.h
@@ -0,0 +1,54 @@
+#ifndef MYSQL_PLUGIN_PASSWORD_VALIDATION_INCLUDED
+/* Copyright (C) 2014 Sergei Golubchik and MariaDB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */
+
+/**
+ @file
+
+ Password Validation Plugin API.
+
+ This file defines the API for server password validation plugins.
+*/
+
+#define MYSQL_PLUGIN_PASSWORD_VALIDATION_INCLUDED
+
+#include <mysql/plugin.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define MariaDB_PASSWORD_VALIDATION_INTERFACE_VERSION 0x0100
+
+/**
+ Password validation plugin descriptor
+*/
+struct st_mariadb_password_validation
+{
+ int interface_version; /**< version plugin uses */
+ /**
+ Function provided by the plugin which should perform password validation
+ and return 0 if the password has passed the validation.
+ */
+ int (*validate_password)(const MYSQL_CONST_LEX_STRING *username,
+ const MYSQL_CONST_LEX_STRING *password);
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/include/mysql/plugin_password_validation.h.pp b/include/mysql/plugin_password_validation.h.pp
new file mode 100644
index 00000000..fc8c3848
--- /dev/null
+++ b/include/mysql/plugin_password_validation.h.pp
@@ -0,0 +1,632 @@
+class THD;
+class Item;
+typedef char my_bool;
+typedef void * MYSQL_PLUGIN;
+extern "C" {
+extern "C" {
+extern struct base64_service_st {
+ int (*base64_needed_encoded_length_ptr)(int length_of_data);
+ int (*base64_encode_max_arg_length_ptr)(void);
+ int (*base64_needed_decoded_length_ptr)(int length_of_encoded_data);
+ int (*base64_decode_max_arg_length_ptr)();
+ int (*base64_encode_ptr)(const void *src, size_t src_len, char *dst);
+ int (*base64_decode_ptr)(const char *src, size_t src_len,
+ void *dst, const char **end_ptr, int flags);
+} *base64_service;
+int my_base64_needed_encoded_length(int length_of_data);
+int my_base64_encode_max_arg_length(void);
+int my_base64_needed_decoded_length(int length_of_encoded_data);
+int my_base64_decode_max_arg_length();
+int my_base64_encode(const void *src, size_t src_len, char *dst);
+int my_base64_decode(const char *src, size_t src_len,
+ void *dst, const char **end_ptr, int flags);
+}
+extern "C" {
+extern void (*debug_sync_C_callback_ptr)(THD*, const char *, size_t);
+}
+extern "C" {
+struct encryption_service_st {
+ unsigned int (*encryption_key_get_latest_version_func)(unsigned int key_id);
+ unsigned int (*encryption_key_get_func)(unsigned int key_id, unsigned int key_version,
+ unsigned char* buffer, unsigned int* length);
+ unsigned int (*encryption_ctx_size_func)(unsigned int key_id, unsigned int key_version);
+ int (*encryption_ctx_init_func)(void *ctx, const unsigned char* key, unsigned int klen,
+ const unsigned char* iv, unsigned int ivlen,
+ int flags, unsigned int key_id,
+ unsigned int key_version);
+ int (*encryption_ctx_update_func)(void *ctx, const unsigned char* src, unsigned int slen,
+ unsigned char* dst, unsigned int* dlen);
+ int (*encryption_ctx_finish_func)(void *ctx, unsigned char* dst, unsigned int* dlen);
+ unsigned int (*encryption_encrypted_length_func)(unsigned int slen, unsigned int key_id, unsigned int key_version);
+};
+extern struct encryption_service_st encryption_handler;
+static inline unsigned int encryption_key_id_exists(unsigned int id)
+{
+ return encryption_handler.encryption_key_get_latest_version_func(id) != (~(unsigned int)0);
+}
+static inline unsigned int encryption_key_version_exists(unsigned int id, unsigned int version)
+{
+ unsigned int unused;
+ return encryption_handler.encryption_key_get_func((id),(version),(NULL),(&unused)) != (~(unsigned int)0);
+}
+static inline int encryption_crypt(const unsigned char* src, unsigned int slen,
+ unsigned char* dst, unsigned int* dlen,
+ const unsigned char* key, unsigned int klen,
+ const unsigned char* iv, unsigned int ivlen,
+ int flags, unsigned int key_id, unsigned int key_version)
+{
+ void *ctx= alloca(encryption_handler.encryption_ctx_size_func((key_id),(key_version)));
+ int res1, res2;
+ unsigned int d1, d2;
+ if ((res1= encryption_handler.encryption_ctx_init_func((ctx),(key),(klen),(iv),(ivlen),(flags),(key_id),(key_version))))
+ return res1;
+ res1= encryption_handler.encryption_ctx_update_func((ctx),(src),(slen),(dst),(&d1));
+ res2= encryption_handler.encryption_ctx_finish_func((ctx),(dst + d1),(&d2));
+ *dlen= d1 + d2;
+ return res1 ? res1 : res2;
+}
+}
+extern "C" {
+struct st_encryption_scheme_key {
+ unsigned int version;
+ unsigned char key[16];
+};
+struct st_encryption_scheme {
+ unsigned char iv[16];
+ struct st_encryption_scheme_key key[3];
+ unsigned int keyserver_requests;
+ unsigned int key_id;
+ unsigned int type;
+ void (*locker)(struct st_encryption_scheme *self, int release);
+};
+extern struct encryption_scheme_service_st {
+ int (*encryption_scheme_encrypt_func)
+ (const unsigned char* src, unsigned int slen,
+ unsigned char* dst, unsigned int* dlen,
+ struct st_encryption_scheme *scheme,
+ unsigned int key_version, unsigned int i32_1,
+ unsigned int i32_2, unsigned long long i64);
+ int (*encryption_scheme_decrypt_func)
+ (const unsigned char* src, unsigned int slen,
+ unsigned char* dst, unsigned int* dlen,
+ struct st_encryption_scheme *scheme,
+ unsigned int key_version, unsigned int i32_1,
+ unsigned int i32_2, unsigned long long i64);
+} *encryption_scheme_service;
+int encryption_scheme_encrypt(const unsigned char* src, unsigned int slen,
+ unsigned char* dst, unsigned int* dlen,
+ struct st_encryption_scheme *scheme,
+ unsigned int key_version, unsigned int i32_1,
+ unsigned int i32_2, unsigned long long i64);
+int encryption_scheme_decrypt(const unsigned char* src, unsigned int slen,
+ unsigned char* dst, unsigned int* dlen,
+ struct st_encryption_scheme *scheme,
+ unsigned int key_version, unsigned int i32_1,
+ unsigned int i32_2, unsigned long long i64);
+}
+extern "C" {
+enum thd_kill_levels {
+ THD_IS_NOT_KILLED=0,
+ THD_ABORT_SOFTLY=50,
+ THD_ABORT_ASAP=100,
+};
+extern struct kill_statement_service_st {
+ enum thd_kill_levels (*thd_kill_level_func)(const THD*);
+} *thd_kill_statement_service;
+enum thd_kill_levels thd_kill_level(const THD*);
+}
+extern "C" {
+typedef struct logger_handle_st LOGGER_HANDLE;
+extern struct logger_service_st {
+ void (*logger_init_mutexes)();
+ LOGGER_HANDLE* (*open)(const char *path,
+ unsigned long long size_limit,
+ unsigned int rotations);
+ int (*close)(LOGGER_HANDLE *log);
+ int (*vprintf)(LOGGER_HANDLE *log, const char *fmt, va_list argptr);
+ int (*printf)(LOGGER_HANDLE *log, const char *fmt, ...);
+ int (*write)(LOGGER_HANDLE *log, const char *buffer, size_t size);
+ int (*rotate)(LOGGER_HANDLE *log);
+} *logger_service;
+ void logger_init_mutexes();
+ LOGGER_HANDLE *logger_open(const char *path,
+ unsigned long long size_limit,
+ unsigned int rotations);
+ int logger_close(LOGGER_HANDLE *log);
+ int logger_vprintf(LOGGER_HANDLE *log, const char *fmt, va_list argptr);
+ int logger_printf(LOGGER_HANDLE *log, const char *fmt, ...);
+ int logger_write(LOGGER_HANDLE *log, const char *buffer, size_t size);
+ int logger_rotate(LOGGER_HANDLE *log);
+}
+extern "C" {
+extern struct my_md5_service_st {
+ void (*my_md5_type)(unsigned char*, const char*, size_t);
+ void (*my_md5_multi_type)(unsigned char*, ...);
+ size_t (*my_md5_context_size_type)();
+ void (*my_md5_init_type)(void *);
+ void (*my_md5_input_type)(void *, const unsigned char *, size_t);
+ void (*my_md5_result_type)(void *, unsigned char *);
+} *my_md5_service;
+void my_md5(unsigned char*, const char*, size_t);
+void my_md5_multi(unsigned char*, ...);
+size_t my_md5_context_size();
+void my_md5_init(void *context);
+void my_md5_input(void *context, const unsigned char *buf, size_t len);
+void my_md5_result(void *context, unsigned char *digest);
+}
+extern "C" {
+enum my_aes_mode {
+ MY_AES_ECB, MY_AES_CBC
+};
+extern struct my_crypt_service_st {
+ int (*my_aes_crypt_init)(void *ctx, enum my_aes_mode mode, int flags,
+ const unsigned char* key, unsigned int klen,
+ const unsigned char* iv, unsigned int ivlen);
+ int (*my_aes_crypt_update)(void *ctx, const unsigned char *src, unsigned int slen,
+ unsigned char *dst, unsigned int *dlen);
+ int (*my_aes_crypt_finish)(void *ctx, unsigned char *dst, unsigned int *dlen);
+ int (*my_aes_crypt)(enum my_aes_mode mode, int flags,
+ const unsigned char *src, unsigned int slen, unsigned char *dst, unsigned int *dlen,
+ const unsigned char *key, unsigned int klen, const unsigned char *iv, unsigned int ivlen);
+ unsigned int (*my_aes_get_size)(enum my_aes_mode mode, unsigned int source_length);
+ unsigned int (*my_aes_ctx_size)(enum my_aes_mode mode);
+ int (*my_random_bytes)(unsigned char* buf, int num);
+} *my_crypt_service;
+int my_aes_crypt_init(void *ctx, enum my_aes_mode mode, int flags,
+ const unsigned char* key, unsigned int klen,
+ const unsigned char* iv, unsigned int ivlen);
+int my_aes_crypt_update(void *ctx, const unsigned char *src, unsigned int slen,
+ unsigned char *dst, unsigned int *dlen);
+int my_aes_crypt_finish(void *ctx, unsigned char *dst, unsigned int *dlen);
+int my_aes_crypt(enum my_aes_mode mode, int flags,
+ const unsigned char *src, unsigned int slen, unsigned char *dst, unsigned int *dlen,
+ const unsigned char *key, unsigned int klen, const unsigned char *iv, unsigned int ivlen);
+int my_random_bytes(unsigned char* buf, int num);
+unsigned int my_aes_get_size(enum my_aes_mode mode, unsigned int source_length);
+unsigned int my_aes_ctx_size(enum my_aes_mode mode);
+}
+extern "C" {
+extern struct my_print_error_service_st {
+ void (*my_error_func)(unsigned int nr, unsigned long MyFlags, ...);
+ void (*my_printf_error_func)(unsigned int nr, const char *fmt, unsigned long MyFlags,...);
+ void (*my_printv_error_func)(unsigned int error, const char *format, unsigned long MyFlags, va_list ap);
+} *my_print_error_service;
+extern void my_error(unsigned int nr, unsigned long MyFlags, ...);
+extern void my_printf_error(unsigned int my_err, const char *format, unsigned long MyFlags, ...);
+extern void my_printv_error(unsigned int error, const char *format, unsigned long MyFlags,va_list ap);
+}
+extern "C" {
+extern struct my_snprintf_service_st {
+ size_t (*my_snprintf_type)(char*, size_t, const char*, ...);
+ size_t (*my_vsnprintf_type)(char *, size_t, const char*, va_list);
+} *my_snprintf_service;
+size_t my_snprintf(char* to, size_t n, const char* fmt, ...);
+size_t my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap);
+}
+extern "C" {
+extern struct progress_report_service_st {
+ void (*thd_progress_init_func)(THD* thd, unsigned int max_stage);
+ void (*thd_progress_report_func)(THD* thd,
+ unsigned long long progress,
+ unsigned long long max_progress);
+ void (*thd_progress_next_stage_func)(THD* thd);
+ void (*thd_progress_end_func)(THD* thd);
+ const char *(*set_thd_proc_info_func)(THD*, const char *info,
+ const char *func,
+ const char *file,
+ unsigned int line);
+} *progress_report_service;
+void thd_progress_init(THD* thd, unsigned int max_stage);
+void thd_progress_report(THD* thd,
+ unsigned long long progress,
+ unsigned long long max_progress);
+void thd_progress_next_stage(THD* thd);
+void thd_progress_end(THD* thd);
+const char *set_thd_proc_info(THD*, const char * info, const char *func,
+ const char *file, unsigned int line);
+}
+extern "C" {
+extern struct my_sha1_service_st {
+ void (*my_sha1_type)(unsigned char*, const char*, size_t);
+ void (*my_sha1_multi_type)(unsigned char*, ...);
+ size_t (*my_sha1_context_size_type)();
+ void (*my_sha1_init_type)(void *);
+ void (*my_sha1_input_type)(void *, const unsigned char *, size_t);
+ void (*my_sha1_result_type)(void *, unsigned char *);
+} *my_sha1_service;
+void my_sha1(unsigned char*, const char*, size_t);
+void my_sha1_multi(unsigned char*, ...);
+size_t my_sha1_context_size();
+void my_sha1_init(void *context);
+void my_sha1_input(void *context, const unsigned char *buf, size_t len);
+void my_sha1_result(void *context, unsigned char *digest);
+}
+extern "C" {
+extern struct my_sha2_service_st {
+ void (*my_sha224_type)(unsigned char*, const char*, size_t);
+ void (*my_sha224_multi_type)(unsigned char*, ...);
+ size_t (*my_sha224_context_size_type)();
+ void (*my_sha224_init_type)(void *);
+ void (*my_sha224_input_type)(void *, const unsigned char *, size_t);
+ void (*my_sha224_result_type)(void *, unsigned char *);
+ void (*my_sha256_type)(unsigned char*, const char*, size_t);
+ void (*my_sha256_multi_type)(unsigned char*, ...);
+ size_t (*my_sha256_context_size_type)();
+ void (*my_sha256_init_type)(void *);
+ void (*my_sha256_input_type)(void *, const unsigned char *, size_t);
+ void (*my_sha256_result_type)(void *, unsigned char *);
+ void (*my_sha384_type)(unsigned char*, const char*, size_t);
+ void (*my_sha384_multi_type)(unsigned char*, ...);
+ size_t (*my_sha384_context_size_type)();
+ void (*my_sha384_init_type)(void *);
+ void (*my_sha384_input_type)(void *, const unsigned char *, size_t);
+ void (*my_sha384_result_type)(void *, unsigned char *);
+ void (*my_sha512_type)(unsigned char*, const char*, size_t);
+ void (*my_sha512_multi_type)(unsigned char*, ...);
+ size_t (*my_sha512_context_size_type)();
+ void (*my_sha512_init_type)(void *);
+ void (*my_sha512_input_type)(void *, const unsigned char *, size_t);
+ void (*my_sha512_result_type)(void *, unsigned char *);
+} *my_sha2_service;
+void my_sha224(unsigned char*, const char*, size_t);
+void my_sha224_multi(unsigned char*, ...);
+size_t my_sha224_context_size();
+void my_sha224_init(void *context);
+void my_sha224_input(void *context, const unsigned char *buf, size_t len);
+void my_sha224_result(void *context, unsigned char *digest);
+void my_sha256(unsigned char*, const char*, size_t);
+void my_sha256_multi(unsigned char*, ...);
+size_t my_sha256_context_size();
+void my_sha256_init(void *context);
+void my_sha256_input(void *context, const unsigned char *buf, size_t len);
+void my_sha256_result(void *context, unsigned char *digest);
+void my_sha384(unsigned char*, const char*, size_t);
+void my_sha384_multi(unsigned char*, ...);
+size_t my_sha384_context_size();
+void my_sha384_init(void *context);
+void my_sha384_input(void *context, const unsigned char *buf, size_t len);
+void my_sha384_result(void *context, unsigned char *digest);
+void my_sha512(unsigned char*, const char*, size_t);
+void my_sha512_multi(unsigned char*, ...);
+size_t my_sha512_context_size();
+void my_sha512_init(void *context);
+void my_sha512_input(void *context, const unsigned char *buf, size_t len);
+void my_sha512_result(void *context, unsigned char *digest);
+}
+extern "C" {
+struct st_mysql_lex_string
+{
+ char *str;
+ size_t length;
+};
+typedef struct st_mysql_lex_string MYSQL_LEX_STRING;
+struct st_mysql_const_lex_string
+{
+ const char *str;
+ size_t length;
+};
+typedef struct st_mysql_const_lex_string MYSQL_CONST_LEX_STRING;
+extern struct thd_alloc_service_st {
+ void *(*thd_alloc_func)(THD*, size_t);
+ void *(*thd_calloc_func)(THD*, size_t);
+ char *(*thd_strdup_func)(THD*, const char *);
+ char *(*thd_strmake_func)(THD*, const char *, size_t);
+ void *(*thd_memdup_func)(THD*, const void*, size_t);
+ MYSQL_CONST_LEX_STRING *(*thd_make_lex_string_func)(THD*,
+ MYSQL_CONST_LEX_STRING *,
+ const char *, size_t, int);
+} *thd_alloc_service;
+void *thd_alloc(THD* thd, size_t size);
+void *thd_calloc(THD* thd, size_t size);
+char *thd_strdup(THD* thd, const char *str);
+char *thd_strmake(THD* thd, const char *str, size_t size);
+void *thd_memdup(THD* thd, const void* str, size_t size);
+MYSQL_CONST_LEX_STRING
+*thd_make_lex_string(THD* thd, MYSQL_CONST_LEX_STRING *lex_str,
+ const char *str, size_t size,
+ int allocate_lex_string);
+}
+extern "C" {
+extern struct thd_autoinc_service_st {
+ void (*thd_get_autoinc_func)(const THD* thd,
+ unsigned long* off, unsigned long* inc);
+} *thd_autoinc_service;
+void thd_get_autoinc(const THD* thd,
+ unsigned long* off, unsigned long* inc);
+}
+extern "C" {
+extern struct thd_error_context_service_st {
+ const char *(*thd_get_error_message_func)(const THD* thd);
+ unsigned int (*thd_get_error_number_func)(const THD* thd);
+ unsigned long (*thd_get_error_row_func)(const THD* thd);
+ void (*thd_inc_error_row_func)(THD* thd);
+ char *(*thd_get_error_context_description_func)(THD* thd,
+ char *buffer,
+ unsigned int length,
+ unsigned int max_query_length);
+} *thd_error_context_service;
+const char *thd_get_error_message(const THD* thd);
+unsigned int thd_get_error_number(const THD* thd);
+unsigned long thd_get_error_row(const THD* thd);
+void thd_inc_error_row(THD* thd);
+char *thd_get_error_context_description(THD* thd,
+ char *buffer, unsigned int length,
+ unsigned int max_query_length);
+}
+extern "C" {
+extern struct thd_rnd_service_st {
+ double (*thd_rnd_ptr)(THD* thd);
+ void (*thd_c_r_p_ptr)(THD* thd, char *to, size_t length);
+} *thd_rnd_service;
+double thd_rnd(THD* thd);
+void thd_create_random_password(THD* thd, char *to, size_t length);
+}
+extern "C" {
+typedef int MYSQL_THD_KEY_T;
+extern struct thd_specifics_service_st {
+ int (*thd_key_create_func)(MYSQL_THD_KEY_T *key);
+ void (*thd_key_delete_func)(MYSQL_THD_KEY_T *key);
+ void *(*thd_getspecific_func)(THD* thd, MYSQL_THD_KEY_T key);
+ int (*thd_setspecific_func)(THD* thd, MYSQL_THD_KEY_T key, void *value);
+} *thd_specifics_service;
+int thd_key_create(MYSQL_THD_KEY_T *key);
+void thd_key_delete(MYSQL_THD_KEY_T *key);
+void* thd_getspecific(THD* thd, MYSQL_THD_KEY_T key);
+int thd_setspecific(THD* thd, MYSQL_THD_KEY_T key, void *value);
+}
+typedef long my_time_t;
+enum enum_mysql_timestamp_type
+{
+ MYSQL_TIMESTAMP_NONE= -2, MYSQL_TIMESTAMP_ERROR= -1,
+ MYSQL_TIMESTAMP_DATE= 0, MYSQL_TIMESTAMP_DATETIME= 1, MYSQL_TIMESTAMP_TIME= 2
+};
+typedef struct st_mysql_time
+{
+ unsigned int year, month, day, hour, minute, second;
+ unsigned long second_part;
+ my_bool neg;
+ enum enum_mysql_timestamp_type time_type;
+} MYSQL_TIME;
+extern "C" {
+extern struct thd_timezone_service_st {
+ my_time_t (*thd_TIME_to_gmt_sec)(THD* thd, const MYSQL_TIME *ltime, unsigned int *errcode);
+ void (*thd_gmt_sec_to_TIME)(THD* thd, MYSQL_TIME *ltime, my_time_t t);
+} *thd_timezone_service;
+my_time_t thd_TIME_to_gmt_sec(THD* thd, const MYSQL_TIME *ltime, unsigned int *errcode);
+void thd_gmt_sec_to_TIME(THD* thd, MYSQL_TIME *ltime, my_time_t t);
+}
+extern "C" {
+typedef enum _thd_wait_type_e {
+ THD_WAIT_SLEEP= 1,
+ THD_WAIT_DISKIO= 2,
+ THD_WAIT_ROW_LOCK= 3,
+ THD_WAIT_GLOBAL_LOCK= 4,
+ THD_WAIT_META_DATA_LOCK= 5,
+ THD_WAIT_TABLE_LOCK= 6,
+ THD_WAIT_USER_LOCK= 7,
+ THD_WAIT_BINLOG= 8,
+ THD_WAIT_GROUP_COMMIT= 9,
+ THD_WAIT_SYNC= 10,
+ THD_WAIT_NET= 11,
+ THD_WAIT_LAST= 12
+} thd_wait_type;
+extern struct thd_wait_service_st {
+ void (*thd_wait_begin_func)(THD*, int);
+ void (*thd_wait_end_func)(THD*);
+} *thd_wait_service;
+void thd_wait_begin(THD* thd, int wait_type);
+void thd_wait_end(THD* thd);
+}
+extern "C" {
+enum json_types
+{
+ JSV_BAD_JSON=-1,
+ JSV_NOTHING=0,
+ JSV_OBJECT=1,
+ JSV_ARRAY=2,
+ JSV_STRING=3,
+ JSV_NUMBER=4,
+ JSV_TRUE=5,
+ JSV_FALSE=6,
+ JSV_NULL=7
+};
+extern struct json_service_st {
+ enum json_types (*json_type)(const char *js, const char *js_end,
+ const char **value, int *value_len);
+ enum json_types (*json_get_array_item)(const char *js, const char *js_end,
+ int n_item,
+ const char **value, int *value_len);
+ enum json_types (*json_get_object_key)(const char *js, const char *js_end,
+ const char *key,
+ const char **value, int *value_len);
+ enum json_types (*json_get_object_nkey)(const char *js,const char *js_end,
+ int nkey,
+ const char **keyname, const char **keyname_end,
+ const char **value, int *value_len);
+ int (*json_escape_string)(const char *str,const char *str_end,
+ char *json, char *json_end);
+ int (*json_unescape_json)(const char *json_str, const char *json_end,
+ char *res, char *res_end);
+} *json_service;
+enum json_types json_type(const char *js, const char *js_end,
+ const char **value, int *value_len);
+enum json_types json_get_array_item(const char *js, const char *js_end,
+ int n_item,
+ const char **value, int *value_len);
+enum json_types json_get_object_key(const char *js, const char *js_end,
+ const char *key,
+ const char **value, int *value_len);
+enum json_types json_get_object_nkey(const char *js,const char *js_end, int nkey,
+ const char **keyname, const char **keyname_end,
+ const char **value, int *value_len);
+int json_escape_string(const char *str,const char *str_end,
+ char *json, char *json_end);
+int json_unescape_json(const char *json_str, const char *json_end,
+ char *res, char *res_end);
+}
+}
+struct st_mysql_xid {
+ long formatID;
+ long gtrid_length;
+ long bqual_length;
+ char data[128];
+};
+typedef struct st_mysql_xid MYSQL_XID;
+enum enum_mysql_show_type
+{
+ SHOW_UNDEF, SHOW_BOOL, SHOW_UINT, SHOW_ULONG,
+ SHOW_ULONGLONG, SHOW_CHAR, SHOW_CHAR_PTR,
+ SHOW_ARRAY, SHOW_FUNC, SHOW_DOUBLE,
+ SHOW_SINT, SHOW_SLONG, SHOW_SLONGLONG, SHOW_SIMPLE_FUNC,
+ SHOW_SIZE_T, SHOW_always_last
+};
+enum enum_var_type
+{
+ SHOW_OPT_DEFAULT= 0, SHOW_OPT_SESSION, SHOW_OPT_GLOBAL
+};
+struct st_mysql_show_var {
+ const char *name;
+ void *value;
+ enum enum_mysql_show_type type;
+};
+struct system_status_var;
+typedef int (*mysql_show_var_func)(THD*, struct st_mysql_show_var*, void *, struct system_status_var *status_var, enum enum_var_type);
+struct st_mysql_sys_var;
+struct st_mysql_value;
+typedef int (*mysql_var_check_func)(THD* thd,
+ struct st_mysql_sys_var *var,
+ void *save, struct st_mysql_value *value);
+typedef void (*mysql_var_update_func)(THD* thd,
+ struct st_mysql_sys_var *var,
+ void *var_ptr, const void *save);
+struct st_mysql_plugin
+{
+ int type;
+ void *info;
+ const char *name;
+ const char *author;
+ const char *descr;
+ int license;
+ int (*init)(void *);
+ int (*deinit)(void *);
+ unsigned int version;
+ struct st_mysql_show_var *status_vars;
+ struct st_mysql_sys_var **system_vars;
+ void * __reserved1;
+ unsigned long flags;
+};
+struct st_maria_plugin
+{
+ int type;
+ void *info;
+ const char *name;
+ const char *author;
+ const char *descr;
+ int license;
+ int (*init)(void *);
+ int (*deinit)(void *);
+ unsigned int version;
+ struct st_mysql_show_var *status_vars;
+ struct st_mysql_sys_var **system_vars;
+ const char *version_info;
+ unsigned int maturity;
+};
+extern "C" {
+enum enum_ftparser_mode
+{
+ MYSQL_FTPARSER_SIMPLE_MODE= 0,
+ MYSQL_FTPARSER_WITH_STOPWORDS= 1,
+ MYSQL_FTPARSER_FULL_BOOLEAN_INFO= 2
+};
+enum enum_ft_token_type
+{
+ FT_TOKEN_EOF= 0,
+ FT_TOKEN_WORD= 1,
+ FT_TOKEN_LEFT_PAREN= 2,
+ FT_TOKEN_RIGHT_PAREN= 3,
+ FT_TOKEN_STOPWORD= 4
+};
+typedef struct st_mysql_ftparser_boolean_info
+{
+ enum enum_ft_token_type type;
+ int yesno;
+ int weight_adjust;
+ char wasign;
+ char trunc;
+ char prev;
+ char *quot;
+} MYSQL_FTPARSER_BOOLEAN_INFO;
+typedef struct st_mysql_ftparser_param
+{
+ int (*mysql_parse)(struct st_mysql_ftparser_param *,
+ const char *doc, int doc_len);
+ int (*mysql_add_word)(struct st_mysql_ftparser_param *,
+ const char *word, int word_len,
+ MYSQL_FTPARSER_BOOLEAN_INFO *boolean_info);
+ void *ftparser_state;
+ void *mysql_ftparam;
+ const struct charset_info_st *cs;
+ const char *doc;
+ int length;
+ unsigned int flags;
+ enum enum_ftparser_mode mode;
+} MYSQL_FTPARSER_PARAM;
+struct st_mysql_ftparser
+{
+ int interface_version;
+ int (*parse)(MYSQL_FTPARSER_PARAM *param);
+ int (*init)(MYSQL_FTPARSER_PARAM *param);
+ int (*deinit)(MYSQL_FTPARSER_PARAM *param);
+};
+}
+struct st_mysql_daemon
+{
+ int interface_version;
+};
+struct st_mysql_information_schema
+{
+ int interface_version;
+};
+struct st_mysql_storage_engine
+{
+ int interface_version;
+};
+struct handlerton;
+ struct Mysql_replication {
+ int interface_version;
+ };
+struct st_mysql_value
+{
+ int (*value_type)(struct st_mysql_value *);
+ const char *(*val_str)(struct st_mysql_value *, char *buffer, int *length);
+ int (*val_real)(struct st_mysql_value *, double *realbuf);
+ int (*val_int)(struct st_mysql_value *, long long *intbuf);
+ int (*is_unsigned)(struct st_mysql_value *);
+};
+extern "C" {
+int thd_in_lock_tables(const THD* thd);
+int thd_tablespace_op(const THD* thd);
+long long thd_test_options(const THD* thd, long long test_options);
+int thd_sql_command(const THD* thd);
+void thd_storage_lock_wait(THD* thd, long long value);
+int thd_tx_isolation(const THD* thd);
+int thd_tx_is_read_only(const THD* thd);
+int mysql_tmpfile(const char *prefix);
+unsigned long thd_get_thread_id(const THD* thd);
+void thd_get_xid(const THD* thd, MYSQL_XID *xid);
+void mysql_query_cache_invalidate4(THD* thd,
+ const char *key, unsigned int key_length,
+ int using_trx);
+void *thd_get_ha_data(const THD* thd, const struct handlerton *hton);
+void thd_set_ha_data(THD* thd, const struct handlerton *hton,
+ const void *ha_data);
+void thd_wakeup_subsequent_commits(THD* thd, int wakeup_error);
+}
+extern "C" {
+struct st_mariadb_password_validation
+{
+ int interface_version;
+ int (*validate_password)(const MYSQL_CONST_LEX_STRING *username,
+ const MYSQL_CONST_LEX_STRING *password);
+};
+}
diff --git a/include/mysql/psi/mysql_file.h b/include/mysql/psi/mysql_file.h
new file mode 100644
index 00000000..761482d0
--- /dev/null
+++ b/include/mysql/psi/mysql_file.h
@@ -0,0 +1,1454 @@
+/* Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License, version 2.0, for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */
+
+#ifndef MYSQL_FILE_H
+#define MYSQL_FILE_H
+
+/* For strlen() */
+#include <string.h>
+/* For MY_STAT */
+#include <my_dir.h>
+/* For my_chsize */
+#include <my_sys.h>
+
+/**
+ @file mysql/psi/mysql_file.h
+ Instrumentation helpers for mysys file io.
+ This header file provides the necessary declarations
+ to use the mysys file API with the performance schema instrumentation.
+ In some compilers (SunStudio), 'static inline' functions, when declared
+ but not used, are not optimized away (because they are unused) by default,
+ so that including a static inline function from a header file does
+ create unwanted dependencies, causing unresolved symbols at link time.
+ Other compilers, like gcc, optimize these dependencies by default.
+
+ Since the instrumented APIs declared here are wrapper on top
+ of mysys file io APIs, including mysql/psi/mysql_file.h assumes that
+ the dependency on my_sys already exists.
+*/
+
+#include "mysql/psi/psi.h"
+
+#ifndef PSI_FILE_CALL
+#define PSI_FILE_CALL(M) PSI_DYNAMIC_CALL(M)
+#endif
+
+/**
+ @defgroup File_instrumentation File Instrumentation
+ @ingroup Instrumentation_interface
+ @{
+*/
+
+/**
+ @def mysql_file_register(P1, P2, P3)
+ File registration.
+*/
+#define mysql_file_register(P1, P2, P3) \
+ inline_mysql_file_register(P1, P2, P3)
+
+/**
+ @def mysql_file_fgets(P1, P2, F)
+ Instrumented fgets.
+ @c mysql_file_fgets is a replacement for @c fgets.
+*/
+#ifdef HAVE_PSI_FILE_INTERFACE
+ #define mysql_file_fgets(P1, P2, F) \
+ inline_mysql_file_fgets(__FILE__, __LINE__, P1, P2, F)
+#else
+ #define mysql_file_fgets(P1, P2, F) \
+ inline_mysql_file_fgets(P1, P2, F)
+#endif
+
+/**
+ @def mysql_file_fgetc(F)
+ Instrumented fgetc.
+ @c mysql_file_fgetc is a replacement for @c fgetc.
+*/
+#ifdef HAVE_PSI_FILE_INTERFACE
+ #define mysql_file_fgetc(F) inline_mysql_file_fgetc(__FILE__, __LINE__, F)
+#else
+ #define mysql_file_fgetc(F) inline_mysql_file_fgetc(F)
+#endif
+
+/**
+ @def mysql_file_fputs(P1, F)
+ Instrumented fputs.
+ @c mysql_file_fputs is a replacement for @c fputs.
+*/
+#ifdef HAVE_PSI_FILE_INTERFACE
+ #define mysql_file_fputs(P1, F) \
+ inline_mysql_file_fputs(__FILE__, __LINE__, P1, F)
+#else
+ #define mysql_file_fputs(P1, F)\
+ inline_mysql_file_fputs(P1, F)
+#endif
+
+/**
+ @def mysql_file_fputc(P1, F)
+ Instrumented fputc.
+ @c mysql_file_fputc is a replacement for @c fputc.
+*/
+#ifdef HAVE_PSI_FILE_INTERFACE
+ #define mysql_file_fputc(P1, F) \
+ inline_mysql_file_fputc(__FILE__, __LINE__, P1, F)
+#else
+ #define mysql_file_fputc(P1, F) \
+ inline_mysql_file_fputc(P1, F)
+#endif
+
+/**
+ @def mysql_file_fprintf
+ Instrumented fprintf.
+ @c mysql_file_fprintf is a replacement for @c fprintf.
+*/
+#define mysql_file_fprintf inline_mysql_file_fprintf
+
+/**
+ @def mysql_file_vfprintf(F, P1, P2)
+ Instrumented vfprintf.
+ @c mysql_file_vfprintf is a replacement for @c vfprintf.
+*/
+#ifdef HAVE_PSI_FILE_INTERFACE
+ #define mysql_file_vfprintf(F, P1, P2) \
+ inline_mysql_file_vfprintf(__FILE__, __LINE__, F, P1, P2)
+#else
+ #define mysql_file_vfprintf(F, P1, P2) \
+ inline_mysql_file_vfprintf(F, P1, P2)
+#endif
+
+/**
+ @def mysql_file_fflush(F, P1, P2)
+ Instrumented fflush.
+ @c mysql_file_fflush is a replacement for @c fflush.
+*/
+#ifdef HAVE_PSI_FILE_INTERFACE
+ #define mysql_file_fflush(F) \
+ inline_mysql_file_fflush(__FILE__, __LINE__, F)
+#else
+ #define mysql_file_fflush(F) \
+ inline_mysql_file_fflush(F)
+#endif
+
+/**
+ @def mysql_file_feof(F)
+ Instrumented feof.
+ @c mysql_file_feof is a replacement for @c feof.
+*/
+#define mysql_file_feof(F) inline_mysql_file_feof(F)
+
+/**
+ @def mysql_file_fstat(FN, S, FL)
+ Instrumented fstat.
+ @c mysql_file_fstat is a replacement for @c my_fstat.
+*/
+#ifdef HAVE_PSI_FILE_INTERFACE
+ #define mysql_file_fstat(FN, S, FL) \
+ inline_mysql_file_fstat(__FILE__, __LINE__, FN, S, FL)
+#else
+ #define mysql_file_fstat(FN, S, FL) \
+ inline_mysql_file_fstat(FN, S, FL)
+#endif
+
+/**
+ @def mysql_file_stat(K, FN, S, FL)
+ Instrumented stat.
+ @c mysql_file_stat is a replacement for @c my_stat.
+*/
+#ifdef HAVE_PSI_FILE_INTERFACE
+ #define mysql_file_stat(K, FN, S, FL) \
+ inline_mysql_file_stat(K, __FILE__, __LINE__, FN, S, FL)
+#else
+ #define mysql_file_stat(K, FN, S, FL) \
+ inline_mysql_file_stat(FN, S, FL)
+#endif
+
+/**
+ @def mysql_file_chsize(F, P1, P2, P3)
+ Instrumented chsize.
+ @c mysql_file_chsize is a replacement for @c my_chsize.
+*/
+#ifdef HAVE_PSI_FILE_INTERFACE
+ #define mysql_file_chsize(F, P1, P2, P3) \
+ inline_mysql_file_chsize(__FILE__, __LINE__, F, P1, P2, P3)
+#else
+ #define mysql_file_chsize(F, P1, P2, P3) \
+ inline_mysql_file_chsize(F, P1, P2, P3)
+#endif
+
+/**
+ @def mysql_file_fopen(K, N, F1, F2)
+ Instrumented fopen.
+ @c mysql_file_fopen is a replacement for @c my_fopen.
+*/
+#ifdef HAVE_PSI_FILE_INTERFACE
+ #define mysql_file_fopen(K, N, F1, F2) \
+ inline_mysql_file_fopen(K, __FILE__, __LINE__, N, F1, F2)
+#else
+ #define mysql_file_fopen(K, N, F1, F2) \
+ inline_mysql_file_fopen(N, F1, F2)
+#endif
+
+/**
+ @def mysql_file_fclose(FD, FL)
+ Instrumented fclose.
+ @c mysql_file_fclose is a replacement for @c my_fclose.
+ Without the instrumentation, this call will have the same behavior as the
+ undocumented and possibly platform specific my_fclose(NULL, ...) behavior.
+ With the instrumentation, mysql_fclose(NULL, ...) will safely return 0,
+ which is an extension compared to my_fclose and is therefore compliant.
+ mysql_fclose is on purpose *not* implementing
+ @code DBUG_ASSERT(file != NULL) @endcode,
+ since doing so could introduce regressions.
+*/
+#ifdef HAVE_PSI_FILE_INTERFACE
+ #define mysql_file_fclose(FD, FL) \
+ inline_mysql_file_fclose(__FILE__, __LINE__, FD, FL)
+#else
+ #define mysql_file_fclose(FD, FL) \
+ inline_mysql_file_fclose(FD, FL)
+#endif
+
+/**
+ @def mysql_file_fread(FD, P1, P2, P3)
+ Instrumented fread.
+ @c mysql_file_fread is a replacement for @c my_fread.
+*/
+#ifdef HAVE_PSI_FILE_INTERFACE
+ #define mysql_file_fread(FD, P1, P2, P3) \
+ inline_mysql_file_fread(__FILE__, __LINE__, FD, P1, P2, P3)
+#else
+ #define mysql_file_fread(FD, P1, P2, P3) \
+ inline_mysql_file_fread(FD, P1, P2, P3)
+#endif
+
+/**
+ @def mysql_file_fwrite(FD, P1, P2, P3)
+ Instrumented fwrite.
+ @c mysql_file_fwrite is a replacement for @c my_fwrite.
+*/
+#ifdef HAVE_PSI_FILE_INTERFACE
+ #define mysql_file_fwrite(FD, P1, P2, P3) \
+ inline_mysql_file_fwrite(__FILE__, __LINE__, FD, P1, P2, P3)
+#else
+ #define mysql_file_fwrite(FD, P1, P2, P3) \
+ inline_mysql_file_fwrite(FD, P1, P2, P3)
+#endif
+
+/**
+ @def mysql_file_fseek(FD, P, W, F)
+ Instrumented fseek.
+ @c mysql_file_fseek is a replacement for @c my_fseek.
+*/
+#ifdef HAVE_PSI_FILE_INTERFACE
+ #define mysql_file_fseek(FD, P, W, F) \
+ inline_mysql_file_fseek(__FILE__, __LINE__, FD, P, W, F)
+#else
+ #define mysql_file_fseek(FD, P, W, F) \
+ inline_mysql_file_fseek(FD, P, W, F)
+#endif
+
+/**
+ @def mysql_file_ftell(FD, F)
+ Instrumented ftell.
+ @c mysql_file_ftell is a replacement for @c my_ftell.
+*/
+#ifdef HAVE_PSI_FILE_INTERFACE
+ #define mysql_file_ftell(FD, F) \
+ inline_mysql_file_ftell(__FILE__, __LINE__, FD, F)
+#else
+ #define mysql_file_ftell(FD, F) \
+ inline_mysql_file_ftell(FD, F)
+#endif
+
+/**
+ @def mysql_file_create(K, N, F1, F2, F3)
+ Instrumented create.
+ @c mysql_file_create is a replacement for @c my_create.
+*/
+#ifdef HAVE_PSI_FILE_INTERFACE
+ #define mysql_file_create(K, N, F1, F2, F3) \
+ inline_mysql_file_create(K, __FILE__, __LINE__, N, F1, F2, F3)
+#else
+ #define mysql_file_create(K, N, F1, F2, F3) \
+ inline_mysql_file_create(N, F1, F2, F3)
+#endif
+
+/**
+ @def mysql_file_create_temp(K, T, D, P, M, F)
+ Instrumented create_temp_file.
+ @c mysql_file_create_temp is a replacement for @c create_temp_file.
+*/
+#ifdef HAVE_PSI_FILE_INTERFACE
+ #define mysql_file_create_temp(K, T, D, P, M, F) \
+ inline_mysql_file_create_temp(K, __FILE__, __LINE__, T, D, P, M, F)
+#else
+ #define mysql_file_create_temp(K, T, D, P, M, F) \
+ inline_mysql_file_create_temp(T, D, P, M, F)
+#endif
+
+/**
+ @def mysql_file_open(K, N, F1, F2)
+ Instrumented open.
+ @c mysql_file_open is a replacement for @c my_open.
+*/
+#ifdef HAVE_PSI_FILE_INTERFACE
+ #define mysql_file_open(K, N, F1, F2) \
+ inline_mysql_file_open(K, __FILE__, __LINE__, N, F1, F2)
+#else
+ #define mysql_file_open(K, N, F1, F2) \
+ inline_mysql_file_open(N, F1, F2)
+#endif
+
+/**
+ @def mysql_file_close(FD, F)
+ Instrumented close.
+ @c mysql_file_close is a replacement for @c my_close.
+*/
+#ifdef HAVE_PSI_FILE_INTERFACE
+ #define mysql_file_close(FD, F) \
+ inline_mysql_file_close(__FILE__, __LINE__, FD, F)
+#else
+ #define mysql_file_close(FD, F) \
+ inline_mysql_file_close(FD, F)
+#endif
+
+/**
+ @def mysql_file_read(FD, B, S, F)
+ Instrumented read.
+ @c mysql_read is a replacement for @c my_read.
+*/
+#ifdef HAVE_PSI_FILE_INTERFACE
+ #define mysql_file_read(FD, B, S, F) \
+ inline_mysql_file_read(__FILE__, __LINE__, FD, B, S, F)
+#else
+ #define mysql_file_read(FD, B, S, F) \
+ inline_mysql_file_read(FD, B, S, F)
+#endif
+
+/**
+ @def mysql_file_write(FD, B, S, F)
+ Instrumented write.
+ @c mysql_file_write is a replacement for @c my_write.
+*/
+#ifdef HAVE_PSI_FILE_INTERFACE
+ #define mysql_file_write(FD, B, S, F) \
+ inline_mysql_file_write(__FILE__, __LINE__, FD, B, S, F)
+#else
+ #define mysql_file_write(FD, B, S, F) \
+ inline_mysql_file_write(FD, B, S, F)
+#endif
+
+/**
+ @def mysql_file_pread(FD, B, S, O, F)
+ Instrumented pread.
+ @c mysql_pread is a replacement for @c my_pread.
+*/
+#ifdef HAVE_PSI_FILE_INTERFACE
+ #define mysql_file_pread(FD, B, S, O, F) \
+ inline_mysql_file_pread(__FILE__, __LINE__, FD, B, S, O, F)
+#else
+ #define mysql_file_pread(FD, B, S, O, F) \
+ inline_mysql_file_pread(FD, B, S, O, F)
+#endif
+
+/**
+ @def mysql_file_pwrite(FD, B, S, O, F)
+ Instrumented pwrite.
+ @c mysql_file_pwrite is a replacement for @c my_pwrite.
+*/
+#ifdef HAVE_PSI_FILE_INTERFACE
+ #define mysql_file_pwrite(FD, B, S, O, F) \
+ inline_mysql_file_pwrite(__FILE__, __LINE__, FD, B, S, O, F)
+#else
+ #define mysql_file_pwrite(FD, B, S, O, F) \
+ inline_mysql_file_pwrite(FD, B, S, O, F)
+#endif
+
+/**
+ @def mysql_file_seek(FD, P, W, F)
+ Instrumented seek.
+ @c mysql_file_seek is a replacement for @c my_seek.
+*/
+#ifdef HAVE_PSI_FILE_INTERFACE
+ #define mysql_file_seek(FD, P, W, F) \
+ inline_mysql_file_seek(__FILE__, __LINE__, FD, P, W, F)
+#else
+ #define mysql_file_seek(FD, P, W, F) \
+ inline_mysql_file_seek(FD, P, W, F)
+#endif
+
+/**
+ @def mysql_file_tell(FD, F)
+ Instrumented tell.
+ @c mysql_file_tell is a replacement for @c my_tell.
+*/
+#ifdef HAVE_PSI_FILE_INTERFACE
+ #define mysql_file_tell(FD, F) \
+ inline_mysql_file_tell(__FILE__, __LINE__, FD, F)
+#else
+ #define mysql_file_tell(FD, F) \
+ inline_mysql_file_tell(FD, F)
+#endif
+
+/**
+ @def mysql_file_delete(K, P1, P2)
+ Instrumented delete.
+ @c mysql_file_delete is a replacement for @c my_delete.
+*/
+#ifdef HAVE_PSI_FILE_INTERFACE
+ #define mysql_file_delete(K, P1, P2) \
+ inline_mysql_file_delete(K, __FILE__, __LINE__, P1, P2)
+#else
+ #define mysql_file_delete(K, P1, P2) \
+ inline_mysql_file_delete(P1, P2)
+#endif
+
+/**
+ @def mysql_file_rename(K, P1, P2, P3)
+ Instrumented rename.
+ @c mysql_file_rename is a replacement for @c my_rename.
+*/
+#ifdef HAVE_PSI_FILE_INTERFACE
+ #define mysql_file_rename(K, P1, P2, P3) \
+ inline_mysql_file_rename(K, __FILE__, __LINE__, P1, P2, P3)
+#else
+ #define mysql_file_rename(K, P1, P2, P3) \
+ inline_mysql_file_rename(P1, P2, P3)
+#endif
+
+/**
+ @def mysql_file_create_with_symlink(K, P1, P2, P3, P4, P5)
+ Instrumented create with symbolic link.
+ @c mysql_file_create_with_symlink is a replacement
+ for @c my_create_with_symlink.
+*/
+#ifdef HAVE_PSI_FILE_INTERFACE
+ #define mysql_file_create_with_symlink(K, P1, P2, P3, P4, P5) \
+ inline_mysql_file_create_with_symlink(K, __FILE__, __LINE__, \
+ P1, P2, P3, P4, P5)
+#else
+ #define mysql_file_create_with_symlink(K, P1, P2, P3, P4, P5) \
+ inline_mysql_file_create_with_symlink(P1, P2, P3, P4, P5)
+#endif
+
+/**
+ @def mysql_file_delete_with_symlink(K, P1, P2, P3)
+ Instrumented delete with symbolic link.
+ @c mysql_file_delete_with_symlink is a replacement
+ for @c my_handler_delete_with_symlink.
+*/
+#ifdef HAVE_PSI_FILE_INTERFACE
+ #define mysql_file_delete_with_symlink(K, P1, P2, P3) \
+ inline_mysql_file_delete_with_symlink(K, __FILE__, __LINE__, P1, P2, P3)
+#else
+ #define mysql_file_delete_with_symlink(K, P1, P2, P3) \
+ inline_mysql_file_delete_with_symlink(P1, P2, P3)
+#endif
+
+/**
+ @def mysql_file_rename_with_symlink(K, P1, P2, P3)
+ Instrumented rename with symbolic link.
+ @c mysql_file_rename_with_symlink is a replacement
+ for @c my_rename_with_symlink.
+*/
+#ifdef HAVE_PSI_FILE_INTERFACE
+ #define mysql_file_rename_with_symlink(K, P1, P2, P3) \
+ inline_mysql_file_rename_with_symlink(K, __FILE__, __LINE__, P1, P2, P3)
+#else
+ #define mysql_file_rename_with_symlink(K, P1, P2, P3) \
+ inline_mysql_file_rename_with_symlink(P1, P2, P3)
+#endif
+
+/**
+ @def mysql_file_sync(P1, P2)
+ Instrumented file sync.
+ @c mysql_file_sync is a replacement for @c my_sync.
+*/
+#ifdef HAVE_PSI_FILE_INTERFACE
+ #define mysql_file_sync(P1, P2) \
+ inline_mysql_file_sync(__FILE__, __LINE__, P1, P2)
+#else
+ #define mysql_file_sync(P1, P2) \
+ inline_mysql_file_sync(P1, P2)
+#endif
+
+/**
+ An instrumented FILE structure.
+ @sa MYSQL_FILE
+*/
+struct st_mysql_file
+{
+ /** The real file. */
+ FILE *m_file;
+ /**
+ The instrumentation hook.
+ Note that this hook is not conditionally defined,
+ for binary compatibility of the @c MYSQL_FILE interface.
+ */
+ struct PSI_file *m_psi;
+};
+
+/**
+ Type of an instrumented file.
+ @c MYSQL_FILE is a drop-in replacement for @c FILE.
+ @sa mysql_file_open
+*/
+typedef struct st_mysql_file MYSQL_FILE;
+
+static inline void inline_mysql_file_register(
+#ifdef HAVE_PSI_FILE_INTERFACE
+ const char *category,
+ PSI_file_info *info,
+ int count
+#else
+ const char *category __attribute__ ((unused)),
+ void *info __attribute__ ((unused)),
+ int count __attribute__ ((unused))
+#endif
+)
+{
+#ifdef HAVE_PSI_FILE_INTERFACE
+ PSI_FILE_CALL(register_file)(category, info, count);
+#endif
+}
+
+static inline char *
+inline_mysql_file_fgets(
+#ifdef HAVE_PSI_FILE_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ char *str, int size, MYSQL_FILE *file)
+{
+ char *result;
+#ifdef HAVE_PSI_FILE_INTERFACE
+ if (psi_likely(file->m_psi))
+ {
+ struct PSI_file_locker *locker;
+ PSI_file_locker_state state;
+ locker= PSI_FILE_CALL(get_thread_file_stream_locker) (&state, file->m_psi, PSI_FILE_READ);
+ if (likely(locker != NULL))
+ {
+ PSI_FILE_CALL(start_file_wait)(locker, (size_t) size, src_file, src_line);
+ result= fgets(str, size, file->m_file);
+ PSI_FILE_CALL(end_file_wait)(locker, result ? strlen(result) : 0);
+ return result;
+ }
+ }
+#endif
+
+ result= fgets(str, size, file->m_file);
+ return result;
+}
+
+static inline int
+inline_mysql_file_fgetc(
+#ifdef HAVE_PSI_FILE_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ MYSQL_FILE *file)
+{
+ int result;
+#ifdef HAVE_PSI_FILE_INTERFACE
+ if (psi_likely(file->m_psi))
+ {
+ struct PSI_file_locker *locker;
+ PSI_file_locker_state state;
+ locker= PSI_FILE_CALL(get_thread_file_stream_locker)(&state, file->m_psi, PSI_FILE_READ);
+ if (likely(locker != NULL))
+ {
+ PSI_FILE_CALL(start_file_wait)(locker, (size_t) 1, src_file, src_line);
+ result= fgetc(file->m_file);
+ PSI_FILE_CALL(end_file_wait)(locker, (size_t) 1);
+ return result;
+ }
+ }
+#endif
+
+ result= fgetc(file->m_file);
+ return result;
+}
+
+static inline int
+inline_mysql_file_fputs(
+#ifdef HAVE_PSI_FILE_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ const char *str, MYSQL_FILE *file)
+{
+ int result;
+#ifdef HAVE_PSI_FILE_INTERFACE
+ if (psi_likely(file->m_psi))
+ {
+ struct PSI_file_locker *locker;
+ PSI_file_locker_state state;
+ size_t bytes;
+ locker= PSI_FILE_CALL(get_thread_file_stream_locker) (&state, file->m_psi, PSI_FILE_WRITE);
+ if (likely(locker != NULL))
+ {
+ bytes= str ? strlen(str) : 0;
+ PSI_FILE_CALL(start_file_wait)(locker, bytes, src_file, src_line);
+ result= fputs(str, file->m_file);
+ PSI_FILE_CALL(end_file_wait)(locker, bytes);
+ return result;
+ }
+ }
+#endif
+
+ result= fputs(str, file->m_file);
+ return result;
+}
+
+static inline int
+inline_mysql_file_fputc(
+#ifdef HAVE_PSI_FILE_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ char c, MYSQL_FILE *file)
+{
+ int result;
+#ifdef HAVE_PSI_FILE_INTERFACE
+ if (psi_likely(file->m_psi))
+ {
+ struct PSI_file_locker *locker;
+ PSI_file_locker_state state;
+ locker= PSI_FILE_CALL(get_thread_file_stream_locker) (&state, file->m_psi, PSI_FILE_WRITE);
+ if (likely(locker != NULL))
+ {
+ PSI_FILE_CALL(start_file_wait)(locker, (size_t) 1, src_file, src_line);
+ result= fputc(c, file->m_file);
+ PSI_FILE_CALL(end_file_wait)(locker, (size_t) 1);
+ return result;
+ }
+ }
+#endif
+
+ result= fputc(c, file->m_file);
+ return result;
+}
+
+static inline int
+inline_mysql_file_fprintf(MYSQL_FILE *file, const char *format, ...)
+{
+ /*
+ TODO: figure out how to pass src_file and src_line from the caller.
+ */
+ int result;
+ va_list args;
+#ifdef HAVE_PSI_FILE_INTERFACE
+ if (psi_likely(file->m_psi))
+ {
+ struct PSI_file_locker *locker;
+ PSI_file_locker_state state;
+ locker= PSI_FILE_CALL(get_thread_file_stream_locker) (&state, file->m_psi, PSI_FILE_WRITE);
+ if (likely(locker != NULL))
+ {
+ PSI_FILE_CALL(start_file_wait)(locker, (size_t) 0, __FILE__, __LINE__);
+ va_start(args, format);
+ result= vfprintf(file->m_file, format, args);
+ va_end(args);
+ PSI_FILE_CALL(end_file_wait)(locker, (size_t) result);
+ return result;
+ }
+ }
+#endif
+
+ va_start(args, format);
+ result= vfprintf(file->m_file, format, args);
+ va_end(args);
+ return result;
+}
+
+static inline int
+inline_mysql_file_vfprintf(
+#ifdef HAVE_PSI_FILE_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ MYSQL_FILE *file, const char *format, va_list args)
+{
+ int result;
+#ifdef HAVE_PSI_FILE_INTERFACE
+ if (psi_likely(file->m_psi))
+ {
+ struct PSI_file_locker *locker;
+ PSI_file_locker_state state;
+ locker= PSI_FILE_CALL(get_thread_file_stream_locker) (&state, file->m_psi, PSI_FILE_WRITE);
+ if (likely(locker != NULL))
+ {
+ PSI_FILE_CALL(start_file_wait)(locker, (size_t) 0, src_file, src_line);
+ result= vfprintf(file->m_file, format, args);
+ PSI_FILE_CALL(end_file_wait)(locker, (size_t) result);
+ return result;
+ }
+ }
+#endif
+
+ result= vfprintf(file->m_file, format, args);
+ return result;
+}
+
+static inline int
+inline_mysql_file_fflush(
+#ifdef HAVE_PSI_FILE_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ MYSQL_FILE *file)
+{
+ int result;
+#ifdef HAVE_PSI_FILE_INTERFACE
+ if (psi_likely(file->m_psi))
+ {
+ struct PSI_file_locker *locker;
+ PSI_file_locker_state state;
+ locker= PSI_FILE_CALL(get_thread_file_stream_locker)(&state, file->m_psi, PSI_FILE_FLUSH);
+ if (likely(locker != NULL))
+ {
+ PSI_FILE_CALL(start_file_wait)(locker, (size_t) 0, src_file, src_line);
+ result= fflush(file->m_file);
+ PSI_FILE_CALL(end_file_wait)(locker, (size_t) 0);
+ return result;
+ }
+ }
+#endif
+
+ result= fflush(file->m_file);
+ return result;
+}
+
+static inline int inline_mysql_file_feof(MYSQL_FILE *file)
+{
+ /* Not instrumented, there is no wait involved */
+ return feof(file->m_file);
+}
+
+static inline int
+inline_mysql_file_fstat(
+#ifdef HAVE_PSI_FILE_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ int filenr, MY_STAT *stat_area, myf flags)
+{
+ int result;
+#ifdef HAVE_PSI_FILE_INTERFACE
+ struct PSI_file_locker *locker;
+ PSI_file_locker_state state;
+ locker= PSI_FILE_CALL(get_thread_file_descriptor_locker)(&state, filenr, PSI_FILE_FSTAT);
+ if (psi_likely(locker != NULL))
+ {
+ PSI_FILE_CALL(start_file_wait)(locker, (size_t) 0, src_file, src_line);
+ result= my_fstat(filenr, stat_area, flags);
+ PSI_FILE_CALL(end_file_wait)(locker, (size_t) 0);
+ return result;
+ }
+#endif
+
+ result= my_fstat(filenr, stat_area, flags);
+ return result;
+}
+
+static inline MY_STAT *
+inline_mysql_file_stat(
+#ifdef HAVE_PSI_FILE_INTERFACE
+ PSI_file_key key, const char *src_file, uint src_line,
+#endif
+ const char *path, MY_STAT *stat_area, myf flags)
+{
+ MY_STAT *result;
+#ifdef HAVE_PSI_FILE_INTERFACE
+ struct PSI_file_locker *locker;
+ PSI_file_locker_state state;
+ locker= PSI_FILE_CALL(get_thread_file_name_locker)(&state, key, PSI_FILE_STAT, path, &locker);
+ if (psi_likely(locker != NULL))
+ {
+ PSI_FILE_CALL(start_file_open_wait)(locker, src_file, src_line);
+ result= my_stat(path, stat_area, flags);
+ PSI_FILE_CALL(end_file_open_wait)(locker, result);
+ return result;
+ }
+#endif
+
+ result= my_stat(path, stat_area, flags);
+ return result;
+}
+
+static inline int
+inline_mysql_file_chsize(
+#ifdef HAVE_PSI_FILE_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ File file, my_off_t newlength, int filler, myf flags)
+{
+ int result;
+#ifdef HAVE_PSI_FILE_INTERFACE
+ struct PSI_file_locker *locker;
+ PSI_file_locker_state state;
+ locker= PSI_FILE_CALL(get_thread_file_descriptor_locker)(&state, file, PSI_FILE_CHSIZE);
+ if (psi_likely(locker != NULL))
+ {
+ PSI_FILE_CALL(start_file_wait)(locker, (size_t) newlength, src_file,
+ src_line);
+ result= my_chsize(file, newlength, filler, flags);
+ PSI_FILE_CALL(end_file_wait)(locker, (size_t) newlength);
+ return result;
+ }
+#endif
+
+ result= my_chsize(file, newlength, filler, flags);
+ return result;
+}
+
+static inline MYSQL_FILE*
+inline_mysql_file_fopen(
+#ifdef HAVE_PSI_FILE_INTERFACE
+ PSI_file_key key, const char *src_file, uint src_line,
+#endif
+ const char *filename, int flags, myf myFlags)
+{
+ MYSQL_FILE *that;
+ that= (MYSQL_FILE*) my_malloc(PSI_NOT_INSTRUMENTED,
+ sizeof(MYSQL_FILE), MYF(MY_WME));
+ if (likely(that != NULL))
+ {
+#ifdef HAVE_PSI_FILE_INTERFACE
+ struct PSI_file_locker *locker;
+ PSI_file_locker_state state;
+ locker= PSI_FILE_CALL(get_thread_file_name_locker)(&state, key, PSI_FILE_STREAM_OPEN,
+ filename, that);
+ if (psi_likely(locker != NULL))
+ {
+ PSI_FILE_CALL(start_file_open_wait)(locker, src_file, src_line);
+ that->m_file= my_fopen(filename, flags, myFlags);
+ that->m_psi= PSI_FILE_CALL(end_file_open_wait)(locker, that->m_file);
+ if (unlikely(that->m_file == NULL))
+ {
+ my_free(that);
+ return NULL;
+ }
+ return that;
+ }
+#endif
+
+ that->m_psi= NULL;
+ that->m_file= my_fopen(filename, flags, myFlags);
+ if (unlikely(that->m_file == NULL))
+ {
+ my_free(that);
+ return NULL;
+ }
+ }
+ return that;
+}
+
+static inline int
+inline_mysql_file_fclose(
+#ifdef HAVE_PSI_FILE_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ MYSQL_FILE *file, myf flags)
+{
+ int result= 0;
+ if (likely(file != NULL))
+ {
+#ifdef HAVE_PSI_FILE_INTERFACE
+ if (psi_likely(file->m_psi))
+ {
+ struct PSI_file_locker *locker;
+ PSI_file_locker_state state;
+ locker= PSI_FILE_CALL(get_thread_file_stream_locker)(&state, file->m_psi,
+ PSI_FILE_STREAM_CLOSE);
+ if (likely(locker != NULL))
+ {
+ PSI_FILE_CALL(start_file_close_wait)(locker, src_file, src_line);
+ result= my_fclose(file->m_file, flags);
+ PSI_FILE_CALL(end_file_close_wait)(locker, result);
+ my_free(file);
+ return result;
+ }
+ }
+#endif
+
+ result= my_fclose(file->m_file, flags);
+ my_free(file);
+ }
+ return result;
+}
+
+static inline size_t
+inline_mysql_file_fread(
+#ifdef HAVE_PSI_FILE_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ MYSQL_FILE *file, uchar *buffer, size_t count, myf flags)
+{
+ size_t result;
+#ifdef HAVE_PSI_FILE_INTERFACE
+ if (psi_likely(file->m_psi))
+ {
+ struct PSI_file_locker *locker;
+ PSI_file_locker_state state;
+ size_t bytes_read;
+ locker= PSI_FILE_CALL(get_thread_file_stream_locker)(&state, file->m_psi, PSI_FILE_READ);
+ if (likely(locker != NULL))
+ {
+ PSI_FILE_CALL(start_file_wait)(locker, count, src_file, src_line);
+ result= my_fread(file->m_file, buffer, count, flags);
+ if (flags & (MY_NABP | MY_FNABP))
+ bytes_read= (result == 0) ? count : 0;
+ else
+ bytes_read= (result != MY_FILE_ERROR) ? result : 0;
+ PSI_FILE_CALL(end_file_wait)(locker, bytes_read);
+ return result;
+ }
+ }
+#endif
+
+ result= my_fread(file->m_file, buffer, count, flags);
+ return result;
+}
+
+static inline size_t
+inline_mysql_file_fwrite(
+#ifdef HAVE_PSI_FILE_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ MYSQL_FILE *file, const uchar *buffer, size_t count, myf flags)
+{
+ size_t result;
+#ifdef HAVE_PSI_FILE_INTERFACE
+ if (psi_likely(file->m_psi))
+ {
+ struct PSI_file_locker *locker;
+ PSI_file_locker_state state;
+ size_t bytes_written;
+ locker= PSI_FILE_CALL(get_thread_file_stream_locker)(&state, file->m_psi, PSI_FILE_WRITE);
+ if (likely(locker != NULL))
+ {
+ PSI_FILE_CALL(start_file_wait)(locker, count, src_file, src_line);
+ result= my_fwrite(file->m_file, buffer, count, flags);
+ if (flags & (MY_NABP | MY_FNABP))
+ bytes_written= (result == 0) ? count : 0;
+ else
+ bytes_written= (result != MY_FILE_ERROR) ? result : 0;
+ PSI_FILE_CALL(end_file_wait)(locker, bytes_written);
+ return result;
+ }
+ }
+#endif
+
+ result= my_fwrite(file->m_file, buffer, count, flags);
+ return result;
+}
+
+static inline my_off_t
+inline_mysql_file_fseek(
+#ifdef HAVE_PSI_FILE_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ MYSQL_FILE *file, my_off_t pos, int whence, myf flags)
+{
+ my_off_t result;
+#ifdef HAVE_PSI_FILE_INTERFACE
+ if (psi_likely(file->m_psi))
+ {
+ struct PSI_file_locker *locker;
+ PSI_file_locker_state state;
+ locker= PSI_FILE_CALL(get_thread_file_stream_locker)(&state, file->m_psi, PSI_FILE_SEEK);
+ if (likely(locker != NULL))
+ {
+ PSI_FILE_CALL(start_file_wait)(locker, (size_t) 0, src_file, src_line);
+ result= my_fseek(file->m_file, pos, whence, flags);
+ PSI_FILE_CALL(end_file_wait)(locker, (size_t) 0);
+ return result;
+ }
+ }
+#endif
+
+ result= my_fseek(file->m_file, pos, whence, flags);
+ return result;
+}
+
+static inline my_off_t
+inline_mysql_file_ftell(
+#ifdef HAVE_PSI_FILE_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ MYSQL_FILE *file, myf flags)
+{
+ my_off_t result;
+#ifdef HAVE_PSI_FILE_INTERFACE
+ if (psi_likely(file->m_psi))
+ {
+ struct PSI_file_locker *locker;
+ PSI_file_locker_state state;
+ locker= PSI_FILE_CALL(get_thread_file_stream_locker)(&state, file->m_psi, PSI_FILE_TELL);
+ if (likely(locker != NULL))
+ {
+ PSI_FILE_CALL(start_file_wait)(locker, (size_t) 0, src_file, src_line);
+ result= my_ftell(file->m_file, flags);
+ PSI_FILE_CALL(end_file_wait)(locker, (size_t) 0);
+ return result;
+ }
+ }
+#endif
+
+ result= my_ftell(file->m_file, flags);
+ return result;
+}
+
+static inline File
+inline_mysql_file_create(
+#ifdef HAVE_PSI_FILE_INTERFACE
+ PSI_file_key key, const char *src_file, uint src_line,
+#endif
+ const char *filename, int create_flags, int access_flags, myf myFlags)
+{
+ File file;
+#ifdef HAVE_PSI_FILE_INTERFACE
+ struct PSI_file_locker *locker;
+ PSI_file_locker_state state;
+ locker= PSI_FILE_CALL(get_thread_file_name_locker)(&state, key, PSI_FILE_CREATE, filename,
+ &locker);
+ if (psi_likely(locker != NULL))
+ {
+ PSI_FILE_CALL(start_file_open_wait)(locker, src_file, src_line);
+ file= my_create(filename, create_flags, access_flags, myFlags);
+ PSI_FILE_CALL(end_file_open_wait_and_bind_to_descriptor)(locker, file);
+ return file;
+ }
+#endif
+
+ file= my_create(filename, create_flags, access_flags, myFlags);
+ return file;
+}
+
+static inline File
+inline_mysql_file_create_temp(
+#ifdef HAVE_PSI_FILE_INTERFACE
+ PSI_file_key key, const char *src_file, uint src_line,
+#endif
+ char *to, const char *dir, const char *pfx, int mode, myf myFlags)
+{
+ File file;
+#ifdef HAVE_PSI_FILE_INTERFACE
+ struct PSI_file_locker *locker;
+ PSI_file_locker_state state;
+ locker= PSI_FILE_CALL(get_thread_file_name_locker)
+ (&state, key, PSI_FILE_CREATE, NULL, &locker);
+ if (psi_likely(locker != NULL))
+ {
+ PSI_FILE_CALL(start_file_open_wait)(locker, src_file, src_line);
+ /* The file name is generated by create_temp_file(). */
+ file= create_temp_file(to, dir, pfx, mode, myFlags);
+ PSI_FILE_CALL(end_temp_file_open_wait_and_bind_to_descriptor)(locker, file, (const char*)to);
+ return file;
+ }
+#endif
+
+ file= create_temp_file(to, dir, pfx, mode, myFlags);
+ return file;
+}
+
+static inline File
+inline_mysql_file_open(
+#ifdef HAVE_PSI_FILE_INTERFACE
+ PSI_file_key key, const char *src_file, uint src_line,
+#endif
+ const char *filename, int flags, myf myFlags)
+{
+ File file;
+#ifdef HAVE_PSI_FILE_INTERFACE
+ struct PSI_file_locker *locker;
+ PSI_file_locker_state state;
+ locker= PSI_FILE_CALL(get_thread_file_name_locker)(&state, key, PSI_FILE_OPEN, filename,
+ &locker);
+ if (psi_likely(locker != NULL))
+ {
+ PSI_FILE_CALL(start_file_open_wait)(locker, src_file, src_line);
+ file= my_open(filename, flags, myFlags);
+ PSI_FILE_CALL(end_file_open_wait_and_bind_to_descriptor)(locker, file);
+ return file;
+ }
+#endif
+
+ file= my_open(filename, flags, myFlags);
+ return file;
+}
+
+static inline int
+inline_mysql_file_close(
+#ifdef HAVE_PSI_FILE_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ File file, myf flags)
+{
+ int result;
+#ifdef HAVE_PSI_FILE_INTERFACE
+ struct PSI_file_locker *locker;
+ PSI_file_locker_state state;
+ locker= PSI_FILE_CALL(get_thread_file_descriptor_locker)(&state, file, PSI_FILE_CLOSE);
+ if (psi_likely(locker != NULL))
+ {
+ PSI_FILE_CALL(start_file_close_wait)(locker, src_file, src_line);
+ result= my_close(file, flags);
+ PSI_FILE_CALL(end_file_close_wait)(locker, result);
+ return result;
+ }
+#endif
+
+ result= my_close(file, flags);
+ return result;
+}
+
+static inline size_t
+inline_mysql_file_read(
+#ifdef HAVE_PSI_FILE_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ File file, uchar *buffer, size_t count, myf flags)
+{
+ size_t result;
+#ifdef HAVE_PSI_FILE_INTERFACE
+ struct PSI_file_locker *locker;
+ PSI_file_locker_state state;
+ size_t bytes_read;
+ locker= PSI_FILE_CALL(get_thread_file_descriptor_locker)(&state, file, PSI_FILE_READ);
+ if (psi_likely(locker != NULL))
+ {
+ PSI_FILE_CALL(start_file_wait)(locker, count, src_file, src_line);
+ result= my_read(file, buffer, count, flags);
+ if (flags & (MY_NABP | MY_FNABP))
+ bytes_read= (result == 0) ? count : 0;
+ else
+ bytes_read= (result != MY_FILE_ERROR) ? result : 0;
+ PSI_FILE_CALL(end_file_wait)(locker, bytes_read);
+ return result;
+ }
+#endif
+
+ result= my_read(file, buffer, count, flags);
+ return result;
+}
+
+static inline size_t
+inline_mysql_file_write(
+#ifdef HAVE_PSI_FILE_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ File file, const uchar *buffer, size_t count, myf flags)
+{
+ size_t result;
+#ifdef HAVE_PSI_FILE_INTERFACE
+ struct PSI_file_locker *locker;
+ PSI_file_locker_state state;
+ size_t bytes_written;
+ locker= PSI_FILE_CALL(get_thread_file_descriptor_locker)(&state, file, PSI_FILE_WRITE);
+ if (psi_likely(locker != NULL))
+ {
+ PSI_FILE_CALL(start_file_wait)(locker, count, src_file, src_line);
+ result= my_write(file, buffer, count, flags);
+ if (flags & (MY_NABP | MY_FNABP))
+ bytes_written= (result == 0) ? count : 0;
+ else
+ bytes_written= (result != MY_FILE_ERROR) ? result : 0;
+ PSI_FILE_CALL(end_file_wait)(locker, bytes_written);
+ return result;
+ }
+#endif
+
+ result= my_write(file, buffer, count, flags);
+ return result;
+}
+
+static inline size_t
+inline_mysql_file_pread(
+#ifdef HAVE_PSI_FILE_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ File file, uchar *buffer, size_t count, my_off_t offset, myf flags)
+{
+ size_t result;
+#ifdef HAVE_PSI_FILE_INTERFACE
+ struct PSI_file_locker *locker;
+ PSI_file_locker_state state;
+ size_t bytes_read;
+ locker= PSI_FILE_CALL(get_thread_file_descriptor_locker)(&state, file, PSI_FILE_READ);
+ if (psi_likely(locker != NULL))
+ {
+ PSI_FILE_CALL(start_file_wait)(locker, count, src_file, src_line);
+ result= my_pread(file, buffer, count, offset, flags);
+ if (flags & (MY_NABP | MY_FNABP))
+ bytes_read= (result == 0) ? count : 0;
+ else
+ bytes_read= (result != MY_FILE_ERROR) ? result : 0;
+ PSI_FILE_CALL(end_file_wait)(locker, bytes_read);
+ return result;
+ }
+#endif
+
+ result= my_pread(file, buffer, count, offset, flags);
+ return result;
+}
+
+static inline size_t
+inline_mysql_file_pwrite(
+#ifdef HAVE_PSI_FILE_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ File file, const uchar *buffer, size_t count, my_off_t offset, myf flags)
+{
+ size_t result;
+#ifdef HAVE_PSI_FILE_INTERFACE
+ struct PSI_file_locker *locker;
+ PSI_file_locker_state state;
+ size_t bytes_written;
+ locker= PSI_FILE_CALL(get_thread_file_descriptor_locker)(&state, file, PSI_FILE_WRITE);
+ if (psi_likely(locker != NULL))
+ {
+ PSI_FILE_CALL(start_file_wait)(locker, count, src_file, src_line);
+ result= my_pwrite(file, buffer, count, offset, flags);
+ if (flags & (MY_NABP | MY_FNABP))
+ bytes_written= (result == 0) ? count : 0;
+ else
+ bytes_written= (result != MY_FILE_ERROR) ? result : 0;
+ PSI_FILE_CALL(end_file_wait)(locker, bytes_written);
+ return result;
+ }
+#endif
+
+ result= my_pwrite(file, buffer, count, offset, flags);
+ return result;
+}
+
+static inline my_off_t
+inline_mysql_file_seek(
+#ifdef HAVE_PSI_FILE_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ File file, my_off_t pos, int whence, myf flags)
+{
+ my_off_t result;
+#ifdef HAVE_PSI_FILE_INTERFACE
+ struct PSI_file_locker *locker;
+ PSI_file_locker_state state;
+ locker= PSI_FILE_CALL(get_thread_file_descriptor_locker)(&state, file, PSI_FILE_SEEK);
+ if (psi_likely(locker != NULL))
+ {
+ PSI_FILE_CALL(start_file_wait)(locker, (size_t) 0, src_file, src_line);
+ result= my_seek(file, pos, whence, flags);
+ PSI_FILE_CALL(end_file_wait)(locker, (size_t) 0);
+ return result;
+ }
+#endif
+
+ result= my_seek(file, pos, whence, flags);
+ return result;
+}
+
+static inline my_off_t
+inline_mysql_file_tell(
+#ifdef HAVE_PSI_FILE_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ File file, myf flags)
+{
+ my_off_t result;
+#ifdef HAVE_PSI_FILE_INTERFACE
+ struct PSI_file_locker *locker;
+ PSI_file_locker_state state;
+ locker= PSI_FILE_CALL(get_thread_file_descriptor_locker)(&state, file, PSI_FILE_TELL);
+ if (psi_likely(locker != NULL))
+ {
+ PSI_FILE_CALL(start_file_wait)(locker, (size_t) 0, src_file, src_line);
+ result= my_tell(file, flags);
+ PSI_FILE_CALL(end_file_wait)(locker, (size_t) 0);
+ return result;
+ }
+#endif
+
+ result= my_tell(file, flags);
+ return result;
+}
+
+static inline int
+inline_mysql_file_delete(
+#ifdef HAVE_PSI_FILE_INTERFACE
+ PSI_file_key key, const char *src_file, uint src_line,
+#endif
+ const char *name, myf flags)
+{
+ int result;
+#ifdef HAVE_PSI_FILE_INTERFACE
+ struct PSI_file_locker *locker;
+ PSI_file_locker_state state;
+ locker= PSI_FILE_CALL(get_thread_file_name_locker)(&state, key, PSI_FILE_DELETE, name, &locker);
+ if (psi_likely(locker != NULL))
+ {
+ PSI_FILE_CALL(start_file_close_wait)(locker, src_file, src_line);
+ result= my_delete(name, flags);
+ PSI_FILE_CALL(end_file_close_wait)(locker, result);
+ return result;
+ }
+#endif
+
+ result= my_delete(name, flags);
+ return result;
+}
+
+static inline int
+inline_mysql_file_rename(
+#ifdef HAVE_PSI_FILE_INTERFACE
+ PSI_file_key key, const char *src_file, uint src_line,
+#endif
+ const char *from, const char *to, myf flags)
+{
+ int result;
+#ifdef HAVE_PSI_FILE_INTERFACE
+ struct PSI_file_locker *locker;
+ PSI_file_locker_state state;
+ locker= PSI_FILE_CALL(get_thread_file_name_locker)
+ (&state, key, PSI_FILE_RENAME, from, &locker);
+ if (psi_likely(locker != NULL))
+ {
+ PSI_FILE_CALL(start_file_wait)(locker, (size_t) 0, src_file, src_line);
+ result= my_rename(from, to, flags);
+ PSI_FILE_CALL(end_file_rename_wait)(locker, from, to, result);
+ return result;
+ }
+#endif
+
+ result= my_rename(from, to, flags);
+ return result;
+}
+
+
+static inline File
+inline_mysql_file_create_with_symlink(
+#ifdef HAVE_PSI_FILE_INTERFACE
+ PSI_file_key key, const char *src_file, uint src_line,
+#endif
+ const char *linkname, const char *filename, int create_flags,
+ int access_flags, myf flags)
+{
+ File file;
+#ifdef HAVE_PSI_FILE_INTERFACE
+ struct PSI_file_locker *locker;
+ PSI_file_locker_state state;
+ locker= PSI_FILE_CALL(get_thread_file_name_locker)(&state, key, PSI_FILE_CREATE, filename,
+ &locker);
+ if (psi_likely(locker != NULL))
+ {
+ PSI_FILE_CALL(start_file_open_wait)(locker, src_file, src_line);
+ file= my_create_with_symlink(linkname, filename, create_flags, access_flags,
+ flags);
+ PSI_FILE_CALL(end_file_open_wait_and_bind_to_descriptor)(locker, file);
+ return file;
+ }
+#endif
+
+ file= my_create_with_symlink(linkname, filename, create_flags, access_flags,
+ flags);
+ return file;
+}
+
+
+static inline int
+inline_mysql_file_delete_with_symlink(
+#ifdef HAVE_PSI_FILE_INTERFACE
+ PSI_file_key key, const char *src_file, uint src_line,
+#endif
+ const char *name, const char *ext, myf flags)
+{
+ int result;
+ char buf[FN_REFLEN];
+ char *fullname= fn_format(buf, name, "", ext, MY_UNPACK_FILENAME | MY_APPEND_EXT);
+#ifdef HAVE_PSI_FILE_INTERFACE
+ struct PSI_file_locker *locker;
+ PSI_file_locker_state state;
+ locker= PSI_FILE_CALL(get_thread_file_name_locker)(&state, key, PSI_FILE_DELETE, fullname,
+ &locker);
+ if (psi_likely(locker != NULL))
+ {
+ PSI_FILE_CALL(start_file_close_wait)(locker, src_file, src_line);
+ result= my_handler_delete_with_symlink(fullname, flags);
+ PSI_FILE_CALL(end_file_close_wait)(locker, result);
+ return result;
+ }
+#endif
+
+ result= my_handler_delete_with_symlink(fullname, flags);
+ return result;
+}
+
+
+static inline int
+inline_mysql_file_rename_with_symlink(
+#ifdef HAVE_PSI_FILE_INTERFACE
+ PSI_file_key key, const char *src_file, uint src_line,
+#endif
+ const char *from, const char *to, myf flags)
+{
+ int result;
+#ifdef HAVE_PSI_FILE_INTERFACE
+ struct PSI_file_locker *locker;
+ PSI_file_locker_state state;
+ locker= PSI_FILE_CALL(get_thread_file_name_locker)
+ (&state, key, PSI_FILE_RENAME, from, &locker);
+ if (psi_likely(locker != NULL))
+ {
+ PSI_FILE_CALL(start_file_wait)(locker, (size_t) 0, src_file, src_line);
+ result= my_rename_with_symlink(from, to, flags);
+ PSI_FILE_CALL(end_file_rename_wait)(locker, from, to, result);
+ return result;
+ }
+#endif
+
+ result= my_rename_with_symlink(from, to, flags);
+ return result;
+}
+
+static inline int
+inline_mysql_file_sync(
+#ifdef HAVE_PSI_FILE_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ File fd, myf flags)
+{
+ int result= 0;
+#ifdef HAVE_PSI_FILE_INTERFACE
+ struct PSI_file_locker *locker;
+ PSI_file_locker_state state;
+ locker= PSI_FILE_CALL(get_thread_file_descriptor_locker)(&state, fd, PSI_FILE_SYNC);
+ if (psi_likely(locker != NULL))
+ {
+ PSI_FILE_CALL(start_file_wait)(locker, (size_t) 0, src_file, src_line);
+ result= my_sync(fd, flags);
+ PSI_FILE_CALL(end_file_wait)(locker, (size_t) 0);
+ return result;
+ }
+#endif
+
+ result= my_sync(fd, flags);
+ return result;
+}
+
+/** @} (end of group File_instrumentation) */
+
+#endif
diff --git a/include/mysql/psi/mysql_idle.h b/include/mysql/psi/mysql_idle.h
new file mode 100644
index 00000000..f8085073
--- /dev/null
+++ b/include/mysql/psi/mysql_idle.h
@@ -0,0 +1,104 @@
+/* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2017, 2019, MariaDB Corporation.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License, version 2.0, for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */
+
+#ifndef MYSQL_IDLE_H
+#define MYSQL_IDLE_H
+
+/**
+ @file mysql/psi/mysql_idle.h
+ Instrumentation helpers for idle waits.
+*/
+
+#include "mysql/psi/psi.h"
+
+#ifndef PSI_IDLE_CALL
+#define PSI_IDLE_CALL(M) PSI_DYNAMIC_CALL(M)
+#endif
+
+/**
+ @defgroup Idle_instrumentation Idle Instrumentation
+ @ingroup Instrumentation_interface
+ @{
+*/
+
+/**
+ @def MYSQL_START_IDLE_WAIT
+ Instrumentation helper for table io_waits.
+ This instrumentation marks the start of a wait event.
+ @param LOCKER the locker
+ @param STATE the locker state
+ @sa MYSQL_END_IDLE_WAIT.
+*/
+#ifdef HAVE_PSI_IDLE_INTERFACE
+ #define MYSQL_START_IDLE_WAIT(LOCKER, STATE) \
+ LOCKER= inline_mysql_start_idle_wait(STATE, __FILE__, __LINE__)
+#else
+ #define MYSQL_START_IDLE_WAIT(LOCKER, STATE) \
+ do {} while (0)
+#endif
+
+/**
+ @def MYSQL_END_IDLE_WAIT
+ Instrumentation helper for idle waits.
+ This instrumentation marks the end of a wait event.
+ @param LOCKER the locker
+ @sa MYSQL_START_IDLE_WAIT.
+*/
+#ifdef HAVE_PSI_IDLE_INTERFACE
+ #define MYSQL_END_IDLE_WAIT(LOCKER) \
+ inline_mysql_end_idle_wait(LOCKER)
+#else
+ #define MYSQL_END_IDLE_WAIT(LOCKER) \
+ do {} while (0)
+#endif
+
+#ifdef HAVE_PSI_IDLE_INTERFACE
+/**
+ Instrumentation calls for MYSQL_START_IDLE_WAIT.
+ @sa MYSQL_END_IDLE_WAIT.
+*/
+static inline struct PSI_idle_locker *
+inline_mysql_start_idle_wait(PSI_idle_locker_state *state,
+ const char *src_file, uint src_line)
+{
+ struct PSI_idle_locker *locker;
+ locker= PSI_IDLE_CALL(start_idle_wait)(state, src_file, src_line);
+ return locker;
+}
+
+/**
+ Instrumentation calls for MYSQL_END_IDLE_WAIT.
+ @sa MYSQL_START_IDLE_WAIT.
+*/
+static inline void
+inline_mysql_end_idle_wait(struct PSI_idle_locker *locker)
+{
+ if (psi_likely(locker != NULL))
+ PSI_IDLE_CALL(end_idle_wait)(locker);
+}
+#endif
+
+/** @} (end of group Idle_instrumentation) */
+
+#endif
+
diff --git a/include/mysql/psi/mysql_mdl.h b/include/mysql/psi/mysql_mdl.h
new file mode 100644
index 00000000..20d6c94c
--- /dev/null
+++ b/include/mysql/psi/mysql_mdl.h
@@ -0,0 +1,143 @@
+/* Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License, version 2.0, for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
+
+#ifndef MYSQL_MDL_H
+#define MYSQL_MDL_H
+
+/**
+ @file mysql/psi/mysql_mdl.h
+ Instrumentation helpers for metadata locks.
+*/
+
+#include "mysql/psi/psi.h"
+
+#ifdef HAVE_PSI_METADATA_INTERFACE
+
+#ifndef PSI_METADATA_CALL
+#define PSI_METADATA_CALL(M) PSI_DYNAMIC_CALL(M)
+#endif
+
+#define PSI_CALL_start_metadata_wait(A,B,C,D) PSI_METADATA_CALL(start_metadata_wait)(A,B,C,D)
+#define PSI_CALL_end_metadata_wait(A,B) PSI_METADATA_CALL(end_metadata_wait)(A,B)
+#define PSI_CALL_create_metadata_lock(A,B,C,D,E,F,G) PSI_METADATA_CALL(create_metadata_lock)(A,B,C,D,E,F,G)
+#define PSI_CALL_set_metadata_lock_status(A,B) PSI_METADATA_CALL(set_metadata_lock_status)(A,B)
+#define PSI_CALL_destroy_metadata_lock(A) PSI_METADATA_CALL(destroy_metadata_lock)(A)
+#else
+#define PSI_CALL_start_metadata_wait(A,B,C,D) 0
+#define PSI_CALL_end_metadata_wait(A,B) do { } while(0)
+#define PSI_CALL_create_metadata_lock(A,B,C,D,E,F,G) 0
+#define PSI_CALL_set_metadata_lock_status(A,B) do {} while(0)
+#define PSI_CALL_destroy_metadata_lock(A) do {} while(0)
+#endif
+
+/**
+ @defgroup Thread_instrumentation Metadata Instrumentation
+ @ingroup Instrumentation_interface
+ @{
+*/
+
+/**
+ @def mysql_mdl_create(K, M, A)
+ Instrumented metadata lock creation.
+ @param I Metadata lock identity
+ @param K Metadata key
+ @param T Metadata lock type
+ @param D Metadata lock duration
+ @param S Metadata lock status
+ @param F request source file
+ @param L request source line
+*/
+
+#ifdef HAVE_PSI_METADATA_INTERFACE
+ #define mysql_mdl_create(I, K, T, D, S, F, L) \
+ inline_mysql_mdl_create(I, K, T, D, S, F, L)
+#else
+ #define mysql_mdl_create(I, K, T, D, S, F, L) NULL
+#endif
+
+#ifdef HAVE_PSI_METADATA_INTERFACE
+ #define mysql_mdl_set_status(L, S) \
+ inline_mysql_mdl_set_status(L, S)
+#else
+ #define mysql_mdl_set_status(L, S) \
+ do {} while (0)
+#endif
+
+
+/**
+ @def mysql_mdl_destroy(M)
+ Instrumented metadata lock destruction.
+ @param M Metadata lock
+*/
+#ifdef HAVE_PSI_METADATA_INTERFACE
+ #define mysql_mdl_destroy(M) \
+ inline_mysql_mdl_destroy(M, __FILE__, __LINE__)
+#else
+ #define mysql_mdl_destroy(M) \
+ do {} while (0)
+#endif
+
+#ifdef HAVE_PSI_METADATA_INTERFACE
+
+static inline PSI_metadata_lock *
+inline_mysql_mdl_create(void *identity,
+ const MDL_key *mdl_key,
+ enum_mdl_type mdl_type,
+ enum_mdl_duration mdl_duration,
+ MDL_ticket::enum_psi_status mdl_status,
+ const char *src_file, uint src_line)
+{
+ PSI_metadata_lock *result;
+
+ /* static_cast: Fit a round C++ enum peg into a square C int hole ... */
+ result= PSI_METADATA_CALL(create_metadata_lock)
+ (identity,
+ mdl_key,
+ static_cast<opaque_mdl_type> (mdl_type),
+ static_cast<opaque_mdl_duration> (mdl_duration),
+ static_cast<opaque_mdl_status> (mdl_status),
+ src_file, src_line);
+
+ return result;
+}
+
+static inline void inline_mysql_mdl_set_status(
+ PSI_metadata_lock *psi,
+ MDL_ticket::enum_psi_status mdl_status)
+{
+ if (psi != NULL)
+ PSI_METADATA_CALL(set_metadata_lock_status)(psi, mdl_status);
+}
+
+static inline void inline_mysql_mdl_destroy(
+ PSI_metadata_lock *psi,
+ const char *src_file, uint src_line)
+{
+ if (psi != NULL)
+ PSI_METADATA_CALL(destroy_metadata_lock)(psi);
+}
+#endif /* HAVE_PSI_METADATA_INTERFACE */
+
+/** @} (end of group Metadata_instrumentation) */
+
+#endif
+
diff --git a/include/mysql/psi/mysql_memory.h b/include/mysql/psi/mysql_memory.h
new file mode 100644
index 00000000..a79579c2
--- /dev/null
+++ b/include/mysql/psi/mysql_memory.h
@@ -0,0 +1,79 @@
+/* Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License, version 2.0, for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
+
+#ifndef MYSQL_MEMORY_H
+#define MYSQL_MEMORY_H
+
+/**
+ @file mysql/psi/mysql_memory.h
+ Instrumentation helpers for memory allocation.
+*/
+
+#include "mysql/psi/psi.h"
+
+#ifdef HAVE_PSI_MEMORY_INTERFACE
+#define PSI_CALL_memory_alloc(A1,A2,A3) PSI_MEMORY_CALL(memory_alloc)(A1,A2,A3)
+#define PSI_CALL_memory_free(A1,A2,A3) PSI_MEMORY_CALL(memory_free)(A1,A2,A3)
+#define PSI_CALL_memory_realloc(A1,A2,A3,A4) PSI_MEMORY_CALL(memory_realloc)(A1,A2,A3,A4)
+#define PSI_CALL_register_memory(A1,A2,A3) PSI_MEMORY_CALL(register_memory)(A1,A2,A3)
+#else
+#define PSI_CALL_memory_alloc(A1,A2,A3) 0
+#define PSI_CALL_memory_free(A1,A2,A3) do { } while(0)
+#define PSI_CALL_memory_realloc(A1,A2,A3,A4) 0
+#define PSI_CALL_register_memory(A1,A2,A3) do { } while(0)
+#endif
+
+#ifndef PSI_MEMORY_CALL
+#define PSI_MEMORY_CALL(M) PSI_DYNAMIC_CALL(M)
+#endif
+
+/**
+ @defgroup Memory_instrumentation Memory Instrumentation
+ @ingroup Instrumentation_interface
+ @{
+*/
+
+/**
+ @def mysql_memory_register(P1, P2, P3)
+ Memory registration.
+*/
+#define mysql_memory_register(P1, P2, P3) \
+ inline_mysql_memory_register(P1, P2, P3)
+
+static inline void inline_mysql_memory_register(
+#ifdef HAVE_PSI_MEMORY_INTERFACE
+ const char *category,
+ PSI_memory_info *info,
+ int count)
+#else
+ const char *category __attribute__((unused)),
+ void *info __attribute__((unused)),
+ int count __attribute__((unused)))
+#endif
+{
+ PSI_CALL_register_memory(category, info, count);
+}
+
+/** @} (end of group Memory_instrumentation) */
+
+#endif
+
diff --git a/include/mysql/psi/mysql_ps.h b/include/mysql/psi/mysql_ps.h
new file mode 100644
index 00000000..f0b27332
--- /dev/null
+++ b/include/mysql/psi/mysql_ps.h
@@ -0,0 +1,108 @@
+/* Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License, version 2.0, for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
+
+#ifndef MYSQL_PS_H
+#define MYSQL_PS_H
+
+/**
+ @file mysql/psi/mysql_ps.h
+ Instrumentation helpers for prepared statements.
+*/
+
+#include "mysql/psi/psi.h"
+
+#ifndef PSI_PS_CALL
+#define PSI_PS_CALL(M) PSI_DYNAMIC_CALL(M)
+#endif
+
+#ifdef HAVE_PSI_PS_INTERFACE
+ #define MYSQL_CREATE_PS(IDENTITY, ID, LOCKER, NAME, NAME_LENGTH) \
+ inline_mysql_create_prepared_stmt(IDENTITY, ID, LOCKER, NAME, NAME_LENGTH)
+ #define MYSQL_EXECUTE_PS(LOCKER, PREPARED_STMT) \
+ inline_mysql_execute_prepared_stmt(LOCKER, PREPARED_STMT)
+ #define MYSQL_DESTROY_PS(PREPARED_STMT) \
+ inline_mysql_destroy_prepared_stmt(PREPARED_STMT)
+ #define MYSQL_REPREPARE_PS(PREPARED_STMT) \
+ inline_mysql_reprepare_prepared_stmt(PREPARED_STMT)
+ #define MYSQL_SET_PS_TEXT(PREPARED_STMT, SQLTEXT, SQLTEXT_LENGTH) \
+ inline_mysql_set_prepared_stmt_text(PREPARED_STMT, SQLTEXT, SQLTEXT_LENGTH)
+#else
+ #define MYSQL_CREATE_PS(IDENTITY, ID, LOCKER, NAME, NAME_LENGTH) \
+ NULL
+ #define MYSQL_EXECUTE_PS(LOCKER, PREPARED_STMT) \
+ do {} while (0)
+ #define MYSQL_DESTROY_PS(PREPARED_STMT) \
+ do {} while (0)
+ #define MYSQL_REPREPARE_PS(PREPARED_STMT) \
+ do {} while (0)
+ #define MYSQL_SET_PS_TEXT(PREPARED_STMT, SQLTEXT, SQLTEXT_LENGTH) \
+ do {} while (0)
+#endif
+
+#ifdef HAVE_PSI_PS_INTERFACE
+static inline struct PSI_prepared_stmt*
+inline_mysql_create_prepared_stmt(void *identity, uint stmt_id,
+ PSI_statement_locker *locker,
+ const char *stmt_name, size_t stmt_name_length)
+{
+ if (locker == NULL)
+ return NULL;
+ return PSI_PS_CALL(create_prepared_stmt)(identity, stmt_id,
+ locker,
+ stmt_name, stmt_name_length);
+}
+
+static inline void
+inline_mysql_execute_prepared_stmt(PSI_statement_locker *locker,
+ PSI_prepared_stmt* prepared_stmt)
+{
+ if (prepared_stmt != NULL && locker != NULL)
+ PSI_PS_CALL(execute_prepared_stmt)(locker, prepared_stmt);
+}
+
+static inline void
+inline_mysql_destroy_prepared_stmt(PSI_prepared_stmt *prepared_stmt)
+{
+ if (prepared_stmt != NULL)
+ PSI_PS_CALL(destroy_prepared_stmt)(prepared_stmt);
+}
+
+static inline void
+inline_mysql_reprepare_prepared_stmt(PSI_prepared_stmt *prepared_stmt)
+{
+ if (prepared_stmt != NULL)
+ PSI_PS_CALL(reprepare_prepared_stmt)(prepared_stmt);
+}
+
+static inline void
+inline_mysql_set_prepared_stmt_text(PSI_prepared_stmt *prepared_stmt,
+ const char *text,
+ uint text_len)
+{
+ if (prepared_stmt != NULL)
+ {
+ PSI_PS_CALL(set_prepared_stmt_text)(prepared_stmt, text, text_len);
+ }
+}
+#endif
+
+#endif
diff --git a/include/mysql/psi/mysql_socket.h b/include/mysql/psi/mysql_socket.h
new file mode 100644
index 00000000..aa85daaa
--- /dev/null
+++ b/include/mysql/psi/mysql_socket.h
@@ -0,0 +1,1295 @@
+/* Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2017, MariaDB Corporation.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License, version 2.0,
+as published by the Free Software Foundation.
+
+This program is also distributed with certain software (including
+but not limited to OpenSSL) that is licensed under separate terms,
+as designated in a particular file or component or in included license
+documentation. The authors of MySQL hereby grant you an additional
+permission to link the program and your derivative works with the
+separately licensed software that they have included with MySQL.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License, version 2.0, for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+02110-1335 USA
+*/
+
+#ifndef MYSQL_SOCKET_H
+#define MYSQL_SOCKET_H
+
+/* For MY_STAT */
+#include <my_dir.h>
+/* For my_chsize */
+#include <my_sys.h>
+/* For socket api */
+#ifdef _WIN32
+ #include <ws2def.h>
+ #include <winsock2.h>
+ #include <MSWSock.h>
+ #define SOCKBUF_T char
+#else
+ #include <netinet/in.h>
+ #define SOCKBUF_T void
+#endif
+/**
+ @file mysql/psi/mysql_socket.h
+[...]
+*/
+
+#include "mysql/psi/psi.h"
+
+#ifndef PSI_SOCKET_CALL
+#define PSI_SOCKET_CALL(M) PSI_DYNAMIC_CALL(M)
+#endif
+
+/**
+ @defgroup Socket_instrumentation Socket Instrumentation
+ @ingroup Instrumentation_interface
+ @{
+*/
+
+/**
+ @def mysql_socket_register(P1, P2, P3)
+ Socket registration.
+*/
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ #define mysql_socket_register(P1, P2, P3) \
+ inline_mysql_socket_register(P1, P2, P3)
+#else
+ #define mysql_socket_register(P1, P2, P3) \
+ do {} while (0)
+#endif
+
+/** An instrumented socket. */
+struct st_mysql_socket
+{
+ /** The real socket descriptor. */
+ my_socket fd;
+
+ /**
+ The instrumentation hook.
+ Note that this hook is not conditionally defined,
+ for binary compatibility of the @c MYSQL_SOCKET interface.
+ */
+ struct PSI_socket *m_psi;
+};
+
+/**
+ An instrumented socket.
+ @c MYSQL_SOCKET is a replacement for @c my_socket.
+*/
+typedef struct st_mysql_socket MYSQL_SOCKET;
+
+
+/**
+ @def MYSQL_INVALID_SOCKET
+ MYSQL_SOCKET initial value.
+*/
+//MYSQL_SOCKET MYSQL_INVALID_SOCKET= {INVALID_SOCKET, NULL};
+#define MYSQL_INVALID_SOCKET mysql_socket_invalid()
+
+/**
+ MYSQL_SOCKET helper. Initialize instrumented socket.
+ @sa mysql_socket_getfd
+ @sa mysql_socket_setfd
+*/
+static inline MYSQL_SOCKET
+mysql_socket_invalid()
+{
+ MYSQL_SOCKET mysql_socket= {INVALID_SOCKET, NULL};
+ return mysql_socket;
+}
+
+/**
+ Set socket descriptor and address.
+ @param socket nstrumented socket
+ @param addr unformatted socket address
+ @param addr_len length of socket address
+*/
+
+static inline void
+mysql_socket_set_address(
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ MYSQL_SOCKET socket,
+ const struct sockaddr *addr,
+ socklen_t addr_len
+#else
+ MYSQL_SOCKET socket __attribute__ ((unused)),
+ const struct sockaddr *addr __attribute__ ((unused)),
+ socklen_t addr_len __attribute__ ((unused))
+#endif
+)
+{
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ if (socket.m_psi != NULL)
+ PSI_SOCKET_CALL(set_socket_info)(socket.m_psi, NULL, addr, addr_len);
+#endif
+}
+
+/**
+ Set socket descriptor and address.
+ @param socket instrumented socket
+*/
+static inline void
+mysql_socket_set_thread_owner(
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+MYSQL_SOCKET socket
+#else
+MYSQL_SOCKET socket __attribute__ ((unused))
+#endif
+)
+{
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ if (socket.m_psi != NULL)
+ PSI_SOCKET_CALL(set_socket_thread_owner)(socket.m_psi);
+#endif
+}
+
+/**
+ MYSQL_SOCKET helper. Get socket descriptor.
+ @param mysql_socket Instrumented socket
+ @sa mysql_socket_getfd
+*/
+static inline my_socket
+mysql_socket_getfd(MYSQL_SOCKET mysql_socket)
+{
+ return mysql_socket.fd;
+}
+
+/**
+ MYSQL_SOCKET helper. Set socket descriptor.
+ @param mysql_socket Instrumented socket
+ @param fd Socket descriptor
+ @sa mysql_socket_setfd
+*/
+static inline void
+mysql_socket_setfd(MYSQL_SOCKET *mysql_socket, my_socket fd)
+{
+ if (likely(mysql_socket != NULL))
+ mysql_socket->fd= fd;
+}
+
+/**
+ @def MYSQL_SOCKET_WAIT_VARIABLES
+ Instrumentation helper for socket waits.
+ This instrumentation declares local variables.
+ Do not use a ';' after this macro
+ @param LOCKER locker
+ @param STATE locker state
+ @sa MYSQL_START_SOCKET_WAIT.
+ @sa MYSQL_END_SOCKET_WAIT.
+*/
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ #define MYSQL_SOCKET_WAIT_VARIABLES(LOCKER, STATE) \
+ struct PSI_socket_locker* LOCKER; \
+ PSI_socket_locker_state STATE;
+#else
+ #define MYSQL_SOCKET_WAIT_VARIABLES(LOCKER, STATE)
+#endif
+
+/**
+ @def MYSQL_START_SOCKET_WAIT
+ Instrumentation helper for socket waits.
+ This instrumentation marks the start of a wait event.
+ @param LOCKER locker
+ @param STATE locker state
+ @param SOCKET instrumented socket
+ @param OP The socket operation to be performed
+ @param COUNT bytes to be written/read
+ @sa MYSQL_END_SOCKET_WAIT.
+*/
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ #define MYSQL_START_SOCKET_WAIT(LOCKER, STATE, SOCKET, OP, COUNT) \
+ LOCKER= inline_mysql_start_socket_wait(STATE, SOCKET, OP, COUNT,\
+ __FILE__, __LINE__)
+#else
+ #define MYSQL_START_SOCKET_WAIT(LOCKER, STATE, SOCKET, OP, COUNT) \
+ do {} while (0)
+#endif
+
+/**
+ @def MYSQL_END_SOCKET_WAIT
+ Instrumentation helper for socket waits.
+ This instrumentation marks the end of a wait event.
+ @param LOCKER locker
+ @param COUNT actual bytes written/read, or -1
+ @sa MYSQL_START_SOCKET_WAIT.
+*/
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ #define MYSQL_END_SOCKET_WAIT(LOCKER, COUNT) \
+ inline_mysql_end_socket_wait(LOCKER, COUNT)
+#else
+ #define MYSQL_END_SOCKET_WAIT(LOCKER, COUNT) \
+ do {} while (0)
+#endif
+
+/**
+ @def MYSQL_SOCKET_SET_STATE
+ Set the state (IDLE, ACTIVE) of an instrumented socket.
+ @param SOCKET the instrumented socket
+ @param STATE the new state
+ @sa PSI_socket_state
+*/
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ #define MYSQL_SOCKET_SET_STATE(SOCKET, STATE) \
+ inline_mysql_socket_set_state(SOCKET, STATE)
+#else
+ #define MYSQL_SOCKET_SET_STATE(SOCKET, STATE) \
+ do {} while (0)
+#endif
+
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+/**
+ Instrumentation calls for MYSQL_START_SOCKET_WAIT.
+ @sa MYSQL_START_SOCKET_WAIT.
+*/
+static inline struct PSI_socket_locker*
+inline_mysql_start_socket_wait(PSI_socket_locker_state *state,
+ MYSQL_SOCKET mysql_socket,
+ enum PSI_socket_operation op,
+ size_t byte_count,
+ const char *src_file, uint src_line)
+{
+ struct PSI_socket_locker *locker;
+ if (psi_likely(mysql_socket.m_psi != NULL))
+ {
+ locker= PSI_SOCKET_CALL(start_socket_wait)
+ (state, mysql_socket.m_psi, op, byte_count, src_file, src_line);
+ }
+ else
+ locker= NULL;
+ return locker;
+}
+
+/**
+ Instrumentation calls for MYSQL_END_SOCKET_WAIT.
+ @sa MYSQL_END_SOCKET_WAIT.
+*/
+static inline void
+inline_mysql_end_socket_wait(struct PSI_socket_locker *locker, size_t byte_count)
+{
+ if (psi_likely(locker != NULL))
+ PSI_SOCKET_CALL(end_socket_wait)(locker, byte_count);
+}
+
+/**
+ Set the state (IDLE, ACTIVE) of an instrumented socket.
+ @param socket the instrumented socket
+ @param state the new state
+ @sa PSI_socket_state
+*/
+static inline void
+inline_mysql_socket_set_state(MYSQL_SOCKET socket, enum PSI_socket_state state)
+{
+ if (socket.m_psi != NULL)
+ PSI_SOCKET_CALL(set_socket_state)(socket.m_psi, state);
+}
+#endif /* HAVE_PSI_SOCKET_INTERFACE */
+
+/**
+ @def mysql_socket_socket(K, D, T, P)
+ Create a socket.
+ @c mysql_socket_socket is a replacement for @c socket.
+ @param K PSI_socket_key for this instrumented socket
+ @param D Socket domain
+ @param T Protocol type
+ @param P Transport protocol
+*/
+
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ #define mysql_socket_socket(K, D, T, P) \
+ inline_mysql_socket_socket(K, D, T, P)
+#else
+ #define mysql_socket_socket(K, D, T, P) \
+ inline_mysql_socket_socket(D, T, P)
+#endif
+
+/**
+ @def mysql_socket_bind(FD, AP, L)
+ Bind a socket to a local port number and IP address
+ @c mysql_socket_bind is a replacement for @c bind.
+ @param FD Instrumented socket descriptor returned by socket()
+ @param AP Pointer to local port number and IP address in sockaddr structure
+ @param L Length of sockaddr structure
+*/
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ #define mysql_socket_bind(FD, AP, L) \
+ inline_mysql_socket_bind(__FILE__, __LINE__, FD, AP, L)
+#else
+ #define mysql_socket_bind(FD, AP, L) \
+ inline_mysql_socket_bind(FD, AP, L)
+#endif
+
+/**
+ @def mysql_socket_getsockname(FD, AP, LP)
+ Return port number and IP address of the local host
+ @c mysql_socket_getsockname is a replacement for @c getsockname.
+ @param FD Instrumented socket descriptor returned by socket()
+ @param AP Pointer to returned address of local host in @c sockaddr structure
+ @param LP Pointer to length of @c sockaddr structure
+*/
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ #define mysql_socket_getsockname(FD, AP, LP) \
+ inline_mysql_socket_getsockname(__FILE__, __LINE__, FD, AP, LP)
+#else
+ #define mysql_socket_getsockname(FD, AP, LP) \
+ inline_mysql_socket_getsockname(FD, AP, LP)
+#endif
+
+/**
+ @def mysql_socket_connect(FD, AP, L)
+ Establish a connection to a remote host.
+ @c mysql_socket_connect is a replacement for @c connect.
+ @param FD Instrumented socket descriptor returned by socket()
+ @param AP Pointer to target address in sockaddr structure
+ @param L Length of sockaddr structure
+*/
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ #define mysql_socket_connect(FD, AP, L) \
+ inline_mysql_socket_connect(__FILE__, __LINE__, FD, AP, L)
+#else
+ #define mysql_socket_connect(FD, AP, L) \
+ inline_mysql_socket_connect(FD, AP, L)
+#endif
+
+/**
+ @def mysql_socket_getpeername(FD, AP, LP)
+ Get port number and IP address of remote host that a socket is connected to.
+ @c mysql_socket_getpeername is a replacement for @c getpeername.
+ @param FD Instrumented socket descriptor returned by socket() or accept()
+ @param AP Pointer to returned address of remote host in sockaddr structure
+ @param LP Pointer to length of sockaddr structure
+*/
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ #define mysql_socket_getpeername(FD, AP, LP) \
+ inline_mysql_socket_getpeername(__FILE__, __LINE__, FD, AP, LP)
+#else
+ #define mysql_socket_getpeername(FD, AP, LP) \
+ inline_mysql_socket_getpeername(FD, AP, LP)
+#endif
+
+/**
+ @def mysql_socket_send(FD, B, N, FL)
+ Send data from the buffer, B, to a connected socket.
+ @c mysql_socket_send is a replacement for @c send.
+ @param FD Instrumented socket descriptor returned by socket() or accept()
+ @param B Buffer to send
+ @param N Number of bytes to send
+ @param FL Control flags
+*/
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ #define mysql_socket_send(FD, B, N, FL) \
+ inline_mysql_socket_send(__FILE__, __LINE__, FD, B, N, FL)
+#else
+ #define mysql_socket_send(FD, B, N, FL) \
+ inline_mysql_socket_send(FD, B, N, FL)
+#endif
+
+/**
+ @def mysql_socket_recv(FD, B, N, FL)
+ Receive data from a connected socket.
+ @c mysql_socket_recv is a replacement for @c recv.
+ @param FD Instrumented socket descriptor returned by socket() or accept()
+ @param B Buffer to receive to
+ @param N Maximum bytes to receive
+ @param FL Control flags
+*/
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ #define mysql_socket_recv(FD, B, N, FL) \
+ inline_mysql_socket_recv(__FILE__, __LINE__, FD, B, N, FL)
+#else
+ #define mysql_socket_recv(FD, B, N, FL) \
+ inline_mysql_socket_recv(FD, B, N, FL)
+#endif
+
+/**
+ @def mysql_socket_sendto(FD, B, N, FL, AP, L)
+ Send data to a socket at the specified address.
+ @c mysql_socket_sendto is a replacement for @c sendto.
+ @param FD Instrumented socket descriptor returned by socket()
+ @param B Buffer to send
+ @param N Number of bytes to send
+ @param FL Control flags
+ @param AP Pointer to destination sockaddr structure
+ @param L Size of sockaddr structure
+*/
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ #define mysql_socket_sendto(FD, B, N, FL, AP, L) \
+ inline_mysql_socket_sendto(__FILE__, __LINE__, FD, B, N, FL, AP, L)
+#else
+ #define mysql_socket_sendto(FD, B, N, FL, AP, L) \
+ inline_mysql_socket_sendto(FD, B, N, FL, AP, L)
+#endif
+
+/**
+ @def mysql_socket_recvfrom(FD, B, N, FL, AP, L)
+ Receive data from a socket and return source address information
+ @c mysql_socket_recvfrom is a replacement for @c recvfrom.
+ @param FD Instrumented socket descriptor returned by socket()
+ @param B Buffer to receive to
+ @param N Maximum bytes to receive
+ @param FL Control flags
+ @param AP Pointer to source address in sockaddr_storage structure
+ @param LP Size of sockaddr_storage structure
+*/
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ #define mysql_socket_recvfrom(FD, B, N, FL, AP, LP) \
+ inline_mysql_socket_recvfrom(__FILE__, __LINE__, FD, B, N, FL, AP, LP)
+#else
+ #define mysql_socket_recvfrom(FD, B, N, FL, AP, LP) \
+ inline_mysql_socket_recvfrom(FD, B, N, FL, AP, LP)
+#endif
+
+/**
+ @def mysql_socket_getsockopt(FD, LV, ON, OP, OL)
+ Get a socket option for the specified socket.
+ @c mysql_socket_getsockopt is a replacement for @c getsockopt.
+ @param FD Instrumented socket descriptor returned by socket()
+ @param LV Protocol level
+ @param ON Option to query
+ @param OP Buffer which will contain the value for the requested option
+ @param OL Pointer to length of OP
+*/
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ #define mysql_socket_getsockopt(FD, LV, ON, OP, OL) \
+ inline_mysql_socket_getsockopt(__FILE__, __LINE__, FD, LV, ON, OP, OL)
+#else
+ #define mysql_socket_getsockopt(FD, LV, ON, OP, OL) \
+ inline_mysql_socket_getsockopt(FD, LV, ON, OP, OL)
+#endif
+
+/**
+ @def mysql_socket_setsockopt(FD, LV, ON, OP, OL)
+ Set a socket option for the specified socket.
+ @c mysql_socket_setsockopt is a replacement for @c setsockopt.
+ @param FD Instrumented socket descriptor returned by socket()
+ @param LV Protocol level
+ @param ON Option to modify
+ @param OP Buffer containing the value for the specified option
+ @param OL Pointer to length of OP
+*/
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ #define mysql_socket_setsockopt(FD, LV, ON, OP, OL) \
+ inline_mysql_socket_setsockopt(__FILE__, __LINE__, FD, LV, ON, OP, OL)
+#else
+ #define mysql_socket_setsockopt(FD, LV, ON, OP, OL) \
+ inline_mysql_socket_setsockopt(FD, LV, ON, OP, OL)
+#endif
+
+/**
+ @def mysql_sock_set_nonblocking
+ Set socket to non-blocking.
+ @param FD instrumented socket descriptor
+*/
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ #define mysql_sock_set_nonblocking(FD) \
+ inline_mysql_sock_set_nonblocking(__FILE__, __LINE__, FD)
+#else
+ #define mysql_sock_set_nonblocking(FD) \
+ inline_mysql_sock_set_nonblocking(FD)
+#endif
+
+/**
+ @def mysql_socket_listen(FD, N)
+ Set socket state to listen for an incoming connection.
+ @c mysql_socket_listen is a replacement for @c listen.
+ @param FD Instrumented socket descriptor, bound and connected
+ @param N Maximum number of pending connections allowed.
+*/
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ #define mysql_socket_listen(FD, N) \
+ inline_mysql_socket_listen(__FILE__, __LINE__, FD, N)
+#else
+ #define mysql_socket_listen(FD, N) \
+ inline_mysql_socket_listen(FD, N)
+#endif
+
+/**
+ @def mysql_socket_accept(K, FD, AP, LP)
+ Accept a connection from any remote host; TCP only.
+ @c mysql_socket_accept is a replacement for @c accept.
+ @param K PSI_socket_key for this instrumented socket
+ @param FD Instrumented socket descriptor, bound and placed in a listen state
+ @param AP Pointer to sockaddr structure with returned IP address and port of connected host
+ @param LP Pointer to length of valid information in AP
+*/
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ #define mysql_socket_accept(K, FD, AP, LP) \
+ inline_mysql_socket_accept(__FILE__, __LINE__, K, FD, AP, LP)
+#else
+ #define mysql_socket_accept(K, FD, AP, LP) \
+ inline_mysql_socket_accept(FD, AP, LP)
+#endif
+
+/**
+ @def mysql_socket_close(FD)
+ Close a socket and sever any connections.
+ @c mysql_socket_close is a replacement for @c close.
+ @param FD Instrumented socket descriptor returned by socket() or accept()
+*/
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ #define mysql_socket_close(FD) \
+ inline_mysql_socket_close(__FILE__, __LINE__, FD)
+#else
+ #define mysql_socket_close(FD) \
+ inline_mysql_socket_close(FD)
+#endif
+
+/**
+ @def mysql_socket_shutdown(FD, H)
+ Disable receives and/or sends on a socket.
+ @c mysql_socket_shutdown is a replacement for @c shutdown.
+ @param FD Instrumented socket descriptor returned by socket() or accept()
+ @param H Specifies which operations to shutdown
+*/
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ #define mysql_socket_shutdown(FD, H) \
+ inline_mysql_socket_shutdown(__FILE__, __LINE__, FD, H)
+#else
+ #define mysql_socket_shutdown(FD, H) \
+ inline_mysql_socket_shutdown(FD, H)
+#endif
+
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+static inline void inline_mysql_socket_register(
+ const char *category,
+ PSI_socket_info *info,
+ int count)
+{
+ PSI_SOCKET_CALL(register_socket)(category, info, count);
+}
+#endif
+
+/** mysql_socket_socket */
+
+static inline MYSQL_SOCKET
+inline_mysql_socket_socket
+(
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ PSI_socket_key key,
+#endif
+ int domain, int type, int protocol)
+{
+ MYSQL_SOCKET mysql_socket= MYSQL_INVALID_SOCKET;
+ mysql_socket.fd= socket(domain, type | SOCK_CLOEXEC, protocol);
+
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ if (likely(mysql_socket.fd != INVALID_SOCKET))
+ {
+ mysql_socket.m_psi= PSI_SOCKET_CALL(init_socket)
+ (key, (const my_socket*)&mysql_socket.fd, NULL, 0);
+ }
+#endif
+
+ /* SOCK_CLOEXEC isn't always a number - can't preprocessor compare */
+#if defined(HAVE_FCNTL) && defined(FD_CLOEXEC) && !defined(HAVE_SOCK_CLOEXEC)
+ (void) fcntl(mysql_socket.fd, F_SETFD, FD_CLOEXEC);
+#endif
+
+ return mysql_socket;
+}
+
+/** mysql_socket_bind */
+
+static inline int
+inline_mysql_socket_bind
+(
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ MYSQL_SOCKET mysql_socket, const struct sockaddr *addr, size_t len)
+{
+ int result;
+
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ if (psi_likely(mysql_socket.m_psi != NULL))
+ {
+ /* Instrumentation start */
+ PSI_socket_locker_state state;
+ PSI_socket_locker *locker;
+ locker= PSI_SOCKET_CALL(start_socket_wait)
+ (&state, mysql_socket.m_psi, PSI_SOCKET_BIND, (size_t)0, src_file, src_line);
+
+ /* Instrumented code */
+ result= bind(mysql_socket.fd, addr, (int)len);
+
+ /* Instrumentation end */
+ if (result == 0)
+ PSI_SOCKET_CALL(set_socket_info)(mysql_socket.m_psi, NULL, addr, (socklen_t)len);
+
+ if (locker != NULL)
+ PSI_SOCKET_CALL(end_socket_wait)(locker, (size_t)0);
+
+ return result;
+ }
+#endif
+
+ /* Non instrumented code */
+ result= bind(mysql_socket.fd, addr, (int)len);
+ return result;
+}
+
+/** mysql_socket_getsockname */
+
+static inline int
+inline_mysql_socket_getsockname
+(
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ MYSQL_SOCKET mysql_socket, struct sockaddr *addr, socklen_t *len)
+{
+ int result;
+
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ if (psi_likely(mysql_socket.m_psi != NULL))
+ {
+ /* Instrumentation start */
+ PSI_socket_locker *locker;
+ PSI_socket_locker_state state;
+ locker= PSI_SOCKET_CALL(start_socket_wait)
+ (&state, mysql_socket.m_psi, PSI_SOCKET_BIND, (size_t)0, src_file, src_line);
+
+ /* Instrumented code */
+ result= getsockname(mysql_socket.fd, addr, len);
+
+ /* Instrumentation end */
+ if (locker != NULL)
+ PSI_SOCKET_CALL(end_socket_wait)(locker, (size_t)0);
+
+ return result;
+ }
+#endif
+
+ /* Non instrumented code */
+ result= getsockname(mysql_socket.fd, addr, len);
+
+ return result;
+}
+
+/** mysql_socket_connect */
+
+static inline int
+inline_mysql_socket_connect
+(
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ MYSQL_SOCKET mysql_socket, const struct sockaddr *addr, socklen_t len)
+{
+ int result;
+
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ if (psi_likely(mysql_socket.m_psi != NULL))
+ {
+ /* Instrumentation start */
+ PSI_socket_locker *locker;
+ PSI_socket_locker_state state;
+ locker= PSI_SOCKET_CALL(start_socket_wait)
+ (&state, mysql_socket.m_psi, PSI_SOCKET_CONNECT, (size_t)0, src_file, src_line);
+
+ /* Instrumented code */
+ result= connect(mysql_socket.fd, addr, len);
+
+ /* Instrumentation end */
+ if (locker != NULL)
+ PSI_SOCKET_CALL(end_socket_wait)(locker, (size_t)0);
+
+ return result;
+ }
+#endif
+
+ /* Non instrumented code */
+ result= connect(mysql_socket.fd, addr, len);
+
+ return result;
+}
+
+/** mysql_socket_getpeername */
+
+static inline int
+inline_mysql_socket_getpeername
+(
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ MYSQL_SOCKET mysql_socket, struct sockaddr *addr, socklen_t *len)
+{
+ int result;
+
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ if (psi_likely(mysql_socket.m_psi != NULL))
+ {
+ /* Instrumentation start */
+ PSI_socket_locker *locker;
+ PSI_socket_locker_state state;
+ locker= PSI_SOCKET_CALL(start_socket_wait)
+ (&state, mysql_socket.m_psi, PSI_SOCKET_BIND, (size_t)0, src_file, src_line);
+
+ /* Instrumented code */
+ result= getpeername(mysql_socket.fd, addr, len);
+
+ /* Instrumentation end */
+ if (locker != NULL)
+ PSI_SOCKET_CALL(end_socket_wait)(locker, (size_t)0);
+
+ return result;
+ }
+#endif
+
+ /* Non instrumented code */
+ result= getpeername(mysql_socket.fd, addr, len);
+
+ return result;
+}
+
+/** mysql_socket_send */
+
+static inline ssize_t
+inline_mysql_socket_send
+(
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ MYSQL_SOCKET mysql_socket, const SOCKBUF_T *buf, size_t n, int flags)
+{
+ ssize_t result;
+ DBUG_ASSERT(mysql_socket.fd != INVALID_SOCKET);
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ if (psi_likely(mysql_socket.m_psi != NULL))
+ {
+ /* Instrumentation start */
+ PSI_socket_locker *locker;
+ PSI_socket_locker_state state;
+ locker= PSI_SOCKET_CALL(start_socket_wait)
+ (&state, mysql_socket.m_psi, PSI_SOCKET_SEND, n, src_file, src_line);
+
+ /* Instrumented code */
+ result= send(mysql_socket.fd, buf, IF_WIN((int),) n, flags);
+
+ /* Instrumentation end */
+ if (locker != NULL)
+ {
+ size_t bytes_written= (result > 0) ? (size_t) result : 0;
+ PSI_SOCKET_CALL(end_socket_wait)(locker, bytes_written);
+ }
+
+ return result;
+ }
+#endif
+
+ /* Non instrumented code */
+ result= send(mysql_socket.fd, buf, IF_WIN((int),) n, flags);
+
+ return result;
+}
+
+/** mysql_socket_recv */
+
+static inline ssize_t
+inline_mysql_socket_recv
+(
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ MYSQL_SOCKET mysql_socket, SOCKBUF_T *buf, size_t n, int flags)
+{
+ ssize_t result;
+ DBUG_ASSERT(mysql_socket.fd != INVALID_SOCKET);
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ if (psi_likely(mysql_socket.m_psi != NULL))
+ {
+ /* Instrumentation start */
+ PSI_socket_locker *locker;
+ PSI_socket_locker_state state;
+ locker= PSI_SOCKET_CALL(start_socket_wait)
+ (&state, mysql_socket.m_psi, PSI_SOCKET_RECV, (size_t)0, src_file, src_line);
+
+ /* Instrumented code */
+ result= recv(mysql_socket.fd, buf, IF_WIN((int),) n, flags);
+
+ /* Instrumentation end */
+ if (locker != NULL)
+ {
+ size_t bytes_read= (result > 0) ? (size_t) result : 0;
+ PSI_SOCKET_CALL(end_socket_wait)(locker, bytes_read);
+ }
+
+ return result;
+ }
+#endif
+
+ /* Non instrumented code */
+ result= recv(mysql_socket.fd, buf, IF_WIN((int),) n, flags);
+
+ return result;
+}
+
+/** mysql_socket_sendto */
+
+static inline ssize_t
+inline_mysql_socket_sendto
+(
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ MYSQL_SOCKET mysql_socket, const SOCKBUF_T *buf, size_t n, int flags, const struct sockaddr *addr, socklen_t addr_len)
+{
+ ssize_t result;
+
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ if (psi_likely(mysql_socket.m_psi != NULL))
+ {
+ /* Instrumentation start */
+ PSI_socket_locker *locker;
+ PSI_socket_locker_state state;
+ locker= PSI_SOCKET_CALL(start_socket_wait)
+ (&state, mysql_socket.m_psi, PSI_SOCKET_SEND, n, src_file, src_line);
+
+ /* Instrumented code */
+ result= sendto(mysql_socket.fd, buf, IF_WIN((int),) n, flags, addr, addr_len);
+
+ /* Instrumentation end */
+ if (locker != NULL)
+ {
+ size_t bytes_written = (result > 0) ? (size_t) result : 0;
+ PSI_SOCKET_CALL(end_socket_wait)(locker, bytes_written);
+ }
+
+ return result;
+ }
+#endif
+
+ /* Non instrumented code */
+ result= sendto(mysql_socket.fd, buf, IF_WIN((int),) n, flags, addr, addr_len);
+
+ return result;
+}
+
+/** mysql_socket_recvfrom */
+
+static inline ssize_t
+inline_mysql_socket_recvfrom
+(
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ MYSQL_SOCKET mysql_socket, SOCKBUF_T *buf, size_t n, int flags,
+ struct sockaddr *addr, socklen_t *addr_len)
+{
+ ssize_t result;
+
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ if (psi_likely(mysql_socket.m_psi != NULL))
+ {
+ /* Instrumentation start */
+ PSI_socket_locker *locker;
+ PSI_socket_locker_state state;
+ locker= PSI_SOCKET_CALL(start_socket_wait)
+ (&state, mysql_socket.m_psi, PSI_SOCKET_RECV, (size_t)0, src_file, src_line);
+
+ /* Instrumented code */
+ result= recvfrom(mysql_socket.fd, buf, IF_WIN((int),) n, flags, addr, addr_len);
+
+ /* Instrumentation end */
+ if (locker != NULL)
+ {
+ size_t bytes_read= (result > 0) ? (size_t) result : 0;
+ PSI_SOCKET_CALL(end_socket_wait)(locker, bytes_read);
+ }
+
+ return result;
+ }
+#endif
+
+ /* Non instrumented code */
+ result= recvfrom(mysql_socket.fd, buf, IF_WIN((int),) n, flags, addr, addr_len);
+
+ return result;
+}
+
+/** mysql_socket_getsockopt */
+
+static inline int
+inline_mysql_socket_getsockopt
+(
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ MYSQL_SOCKET mysql_socket, int level, int optname, SOCKBUF_T *optval, socklen_t *optlen)
+{
+ int result;
+
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ if (psi_likely(mysql_socket.m_psi != NULL))
+ {
+ /* Instrumentation start */
+ PSI_socket_locker *locker;
+ PSI_socket_locker_state state;
+ locker= PSI_SOCKET_CALL(start_socket_wait)
+ (&state, mysql_socket.m_psi, PSI_SOCKET_OPT, (size_t)0, src_file, src_line);
+
+ /* Instrumented code */
+ result= getsockopt(mysql_socket.fd, level, optname, optval, optlen);
+
+ /* Instrumentation end */
+ if (locker != NULL)
+ PSI_SOCKET_CALL(end_socket_wait)(locker, (size_t)0);
+
+ return result;
+ }
+#endif
+
+ /* Non instrumented code */
+ result= getsockopt(mysql_socket.fd, level, optname, optval, optlen);
+
+ return result;
+}
+
+/** mysql_socket_setsockopt */
+
+static inline int
+inline_mysql_socket_setsockopt
+(
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ MYSQL_SOCKET mysql_socket, int level, int optname, const SOCKBUF_T *optval,
+ socklen_t optlen)
+{
+ int result;
+
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ if (psi_likely(mysql_socket.m_psi))
+ {
+ /* Instrumentation start */
+ PSI_socket_locker *locker;
+ PSI_socket_locker_state state;
+ locker= PSI_SOCKET_CALL(start_socket_wait)
+ (&state, mysql_socket.m_psi, PSI_SOCKET_OPT, (size_t)0, src_file, src_line);
+
+ /* Instrumented code */
+ result= setsockopt(mysql_socket.fd, level, optname, optval, optlen);
+
+ /* Instrumentation end */
+ if (locker != NULL)
+ PSI_SOCKET_CALL(end_socket_wait)(locker, (size_t)0);
+
+ return result;
+ }
+#endif
+
+ /* Non instrumented code */
+ result= setsockopt(mysql_socket.fd, level, optname, optval, optlen);
+
+ return result;
+}
+
+/** set_socket_nonblock */
+static inline int
+set_socket_nonblock(my_socket fd)
+{
+ int ret= 0;
+#ifdef _WIN32
+ {
+ u_long nonblocking= 1;
+ ret= ioctlsocket(fd, FIONBIO, &nonblocking);
+ }
+#else
+ {
+ int fd_flags;
+ fd_flags= fcntl(fd, F_GETFL, 0);
+ if (fd_flags < 0)
+ return errno;
+#if defined(O_NONBLOCK)
+ fd_flags |= O_NONBLOCK;
+#elif defined(O_NDELAY)
+ fd_flags |= O_NDELAY;
+#elif defined(O_FNDELAY)
+ fd_flags |= O_FNDELAY;
+#else
+#error "No definition of non-blocking flag found."
+#endif /* O_NONBLOCK */
+ if (fcntl(fd, F_SETFL, fd_flags) == -1)
+ ret= errno;
+ }
+#endif /* _WIN32 */
+ return ret;
+}
+
+/** mysql_socket_set_nonblocking */
+
+static inline int
+inline_mysql_sock_set_nonblocking
+(
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ MYSQL_SOCKET mysql_socket
+)
+{
+ int result= 0;
+
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ if (mysql_socket.m_psi)
+ {
+ /* Instrumentation start */
+ PSI_socket_locker *locker;
+ PSI_socket_locker_state state;
+ locker= PSI_SOCKET_CALL(start_socket_wait)
+ (&state, mysql_socket.m_psi, PSI_SOCKET_OPT,
+ (size_t)0, src_file, src_line);
+
+ /* Instrumented code */
+ result= set_socket_nonblock(mysql_socket.fd);
+
+ /* Instrumentation end */
+ if (locker != NULL)
+ PSI_SOCKET_CALL(end_socket_wait)(locker, (size_t)0);
+
+ return result;
+ }
+#endif
+
+ /* Non instrumented code */
+ result= set_socket_nonblock(mysql_socket.fd);
+
+ return result;
+}
+
+/** mysql_socket_listen */
+
+static inline int
+inline_mysql_socket_listen
+(
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ MYSQL_SOCKET mysql_socket, int backlog)
+{
+ int result;
+
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ if (psi_likely(mysql_socket.m_psi != NULL))
+ {
+ /* Instrumentation start */
+ PSI_socket_locker *locker;
+ PSI_socket_locker_state state;
+ locker= PSI_SOCKET_CALL(start_socket_wait)
+ (&state, mysql_socket.m_psi, PSI_SOCKET_CONNECT, (size_t)0, src_file, src_line);
+
+ /* Instrumented code */
+ result= listen(mysql_socket.fd, backlog);
+
+ /* Instrumentation end */
+ if (locker != NULL)
+ PSI_SOCKET_CALL(end_socket_wait)(locker, (size_t)0);
+
+ return result;
+ }
+#endif
+
+ /* Non instrumented code */
+ result= listen(mysql_socket.fd, backlog);
+
+ return result;
+}
+
+/** mysql_socket_accept */
+
+static inline MYSQL_SOCKET
+inline_mysql_socket_accept
+(
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ const char *src_file, uint src_line, PSI_socket_key key,
+#endif
+ MYSQL_SOCKET socket_listen, struct sockaddr *addr, socklen_t *addr_len)
+{
+#ifdef FD_CLOEXEC
+ int flags __attribute__ ((unused));
+#endif
+
+ MYSQL_SOCKET socket_accept;
+
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ if (socket_listen.m_psi != NULL)
+ {
+ /* Instrumentation start */
+ PSI_socket_locker *locker;
+ PSI_socket_locker_state state;
+ locker= PSI_SOCKET_CALL(start_socket_wait)
+ (&state, socket_listen.m_psi, PSI_SOCKET_CONNECT, (size_t)0, src_file, src_line);
+
+ /* Instrumented code */
+#ifdef HAVE_ACCEPT4
+ socket_accept.fd= accept4(socket_listen.fd, addr, addr_len, SOCK_CLOEXEC);
+#else
+ socket_accept.fd= accept(socket_listen.fd, addr, addr_len);
+#ifdef FD_CLOEXEC
+ if (socket_accept.fd != INVALID_SOCKET)
+ {
+ flags= fcntl(socket_accept.fd, F_GETFD);
+ if (flags != -1)
+ {
+ flags |= FD_CLOEXEC;
+ fcntl(socket_accept.fd, F_SETFD, flags);
+ }
+ }
+#endif
+#endif
+
+ /* Instrumentation end */
+ if (locker != NULL)
+ PSI_SOCKET_CALL(end_socket_wait)(locker, (size_t)0);
+ }
+ else
+#endif
+ {
+ /* Non instrumented code */
+#ifdef HAVE_ACCEPT4
+ socket_accept.fd= accept4(socket_listen.fd, addr, addr_len, SOCK_CLOEXEC);
+#else
+ socket_accept.fd= accept(socket_listen.fd, addr, addr_len);
+#ifdef FD_CLOEXEC
+ if (socket_accept.fd != INVALID_SOCKET)
+ {
+ flags= fcntl(socket_accept.fd, F_GETFD);
+ if (flags != -1)
+ {
+ flags |= FD_CLOEXEC;
+ fcntl(socket_accept.fd, F_SETFD, flags);
+ }
+ }
+#endif
+#endif
+ }
+
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ if (likely(socket_accept.fd != INVALID_SOCKET))
+ {
+ /* Initialize the instrument with the new socket descriptor and address */
+ socket_accept.m_psi= PSI_SOCKET_CALL(init_socket)
+ (key, (const my_socket*)&socket_accept.fd, addr, *addr_len);
+ }
+#endif
+
+ return socket_accept;
+}
+
+/** mysql_socket_close */
+
+static inline int
+inline_mysql_socket_close
+(
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ MYSQL_SOCKET mysql_socket)
+{
+ int result;
+
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ if (psi_likely(mysql_socket.m_psi != NULL))
+ {
+ /* Instrumentation start */
+ PSI_socket_locker *locker;
+ PSI_socket_locker_state state;
+ locker= PSI_SOCKET_CALL(start_socket_wait)
+ (&state, mysql_socket.m_psi, PSI_SOCKET_CLOSE, (size_t)0, src_file, src_line);
+
+ /* Instrumented code */
+ result= closesocket(mysql_socket.fd);
+
+ /* Instrumentation end */
+ if (locker != NULL)
+ PSI_SOCKET_CALL(end_socket_wait)(locker, (size_t)0);
+ /* Remove the instrumentation for this socket. */
+ if (mysql_socket.m_psi != NULL)
+ PSI_SOCKET_CALL(destroy_socket)(mysql_socket.m_psi);
+
+ return result;
+ }
+#endif
+
+ /* Non instrumented code */
+ result= closesocket(mysql_socket.fd);
+
+ return result;
+}
+
+/** mysql_socket_shutdown */
+
+static inline int
+inline_mysql_socket_shutdown
+(
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ MYSQL_SOCKET mysql_socket, int how)
+{
+ int result;
+
+#ifdef _WIN32
+ static LPFN_DISCONNECTEX DisconnectEx = NULL;
+ if (DisconnectEx == NULL)
+ {
+ DWORD dwBytesReturned;
+ GUID guidDisconnectEx = WSAID_DISCONNECTEX;
+ WSAIoctl(mysql_socket.fd, SIO_GET_EXTENSION_FUNCTION_POINTER,
+ &guidDisconnectEx, sizeof(GUID),
+ &DisconnectEx, sizeof(DisconnectEx),
+ &dwBytesReturned, NULL, NULL);
+ }
+#endif
+
+/* Instrumentation start */
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ if (psi_likely(mysql_socket.m_psi != NULL))
+ {
+ PSI_socket_locker *locker;
+ PSI_socket_locker_state state;
+ locker= PSI_SOCKET_CALL(start_socket_wait)
+ (&state, mysql_socket.m_psi, PSI_SOCKET_SHUTDOWN, (size_t)0, src_file, src_line);
+
+ /* Instrumented code */
+#ifdef _WIN32
+ if (DisconnectEx)
+ result= (DisconnectEx(mysql_socket.fd, (LPOVERLAPPED) NULL,
+ (DWORD) 0, (DWORD) 0) == TRUE) ? 0 : -1;
+ else
+#endif
+ result= shutdown(mysql_socket.fd, how);
+
+ /* Instrumentation end */
+ if (locker != NULL)
+ PSI_SOCKET_CALL(end_socket_wait)(locker, (size_t)0);
+
+ return result;
+ }
+#endif
+
+ /* Non instrumented code */
+#ifdef _WIN32
+ if (DisconnectEx)
+ result= (DisconnectEx(mysql_socket.fd, (LPOVERLAPPED) NULL,
+ (DWORD) 0, (DWORD) 0) == TRUE) ? 0 : -1;
+ else
+#endif
+ result= shutdown(mysql_socket.fd, how);
+
+ return result;
+}
+
+/** @} (end of group Socket_instrumentation) */
+
+#endif
+
diff --git a/include/mysql/psi/mysql_sp.h b/include/mysql/psi/mysql_sp.h
new file mode 100644
index 00000000..5eeea37f
--- /dev/null
+++ b/include/mysql/psi/mysql_sp.h
@@ -0,0 +1,104 @@
+/* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License, version 2.0, for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
+
+#ifndef MYSQL_SP_H
+#define MYSQL_SP_H
+
+/**
+ @file mysql/psi/mysql_sp.h
+ Instrumentation helpers for stored programs.
+*/
+
+#include "mysql/psi/psi.h"
+
+#ifndef PSI_SP_CALL
+#define PSI_SP_CALL(M) PSI_DYNAMIC_CALL(M)
+#endif
+
+#ifdef HAVE_PSI_SP_INTERFACE
+ #define MYSQL_START_SP(STATE, SP_SHARE) \
+ inline_mysql_start_sp(STATE, SP_SHARE)
+#else
+ #define MYSQL_START_SP(STATE, SP_SHARE) \
+ NULL
+#endif
+
+
+#ifdef HAVE_PSI_SP_INTERFACE
+ #define MYSQL_END_SP(LOCKER) \
+ inline_mysql_end_sp(LOCKER)
+#else
+ #define MYSQL_END_SP(LOCKER) \
+ do {} while (0)
+#endif
+
+#ifdef HAVE_PSI_SP_INTERFACE
+ #define MYSQL_DROP_SP(OT, SN, SNL, ON, ONL) \
+ inline_mysql_drop_sp(OT, SN, SNL, ON, ONL)
+#else
+ #define MYSQL_DROP_SP(OT, SN, SNL, ON, ONL) \
+ do {} while (0)
+#endif
+
+#ifdef HAVE_PSI_SP_INTERFACE
+ #define MYSQL_GET_SP_SHARE(OT, SN, SNL, ON, ONL) \
+ inline_mysql_get_sp_share(OT, SN, SNL, ON, ONL)
+#else
+ #define MYSQL_GET_SP_SHARE(OT, SN, SNL, ON, ONL) \
+ NULL
+#endif
+
+#ifdef HAVE_PSI_SP_INTERFACE
+static inline struct PSI_sp_locker*
+inline_mysql_start_sp(PSI_sp_locker_state *state, PSI_sp_share *sp_share)
+{
+ return PSI_SP_CALL(start_sp)(state, sp_share);
+}
+
+static inline void inline_mysql_end_sp(PSI_sp_locker *locker)
+{
+ if (likely(locker != NULL))
+ PSI_SP_CALL(end_sp)(locker);
+}
+
+static inline void
+inline_mysql_drop_sp(uint sp_type,
+ const char* schema_name, uint shcema_name_length,
+ const char* object_name, uint object_name_length)
+{
+ PSI_SP_CALL(drop_sp)(sp_type,
+ schema_name, shcema_name_length,
+ object_name, object_name_length);
+}
+
+static inline PSI_sp_share*
+inline_mysql_get_sp_share(uint sp_type,
+ const char* schema_name, uint shcema_name_length,
+ const char* object_name, uint object_name_length)
+{
+ return PSI_SP_CALL(get_sp_share)(sp_type,
+ schema_name, shcema_name_length,
+ object_name, object_name_length);
+}
+#endif
+
+#endif
diff --git a/include/mysql/psi/mysql_stage.h b/include/mysql/psi/mysql_stage.h
new file mode 100644
index 00000000..732df6bd
--- /dev/null
+++ b/include/mysql/psi/mysql_stage.h
@@ -0,0 +1,205 @@
+/* Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License, version 2.0, for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */
+
+#ifndef MYSQL_STAGE_H
+#define MYSQL_STAGE_H
+
+/**
+ @file mysql/psi/mysql_stage.h
+ Instrumentation helpers for stages.
+*/
+
+#include "mysql/psi/psi.h"
+
+#ifndef PSI_STAGE_CALL
+#define PSI_STAGE_CALL(M) PSI_DYNAMIC_CALL(M)
+#endif
+
+/**
+ @defgroup Stage_instrumentation Stage Instrumentation
+ @ingroup Instrumentation_interface
+ @{
+*/
+
+/**
+ @def mysql_stage_register(P1, P2, P3)
+ Stage registration.
+*/
+#ifdef HAVE_PSI_STAGE_INTERFACE
+#define mysql_stage_register(P1, P2, P3) \
+ inline_mysql_stage_register(P1, P2, P3)
+#else
+#define mysql_stage_register(P1, P2, P3) \
+ do {} while (0)
+#endif
+
+/**
+ @def MYSQL_SET_STAGE
+ Set the current stage.
+ Use this API when the file and line
+ is passed from the caller.
+ @param K the stage key
+ @param F the source file name
+ @param L the source file line
+ @return the current stage progress
+*/
+#ifdef HAVE_PSI_STAGE_INTERFACE
+ #define MYSQL_SET_STAGE(K, F, L) \
+ inline_mysql_set_stage(K, F, L)
+#else
+ #define MYSQL_SET_STAGE(K, F, L) \
+ NULL
+#endif
+
+/**
+ @def mysql_set_stage
+ Set the current stage.
+ @param K the stage key
+ @return the current stage progress
+*/
+#ifdef HAVE_PSI_STAGE_INTERFACE
+ #define mysql_set_stage(K) \
+ inline_mysql_set_stage(K, __FILE__, __LINE__)
+#else
+ #define mysql_set_stage(K) \
+ NULL
+#endif
+
+/**
+ @def mysql_end_stage
+ End the last stage
+*/
+#ifdef HAVE_PSI_STAGE_INTERFACE
+ #define mysql_end_stage() \
+ inline_mysql_end_stage()
+#else
+ #define mysql_end_stage() \
+ do {} while (0)
+#endif
+
+#ifdef HAVE_PSI_STAGE_INTERFACE
+static inline void inline_mysql_stage_register(
+ const char *category, PSI_stage_info **info, int count)
+{
+ PSI_STAGE_CALL(register_stage)(category, info, count);
+}
+#endif
+
+#ifdef HAVE_PSI_STAGE_INTERFACE
+static inline PSI_stage_progress*
+inline_mysql_set_stage(PSI_stage_key key,
+ const char *src_file, int src_line)
+{
+ return PSI_STAGE_CALL(start_stage)(key, src_file, src_line);
+}
+#endif
+
+#ifdef HAVE_PSI_STAGE_INTERFACE
+static inline void
+inline_mysql_end_stage()
+{
+ PSI_STAGE_CALL(end_stage)();
+}
+#endif
+
+#ifdef HAVE_PSI_STAGE_INTERFACE
+#define mysql_stage_set_work_completed(P1, P2) \
+ inline_mysql_stage_set_work_completed(P1, P2)
+
+#define mysql_stage_get_work_completed(P1) \
+ inline_mysql_stage_get_work_completed(P1)
+#else
+#define mysql_stage_set_work_completed(P1, P2) \
+ do {} while (0)
+
+#define mysql_stage_get_work_completed(P1) \
+ do {} while (0)
+#endif
+
+#ifdef HAVE_PSI_STAGE_INTERFACE
+#define mysql_stage_inc_work_completed(P1, P2) \
+ inline_mysql_stage_inc_work_completed(P1, P2)
+#else
+#define mysql_stage_inc_work_completed(P1, P2) \
+ do {} while (0)
+#endif
+
+#ifdef HAVE_PSI_STAGE_INTERFACE
+#define mysql_stage_set_work_estimated(P1, P2) \
+ inline_mysql_stage_set_work_estimated(P1, P2)
+
+#define mysql_stage_get_work_estimated(P1) \
+ inline_mysql_stage_get_work_estimated(P1)
+#else
+#define mysql_stage_set_work_estimated(P1, P2) \
+ do {} while (0)
+
+#define mysql_stage_get_work_estimated(P1) \
+ do {} while (0)
+#endif
+
+#ifdef HAVE_PSI_STAGE_INTERFACE
+static inline void
+inline_mysql_stage_set_work_completed(PSI_stage_progress *progress,
+ ulonglong val)
+{
+ if (progress != NULL)
+ progress->m_work_completed= val;
+}
+
+static inline ulonglong
+inline_mysql_stage_get_work_completed(PSI_stage_progress *progress)
+{
+ return progress->m_work_completed;
+}
+#endif
+
+#ifdef HAVE_PSI_STAGE_INTERFACE
+static inline void
+inline_mysql_stage_inc_work_completed(PSI_stage_progress *progress,
+ ulonglong val)
+{
+ if (progress != NULL)
+ progress->m_work_completed+= val;
+}
+#endif
+
+#ifdef HAVE_PSI_STAGE_INTERFACE
+static inline void
+inline_mysql_stage_set_work_estimated(PSI_stage_progress *progress,
+ ulonglong val)
+{
+ if (progress != NULL)
+ progress->m_work_estimated= val;
+}
+
+static inline ulonglong
+inline_mysql_stage_get_work_estimated(PSI_stage_progress *progress)
+{
+ return progress->m_work_estimated;
+}
+#endif
+
+/** @} (end of group Stage_instrumentation) */
+
+#endif
+
diff --git a/include/mysql/psi/mysql_statement.h b/include/mysql/psi/mysql_statement.h
new file mode 100644
index 00000000..fab23d2c
--- /dev/null
+++ b/include/mysql/psi/mysql_statement.h
@@ -0,0 +1,243 @@
+/* Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2017, 2019, MariaDB Corporation.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License, version 2.0, for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */
+
+#ifndef MYSQL_STATEMENT_H
+#define MYSQL_STATEMENT_H
+
+/**
+ @file mysql/psi/mysql_statement.h
+ Instrumentation helpers for statements.
+*/
+
+#include "mysql/psi/psi.h"
+
+class Diagnostics_area;
+typedef const struct charset_info_st CHARSET_INFO;
+
+#ifndef PSI_STATEMENT_CALL
+#define PSI_STATEMENT_CALL(M) PSI_DYNAMIC_CALL(M)
+#endif
+
+#ifndef PSI_DIGEST_CALL
+#define PSI_DIGEST_CALL(M) PSI_DYNAMIC_CALL(M)
+#endif
+
+/**
+ @defgroup Statement_instrumentation Statement Instrumentation
+ @ingroup Instrumentation_interface
+ @{
+*/
+
+/**
+ @def mysql_statement_register(P1, P2, P3)
+ Statement registration.
+*/
+#ifdef HAVE_PSI_STATEMENT_INTERFACE
+#define mysql_statement_register(P1, P2, P3) \
+ inline_mysql_statement_register(P1, P2, P3)
+#else
+#define mysql_statement_register(P1, P2, P3) \
+ do {} while (0)
+#endif
+
+#ifdef HAVE_PSI_STATEMENT_DIGEST_INTERFACE
+ #define MYSQL_DIGEST_START(LOCKER) \
+ inline_mysql_digest_start(LOCKER)
+#else
+ #define MYSQL_DIGEST_START(LOCKER) \
+ NULL
+#endif
+
+#ifdef HAVE_PSI_STATEMENT_DIGEST_INTERFACE
+ #define MYSQL_DIGEST_END(LOCKER, DIGEST) \
+ inline_mysql_digest_end(LOCKER, DIGEST)
+#else
+ #define MYSQL_DIGEST_END(LOCKER, DIGEST) \
+ do {} while (0)
+#endif
+
+#ifdef HAVE_PSI_STATEMENT_INTERFACE
+ #define MYSQL_START_STATEMENT(STATE, K, DB, DB_LEN, CS, SPS) \
+ inline_mysql_start_statement(STATE, K, DB, DB_LEN, CS, SPS, __FILE__, __LINE__)
+#else
+ #define MYSQL_START_STATEMENT(STATE, K, DB, DB_LEN, CS, SPS) \
+ NULL
+#endif
+
+#ifdef HAVE_PSI_STATEMENT_INTERFACE
+ #define MYSQL_REFINE_STATEMENT(LOCKER, K) \
+ inline_mysql_refine_statement(LOCKER, K)
+#else
+ #define MYSQL_REFINE_STATEMENT(LOCKER, K) \
+ NULL
+#endif
+
+#ifdef HAVE_PSI_STATEMENT_INTERFACE
+ #define MYSQL_SET_STATEMENT_TEXT(LOCKER, P1, P2) \
+ inline_mysql_set_statement_text(LOCKER, P1, P2)
+#else
+ #define MYSQL_SET_STATEMENT_TEXT(LOCKER, P1, P2) \
+ do {} while (0)
+#endif
+
+#ifdef HAVE_PSI_STATEMENT_INTERFACE
+ #define MYSQL_SET_STATEMENT_LOCK_TIME(LOCKER, P1) \
+ inline_mysql_set_statement_lock_time(LOCKER, P1)
+#else
+ #define MYSQL_SET_STATEMENT_LOCK_TIME(LOCKER, P1) \
+ do {} while (0)
+#endif
+
+#ifdef HAVE_PSI_STATEMENT_INTERFACE
+ #define MYSQL_SET_STATEMENT_ROWS_SENT(LOCKER, P1) \
+ inline_mysql_set_statement_rows_sent(LOCKER, P1)
+#else
+ #define MYSQL_SET_STATEMENT_ROWS_SENT(LOCKER, P1) \
+ do {} while (0)
+#endif
+
+#ifdef HAVE_PSI_STATEMENT_INTERFACE
+ #define MYSQL_SET_STATEMENT_ROWS_EXAMINED(LOCKER, P1) \
+ inline_mysql_set_statement_rows_examined(LOCKER, P1)
+#else
+ #define MYSQL_SET_STATEMENT_ROWS_EXAMINED(LOCKER, P1) \
+ do {} while (0)
+#endif
+
+#ifdef HAVE_PSI_STATEMENT_INTERFACE
+ #define MYSQL_END_STATEMENT(LOCKER, DA) \
+ inline_mysql_end_statement(LOCKER, DA)
+#else
+ #define MYSQL_END_STATEMENT(LOCKER, DA) \
+ do {} while (0)
+#endif
+
+#ifdef HAVE_PSI_STATEMENT_INTERFACE
+static inline void inline_mysql_statement_register(
+ const char *category, PSI_statement_info *info, int count)
+{
+ PSI_STATEMENT_CALL(register_statement)(category, info, count);
+}
+
+#ifdef HAVE_PSI_STATEMENT_DIGEST_INTERFACE
+static inline struct PSI_digest_locker *
+inline_mysql_digest_start(PSI_statement_locker *locker)
+{
+ PSI_digest_locker* digest_locker= NULL;
+
+ if (psi_likely(locker != NULL))
+ digest_locker= PSI_DIGEST_CALL(digest_start)(locker);
+ return digest_locker;
+}
+#endif
+
+#ifdef HAVE_PSI_STATEMENT_DIGEST_INTERFACE
+static inline void
+inline_mysql_digest_end(PSI_digest_locker *locker, const sql_digest_storage *digest)
+{
+ if (psi_likely(locker != NULL))
+ PSI_DIGEST_CALL(digest_end)(locker, digest);
+}
+#endif
+
+static inline struct PSI_statement_locker *
+inline_mysql_start_statement(PSI_statement_locker_state *state,
+ PSI_statement_key key,
+ const char *db, size_t db_len,
+ CHARSET_INFO *charset,
+ PSI_sp_share *sp_share,
+ const char *src_file, uint src_line)
+{
+ PSI_statement_locker *locker;
+ locker= PSI_STATEMENT_CALL(get_thread_statement_locker)(state, key, charset,
+ sp_share);
+ if (psi_likely(locker != NULL))
+ PSI_STATEMENT_CALL(start_statement)(locker, db, (uint)db_len, src_file, src_line);
+ return locker;
+}
+
+static inline struct PSI_statement_locker *
+inline_mysql_refine_statement(PSI_statement_locker *locker,
+ PSI_statement_key key)
+{
+ if (psi_likely(locker != NULL))
+ {
+ locker= PSI_STATEMENT_CALL(refine_statement)(locker, key);
+ }
+ return locker;
+}
+
+static inline void
+inline_mysql_set_statement_text(PSI_statement_locker *locker,
+ const char *text, uint text_len)
+{
+ if (psi_likely(locker != NULL))
+ {
+ PSI_STATEMENT_CALL(set_statement_text)(locker, text, text_len);
+ }
+}
+
+static inline void
+inline_mysql_set_statement_lock_time(PSI_statement_locker *locker,
+ ulonglong count)
+{
+ if (psi_likely(locker != NULL))
+ {
+ PSI_STATEMENT_CALL(set_statement_lock_time)(locker, count);
+ }
+}
+
+static inline void
+inline_mysql_set_statement_rows_sent(PSI_statement_locker *locker,
+ ulonglong count)
+{
+ if (psi_likely(locker != NULL))
+ {
+ PSI_STATEMENT_CALL(set_statement_rows_sent)(locker, count);
+ }
+}
+
+static inline void
+inline_mysql_set_statement_rows_examined(PSI_statement_locker *locker,
+ ulonglong count)
+{
+ if (psi_likely(locker != NULL))
+ {
+ PSI_STATEMENT_CALL(set_statement_rows_examined)(locker, count);
+ }
+}
+
+static inline void
+inline_mysql_end_statement(struct PSI_statement_locker *locker,
+ Diagnostics_area *stmt_da)
+{
+ PSI_STAGE_CALL(end_stage)();
+ if (psi_likely(locker != NULL))
+ PSI_STATEMENT_CALL(end_statement)(locker, stmt_da);
+}
+#endif
+
+/** @} (end of group Statement_instrumentation) */
+
+#endif
+
diff --git a/include/mysql/psi/mysql_table.h b/include/mysql/psi/mysql_table.h
new file mode 100644
index 00000000..a2124064
--- /dev/null
+++ b/include/mysql/psi/mysql_table.h
@@ -0,0 +1,172 @@
+/* Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2017, 2019, MariaDB Corporation.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License, version 2.0, for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */
+
+#ifndef MYSQL_TABLE_H
+#define MYSQL_TABLE_H
+
+/**
+ @file mysql/psi/mysql_table.h
+ Instrumentation helpers for table io.
+*/
+
+#include "mysql/psi/psi.h"
+
+#ifndef PSI_TABLE_CALL
+#define PSI_TABLE_CALL(M) PSI_DYNAMIC_CALL(M)
+#endif
+
+/**
+ @defgroup Table_instrumentation Table Instrumentation
+ @ingroup Instrumentation_interface
+ @{
+*/
+
+#ifdef HAVE_PSI_TABLE_INTERFACE
+#define MYSQL_UNBIND_TABLE(handler) (handler)->unbind_psi()
+
+#define PSI_CALL_unbind_table PSI_TABLE_CALL(unbind_table)
+#define PSI_CALL_rebind_table PSI_TABLE_CALL(rebind_table)
+#define PSI_CALL_open_table PSI_TABLE_CALL(open_table)
+#define PSI_CALL_close_table PSI_TABLE_CALL(close_table)
+#define PSI_CALL_get_table_share PSI_TABLE_CALL(get_table_share)
+#define PSI_CALL_release_table_share PSI_TABLE_CALL(release_table_share)
+#define PSI_CALL_drop_table_share PSI_TABLE_CALL(drop_table_share)
+#else
+#define MYSQL_UNBIND_TABLE(handler) do { } while(0)
+
+#define PSI_CALL_unbind_table(A1) do { } while(0)
+#define PSI_CALL_rebind_table(A1,A2,A3) NULL
+#define PSI_CALL_close_table(A1,A2) do { } while(0)
+#define PSI_CALL_open_table(A1,A2) NULL
+#define PSI_CALL_get_table_share(A1,A2) NULL
+#define PSI_CALL_release_table_share(A1) do { } while(0)
+#define PSI_CALL_drop_table_share(A1,A2,A3,A4,A5) do { } while(0)
+#endif
+
+/**
+ @def MYSQL_TABLE_WAIT_VARIABLES
+ Instrumentation helper for table waits.
+ This instrumentation declares local variables.
+ Do not use a ';' after this macro
+ @param LOCKER the locker
+ @param STATE the locker state
+ @sa MYSQL_START_TABLE_IO_WAIT.
+ @sa MYSQL_END_TABLE_IO_WAIT.
+ @sa MYSQL_START_TABLE_LOCK_WAIT.
+ @sa MYSQL_END_TABLE_LOCK_WAIT.
+*/
+#ifdef HAVE_PSI_TABLE_INTERFACE
+ #define MYSQL_TABLE_WAIT_VARIABLES(LOCKER, STATE) \
+ struct PSI_table_locker* LOCKER; \
+ PSI_table_locker_state STATE;
+#else
+ #define MYSQL_TABLE_WAIT_VARIABLES(LOCKER, STATE)
+#endif
+
+/**
+ @def MYSQL_START_TABLE_LOCK_WAIT
+ Instrumentation helper for table lock waits.
+ This instrumentation marks the start of a wait event.
+ @param LOCKER the locker
+ @param STATE the locker state
+ @param PSI the instrumented table
+ @param OP the table operation to be performed
+ @param FLAGS per table operation flags.
+ @sa MYSQL_END_TABLE_LOCK_WAIT.
+*/
+#ifdef HAVE_PSI_TABLE_INTERFACE
+ #define MYSQL_START_TABLE_LOCK_WAIT(LOCKER, STATE, PSI, OP, FLAGS) \
+ LOCKER= inline_mysql_start_table_lock_wait(STATE, PSI, \
+ OP, FLAGS, __FILE__, __LINE__)
+#else
+ #define MYSQL_START_TABLE_LOCK_WAIT(LOCKER, STATE, PSI, OP, FLAGS) \
+ do {} while (0)
+#endif
+
+/**
+ @def MYSQL_END_TABLE_LOCK_WAIT
+ Instrumentation helper for table lock waits.
+ This instrumentation marks the end of a wait event.
+ @param LOCKER the locker
+ @sa MYSQL_START_TABLE_LOCK_WAIT.
+*/
+#ifdef HAVE_PSI_TABLE_INTERFACE
+ #define MYSQL_END_TABLE_LOCK_WAIT(LOCKER) \
+ inline_mysql_end_table_lock_wait(LOCKER)
+#else
+ #define MYSQL_END_TABLE_LOCK_WAIT(LOCKER) \
+ do {} while (0)
+#endif
+
+#ifdef HAVE_PSI_TABLE_INTERFACE
+ #define MYSQL_UNLOCK_TABLE(T) \
+ inline_mysql_unlock_table(T)
+#else
+ #define MYSQL_UNLOCK_TABLE(T) \
+ do {} while (0)
+#endif
+
+#ifdef HAVE_PSI_TABLE_INTERFACE
+/**
+ Instrumentation calls for MYSQL_START_TABLE_LOCK_WAIT.
+ @sa MYSQL_END_TABLE_LOCK_WAIT.
+*/
+static inline struct PSI_table_locker *
+inline_mysql_start_table_lock_wait(PSI_table_locker_state *state,
+ struct PSI_table *psi,
+ enum PSI_table_lock_operation op,
+ ulong flags, const char *src_file, uint src_line)
+{
+ if (psi_likely(psi != NULL))
+ {
+ struct PSI_table_locker *locker;
+ locker= PSI_TABLE_CALL(start_table_lock_wait)
+ (state, psi, op, flags, src_file, src_line);
+ return locker;
+ }
+ return NULL;
+}
+
+/**
+ Instrumentation calls for MYSQL_END_TABLE_LOCK_WAIT.
+ @sa MYSQL_START_TABLE_LOCK_WAIT.
+*/
+static inline void
+inline_mysql_end_table_lock_wait(struct PSI_table_locker *locker)
+{
+ if (psi_likely(locker != NULL))
+ PSI_TABLE_CALL(end_table_lock_wait)(locker);
+}
+
+static inline void
+inline_mysql_unlock_table(struct PSI_table *table)
+{
+ if (table != NULL)
+ PSI_TABLE_CALL(unlock_table)(table);
+}
+#endif
+
+/** @} (end of group Table_instrumentation) */
+
+#endif
+
diff --git a/include/mysql/psi/mysql_thread.h b/include/mysql/psi/mysql_thread.h
new file mode 100644
index 00000000..47f89f76
--- /dev/null
+++ b/include/mysql/psi/mysql_thread.h
@@ -0,0 +1,1349 @@
+/* Copyright (c) 2008, 2013, Oracle and/or its affiliates.
+ Copyright (c) 2020, MariaDB Corporation.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License, version 2.0, for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */
+
+#ifndef MYSQL_THREAD_H
+#define MYSQL_THREAD_H
+
+/**
+ @file mysql/psi/mysql_thread.h
+ Instrumentation helpers for mysys threads, mutexes,
+ read write locks and conditions.
+ This header file provides the necessary declarations
+ to use the mysys thread API with the performance schema instrumentation.
+ In some compilers (SunStudio), 'static inline' functions, when declared
+ but not used, are not optimized away (because they are unused) by default,
+ so that including a static inline function from a header file does
+ create unwanted dependencies, causing unresolved symbols at link time.
+ Other compilers, like gcc, optimize these dependencies by default.
+
+ Since the instrumented APIs declared here are wrapper on top
+ of my_pthread / safemutex / etc APIs,
+ including mysql/psi/mysql_thread.h assumes that
+ the dependency on my_pthread and safemutex already exists.
+*/
+/*
+ Note: there are several orthogonal dimensions here.
+
+ Dimension 1: Instrumentation
+ HAVE_PSI_INTERFACE is defined when the instrumentation is compiled in.
+ This may happen both in debug or production builds.
+
+ Dimension 2: Debug
+ SAFE_MUTEX is defined when debug is compiled in.
+ This may happen both with and without instrumentation.
+
+ Dimension 3: Platform
+ Mutexes are implemented with one of:
+ - the pthread library
+ - fast mutexes
+ - window apis
+ This is implemented by various macro definitions in my_pthread.h
+
+ This causes complexity with '#ifdef'-ery that can't be avoided.
+*/
+
+#include "mysql/psi/psi.h"
+#ifdef MYSQL_SERVER
+#ifndef MYSQL_DYNAMIC_PLUGIN
+#include "pfs_thread_provider.h"
+#endif
+#endif
+
+#ifndef PSI_MUTEX_CALL
+#define PSI_MUTEX_CALL(M) PSI_DYNAMIC_CALL(M)
+#endif
+
+#ifndef PSI_RWLOCK_CALL
+#define PSI_RWLOCK_CALL(M) PSI_DYNAMIC_CALL(M)
+#endif
+
+#ifndef PSI_COND_CALL
+#define PSI_COND_CALL(M) PSI_DYNAMIC_CALL(M)
+#endif
+
+#ifndef PSI_THREAD_CALL
+#define PSI_THREAD_CALL(M) PSI_DYNAMIC_CALL(M)
+#endif
+
+/**
+ @defgroup Thread_instrumentation Thread Instrumentation
+ @ingroup Instrumentation_interface
+ @{
+*/
+
+#ifdef HAVE_PSI_THREAD_INTERFACE
+#define PSI_CALL_delete_current_thread PSI_THREAD_CALL(delete_current_thread)
+#define PSI_CALL_get_thread PSI_THREAD_CALL(get_thread)
+#define PSI_CALL_new_thread PSI_THREAD_CALL(new_thread)
+#define PSI_CALL_register_thread PSI_THREAD_CALL(register_thread)
+#define PSI_CALL_set_thread PSI_THREAD_CALL(set_thread)
+#define PSI_CALL_set_thread_THD PSI_THREAD_CALL(set_thread_THD)
+#define PSI_CALL_set_thread_connect_attrs PSI_THREAD_CALL(set_thread_connect_attrs)
+#define PSI_CALL_set_thread_db PSI_THREAD_CALL(set_thread_db)
+#define PSI_CALL_set_thread_id PSI_THREAD_CALL(set_thread_id)
+#define PSI_CALL_set_thread_os_id PSI_THREAD_CALL(set_thread_os_id)
+#define PSI_CALL_set_thread_info PSI_THREAD_CALL(set_thread_info)
+#define PSI_CALL_set_thread_start_time PSI_THREAD_CALL(set_thread_start_time)
+#define PSI_CALL_set_thread_account PSI_THREAD_CALL(set_thread_account)
+#define PSI_CALL_spawn_thread PSI_THREAD_CALL(spawn_thread)
+#define PSI_CALL_set_connection_type PSI_THREAD_CALL(set_connection_type)
+#else
+#define PSI_CALL_delete_current_thread() do { } while(0)
+#define PSI_CALL_get_thread() NULL
+#define PSI_CALL_new_thread(A1,A2,A3) NULL
+#define PSI_CALL_register_thread(A1,A2,A3) do { } while(0)
+#define PSI_CALL_set_thread(A1) do { } while(0)
+#define PSI_CALL_set_thread_THD(A1,A2) do { } while(0)
+#define PSI_CALL_set_thread_connect_attrs(A1,A2,A3) 0
+#define PSI_CALL_set_thread_db(A1,A2) do { } while(0)
+#define PSI_CALL_set_thread_id(A1,A2) do { } while(0)
+#define PSI_CALL_set_thread_os_id(A1) do { } while(0)
+#define PSI_CALL_set_thread_info(A1, A2) do { } while(0)
+#define PSI_CALL_set_thread_start_time(A1) do { } while(0)
+#define PSI_CALL_set_thread_account(A1, A2, A3, A4) do { } while(0)
+#define PSI_CALL_spawn_thread(A1, A2, A3, A4, A5) 0
+#define PSI_CALL_set_connection_type(A) do { } while(0)
+#endif
+
+
+/**
+ An instrumented mutex structure.
+ @sa mysql_mutex_t
+*/
+struct st_mysql_mutex
+{
+ /** The real mutex. */
+#ifdef SAFE_MUTEX
+ safe_mutex_t m_mutex;
+#else
+ pthread_mutex_t m_mutex;
+#endif
+ /**
+ The instrumentation hook.
+ Note that this hook is not conditionally defined,
+ for binary compatibility of the @c mysql_mutex_t interface.
+ */
+ struct PSI_mutex *m_psi;
+};
+
+/**
+ Type of an instrumented mutex.
+ @c mysql_mutex_t is a drop-in replacement for @c pthread_mutex_t.
+ @sa mysql_mutex_assert_owner
+ @sa mysql_mutex_assert_not_owner
+ @sa mysql_mutex_init
+ @sa mysql_mutex_lock
+ @sa mysql_mutex_unlock
+ @sa mysql_mutex_destroy
+*/
+typedef struct st_mysql_mutex mysql_mutex_t;
+
+/**
+ An instrumented rwlock structure.
+ @sa mysql_rwlock_t
+*/
+struct st_mysql_rwlock
+{
+ /** The real rwlock */
+ rw_lock_t m_rwlock;
+ /**
+ The instrumentation hook.
+ Note that this hook is not conditionally defined,
+ for binary compatibility of the @c mysql_rwlock_t interface.
+ */
+ struct PSI_rwlock *m_psi;
+};
+
+/**
+ An instrumented prlock structure.
+ @sa mysql_prlock_t
+*/
+struct st_mysql_prlock
+{
+ /** The real prlock */
+ rw_pr_lock_t m_prlock;
+ /**
+ The instrumentation hook.
+ Note that this hook is not conditionally defined,
+ for binary compatibility of the @c mysql_rwlock_t interface.
+ */
+ struct PSI_rwlock *m_psi;
+};
+
+/**
+ Type of an instrumented rwlock.
+ @c mysql_rwlock_t is a drop-in replacement for @c pthread_rwlock_t.
+ @sa mysql_rwlock_init
+ @sa mysql_rwlock_rdlock
+ @sa mysql_rwlock_tryrdlock
+ @sa mysql_rwlock_wrlock
+ @sa mysql_rwlock_trywrlock
+ @sa mysql_rwlock_unlock
+ @sa mysql_rwlock_destroy
+*/
+typedef struct st_mysql_rwlock mysql_rwlock_t;
+
+/**
+ Type of an instrumented prlock.
+ A prlock is a read write lock that 'prefers readers' (pr).
+ @c mysql_prlock_t is a drop-in replacement for @c rw_pr_lock_t.
+ @sa mysql_prlock_init
+ @sa mysql_prlock_rdlock
+ @sa mysql_prlock_wrlock
+ @sa mysql_prlock_unlock
+ @sa mysql_prlock_destroy
+*/
+typedef struct st_mysql_prlock mysql_prlock_t;
+
+/**
+ An instrumented cond structure.
+ @sa mysql_cond_t
+*/
+struct st_mysql_cond
+{
+ /** The real condition */
+ pthread_cond_t m_cond;
+ /**
+ The instrumentation hook.
+ Note that this hook is not conditionally defined,
+ for binary compatibility of the @c mysql_cond_t interface.
+ */
+ struct PSI_cond *m_psi;
+};
+
+/**
+ Type of an instrumented condition.
+ @c mysql_cond_t is a drop-in replacement for @c pthread_cond_t.
+ @sa mysql_cond_init
+ @sa mysql_cond_wait
+ @sa mysql_cond_timedwait
+ @sa mysql_cond_signal
+ @sa mysql_cond_broadcast
+ @sa mysql_cond_destroy
+*/
+typedef struct st_mysql_cond mysql_cond_t;
+
+/*
+ Consider the following code:
+ static inline void foo() { bar(); }
+ when foo() is never called.
+
+ With gcc, foo() is a local static function, so the dependencies
+ are optimized away at compile time, and there is no dependency on bar().
+ With other compilers (HP, Sun Studio), the function foo() implementation
+ is compiled, and bar() needs to be present to link.
+
+ Due to the existing header dependencies in MySQL code, this header file
+ is sometime used when it is not needed, which in turn cause link failures
+ on some platforms.
+ The proper fix would be to cut these extra dependencies in the calling code.
+ DISABLE_MYSQL_THREAD_H is a work around to limit dependencies.
+ DISABLE_MYSQL_PRLOCK_H is similar, and is used to disable specifically
+ the prlock wrappers.
+*/
+#ifndef DISABLE_MYSQL_THREAD_H
+
+#define mysql_mutex_is_owner(M) safe_mutex_is_owner(&(M)->m_mutex)
+/**
+ @def mysql_mutex_assert_owner(M)
+ Wrapper, to use safe_mutex_assert_owner with instrumented mutexes.
+ @c mysql_mutex_assert_owner is a drop-in replacement
+ for @c safe_mutex_assert_owner.
+*/
+#define mysql_mutex_assert_owner(M) \
+ safe_mutex_assert_owner(&(M)->m_mutex)
+
+/**
+ @def mysql_mutex_assert_not_owner(M)
+ Wrapper, to use safe_mutex_assert_not_owner with instrumented mutexes.
+ @c mysql_mutex_assert_not_owner is a drop-in replacement
+ for @c safe_mutex_assert_not_owner.
+*/
+#define mysql_mutex_assert_not_owner(M) \
+ safe_mutex_assert_not_owner(&(M)->m_mutex)
+
+#define mysql_mutex_setflags(M, F) \
+ safe_mutex_setflags(&(M)->m_mutex, (F))
+
+/**
+ @def mysql_prlock_assert_write_owner(M)
+ Drop-in replacement
+ for @c rw_pr_lock_assert_write_owner.
+*/
+#define mysql_prlock_assert_write_owner(M) \
+ rw_pr_lock_assert_write_owner(&(M)->m_prlock)
+
+/**
+ @def mysql_prlock_assert_not_write_owner(M)
+ Drop-in replacement
+ for @c rw_pr_lock_assert_not_write_owner.
+*/
+#define mysql_prlock_assert_not_write_owner(M) \
+ rw_pr_lock_assert_not_write_owner(&(M)->m_prlock)
+
+/**
+ @def mysql_mutex_register(P1, P2, P3)
+ Mutex registration.
+*/
+#define mysql_mutex_register(P1, P2, P3) \
+ inline_mysql_mutex_register(P1, P2, P3)
+
+/**
+ @def mysql_mutex_init(K, M, A)
+ Instrumented mutex_init.
+ @c mysql_mutex_init is a replacement for @c pthread_mutex_init.
+ @param K The PSI_mutex_key for this instrumented mutex
+ @param M The mutex to initialize
+ @param A Mutex attributes
+*/
+
+#ifdef HAVE_PSI_MUTEX_INTERFACE
+ #ifdef SAFE_MUTEX
+ #define mysql_mutex_init(K, M, A) \
+ inline_mysql_mutex_init(K, M, A, #M, __FILE__, __LINE__)
+ #else
+ #define mysql_mutex_init(K, M, A) \
+ inline_mysql_mutex_init(K, M, A)
+ #endif
+#else
+ #ifdef SAFE_MUTEX
+ #define mysql_mutex_init(K, M, A) \
+ inline_mysql_mutex_init(M, A, #M, __FILE__, __LINE__)
+ #else
+ #define mysql_mutex_init(K, M, A) \
+ inline_mysql_mutex_init(M, A)
+ #endif
+#endif
+
+/**
+ @def mysql_mutex_destroy(M)
+ Instrumented mutex_destroy.
+ @c mysql_mutex_destroy is a drop-in replacement
+ for @c pthread_mutex_destroy.
+*/
+#ifdef SAFE_MUTEX
+ #define mysql_mutex_destroy(M) \
+ inline_mysql_mutex_destroy(M, __FILE__, __LINE__)
+#else
+ #define mysql_mutex_destroy(M) \
+ inline_mysql_mutex_destroy(M)
+#endif
+
+/**
+ @def mysql_mutex_lock(M)
+ Instrumented mutex_lock.
+ @c mysql_mutex_lock is a drop-in replacement for @c pthread_mutex_lock.
+ @param M The mutex to lock
+*/
+
+#if defined(SAFE_MUTEX) || defined (HAVE_PSI_MUTEX_INTERFACE)
+ #define mysql_mutex_lock(M) \
+ inline_mysql_mutex_lock(M, __FILE__, __LINE__)
+#else
+ #define mysql_mutex_lock(M) \
+ inline_mysql_mutex_lock(M)
+#endif
+
+/**
+ @def mysql_mutex_trylock(M)
+ Instrumented mutex_lock.
+ @c mysql_mutex_trylock is a drop-in replacement
+ for @c pthread_mutex_trylock.
+*/
+
+#if defined(SAFE_MUTEX) || defined (HAVE_PSI_MUTEX_INTERFACE)
+ #define mysql_mutex_trylock(M) \
+ inline_mysql_mutex_trylock(M, __FILE__, __LINE__)
+#else
+ #define mysql_mutex_trylock(M) \
+ inline_mysql_mutex_trylock(M)
+#endif
+
+/**
+ @def mysql_mutex_unlock(M)
+ Instrumented mutex_unlock.
+ @c mysql_mutex_unlock is a drop-in replacement for @c pthread_mutex_unlock.
+*/
+#ifdef SAFE_MUTEX
+ #define mysql_mutex_unlock(M) \
+ inline_mysql_mutex_unlock(M, __FILE__, __LINE__)
+#else
+ #define mysql_mutex_unlock(M) \
+ inline_mysql_mutex_unlock(M)
+#endif
+
+/**
+ @def mysql_rwlock_register(P1, P2, P3)
+ Rwlock registration.
+*/
+#define mysql_rwlock_register(P1, P2, P3) \
+ inline_mysql_rwlock_register(P1, P2, P3)
+
+/**
+ @def mysql_rwlock_init(K, RW)
+ Instrumented rwlock_init.
+ @c mysql_rwlock_init is a replacement for @c pthread_rwlock_init.
+ Note that pthread_rwlockattr_t is not supported in MySQL.
+ @param K The PSI_rwlock_key for this instrumented rwlock
+ @param RW The rwlock to initialize
+*/
+#ifdef HAVE_PSI_RWLOCK_INTERFACE
+ #define mysql_rwlock_init(K, RW) inline_mysql_rwlock_init(K, RW)
+#else
+ #define mysql_rwlock_init(K, RW) inline_mysql_rwlock_init(RW)
+#endif
+
+/**
+ @def mysql_prlock_init(K, RW)
+ Instrumented rw_pr_init.
+ @c mysql_prlock_init is a replacement for @c rw_pr_init.
+ @param K The PSI_rwlock_key for this instrumented prlock
+ @param RW The prlock to initialize
+*/
+#ifdef HAVE_PSI_RWLOCK_INTERFACE
+ #define mysql_prlock_init(K, RW) inline_mysql_prlock_init(K, RW)
+#else
+ #define mysql_prlock_init(K, RW) inline_mysql_prlock_init(RW)
+#endif
+
+/**
+ @def mysql_rwlock_destroy(RW)
+ Instrumented rwlock_destroy.
+ @c mysql_rwlock_destroy is a drop-in replacement
+ for @c pthread_rwlock_destroy.
+*/
+#define mysql_rwlock_destroy(RW) inline_mysql_rwlock_destroy(RW)
+
+/**
+ @def mysql_prlock_destroy(RW)
+ Instrumented rw_pr_destroy.
+ @c mysql_prlock_destroy is a drop-in replacement
+ for @c rw_pr_destroy.
+*/
+#define mysql_prlock_destroy(RW) inline_mysql_prlock_destroy(RW)
+
+/**
+ @def mysql_rwlock_rdlock(RW)
+ Instrumented rwlock_rdlock.
+ @c mysql_rwlock_rdlock is a drop-in replacement
+ for @c pthread_rwlock_rdlock.
+*/
+#ifdef HAVE_PSI_RWLOCK_INTERFACE
+ #define mysql_rwlock_rdlock(RW) \
+ inline_mysql_rwlock_rdlock(RW, __FILE__, __LINE__)
+#else
+ #define mysql_rwlock_rdlock(RW) \
+ inline_mysql_rwlock_rdlock(RW)
+#endif
+
+/**
+ @def mysql_prlock_rdlock(RW)
+ Instrumented rw_pr_rdlock.
+ @c mysql_prlock_rdlock is a drop-in replacement
+ for @c rw_pr_rdlock.
+*/
+#ifdef HAVE_PSI_RWLOCK_INTERFACE
+ #define mysql_prlock_rdlock(RW) \
+ inline_mysql_prlock_rdlock(RW, __FILE__, __LINE__)
+#else
+ #define mysql_prlock_rdlock(RW) \
+ inline_mysql_prlock_rdlock(RW)
+#endif
+
+/**
+ @def mysql_rwlock_wrlock(RW)
+ Instrumented rwlock_wrlock.
+ @c mysql_rwlock_wrlock is a drop-in replacement
+ for @c pthread_rwlock_wrlock.
+*/
+#ifdef HAVE_PSI_RWLOCK_INTERFACE
+ #define mysql_rwlock_wrlock(RW) \
+ inline_mysql_rwlock_wrlock(RW, __FILE__, __LINE__)
+#else
+ #define mysql_rwlock_wrlock(RW) \
+ inline_mysql_rwlock_wrlock(RW)
+#endif
+
+/**
+ @def mysql_prlock_wrlock(RW)
+ Instrumented rw_pr_wrlock.
+ @c mysql_prlock_wrlock is a drop-in replacement
+ for @c rw_pr_wrlock.
+*/
+#ifdef HAVE_PSI_RWLOCK_INTERFACE
+ #define mysql_prlock_wrlock(RW) \
+ inline_mysql_prlock_wrlock(RW, __FILE__, __LINE__)
+#else
+ #define mysql_prlock_wrlock(RW) \
+ inline_mysql_prlock_wrlock(RW)
+#endif
+
+/**
+ @def mysql_rwlock_tryrdlock(RW)
+ Instrumented rwlock_tryrdlock.
+ @c mysql_rwlock_tryrdlock is a drop-in replacement
+ for @c pthread_rwlock_tryrdlock.
+*/
+#ifdef HAVE_PSI_RWLOCK_INTERFACE
+ #define mysql_rwlock_tryrdlock(RW) \
+ inline_mysql_rwlock_tryrdlock(RW, __FILE__, __LINE__)
+#else
+ #define mysql_rwlock_tryrdlock(RW) \
+ inline_mysql_rwlock_tryrdlock(RW)
+#endif
+
+/**
+ @def mysql_rwlock_trywrlock(RW)
+ Instrumented rwlock_trywrlock.
+ @c mysql_rwlock_trywrlock is a drop-in replacement
+ for @c pthread_rwlock_trywrlock.
+*/
+#ifdef HAVE_PSI_RWLOCK_INTERFACE
+ #define mysql_rwlock_trywrlock(RW) \
+ inline_mysql_rwlock_trywrlock(RW, __FILE__, __LINE__)
+#else
+ #define mysql_rwlock_trywrlock(RW) \
+ inline_mysql_rwlock_trywrlock(RW)
+#endif
+
+/**
+ @def mysql_rwlock_unlock(RW)
+ Instrumented rwlock_unlock.
+ @c mysql_rwlock_unlock is a drop-in replacement
+ for @c pthread_rwlock_unlock.
+*/
+#define mysql_rwlock_unlock(RW) inline_mysql_rwlock_unlock(RW)
+
+/**
+ @def mysql_prlock_unlock(RW)
+ Instrumented rw_pr_unlock.
+ @c mysql_prlock_unlock is a drop-in replacement
+ for @c rw_pr_unlock.
+*/
+#define mysql_prlock_unlock(RW) inline_mysql_prlock_unlock(RW)
+
+/**
+ @def mysql_cond_register(P1, P2, P3)
+ Cond registration.
+*/
+#define mysql_cond_register(P1, P2, P3) \
+ inline_mysql_cond_register(P1, P2, P3)
+
+/**
+ @def mysql_cond_init(K, C, A)
+ Instrumented cond_init.
+ @c mysql_cond_init is a replacement for @c pthread_cond_init.
+ @param C The cond to initialize
+ @param K The PSI_cond_key for this instrumented cond
+ @param A Condition attributes
+*/
+#ifdef HAVE_PSI_COND_INTERFACE
+ #define mysql_cond_init(K, C, A) inline_mysql_cond_init(K, C, A)
+#else
+ #define mysql_cond_init(K, C, A) inline_mysql_cond_init(C, A)
+#endif
+
+/**
+ @def mysql_cond_destroy(C)
+ Instrumented cond_destroy.
+ @c mysql_cond_destroy is a drop-in replacement for @c pthread_cond_destroy.
+*/
+#define mysql_cond_destroy(C) inline_mysql_cond_destroy(C)
+
+/**
+ @def mysql_cond_wait(C)
+ Instrumented cond_wait.
+ @c mysql_cond_wait is a drop-in replacement for @c pthread_cond_wait.
+*/
+#if defined(SAFE_MUTEX) || defined(HAVE_PSI_COND_INTERFACE)
+ #define mysql_cond_wait(C, M) \
+ inline_mysql_cond_wait(C, M, __FILE__, __LINE__)
+#else
+ #define mysql_cond_wait(C, M) \
+ inline_mysql_cond_wait(C, M)
+#endif
+
+/**
+ @def mysql_cond_timedwait(C, M, W)
+ Instrumented cond_timedwait.
+ @c mysql_cond_timedwait is a drop-in replacement
+ for @c pthread_cond_timedwait.
+*/
+#if defined(SAFE_MUTEX) || defined(HAVE_PSI_COND_INTERFACE)
+ #define mysql_cond_timedwait(C, M, W) \
+ inline_mysql_cond_timedwait(C, M, W, __FILE__, __LINE__)
+#else
+ #define mysql_cond_timedwait(C, M, W) \
+ inline_mysql_cond_timedwait(C, M, W)
+#endif
+
+/**
+ @def mysql_cond_signal(C)
+ Instrumented cond_signal.
+ @c mysql_cond_signal is a drop-in replacement for @c pthread_cond_signal.
+*/
+#define mysql_cond_signal(C) inline_mysql_cond_signal(C)
+
+/**
+ @def mysql_cond_broadcast(C)
+ Instrumented cond_broadcast.
+ @c mysql_cond_broadcast is a drop-in replacement
+ for @c pthread_cond_broadcast.
+*/
+#define mysql_cond_broadcast(C) inline_mysql_cond_broadcast(C)
+
+/**
+ @def mysql_thread_register(P1, P2, P3)
+ Thread registration.
+*/
+#define mysql_thread_register(P1, P2, P3) \
+ inline_mysql_thread_register(P1, P2, P3)
+
+/**
+ @def mysql_thread_create(K, P1, P2, P3, P4)
+ Instrumented pthread_create.
+ This function creates both the thread instrumentation and a thread.
+ @c mysql_thread_create is a replacement for @c pthread_create.
+ The parameter P4 (or, if it is NULL, P1) will be used as the
+ instrumented thread "indentity".
+ Providing a P1 / P4 parameter with a different value for each call
+ will on average improve performances, since this thread identity value
+ is used internally to randomize access to data and prevent contention.
+ This is optional, and the improvement is not guaranteed, only statistical.
+ @param K The PSI_thread_key for this instrumented thread
+ @param P1 pthread_create parameter 1
+ @param P2 pthread_create parameter 2
+ @param P3 pthread_create parameter 3
+ @param P4 pthread_create parameter 4
+*/
+#ifdef HAVE_PSI_THREAD_INTERFACE
+ #define mysql_thread_create(K, P1, P2, P3, P4) \
+ inline_mysql_thread_create(K, P1, P2, P3, P4)
+#else
+ #define mysql_thread_create(K, P1, P2, P3, P4) \
+ pthread_create(P1, P2, P3, P4)
+#endif
+
+/**
+ @def mysql_thread_set_psi_id(I)
+ Set the thread identifier for the instrumentation.
+ @param I The thread identifier
+*/
+#ifdef HAVE_PSI_THREAD_INTERFACE
+ #define mysql_thread_set_psi_id(I) inline_mysql_thread_set_psi_id(I)
+#else
+ #define mysql_thread_set_psi_id(I) do {} while (0)
+#endif
+
+/**
+ @def mysql_thread_set_psi_THD(T)
+ Set the thread sql session for the instrumentation.
+ @param I The thread identifier
+*/
+#ifdef HAVE_PSI_THREAD_INTERFACE
+ #define mysql_thread_set_psi_THD(T) inline_mysql_thread_set_psi_THD(T)
+#else
+ #define mysql_thread_set_psi_THD(T) do {} while (0)
+#endif
+
+static inline void inline_mysql_mutex_register(
+#ifdef HAVE_PSI_MUTEX_INTERFACE
+ const char *category,
+ PSI_mutex_info *info,
+ int count
+#else
+ const char *category __attribute__ ((unused)),
+ void *info __attribute__ ((unused)),
+ int count __attribute__ ((unused))
+#endif
+)
+{
+#ifdef HAVE_PSI_MUTEX_INTERFACE
+ PSI_MUTEX_CALL(register_mutex)(category, info, count);
+#endif
+}
+
+static inline int inline_mysql_mutex_init(
+#ifdef HAVE_PSI_MUTEX_INTERFACE
+ PSI_mutex_key key,
+#endif
+ mysql_mutex_t *that,
+ const pthread_mutexattr_t *attr
+#ifdef SAFE_MUTEX
+ , const char *src_name, const char *src_file, uint src_line
+#endif
+ )
+{
+#ifdef HAVE_PSI_MUTEX_INTERFACE
+ that->m_psi= PSI_MUTEX_CALL(init_mutex)(key, &that->m_mutex);
+#else
+ that->m_psi= NULL;
+#endif
+#ifdef SAFE_MUTEX
+ return safe_mutex_init(&that->m_mutex, attr, src_name, src_file, src_line);
+#else
+ return pthread_mutex_init(&that->m_mutex, attr);
+#endif
+}
+
+static inline int inline_mysql_mutex_destroy(
+ mysql_mutex_t *that
+#ifdef SAFE_MUTEX
+ , const char *src_file, uint src_line
+#endif
+ )
+{
+#ifdef HAVE_PSI_MUTEX_INTERFACE
+ if (that->m_psi != NULL)
+ {
+ PSI_MUTEX_CALL(destroy_mutex)(that->m_psi);
+ that->m_psi= NULL;
+ }
+#endif
+#ifdef SAFE_MUTEX
+ return safe_mutex_destroy(&that->m_mutex, src_file, src_line);
+#else
+ return pthread_mutex_destroy(&that->m_mutex);
+#endif
+}
+
+static inline int inline_mysql_mutex_lock(
+ mysql_mutex_t *that
+#if defined(SAFE_MUTEX) || defined (HAVE_PSI_MUTEX_INTERFACE)
+ , const char *src_file, uint src_line
+#endif
+ )
+{
+ int result;
+
+#ifdef HAVE_PSI_MUTEX_INTERFACE
+ if (psi_likely(that->m_psi != NULL))
+ {
+ /* Instrumentation start */
+ PSI_mutex_locker *locker;
+ PSI_mutex_locker_state state;
+ locker= PSI_MUTEX_CALL(start_mutex_wait)(&state, that->m_psi,
+ PSI_MUTEX_LOCK, src_file, src_line);
+
+ /* Instrumented code */
+#ifdef SAFE_MUTEX
+ result= safe_mutex_lock(&that->m_mutex, FALSE, src_file, src_line);
+#else
+ result= pthread_mutex_lock(&that->m_mutex);
+#endif
+
+ /* Instrumentation end */
+ if (locker != NULL)
+ PSI_MUTEX_CALL(end_mutex_wait)(locker, result);
+
+ return result;
+ }
+#endif
+
+ /* Non instrumented code */
+#ifdef SAFE_MUTEX
+ result= safe_mutex_lock(&that->m_mutex, FALSE, src_file, src_line);
+#else
+ result= pthread_mutex_lock(&that->m_mutex);
+#endif
+
+ return result;
+}
+
+static inline int inline_mysql_mutex_trylock(
+ mysql_mutex_t *that
+#if defined(SAFE_MUTEX) || defined (HAVE_PSI_MUTEX_INTERFACE)
+ , const char *src_file, uint src_line
+#endif
+ )
+{
+ int result;
+
+#ifdef HAVE_PSI_MUTEX_INTERFACE
+ if (psi_likely(that->m_psi != NULL))
+ {
+ /* Instrumentation start */
+ PSI_mutex_locker *locker;
+ PSI_mutex_locker_state state;
+ locker= PSI_MUTEX_CALL(start_mutex_wait)(&state, that->m_psi,
+ PSI_MUTEX_TRYLOCK, src_file, src_line);
+
+ /* Instrumented code */
+#ifdef SAFE_MUTEX
+ result= safe_mutex_lock(&that->m_mutex, TRUE, src_file, src_line);
+#else
+ result= pthread_mutex_trylock(&that->m_mutex);
+#endif
+
+ /* Instrumentation end */
+ if (locker != NULL)
+ PSI_MUTEX_CALL(end_mutex_wait)(locker, result);
+
+ return result;
+ }
+#endif
+
+ /* Non instrumented code */
+#ifdef SAFE_MUTEX
+ result= safe_mutex_lock(&that->m_mutex, TRUE, src_file, src_line);
+#else
+ result= pthread_mutex_trylock(&that->m_mutex);
+#endif
+
+ return result;
+}
+
+static inline int inline_mysql_mutex_unlock(
+ mysql_mutex_t *that
+#ifdef SAFE_MUTEX
+ , const char *src_file, uint src_line
+#endif
+ )
+{
+ int result;
+
+#ifdef HAVE_PSI_MUTEX_INTERFACE
+ if (psi_likely(that->m_psi != NULL))
+ PSI_MUTEX_CALL(unlock_mutex)(that->m_psi);
+#endif
+
+#ifdef SAFE_MUTEX
+ result= safe_mutex_unlock(&that->m_mutex, src_file, src_line);
+#else
+ result= pthread_mutex_unlock(&that->m_mutex);
+#endif
+
+ return result;
+}
+
+static inline void inline_mysql_rwlock_register(
+#ifdef HAVE_PSI_RWLOCK_INTERFACE
+ const char *category,
+ PSI_rwlock_info *info,
+ int count
+#else
+ const char *category __attribute__ ((unused)),
+ void *info __attribute__ ((unused)),
+ int count __attribute__ ((unused))
+#endif
+)
+{
+#ifdef HAVE_PSI_RWLOCK_INTERFACE
+ PSI_RWLOCK_CALL(register_rwlock)(category, info, count);
+#endif
+}
+
+static inline int inline_mysql_rwlock_init(
+#ifdef HAVE_PSI_RWLOCK_INTERFACE
+ PSI_rwlock_key key,
+#endif
+ mysql_rwlock_t *that)
+{
+#ifdef HAVE_PSI_RWLOCK_INTERFACE
+ that->m_psi= PSI_RWLOCK_CALL(init_rwlock)(key, &that->m_rwlock);
+#else
+ that->m_psi= NULL;
+#endif
+ /*
+ pthread_rwlockattr_t is not used in MySQL.
+ */
+ return my_rwlock_init(&that->m_rwlock, NULL);
+}
+
+#ifndef DISABLE_MYSQL_PRLOCK_H
+static inline int inline_mysql_prlock_init(
+#ifdef HAVE_PSI_RWLOCK_INTERFACE
+ PSI_rwlock_key key,
+#endif
+ mysql_prlock_t *that)
+{
+#ifdef HAVE_PSI_RWLOCK_INTERFACE
+ that->m_psi= PSI_RWLOCK_CALL(init_rwlock)(key, &that->m_prlock);
+#else
+ that->m_psi= NULL;
+#endif
+ return rw_pr_init(&that->m_prlock);
+}
+#endif
+
+static inline int inline_mysql_rwlock_destroy(
+ mysql_rwlock_t *that)
+{
+#ifdef HAVE_PSI_RWLOCK_INTERFACE
+ if (psi_likely(that->m_psi != NULL))
+ {
+ PSI_RWLOCK_CALL(destroy_rwlock)(that->m_psi);
+ that->m_psi= NULL;
+ }
+#endif
+ return rwlock_destroy(&that->m_rwlock);
+}
+
+#ifndef DISABLE_MYSQL_PRLOCK_H
+static inline int inline_mysql_prlock_destroy(
+ mysql_prlock_t *that)
+{
+#ifdef HAVE_PSI_RWLOCK_INTERFACE
+ if (psi_likely(that->m_psi != NULL))
+ {
+ PSI_RWLOCK_CALL(destroy_rwlock)(that->m_psi);
+ that->m_psi= NULL;
+ }
+#endif
+ return rw_pr_destroy(&that->m_prlock);
+}
+#endif
+
+static inline int inline_mysql_rwlock_rdlock(
+ mysql_rwlock_t *that
+#ifdef HAVE_PSI_RWLOCK_INTERFACE
+ , const char *src_file, uint src_line
+#endif
+ )
+{
+ int result;
+
+#ifdef HAVE_PSI_RWLOCK_INTERFACE
+ if (psi_likely(that->m_psi != NULL))
+ {
+ /* Instrumentation start */
+ PSI_rwlock_locker *locker;
+ PSI_rwlock_locker_state state;
+ locker= PSI_RWLOCK_CALL(start_rwlock_rdwait)(&state, that->m_psi,
+ PSI_RWLOCK_READLOCK, src_file, src_line);
+
+ /* Instrumented code */
+ result= rw_rdlock(&that->m_rwlock);
+
+ /* Instrumentation end */
+ if (locker != NULL)
+ PSI_RWLOCK_CALL(end_rwlock_rdwait)(locker, result);
+
+ return result;
+ }
+#endif
+
+ /* Non instrumented code */
+ result= rw_rdlock(&that->m_rwlock);
+
+ return result;
+}
+
+#ifndef DISABLE_MYSQL_PRLOCK_H
+static inline int inline_mysql_prlock_rdlock(
+ mysql_prlock_t *that
+#ifdef HAVE_PSI_RWLOCK_INTERFACE
+ , const char *src_file, uint src_line
+#endif
+ )
+{
+ int result;
+
+#ifdef HAVE_PSI_RWLOCK_INTERFACE
+ if (psi_likely(that->m_psi != NULL))
+ {
+ /* Instrumentation start */
+ PSI_rwlock_locker *locker;
+ PSI_rwlock_locker_state state;
+ locker= PSI_RWLOCK_CALL(start_rwlock_rdwait)(&state, that->m_psi,
+ PSI_RWLOCK_READLOCK, src_file, src_line);
+
+ /* Instrumented code */
+ result= rw_pr_rdlock(&that->m_prlock);
+
+ /* Instrumentation end */
+ if (locker != NULL)
+ PSI_RWLOCK_CALL(end_rwlock_rdwait)(locker, result);
+
+ return result;
+ }
+#endif
+
+ /* Non instrumented code */
+ result= rw_pr_rdlock(&that->m_prlock);
+
+ return result;
+}
+#endif
+
+static inline int inline_mysql_rwlock_wrlock(
+ mysql_rwlock_t *that
+#ifdef HAVE_PSI_RWLOCK_INTERFACE
+ , const char *src_file, uint src_line
+#endif
+ )
+{
+ int result;
+
+#ifdef HAVE_PSI_RWLOCK_INTERFACE
+ if (psi_likely(that->m_psi != NULL))
+ {
+ /* Instrumentation start */
+ PSI_rwlock_locker *locker;
+ PSI_rwlock_locker_state state;
+ locker= PSI_RWLOCK_CALL(start_rwlock_wrwait)(&state, that->m_psi,
+ PSI_RWLOCK_WRITELOCK, src_file, src_line);
+
+ /* Instrumented code */
+ result= rw_wrlock(&that->m_rwlock);
+
+ /* Instrumentation end */
+ if (locker != NULL)
+ PSI_RWLOCK_CALL(end_rwlock_wrwait)(locker, result);
+
+ return result;
+ }
+#endif
+
+ /* Non instrumented code */
+ result= rw_wrlock(&that->m_rwlock);
+
+ return result;
+}
+
+#ifndef DISABLE_MYSQL_PRLOCK_H
+static inline int inline_mysql_prlock_wrlock(
+ mysql_prlock_t *that
+#ifdef HAVE_PSI_RWLOCK_INTERFACE
+ , const char *src_file, uint src_line
+#endif
+ )
+{
+ int result;
+
+#ifdef HAVE_PSI_RWLOCK_INTERFACE
+ if (psi_likely(that->m_psi != NULL))
+ {
+ /* Instrumentation start */
+ PSI_rwlock_locker *locker;
+ PSI_rwlock_locker_state state;
+ locker= PSI_RWLOCK_CALL(start_rwlock_wrwait)(&state, that->m_psi,
+ PSI_RWLOCK_WRITELOCK, src_file, src_line);
+
+ /* Instrumented code */
+ result= rw_pr_wrlock(&that->m_prlock);
+
+ /* Instrumentation end */
+ if (locker != NULL)
+ PSI_RWLOCK_CALL(end_rwlock_wrwait)(locker, result);
+
+ return result;
+ }
+#endif
+
+ /* Non instrumented code */
+ result= rw_pr_wrlock(&that->m_prlock);
+
+ return result;
+}
+#endif
+
+static inline int inline_mysql_rwlock_tryrdlock(
+ mysql_rwlock_t *that
+#ifdef HAVE_PSI_RWLOCK_INTERFACE
+ , const char *src_file, uint src_line
+#endif
+ )
+{
+ int result;
+
+#ifdef HAVE_PSI_RWLOCK_INTERFACE
+ if (psi_likely(that->m_psi != NULL))
+ {
+ /* Instrumentation start */
+ PSI_rwlock_locker *locker;
+ PSI_rwlock_locker_state state;
+ locker= PSI_RWLOCK_CALL(start_rwlock_rdwait)(&state, that->m_psi,
+ PSI_RWLOCK_TRYREADLOCK, src_file, src_line);
+
+ /* Instrumented code */
+ result= rw_tryrdlock(&that->m_rwlock);
+
+ /* Instrumentation end */
+ if (locker != NULL)
+ PSI_RWLOCK_CALL(end_rwlock_rdwait)(locker, result);
+
+ return result;
+ }
+#endif
+
+ /* Non instrumented code */
+ result= rw_tryrdlock(&that->m_rwlock);
+
+ return result;
+}
+
+static inline int inline_mysql_rwlock_trywrlock(
+ mysql_rwlock_t *that
+#ifdef HAVE_PSI_RWLOCK_INTERFACE
+ , const char *src_file, uint src_line
+#endif
+ )
+{
+ int result;
+
+#ifdef HAVE_PSI_RWLOCK_INTERFACE
+ if (psi_likely(that->m_psi != NULL))
+ {
+ /* Instrumentation start */
+ PSI_rwlock_locker *locker;
+ PSI_rwlock_locker_state state;
+ locker= PSI_RWLOCK_CALL(start_rwlock_wrwait)(&state, that->m_psi,
+ PSI_RWLOCK_TRYWRITELOCK, src_file, src_line);
+
+ /* Instrumented code */
+ result= rw_trywrlock(&that->m_rwlock);
+
+ /* Instrumentation end */
+ if (locker != NULL)
+ PSI_RWLOCK_CALL(end_rwlock_wrwait)(locker, result);
+
+ return result;
+ }
+#endif
+
+ /* Non instrumented code */
+ result= rw_trywrlock(&that->m_rwlock);
+
+ return result;
+}
+
+static inline int inline_mysql_rwlock_unlock(
+ mysql_rwlock_t *that)
+{
+ int result;
+#ifdef HAVE_PSI_RWLOCK_INTERFACE
+ if (psi_likely(that->m_psi != NULL))
+ PSI_RWLOCK_CALL(unlock_rwlock)(that->m_psi);
+#endif
+ result= rw_unlock(&that->m_rwlock);
+ return result;
+}
+
+#ifndef DISABLE_MYSQL_PRLOCK_H
+static inline int inline_mysql_prlock_unlock(
+ mysql_prlock_t *that)
+{
+ int result;
+#ifdef HAVE_PSI_RWLOCK_INTERFACE
+ if (psi_likely(that->m_psi != NULL))
+ PSI_RWLOCK_CALL(unlock_rwlock)(that->m_psi);
+#endif
+ result= rw_pr_unlock(&that->m_prlock);
+ return result;
+}
+#endif
+
+static inline void inline_mysql_cond_register(
+#ifdef HAVE_PSI_COND_INTERFACE
+ const char *category,
+ PSI_cond_info *info,
+ int count
+#else
+ const char *category __attribute__ ((unused)),
+ void *info __attribute__ ((unused)),
+ int count __attribute__ ((unused))
+#endif
+)
+{
+#ifdef HAVE_PSI_COND_INTERFACE
+ PSI_COND_CALL(register_cond)(category, info, count);
+#endif
+}
+
+static inline int inline_mysql_cond_init(
+#ifdef HAVE_PSI_COND_INTERFACE
+ PSI_cond_key key,
+#endif
+ mysql_cond_t *that,
+ const pthread_condattr_t *attr)
+{
+#ifdef HAVE_PSI_COND_INTERFACE
+ that->m_psi= PSI_COND_CALL(init_cond)(key, &that->m_cond);
+#else
+ that->m_psi= NULL;
+#endif
+ return pthread_cond_init(&that->m_cond, attr);
+}
+
+static inline int inline_mysql_cond_destroy(
+ mysql_cond_t *that)
+{
+#ifdef HAVE_PSI_COND_INTERFACE
+ if (psi_likely(that->m_psi != NULL))
+ {
+ PSI_COND_CALL(destroy_cond)(that->m_psi);
+ that->m_psi= NULL;
+ }
+#endif
+ return pthread_cond_destroy(&that->m_cond);
+}
+
+static inline int inline_mysql_cond_wait(
+ mysql_cond_t *that,
+ mysql_mutex_t *mutex
+#if defined(SAFE_MUTEX) || defined(HAVE_PSI_COND_INTERFACE)
+ , const char *src_file, uint src_line
+#endif
+ )
+{
+ int result;
+
+#ifdef HAVE_PSI_COND_INTERFACE
+ if (psi_likely(that->m_psi != NULL))
+ {
+ /* Instrumentation start */
+ PSI_cond_locker *locker;
+ PSI_cond_locker_state state;
+ locker= PSI_COND_CALL(start_cond_wait)(&state, that->m_psi, mutex->m_psi,
+ PSI_COND_WAIT, src_file, src_line);
+
+ /* Instrumented code */
+ result= my_cond_wait(&that->m_cond, &mutex->m_mutex);
+
+ /* Instrumentation end */
+ if (locker != NULL)
+ PSI_COND_CALL(end_cond_wait)(locker, result);
+
+ return result;
+ }
+#endif
+
+ /* Non instrumented code */
+ result= my_cond_wait(&that->m_cond, &mutex->m_mutex);
+
+ return result;
+}
+
+static inline int inline_mysql_cond_timedwait(
+ mysql_cond_t *that,
+ mysql_mutex_t *mutex,
+ const struct timespec *abstime
+#if defined(SAFE_MUTEX) || defined(HAVE_PSI_COND_INTERFACE)
+ , const char *src_file, uint src_line
+#endif
+ )
+{
+ int result;
+
+#ifdef HAVE_PSI_COND_INTERFACE
+ if (psi_likely(that->m_psi != NULL))
+ {
+ /* Instrumentation start */
+ PSI_cond_locker *locker;
+ PSI_cond_locker_state state;
+ locker= PSI_COND_CALL(start_cond_wait)(&state, that->m_psi, mutex->m_psi,
+ PSI_COND_TIMEDWAIT, src_file, src_line);
+
+ /* Instrumented code */
+ result= my_cond_timedwait(&that->m_cond, &mutex->m_mutex, abstime);
+
+ /* Instrumentation end */
+ if (psi_likely(locker != NULL))
+ PSI_COND_CALL(end_cond_wait)(locker, result);
+
+ return result;
+ }
+#endif
+
+ /* Non instrumented code */
+ result= my_cond_timedwait(&that->m_cond, &mutex->m_mutex, abstime);
+
+ return result;
+}
+
+static inline int inline_mysql_cond_signal(
+ mysql_cond_t *that)
+{
+ int result;
+#ifdef HAVE_PSI_COND_INTERFACE
+ if (psi_likely(that->m_psi != NULL))
+ PSI_COND_CALL(signal_cond)(that->m_psi);
+#endif
+ result= pthread_cond_signal(&that->m_cond);
+ return result;
+}
+
+static inline int inline_mysql_cond_broadcast(
+ mysql_cond_t *that)
+{
+ int result;
+#ifdef HAVE_PSI_COND_INTERFACE
+ if (psi_likely(that->m_psi != NULL))
+ PSI_COND_CALL(broadcast_cond)(that->m_psi);
+#endif
+ result= pthread_cond_broadcast(&that->m_cond);
+ return result;
+}
+
+static inline void inline_mysql_thread_register(
+#ifdef HAVE_PSI_THREAD_INTERFACE
+ const char *category,
+ PSI_thread_info *info,
+ int count
+#else
+ const char *category __attribute__ ((unused)),
+ void *info __attribute__ ((unused)),
+ int count __attribute__ ((unused))
+#endif
+)
+{
+#ifdef HAVE_PSI_THREAD_INTERFACE
+ PSI_THREAD_CALL(register_thread)(category, info, count);
+#endif
+}
+
+#ifdef HAVE_PSI_THREAD_INTERFACE
+static inline int inline_mysql_thread_create(
+ PSI_thread_key key,
+ pthread_t *thread, const pthread_attr_t *attr,
+ void *(*start_routine)(void*), void *arg)
+{
+ int result;
+ result= PSI_THREAD_CALL(spawn_thread)(key, thread, attr, start_routine, arg);
+ return result;
+}
+
+static inline void inline_mysql_thread_set_psi_id(my_thread_id id)
+{
+ struct PSI_thread *psi= PSI_THREAD_CALL(get_thread)();
+ PSI_THREAD_CALL(set_thread_id)(psi, id);
+}
+
+#ifdef __cplusplus
+class THD;
+static inline void inline_mysql_thread_set_psi_THD(THD *thd)
+{
+ struct PSI_thread *psi= PSI_THREAD_CALL(get_thread)();
+ PSI_THREAD_CALL(set_thread_THD)(psi, thd);
+}
+#endif /* __cplusplus */
+
+#endif
+
+#endif /* DISABLE_MYSQL_THREAD_H */
+
+/** @} (end of group Thread_instrumentation) */
+
+#endif
+
diff --git a/include/mysql/psi/mysql_transaction.h b/include/mysql/psi/mysql_transaction.h
new file mode 100644
index 00000000..6de794d9
--- /dev/null
+++ b/include/mysql/psi/mysql_transaction.h
@@ -0,0 +1,220 @@
+/* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License, version 2.0, for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
+
+#ifndef MYSQL_TRANSACTION_H
+#define MYSQL_TRANSACTION_H
+
+/**
+ @file mysql/psi/mysql_transaction.h
+ Instrumentation helpers for transactions.
+*/
+
+#include "mysql/psi/psi.h"
+
+#ifndef PSI_TRANSACTION_CALL
+#define PSI_TRANSACTION_CALL(M) PSI_DYNAMIC_CALL(M)
+#endif
+
+/**
+ @defgroup Transaction_instrumentation Transaction Instrumentation
+ @ingroup Instrumentation_interface
+ @{
+*/
+
+#ifdef HAVE_PSI_TRANSACTION_INTERFACE
+ #define MYSQL_START_TRANSACTION(STATE, XID, TRXID, ISO, RO, AC) \
+ inline_mysql_start_transaction(STATE, XID, TRXID, ISO, RO, AC, __FILE__, __LINE__)
+#else
+ #define MYSQL_START_TRANSACTION(STATE, XID, TRXID, ISO, RO, AC) \
+ 0
+#endif
+
+#ifdef HAVE_PSI_TRANSACTION_INTERFACE
+ #define MYSQL_SET_TRANSACTION_GTID(LOCKER, P1, P2) \
+ inline_mysql_set_transaction_gtid(LOCKER, P1, P2)
+#else
+ #define MYSQL_SET_TRANSACTION_GTID(LOCKER, P1, P2) \
+ do {} while (0)
+#endif
+
+#ifdef HAVE_PSI_TRANSACTION_INTERFACE
+ #define MYSQL_SET_TRANSACTION_XID(LOCKER, P1, P2) \
+ inline_mysql_set_transaction_xid(LOCKER, P1, P2)
+#else
+ #define MYSQL_SET_TRANSACTION_XID(LOCKER, P1, P2) \
+ do {} while (0)
+#endif
+
+#ifdef HAVE_PSI_TRANSACTION_INTERFACE
+ #define MYSQL_SET_TRANSACTION_XA_STATE(LOCKER, P1) \
+ inline_mysql_set_transaction_xa_state(LOCKER, P1)
+#else
+ #define MYSQL_SET_TRANSACTION_XA_STATE(LOCKER, P1) \
+ do {} while (0)
+#endif
+
+#ifdef HAVE_PSI_TRANSACTION_INTERFACE
+ #define MYSQL_SET_TRANSACTION_TRXID(LOCKER, P1) \
+ inline_mysql_set_transaction_trxid(LOCKER, P1)
+#else
+ #define MYSQL_SET_TRANSACTION_TRXID(LOCKER, P1) \
+ do {} while (0)
+#endif
+
+#ifdef HAVE_PSI_TRANSACTION_INTERFACE
+ #define MYSQL_INC_TRANSACTION_SAVEPOINTS(LOCKER, P1) \
+ inline_mysql_inc_transaction_savepoints(LOCKER, P1)
+#else
+ #define MYSQL_INC_TRANSACTION_SAVEPOINTS(LOCKER, P1) \
+ do {} while (0)
+#endif
+
+#ifdef HAVE_PSI_TRANSACTION_INTERFACE
+ #define MYSQL_INC_TRANSACTION_ROLLBACK_TO_SAVEPOINT(LOCKER, P1) \
+ inline_mysql_inc_transaction_rollback_to_savepoint(LOCKER, P1)
+#else
+ #define MYSQL_INC_TRANSACTION_ROLLBACK_TO_SAVEPOINT(LOCKER, P1) \
+ do {} while (0)
+#endif
+
+#ifdef HAVE_PSI_TRANSACTION_INTERFACE
+ #define MYSQL_INC_TRANSACTION_RELEASE_SAVEPOINT(LOCKER, P1) \
+ inline_mysql_inc_transaction_release_savepoint(LOCKER, P1)
+#else
+ #define MYSQL_INC_TRANSACTION_RELEASE_SAVEPOINT(LOCKER, P1) \
+ do {} while (0)
+#endif
+
+#ifdef HAVE_PSI_TRANSACTION_INTERFACE
+ #define MYSQL_ROLLBACK_TRANSACTION(LOCKER) \
+ inline_mysql_rollback_transaction(LOCKER)
+#else
+ #define MYSQL_ROLLBACK_TRANSACTION(LOCKER) \
+ do { } while(0)
+#endif
+
+#ifdef HAVE_PSI_TRANSACTION_INTERFACE
+ #define MYSQL_COMMIT_TRANSACTION(LOCKER) \
+ inline_mysql_commit_transaction(LOCKER)
+#else
+ #define MYSQL_COMMIT_TRANSACTION(LOCKER) \
+ do { } while(0)
+#endif
+
+#ifdef HAVE_PSI_TRANSACTION_INTERFACE
+static inline struct PSI_transaction_locker *
+inline_mysql_start_transaction(PSI_transaction_locker_state *state,
+ const void *xid,
+ ulonglong trxid,
+ int isolation_level,
+ my_bool read_only,
+ my_bool autocommit,
+ const char *src_file, int src_line)
+{
+ PSI_transaction_locker *locker;
+ locker= PSI_TRANSACTION_CALL(get_thread_transaction_locker)(state,
+ xid, trxid,
+ isolation_level,
+ read_only,
+ autocommit);
+ if (likely(locker != NULL))
+ PSI_TRANSACTION_CALL(start_transaction)(locker, src_file, src_line);
+ return locker;
+}
+
+static inline void
+inline_mysql_set_transaction_gtid(PSI_transaction_locker *locker,
+ const void *sid,
+ const void *gtid_spec)
+{
+ if (likely(locker != NULL))
+ PSI_TRANSACTION_CALL(set_transaction_gtid)(locker, sid, gtid_spec);
+}
+
+static inline void
+inline_mysql_set_transaction_xid(PSI_transaction_locker *locker,
+ const void *xid,
+ int xa_state)
+{
+ if (likely(locker != NULL))
+ PSI_TRANSACTION_CALL(set_transaction_xid)(locker, xid, xa_state);
+}
+
+static inline void
+inline_mysql_set_transaction_xa_state(PSI_transaction_locker *locker,
+ int xa_state)
+{
+ if (likely(locker != NULL))
+ PSI_TRANSACTION_CALL(set_transaction_xa_state)(locker, xa_state);
+}
+
+static inline void
+inline_mysql_set_transaction_trxid(PSI_transaction_locker *locker,
+ const ulonglong *trxid)
+{
+ if (likely(locker != NULL))
+ PSI_TRANSACTION_CALL(set_transaction_trxid)(locker, trxid);
+}
+
+static inline void
+inline_mysql_inc_transaction_savepoints(PSI_transaction_locker *locker,
+ ulong count)
+{
+ if (likely(locker != NULL))
+ PSI_TRANSACTION_CALL(inc_transaction_savepoints)(locker, count);
+}
+
+static inline void
+inline_mysql_inc_transaction_rollback_to_savepoint(PSI_transaction_locker *locker,
+ ulong count)
+{
+ if (likely(locker != NULL))
+ PSI_TRANSACTION_CALL(inc_transaction_rollback_to_savepoint)(locker, count);
+}
+
+static inline void
+inline_mysql_inc_transaction_release_savepoint(PSI_transaction_locker *locker,
+ ulong count)
+{
+ if (likely(locker != NULL))
+ PSI_TRANSACTION_CALL(inc_transaction_release_savepoint)(locker, count);
+}
+
+static inline void
+inline_mysql_rollback_transaction(struct PSI_transaction_locker *locker)
+{
+ if (likely(locker != NULL))
+ PSI_TRANSACTION_CALL(end_transaction)(locker, false);
+}
+
+static inline void
+inline_mysql_commit_transaction(struct PSI_transaction_locker *locker)
+{
+ if (likely(locker != NULL))
+ PSI_TRANSACTION_CALL(end_transaction)(locker, true);
+}
+#endif
+
+/** @} (end of group Transaction_instrumentation) */
+
+#endif
+
diff --git a/include/mysql/psi/psi.h b/include/mysql/psi/psi.h
new file mode 100644
index 00000000..958a086f
--- /dev/null
+++ b/include/mysql/psi/psi.h
@@ -0,0 +1,3028 @@
+/* Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License, version 2.0, for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */
+
+#ifndef MYSQL_PERFORMANCE_SCHEMA_INTERFACE_H
+#define MYSQL_PERFORMANCE_SCHEMA_INTERFACE_H
+
+#ifndef MY_GLOBAL_INCLUDED
+/*
+ Make sure a .c or .cc file contains an include to my_global.h first.
+ When this include is missing, all the #ifdef HAVE_XXX have no effect,
+ and the resulting binary won't build, or won't link,
+ or will crash at runtime
+ since various structures will have different binary definitions.
+*/
+#error "You must include my_global.h in the code for the build to be correct."
+#endif
+
+/*
+ If PSI_ON_BY_DFAULT is defined, assume PSI will be enabled by default and
+ optimize jumps testing for PSI this case. If not, optimize the binary for
+ that PSI is not enabled
+*/
+
+#ifdef PSI_ON_BY_DEFAULT
+#define psi_likely(A) likely(A)
+#define psi_unlikely(A) unlikely(A)
+#else
+#define psi_likely(A) unlikely(A)
+#define psi_unlikely(A) likely(A)
+#endif
+
+#include "psi_base.h"
+#include "psi_memory.h"
+
+#ifdef _WIN32
+typedef struct thread_attr pthread_attr_t;
+typedef DWORD pthread_t;
+typedef DWORD pthread_key_t;
+#endif
+
+/*
+ MAINTAINER:
+ The following pattern:
+ typedef struct XYZ XYZ;
+ is not needed in C++, but required for C.
+*/
+
+C_MODE_START
+
+/** @sa MDL_key. */
+struct MDL_key;
+typedef struct MDL_key MDL_key;
+
+/** @sa enum_mdl_type. */
+typedef int opaque_mdl_type;
+
+/** @sa enum_mdl_duration. */
+typedef int opaque_mdl_duration;
+
+/** @sa MDL_wait::enum_wait_status. */
+typedef int opaque_mdl_status;
+
+/** @sa enum_vio_type. */
+typedef int opaque_vio_type;
+
+struct TABLE_SHARE;
+
+struct sql_digest_storage;
+
+#ifdef __cplusplus
+ class THD;
+#else
+ /*
+ Phony declaration when compiling C code.
+ This is ok, because the C code will never have a THD anyway.
+ */
+ struct opaque_THD
+ {
+ int dummy;
+ };
+ typedef struct opaque_THD THD;
+#endif
+
+/**
+ @file mysql/psi/psi.h
+ Performance schema instrumentation interface.
+
+ @defgroup Instrumentation_interface Instrumentation Interface
+ @ingroup Performance_schema
+ @{
+*/
+
+/**
+ Interface for an instrumented mutex.
+ This is an opaque structure.
+*/
+struct PSI_mutex;
+typedef struct PSI_mutex PSI_mutex;
+
+/**
+ Interface for an instrumented rwlock.
+ This is an opaque structure.
+*/
+struct PSI_rwlock;
+typedef struct PSI_rwlock PSI_rwlock;
+
+/**
+ Interface for an instrumented condition.
+ This is an opaque structure.
+*/
+struct PSI_cond;
+typedef struct PSI_cond PSI_cond;
+
+/**
+ Interface for an instrumented table share.
+ This is an opaque structure.
+*/
+struct PSI_table_share;
+typedef struct PSI_table_share PSI_table_share;
+
+/**
+ Interface for an instrumented table handle.
+ This is an opaque structure.
+*/
+struct PSI_table;
+typedef struct PSI_table PSI_table;
+
+/**
+ Interface for an instrumented thread.
+ This is an opaque structure.
+*/
+struct PSI_thread;
+typedef struct PSI_thread PSI_thread;
+
+/**
+ Interface for an instrumented file handle.
+ This is an opaque structure.
+*/
+struct PSI_file;
+typedef struct PSI_file PSI_file;
+
+/**
+ Interface for an instrumented socket descriptor.
+ This is an opaque structure.
+*/
+struct PSI_socket;
+typedef struct PSI_socket PSI_socket;
+
+/**
+ Interface for an instrumented prepared statement.
+ This is an opaque structure.
+*/
+struct PSI_prepared_stmt;
+typedef struct PSI_prepared_stmt PSI_prepared_stmt;
+
+/**
+ Interface for an instrumented table operation.
+ This is an opaque structure.
+*/
+struct PSI_table_locker;
+typedef struct PSI_table_locker PSI_table_locker;
+
+/**
+ Interface for an instrumented statement.
+ This is an opaque structure.
+*/
+struct PSI_statement_locker;
+typedef struct PSI_statement_locker PSI_statement_locker;
+
+/**
+ Interface for an instrumented transaction.
+ This is an opaque structure.
+*/
+struct PSI_transaction_locker;
+typedef struct PSI_transaction_locker PSI_transaction_locker;
+
+/**
+ Interface for an instrumented idle operation.
+ This is an opaque structure.
+*/
+struct PSI_idle_locker;
+typedef struct PSI_idle_locker PSI_idle_locker;
+
+/**
+ Interface for an instrumented statement digest operation.
+ This is an opaque structure.
+*/
+struct PSI_digest_locker;
+typedef struct PSI_digest_locker PSI_digest_locker;
+
+/**
+ Interface for an instrumented stored procedure share.
+ This is an opaque structure.
+*/
+struct PSI_sp_share;
+typedef struct PSI_sp_share PSI_sp_share;
+
+/**
+ Interface for an instrumented stored program.
+ This is an opaque structure.
+*/
+struct PSI_sp_locker;
+typedef struct PSI_sp_locker PSI_sp_locker;
+
+/**
+ Interface for an instrumented metadata lock.
+ This is an opaque structure.
+*/
+struct PSI_metadata_lock;
+typedef struct PSI_metadata_lock PSI_metadata_lock;
+
+/**
+ Interface for an instrumented stage progress.
+ This is a public structure, for efficiency.
+*/
+struct PSI_stage_progress
+{
+ ulonglong m_work_completed;
+ ulonglong m_work_estimated;
+};
+typedef struct PSI_stage_progress PSI_stage_progress;
+
+/** IO operation performed on an instrumented table. */
+enum PSI_table_io_operation
+{
+ /** Row fetch. */
+ PSI_TABLE_FETCH_ROW= 0,
+ /** Row write. */
+ PSI_TABLE_WRITE_ROW= 1,
+ /** Row update. */
+ PSI_TABLE_UPDATE_ROW= 2,
+ /** Row delete. */
+ PSI_TABLE_DELETE_ROW= 3
+};
+typedef enum PSI_table_io_operation PSI_table_io_operation;
+
+/**
+ State data storage for @c start_table_io_wait_v1_t,
+ @c start_table_lock_wait_v1_t.
+ This structure provide temporary storage to a table locker.
+ The content of this structure is considered opaque,
+ the fields are only hints of what an implementation
+ of the psi interface can use.
+ This memory is provided by the instrumented code for performance reasons.
+ @sa start_table_io_wait_v1_t
+ @sa start_table_lock_wait_v1_t
+*/
+struct PSI_table_locker_state
+{
+ /** Internal state. */
+ uint m_flags;
+ /** Current io operation. */
+ enum PSI_table_io_operation m_io_operation;
+ /** Current table handle. */
+ struct PSI_table *m_table;
+ /** Current table share. */
+ struct PSI_table_share *m_table_share;
+ /** Current thread. */
+ struct PSI_thread *m_thread;
+ /** Timer start. */
+ ulonglong m_timer_start;
+ /** Timer function. */
+ ulonglong (*m_timer)(void);
+ /** Internal data. */
+ void *m_wait;
+ /**
+ Implementation specific.
+ For table io, the table io index.
+ For table lock, the lock type.
+ */
+ uint m_index;
+};
+typedef struct PSI_table_locker_state PSI_table_locker_state;
+
+/** Entry point for the performance schema interface. */
+struct PSI_bootstrap
+{
+ /**
+ ABI interface finder.
+ Calling this method with an interface version number returns either
+ an instance of the ABI for this version, or NULL.
+ @param version the interface version number to find
+ @return a versioned interface (PSI_v1, PSI_v2 or PSI)
+ @sa PSI_VERSION_1
+ @sa PSI_v1
+ @sa PSI_VERSION_2
+ @sa PSI_v2
+ @sa PSI_CURRENT_VERSION
+ @sa PSI
+ */
+ void* (*get_interface)(int version);
+};
+typedef struct PSI_bootstrap PSI_bootstrap;
+
+#ifdef HAVE_PSI_INTERFACE
+
+#ifdef DISABLE_ALL_PSI
+
+#ifndef DISABLE_PSI_THREAD
+#define DISABLE_PSI_THREAD
+#endif
+
+#ifndef DISABLE_PSI_MUTEX
+#define DISABLE_PSI_MUTEX
+#endif
+
+#ifndef DISABLE_PSI_RWLOCK
+#define DISABLE_PSI_RWLOCK
+#endif
+
+#ifndef DISABLE_PSI_COND
+#define DISABLE_PSI_COND
+#endif
+
+#ifndef DISABLE_PSI_FILE
+#define DISABLE_PSI_FILE
+#endif
+
+#ifndef DISABLE_PSI_TABLE
+#define DISABLE_PSI_TABLE
+#endif
+
+#ifndef DISABLE_PSI_SOCKET
+#define DISABLE_PSI_SOCKET
+#endif
+
+#ifndef DISABLE_PSI_STAGE
+#define DISABLE_PSI_STAGE
+#endif
+
+#ifndef DISABLE_PSI_STATEMENT
+#define DISABLE_PSI_STATEMENT
+#endif
+
+#ifndef DISABLE_PSI_SP
+#define DISABLE_PSI_SP
+#endif
+
+#ifndef DISABLE_PSI_IDLE
+#define DISABLE_PSI_IDLE
+#endif
+
+#ifndef DISABLE_PSI_STATEMENT_DIGEST
+#define DISABLE_PSI_STATEMENT_DIGEST
+#endif
+
+#ifndef DISABLE_PSI_METADATA
+#define DISABLE_PSI_METADATA
+#endif
+
+#ifndef DISABLE_PSI_MEMORY
+#define DISABLE_PSI_MEMORY
+#endif
+
+#ifndef DISABLE_PSI_TRANSACTION
+#define DISABLE_PSI_TRANSACTION
+#endif
+
+#ifndef DISABLE_PSI_SP
+#define DISABLE_PSI_SP
+#endif
+
+#ifndef DISABLE_PSI_PS
+#define DISABLE_PSI_PS
+#endif
+
+#endif
+
+/**
+ @def DISABLE_PSI_MUTEX
+ Compiling option to disable the mutex instrumentation.
+ This option is mostly intended to be used during development,
+ when doing special builds with only a subset of the performance schema instrumentation,
+ for code analysis / profiling / performance tuning of a specific instrumentation alone.
+ @sa DISABLE_PSI_RWLOCK
+ @sa DISABLE_PSI_COND
+ @sa DISABLE_PSI_FILE
+ @sa DISABLE_PSI_THREAD
+ @sa DISABLE_PSI_TABLE
+ @sa DISABLE_PSI_STAGE
+ @sa DISABLE_PSI_STATEMENT
+ @sa DISABLE_PSI_SP
+ @sa DISABLE_PSI_STATEMENT_DIGEST
+ @sa DISABLE_PSI_SOCKET
+ @sa DISABLE_PSI_MEMORY
+ @sa DISABLE_PSI_IDLE
+ @sa DISABLE_PSI_METADATA
+ @sa DISABLE PSI_TRANSACTION
+*/
+
+#ifndef DISABLE_PSI_MUTEX
+#define HAVE_PSI_MUTEX_INTERFACE
+#endif
+
+/**
+ @def DISABLE_PSI_RWLOCK
+ Compiling option to disable the rwlock instrumentation.
+ @sa DISABLE_PSI_MUTEX
+*/
+
+#ifndef DISABLE_PSI_RWLOCK
+#define HAVE_PSI_RWLOCK_INTERFACE
+#endif
+
+/**
+ @def DISABLE_PSI_COND
+ Compiling option to disable the cond instrumentation.
+ @sa DISABLE_PSI_MUTEX
+*/
+
+#ifndef DISABLE_PSI_COND
+#define HAVE_PSI_COND_INTERFACE
+#endif
+
+/**
+ @def DISABLE_PSI_FILE
+ Compiling option to disable the file instrumentation.
+ @sa DISABLE_PSI_MUTEX
+*/
+
+#ifndef DISABLE_PSI_FILE
+#define HAVE_PSI_FILE_INTERFACE
+#endif
+
+/**
+ @def DISABLE_PSI_THREAD
+ Compiling option to disable the thread instrumentation.
+ @sa DISABLE_PSI_MUTEX
+*/
+#ifndef DISABLE_PSI_THREAD
+#define HAVE_PSI_THREAD_INTERFACE
+#endif
+
+/**
+ @def DISABLE_PSI_TABLE
+ Compiling option to disable the table instrumentation.
+ @sa DISABLE_PSI_MUTEX
+*/
+
+#ifndef DISABLE_PSI_TABLE
+#define HAVE_PSI_TABLE_INTERFACE
+#endif
+
+/**
+ @def DISABLE_PSI_STAGE
+ Compiling option to disable the stage instrumentation.
+ @sa DISABLE_PSI_MUTEX
+*/
+
+#ifndef DISABLE_PSI_STAGE
+#define HAVE_PSI_STAGE_INTERFACE
+#endif
+
+/**
+ @def DISABLE_PSI_STATEMENT
+ Compiling option to disable the statement instrumentation.
+ @sa DISABLE_PSI_MUTEX
+*/
+
+#ifndef DISABLE_PSI_STATEMENT
+#define HAVE_PSI_STATEMENT_INTERFACE
+#endif
+
+/**
+ @def DISABLE_PSI_SP
+ Compiling option to disable the stored program instrumentation.
+ @sa DISABLE_PSI_MUTEX
+*/
+#ifndef DISABLE_PSI_SP
+#define HAVE_PSI_SP_INTERFACE
+#endif
+
+/**
+ @def DISABLE_PSI_PS
+ Compiling option to disable the prepared statement instrumentation.
+ @sa DISABLE_PSI_MUTEX
+*/
+#ifndef DISABLE_PSI_STATEMENT
+#ifndef DISABLE_PSI_PS
+#define HAVE_PSI_PS_INTERFACE
+#endif
+#endif
+
+/**
+ @def DISABLE_PSI_STATEMENT_DIGEST
+ Compiling option to disable the statement digest instrumentation.
+*/
+
+#ifndef DISABLE_PSI_STATEMENT
+#ifndef DISABLE_PSI_STATEMENT_DIGEST
+#define HAVE_PSI_STATEMENT_DIGEST_INTERFACE
+#endif
+#endif
+
+/**
+ @def DISABLE_PSI_TRANSACTION
+ Compiling option to disable the transaction instrumentation.
+ @sa DISABLE_PSI_MUTEX
+*/
+
+#ifndef DISABLE_PSI_TRANSACTION
+#define HAVE_PSI_TRANSACTION_INTERFACE
+#endif
+
+/**
+ @def DISABLE_PSI_SOCKET
+ Compiling option to disable the statement instrumentation.
+ @sa DISABLE_PSI_MUTEX
+*/
+
+#ifndef DISABLE_PSI_SOCKET
+#define HAVE_PSI_SOCKET_INTERFACE
+#endif
+
+/**
+ @def DISABLE_PSI_MEMORY
+ Compiling option to disable the memory instrumentation.
+ @sa DISABLE_PSI_MUTEX
+*/
+
+#ifndef DISABLE_PSI_MEMORY
+#define HAVE_PSI_MEMORY_INTERFACE
+#endif
+
+/**
+ @def DISABLE_PSI_IDLE
+ Compiling option to disable the idle instrumentation.
+ @sa DISABLE_PSI_MUTEX
+*/
+
+#ifndef DISABLE_PSI_IDLE
+#define HAVE_PSI_IDLE_INTERFACE
+#endif
+
+/**
+ @def DISABLE_PSI_METADATA
+ Compiling option to disable the metadata instrumentation.
+ @sa DISABLE_PSI_MUTEX
+*/
+
+#ifndef DISABLE_PSI_METADATA
+#define HAVE_PSI_METADATA_INTERFACE
+#endif
+
+/**
+ @def PSI_VERSION_1
+ Performance Schema Interface number for version 1.
+ This version is supported.
+*/
+#define PSI_VERSION_1 1
+
+/**
+ @def PSI_VERSION_2
+ Performance Schema Interface number for version 2.
+ This version is not implemented, it's a placeholder.
+*/
+#define PSI_VERSION_2 2
+
+/**
+ @def PSI_CURRENT_VERSION
+ Performance Schema Interface number for the most recent version.
+ The most current version is @c PSI_VERSION_1
+*/
+#define PSI_CURRENT_VERSION 1
+
+#ifndef USE_PSI_2
+#ifndef USE_PSI_1
+#define USE_PSI_1
+#endif
+#endif
+
+/**
+ Interface for an instrumented mutex operation.
+ This is an opaque structure.
+*/
+struct PSI_mutex_locker;
+typedef struct PSI_mutex_locker PSI_mutex_locker;
+
+/**
+ Interface for an instrumented rwlock operation.
+ This is an opaque structure.
+*/
+struct PSI_rwlock_locker;
+typedef struct PSI_rwlock_locker PSI_rwlock_locker;
+
+/**
+ Interface for an instrumented condition operation.
+ This is an opaque structure.
+*/
+struct PSI_cond_locker;
+typedef struct PSI_cond_locker PSI_cond_locker;
+
+/**
+ Interface for an instrumented file operation.
+ This is an opaque structure.
+*/
+struct PSI_file_locker;
+typedef struct PSI_file_locker PSI_file_locker;
+
+/**
+ Interface for an instrumented socket operation.
+ This is an opaque structure.
+*/
+struct PSI_socket_locker;
+typedef struct PSI_socket_locker PSI_socket_locker;
+
+/**
+ Interface for an instrumented MDL operation.
+ This is an opaque structure.
+*/
+struct PSI_metadata_locker;
+typedef struct PSI_metadata_locker PSI_metadata_locker;
+
+/** Operation performed on an instrumented mutex. */
+enum PSI_mutex_operation
+{
+ /** Lock. */
+ PSI_MUTEX_LOCK= 0,
+ /** Lock attempt. */
+ PSI_MUTEX_TRYLOCK= 1
+};
+typedef enum PSI_mutex_operation PSI_mutex_operation;
+
+/**
+ Operation performed on an instrumented rwlock.
+ For basic READ / WRITE lock,
+ operations are "READ" or "WRITE".
+ For SX-locks, operations are "SHARED", "SHARED-EXCLUSIVE" or "EXCLUSIVE".
+*/
+enum PSI_rwlock_operation
+{
+ /** Read lock. */
+ PSI_RWLOCK_READLOCK= 0,
+ /** Write lock. */
+ PSI_RWLOCK_WRITELOCK= 1,
+ /** Read lock attempt. */
+ PSI_RWLOCK_TRYREADLOCK= 2,
+ /** Write lock attempt. */
+ PSI_RWLOCK_TRYWRITELOCK= 3,
+
+ /** Shared lock. */
+ PSI_RWLOCK_SHAREDLOCK= 4,
+ /** Shared Exclusive lock. */
+ PSI_RWLOCK_SHAREDEXCLUSIVELOCK= 5,
+ /** Exclusive lock. */
+ PSI_RWLOCK_EXCLUSIVELOCK= 6,
+ /** Shared lock attempt. */
+ PSI_RWLOCK_TRYSHAREDLOCK= 7,
+ /** Shared Exclusive lock attempt. */
+ PSI_RWLOCK_TRYSHAREDEXCLUSIVELOCK= 8,
+ /** Exclusive lock attempt. */
+ PSI_RWLOCK_TRYEXCLUSIVELOCK= 9
+
+};
+typedef enum PSI_rwlock_operation PSI_rwlock_operation;
+
+/** Operation performed on an instrumented condition. */
+enum PSI_cond_operation
+{
+ /** Wait. */
+ PSI_COND_WAIT= 0,
+ /** Wait, with timeout. */
+ PSI_COND_TIMEDWAIT= 1
+};
+typedef enum PSI_cond_operation PSI_cond_operation;
+
+/** Operation performed on an instrumented file. */
+enum PSI_file_operation
+{
+ /** File creation, as in @c create(). */
+ PSI_FILE_CREATE= 0,
+ /** Temporary file creation, as in @c create_temp_file(). */
+ PSI_FILE_CREATE_TMP= 1,
+ /** File open, as in @c open(). */
+ PSI_FILE_OPEN= 2,
+ /** File open, as in @c fopen(). */
+ PSI_FILE_STREAM_OPEN= 3,
+ /** File close, as in @c close(). */
+ PSI_FILE_CLOSE= 4,
+ /** File close, as in @c fclose(). */
+ PSI_FILE_STREAM_CLOSE= 5,
+ /**
+ Generic file read, such as @c fgets(), @c fgetc(), @c fread(), @c read(),
+ @c pread().
+ */
+ PSI_FILE_READ= 6,
+ /**
+ Generic file write, such as @c fputs(), @c fputc(), @c fprintf(),
+ @c vfprintf(), @c fwrite(), @c write(), @c pwrite().
+ */
+ PSI_FILE_WRITE= 7,
+ /** Generic file seek, such as @c fseek() or @c seek(). */
+ PSI_FILE_SEEK= 8,
+ /** Generic file tell, such as @c ftell() or @c tell(). */
+ PSI_FILE_TELL= 9,
+ /** File flush, as in @c fflush(). */
+ PSI_FILE_FLUSH= 10,
+ /** File stat, as in @c stat(). */
+ PSI_FILE_STAT= 11,
+ /** File stat, as in @c fstat(). */
+ PSI_FILE_FSTAT= 12,
+ /** File chsize, as in @c my_chsize(). */
+ PSI_FILE_CHSIZE= 13,
+ /** File delete, such as @c my_delete() or @c my_handler_delete_with_symlink(). */
+ PSI_FILE_DELETE= 14,
+ /** File rename, such as @c my_rename() or @c my_rename_with_symlink(). */
+ PSI_FILE_RENAME= 15,
+ /** File sync, as in @c fsync() or @c my_sync(). */
+ PSI_FILE_SYNC= 16
+};
+typedef enum PSI_file_operation PSI_file_operation;
+
+/** Lock operation performed on an instrumented table. */
+enum PSI_table_lock_operation
+{
+ /** Table lock, in the server layer. */
+ PSI_TABLE_LOCK= 0,
+ /** Table lock, in the storage engine layer. */
+ PSI_TABLE_EXTERNAL_LOCK= 1
+};
+typedef enum PSI_table_lock_operation PSI_table_lock_operation;
+
+/** State of an instrumented socket. */
+enum PSI_socket_state
+{
+ /** Idle, waiting for the next command. */
+ PSI_SOCKET_STATE_IDLE= 1,
+ /** Active, executing a command. */
+ PSI_SOCKET_STATE_ACTIVE= 2
+};
+typedef enum PSI_socket_state PSI_socket_state;
+
+/** Operation performed on an instrumented socket. */
+enum PSI_socket_operation
+{
+ /** Socket creation, as in @c socket() or @c socketpair(). */
+ PSI_SOCKET_CREATE= 0,
+ /** Socket connection, as in @c connect(), @c listen() and @c accept(). */
+ PSI_SOCKET_CONNECT= 1,
+ /** Socket bind, as in @c bind(), @c getsockname() and @c getpeername(). */
+ PSI_SOCKET_BIND= 2,
+ /** Socket close, as in @c shutdown(). */
+ PSI_SOCKET_CLOSE= 3,
+ /** Socket send, @c send(). */
+ PSI_SOCKET_SEND= 4,
+ /** Socket receive, @c recv(). */
+ PSI_SOCKET_RECV= 5,
+ /** Socket send, @c sendto(). */
+ PSI_SOCKET_SENDTO= 6,
+ /** Socket receive, @c recvfrom). */
+ PSI_SOCKET_RECVFROM= 7,
+ /** Socket send, @c sendmsg(). */
+ PSI_SOCKET_SENDMSG= 8,
+ /** Socket receive, @c recvmsg(). */
+ PSI_SOCKET_RECVMSG= 9,
+ /** Socket seek, such as @c fseek() or @c seek(). */
+ PSI_SOCKET_SEEK= 10,
+ /** Socket options, as in @c getsockopt() and @c setsockopt(). */
+ PSI_SOCKET_OPT= 11,
+ /** Socket status, as in @c sockatmark() and @c isfdtype(). */
+ PSI_SOCKET_STAT= 12,
+ /** Socket shutdown, as in @c shutdown(). */
+ PSI_SOCKET_SHUTDOWN= 13,
+ /** Socket select, as in @c select() and @c poll(). */
+ PSI_SOCKET_SELECT= 14
+};
+typedef enum PSI_socket_operation PSI_socket_operation;
+
+#endif
+/**
+ Instrumented mutex key.
+ To instrument a mutex, a mutex key must be obtained using @c register_mutex.
+ Using a zero key always disable the instrumentation.
+*/
+typedef unsigned int PSI_mutex_key;
+
+/**
+ Instrumented rwlock key.
+ To instrument a rwlock, a rwlock key must be obtained
+ using @c register_rwlock.
+ Using a zero key always disable the instrumentation.
+*/
+typedef unsigned int PSI_rwlock_key;
+
+/**
+ Instrumented cond key.
+ To instrument a condition, a condition key must be obtained
+ using @c register_cond.
+ Using a zero key always disable the instrumentation.
+*/
+typedef unsigned int PSI_cond_key;
+
+/**
+ Instrumented thread key.
+ To instrument a thread, a thread key must be obtained
+ using @c register_thread.
+ Using a zero key always disable the instrumentation.
+*/
+typedef unsigned int PSI_thread_key;
+
+/**
+ Instrumented file key.
+ To instrument a file, a file key must be obtained using @c register_file.
+ Using a zero key always disable the instrumentation.
+*/
+typedef unsigned int PSI_file_key;
+
+/**
+ Instrumented stage key.
+ To instrument a stage, a stage key must be obtained using @c register_stage.
+ Using a zero key always disable the instrumentation.
+*/
+typedef unsigned int PSI_stage_key;
+
+/**
+ Instrumented statement key.
+ To instrument a statement, a statement key must be obtained using @c register_statement.
+ Using a zero key always disable the instrumentation.
+*/
+typedef unsigned int PSI_statement_key;
+
+/**
+ Instrumented socket key.
+ To instrument a socket, a socket key must be obtained using @c register_socket.
+ Using a zero key always disable the instrumentation.
+*/
+typedef unsigned int PSI_socket_key;
+
+#ifdef HAVE_PSI_1
+
+/**
+ @defgroup Group_PSI_v1 Application Binary Interface, version 1
+ @ingroup Instrumentation_interface
+ @{
+*/
+
+/**
+ Mutex information.
+ @since PSI_VERSION_1
+ This structure is used to register an instrumented mutex.
+*/
+struct PSI_mutex_info_v1
+{
+ /**
+ Pointer to the key assigned to the registered mutex.
+ */
+ PSI_mutex_key *m_key;
+ /**
+ The name of the mutex to register.
+ */
+ const char *m_name;
+ /**
+ The flags of the mutex to register.
+ @sa PSI_FLAG_GLOBAL
+ */
+ int m_flags;
+};
+typedef struct PSI_mutex_info_v1 PSI_mutex_info_v1;
+
+/**
+ Rwlock information.
+ @since PSI_VERSION_1
+ This structure is used to register an instrumented rwlock.
+*/
+struct PSI_rwlock_info_v1
+{
+ /**
+ Pointer to the key assigned to the registered rwlock.
+ */
+ PSI_rwlock_key *m_key;
+ /**
+ The name of the rwlock to register.
+ */
+ const char *m_name;
+ /**
+ The flags of the rwlock to register.
+ @sa PSI_FLAG_GLOBAL
+ */
+ int m_flags;
+};
+typedef struct PSI_rwlock_info_v1 PSI_rwlock_info_v1;
+
+/**
+ Condition information.
+ @since PSI_VERSION_1
+ This structure is used to register an instrumented cond.
+*/
+struct PSI_cond_info_v1
+{
+ /**
+ Pointer to the key assigned to the registered cond.
+ */
+ PSI_cond_key *m_key;
+ /**
+ The name of the cond to register.
+ */
+ const char *m_name;
+ /**
+ The flags of the cond to register.
+ @sa PSI_FLAG_GLOBAL
+ */
+ int m_flags;
+};
+typedef struct PSI_cond_info_v1 PSI_cond_info_v1;
+
+/**
+ Thread instrument information.
+ @since PSI_VERSION_1
+ This structure is used to register an instrumented thread.
+*/
+struct PSI_thread_info_v1
+{
+ /**
+ Pointer to the key assigned to the registered thread.
+ */
+ PSI_thread_key *m_key;
+ /**
+ The name of the thread instrument to register.
+ */
+ const char *m_name;
+ /**
+ The flags of the thread to register.
+ @sa PSI_FLAG_GLOBAL
+ */
+ int m_flags;
+};
+typedef struct PSI_thread_info_v1 PSI_thread_info_v1;
+
+/**
+ File instrument information.
+ @since PSI_VERSION_1
+ This structure is used to register an instrumented file.
+*/
+struct PSI_file_info_v1
+{
+ /**
+ Pointer to the key assigned to the registered file.
+ */
+ PSI_file_key *m_key;
+ /**
+ The name of the file instrument to register.
+ */
+ const char *m_name;
+ /**
+ The flags of the file instrument to register.
+ @sa PSI_FLAG_GLOBAL
+ */
+ int m_flags;
+};
+typedef struct PSI_file_info_v1 PSI_file_info_v1;
+
+/**
+ Stage instrument information.
+ @since PSI_VERSION_1
+ This structure is used to register an instrumented stage.
+*/
+struct PSI_stage_info_v1
+{
+ /** The registered stage key. */
+ PSI_stage_key m_key;
+ /** The name of the stage instrument to register. */
+ const char *m_name;
+ /** The flags of the stage instrument to register. */
+ int m_flags;
+};
+typedef struct PSI_stage_info_v1 PSI_stage_info_v1;
+
+/**
+ Statement instrument information.
+ @since PSI_VERSION_1
+ This structure is used to register an instrumented statement.
+*/
+struct PSI_statement_info_v1
+{
+ /** The registered statement key. */
+ PSI_statement_key m_key;
+ /** The name of the statement instrument to register. */
+ const char *m_name;
+ /** The flags of the statement instrument to register. */
+ int m_flags;
+};
+typedef struct PSI_statement_info_v1 PSI_statement_info_v1;
+
+/**
+ Socket instrument information.
+ @since PSI_VERSION_1
+ This structure is used to register an instrumented socket.
+*/
+struct PSI_socket_info_v1
+{
+ /**
+ Pointer to the key assigned to the registered socket.
+ */
+ PSI_socket_key *m_key;
+ /**
+ The name of the socket instrument to register.
+ */
+ const char *m_name;
+ /**
+ The flags of the socket instrument to register.
+ @sa PSI_FLAG_GLOBAL
+ */
+ int m_flags;
+};
+typedef struct PSI_socket_info_v1 PSI_socket_info_v1;
+
+/**
+ State data storage for @c start_idle_wait_v1_t.
+ This structure provide temporary storage to an idle locker.
+ The content of this structure is considered opaque,
+ the fields are only hints of what an implementation
+ of the psi interface can use.
+ This memory is provided by the instrumented code for performance reasons.
+ @sa start_idle_wait_v1_t.
+*/
+struct PSI_idle_locker_state_v1
+{
+ /** Internal state. */
+ uint m_flags;
+ /** Current thread. */
+ struct PSI_thread *m_thread;
+ /** Timer start. */
+ ulonglong m_timer_start;
+ /** Timer function. */
+ ulonglong (*m_timer)(void);
+ /** Internal data. */
+ void *m_wait;
+};
+typedef struct PSI_idle_locker_state_v1 PSI_idle_locker_state_v1;
+
+/**
+ State data storage for @c start_mutex_wait_v1_t.
+ This structure provide temporary storage to a mutex locker.
+ The content of this structure is considered opaque,
+ the fields are only hints of what an implementation
+ of the psi interface can use.
+ This memory is provided by the instrumented code for performance reasons.
+ @sa start_mutex_wait_v1_t
+*/
+struct PSI_mutex_locker_state_v1
+{
+ /** Internal state. */
+ uint m_flags;
+ /** Current operation. */
+ enum PSI_mutex_operation m_operation;
+ /** Current mutex. */
+ struct PSI_mutex *m_mutex;
+ /** Current thread. */
+ struct PSI_thread *m_thread;
+ /** Timer start. */
+ ulonglong m_timer_start;
+ /** Timer function. */
+ ulonglong (*m_timer)(void);
+ /** Internal data. */
+ void *m_wait;
+};
+typedef struct PSI_mutex_locker_state_v1 PSI_mutex_locker_state_v1;
+
+/**
+ State data storage for @c start_rwlock_rdwait_v1_t, @c start_rwlock_wrwait_v1_t.
+ This structure provide temporary storage to a rwlock locker.
+ The content of this structure is considered opaque,
+ the fields are only hints of what an implementation
+ of the psi interface can use.
+ This memory is provided by the instrumented code for performance reasons.
+ @sa start_rwlock_rdwait_v1_t
+ @sa start_rwlock_wrwait_v1_t
+*/
+struct PSI_rwlock_locker_state_v1
+{
+ /** Internal state. */
+ uint m_flags;
+ /** Current operation. */
+ enum PSI_rwlock_operation m_operation;
+ /** Current rwlock. */
+ struct PSI_rwlock *m_rwlock;
+ /** Current thread. */
+ struct PSI_thread *m_thread;
+ /** Timer start. */
+ ulonglong m_timer_start;
+ /** Timer function. */
+ ulonglong (*m_timer)(void);
+ /** Internal data. */
+ void *m_wait;
+};
+typedef struct PSI_rwlock_locker_state_v1 PSI_rwlock_locker_state_v1;
+
+/**
+ State data storage for @c start_cond_wait_v1_t.
+ This structure provide temporary storage to a condition locker.
+ The content of this structure is considered opaque,
+ the fields are only hints of what an implementation
+ of the psi interface can use.
+ This memory is provided by the instrumented code for performance reasons.
+ @sa start_cond_wait_v1_t
+*/
+struct PSI_cond_locker_state_v1
+{
+ /** Internal state. */
+ uint m_flags;
+ /** Current operation. */
+ enum PSI_cond_operation m_operation;
+ /** Current condition. */
+ struct PSI_cond *m_cond;
+ /** Current mutex. */
+ struct PSI_mutex *m_mutex;
+ /** Current thread. */
+ struct PSI_thread *m_thread;
+ /** Timer start. */
+ ulonglong m_timer_start;
+ /** Timer function. */
+ ulonglong (*m_timer)(void);
+ /** Internal data. */
+ void *m_wait;
+};
+typedef struct PSI_cond_locker_state_v1 PSI_cond_locker_state_v1;
+
+/**
+ State data storage for @c get_thread_file_name_locker_v1_t.
+ This structure provide temporary storage to a file locker.
+ The content of this structure is considered opaque,
+ the fields are only hints of what an implementation
+ of the psi interface can use.
+ This memory is provided by the instrumented code for performance reasons.
+ @sa get_thread_file_name_locker_v1_t
+ @sa get_thread_file_stream_locker_v1_t
+ @sa get_thread_file_descriptor_locker_v1_t
+*/
+struct PSI_file_locker_state_v1
+{
+ /** Internal state. */
+ uint m_flags;
+ /** Current operation. */
+ enum PSI_file_operation m_operation;
+ /** Current file. */
+ struct PSI_file *m_file;
+ /** Current file name. */
+ const char *m_name;
+ /** Current file class. */
+ void *m_class;
+ /** Current thread. */
+ struct PSI_thread *m_thread;
+ /** Operation number of bytes. */
+ size_t m_number_of_bytes;
+ /** Timer start. */
+ ulonglong m_timer_start;
+ /** Timer function. */
+ ulonglong (*m_timer)(void);
+ /** Internal data. */
+ void *m_wait;
+};
+typedef struct PSI_file_locker_state_v1 PSI_file_locker_state_v1;
+
+/**
+ State data storage for @c start_metadata_wait_v1_t.
+ This structure provide temporary storage to a metadata locker.
+ The content of this structure is considered opaque,
+ the fields are only hints of what an implementation
+ of the psi interface can use.
+ This memory is provided by the instrumented code for performance reasons.
+ @sa start_metadata_wait_v1_t
+*/
+struct PSI_metadata_locker_state_v1
+{
+ /** Internal state. */
+ uint m_flags;
+ /** Current metadata lock. */
+ struct PSI_metadata_lock *m_metadata_lock;
+ /** Current thread. */
+ struct PSI_thread *m_thread;
+ /** Timer start. */
+ ulonglong m_timer_start;
+ /** Timer function. */
+ ulonglong (*m_timer)(void);
+ /** Internal data. */
+ void *m_wait;
+};
+typedef struct PSI_metadata_locker_state_v1 PSI_metadata_locker_state_v1;
+
+/* Duplicate of NAME_LEN, to avoid dependency on mysql_com.h */
+#define PSI_SCHEMA_NAME_LEN (64 * 3)
+
+/**
+ State data storage for @c get_thread_statement_locker_v1_t,
+ @c get_thread_statement_locker_v1_t.
+ This structure provide temporary storage to a statement locker.
+ The content of this structure is considered opaque,
+ the fields are only hints of what an implementation
+ of the psi interface can use.
+ This memory is provided by the instrumented code for performance reasons.
+ @sa get_thread_statement_locker_v1_t
+*/
+struct PSI_statement_locker_state_v1
+{
+ /** Discarded flag. */
+ my_bool m_discarded;
+ /** In prepare flag. */
+ my_bool m_in_prepare;
+ /** Metric, no index used flag. */
+ uchar m_no_index_used;
+ /** Metric, no good index used flag. */
+ uchar m_no_good_index_used;
+ /** Internal state. */
+ uint m_flags;
+ /** Instrumentation class. */
+ void *m_class;
+ /** Current thread. */
+ struct PSI_thread *m_thread;
+ /** Timer start. */
+ ulonglong m_timer_start;
+ /** Timer function. */
+ ulonglong (*m_timer)(void);
+ /** Internal data. */
+ void *m_statement;
+ /** Locked time. */
+ ulonglong m_lock_time;
+ /** Rows sent. */
+ ulonglong m_rows_sent;
+ /** Rows examined. */
+ ulonglong m_rows_examined;
+ /** Metric, temporary tables created on disk. */
+ ulong m_created_tmp_disk_tables;
+ /** Metric, temporary tables created. */
+ ulong m_created_tmp_tables;
+ /** Metric, number of select full join. */
+ ulong m_select_full_join;
+ /** Metric, number of select full range join. */
+ ulong m_select_full_range_join;
+ /** Metric, number of select range. */
+ ulong m_select_range;
+ /** Metric, number of select range check. */
+ ulong m_select_range_check;
+ /** Metric, number of select scan. */
+ ulong m_select_scan;
+ /** Metric, number of sort merge passes. */
+ ulong m_sort_merge_passes;
+ /** Metric, number of sort merge. */
+ ulong m_sort_range;
+ /** Metric, number of sort rows. */
+ ulong m_sort_rows;
+ /** Metric, number of sort scans. */
+ ulong m_sort_scan;
+ /** Statement digest. */
+ const struct sql_digest_storage *m_digest;
+ /** Current schema name. */
+ char m_schema_name[PSI_SCHEMA_NAME_LEN];
+ /** Length in bytes of @c m_schema_name. */
+ uint m_schema_name_length;
+ /** Statement character set number. */
+ uint m_cs_number;
+ PSI_sp_share *m_parent_sp_share;
+ PSI_prepared_stmt *m_parent_prepared_stmt;
+};
+typedef struct PSI_statement_locker_state_v1 PSI_statement_locker_state_v1;
+
+/**
+ State data storage for @c get_thread_transaction_locker_v1_t,
+ @c get_thread_transaction_locker_v1_t.
+ This structure provide temporary storage to a transaction locker.
+ The content of this structure is considered opaque,
+ the fields are only hints of what an implementation
+ of the psi interface can use.
+ This memory is provided by the instrumented code for performance reasons.
+ @sa get_thread_transaction_locker_v1_t
+*/
+struct PSI_transaction_locker_state_v1
+{
+ /** Internal state. */
+ uint m_flags;
+ /** Instrumentation class. */
+ void *m_class;
+ /** Current thread. */
+ struct PSI_thread *m_thread;
+ /** Timer start. */
+ ulonglong m_timer_start;
+ /** Timer function. */
+ ulonglong (*m_timer)(void);
+ /** Internal data. */
+ void *m_transaction;
+ /** True if read-only transaction, false if read-write. */
+ my_bool m_read_only;
+ /** True if transaction is autocommit. */
+ my_bool m_autocommit;
+ /** Number of statements. */
+ ulong m_statement_count;
+ /** Total number of savepoints. */
+ ulong m_savepoint_count;
+ /** Number of rollback_to_savepoint. */
+ ulong m_rollback_to_savepoint_count;
+ /** Number of release_savepoint. */
+ ulong m_release_savepoint_count;
+};
+
+typedef struct PSI_transaction_locker_state_v1 PSI_transaction_locker_state_v1;
+
+/**
+ State data storage for @c start_socket_wait_v1_t.
+ This structure provide temporary storage to a socket locker.
+ The content of this structure is considered opaque,
+ the fields are only hints of what an implementation
+ of the psi interface can use.
+ This memory is provided by the instrumented code for performance reasons.
+ @sa start_socket_wait_v1_t
+*/
+struct PSI_socket_locker_state_v1
+{
+ /** Internal state. */
+ uint m_flags;
+ /** Current socket. */
+ struct PSI_socket *m_socket;
+ /** Current thread. */
+ struct PSI_thread *m_thread;
+ /** Operation number of bytes. */
+ size_t m_number_of_bytes;
+ /** Timer start. */
+ ulonglong m_timer_start;
+ /** Timer function. */
+ ulonglong (*m_timer)(void);
+ /** Current operation. */
+ enum PSI_socket_operation m_operation;
+ /** Source file. */
+ const char* m_src_file;
+ /** Source line number. */
+ int m_src_line;
+ /** Internal data. */
+ void *m_wait;
+};
+typedef struct PSI_socket_locker_state_v1 PSI_socket_locker_state_v1;
+
+struct PSI_sp_locker_state_v1
+{
+ /** Internal state. */
+ uint m_flags;
+ /** Current thread. */
+ struct PSI_thread *m_thread;
+ /** Timer start. */
+ ulonglong m_timer_start;
+ /** Timer function. */
+ ulonglong (*m_timer)(void);
+ /** Stored Procedure share. */
+ PSI_sp_share* m_sp_share;
+};
+typedef struct PSI_sp_locker_state_v1 PSI_sp_locker_state_v1;
+
+/* Using typedef to make reuse between PSI_v1 and PSI_v2 easier later. */
+
+/**
+ Mutex registration API.
+ @param category a category name (typically a plugin name)
+ @param info an array of mutex info to register
+ @param count the size of the info array
+*/
+typedef void (*register_mutex_v1_t)
+ (const char *category, struct PSI_mutex_info_v1 *info, int count);
+
+/**
+ Rwlock registration API.
+ @param category a category name (typically a plugin name)
+ @param info an array of rwlock info to register
+ @param count the size of the info array
+*/
+typedef void (*register_rwlock_v1_t)
+ (const char *category, struct PSI_rwlock_info_v1 *info, int count);
+
+/**
+ Cond registration API.
+ @param category a category name (typically a plugin name)
+ @param info an array of cond info to register
+ @param count the size of the info array
+*/
+typedef void (*register_cond_v1_t)
+ (const char *category, struct PSI_cond_info_v1 *info, int count);
+
+/**
+ Thread registration API.
+ @param category a category name (typically a plugin name)
+ @param info an array of thread info to register
+ @param count the size of the info array
+*/
+typedef void (*register_thread_v1_t)
+ (const char *category, struct PSI_thread_info_v1 *info, int count);
+
+/**
+ File registration API.
+ @param category a category name (typically a plugin name)
+ @param info an array of file info to register
+ @param count the size of the info array
+*/
+typedef void (*register_file_v1_t)
+ (const char *category, struct PSI_file_info_v1 *info, int count);
+
+/**
+ Stage registration API.
+ @param category a category name
+ @param info an array of stage info to register
+ @param count the size of the info array
+*/
+typedef void (*register_stage_v1_t)
+ (const char *category, struct PSI_stage_info_v1 **info, int count);
+
+/**
+ Statement registration API.
+ @param category a category name
+ @param info an array of stage info to register
+ @param count the size of the info array
+*/
+typedef void (*register_statement_v1_t)
+ (const char *category, struct PSI_statement_info_v1 *info, int count);
+
+/**
+ Socket registration API.
+ @param category a category name (typically a plugin name)
+ @param info an array of socket info to register
+ @param count the size of the info array
+*/
+typedef void (*register_socket_v1_t)
+ (const char *category, struct PSI_socket_info_v1 *info, int count);
+
+/**
+ Mutex instrumentation initialisation API.
+ @param key the registered mutex key
+ @param identity the address of the mutex itself
+ @return an instrumented mutex
+*/
+typedef struct PSI_mutex* (*init_mutex_v1_t)
+ (PSI_mutex_key key, const void *identity);
+
+/**
+ Mutex instrumentation destruction API.
+ @param mutex the mutex to destroy
+*/
+typedef void (*destroy_mutex_v1_t)(struct PSI_mutex *mutex);
+
+/**
+ Rwlock instrumentation initialisation API.
+ @param key the registered rwlock key
+ @param identity the address of the rwlock itself
+ @return an instrumented rwlock
+*/
+typedef struct PSI_rwlock* (*init_rwlock_v1_t)
+ (PSI_rwlock_key key, const void *identity);
+
+/**
+ Rwlock instrumentation destruction API.
+ @param rwlock the rwlock to destroy
+*/
+typedef void (*destroy_rwlock_v1_t)(struct PSI_rwlock *rwlock);
+
+/**
+ Cond instrumentation initialisation API.
+ @param key the registered key
+ @param identity the address of the rwlock itself
+ @return an instrumented cond
+*/
+typedef struct PSI_cond* (*init_cond_v1_t)
+ (PSI_cond_key key, const void *identity);
+
+/**
+ Cond instrumentation destruction API.
+ @param cond the rcond to destroy
+*/
+typedef void (*destroy_cond_v1_t)(struct PSI_cond *cond);
+
+/**
+ Socket instrumentation initialisation API.
+ @param key the registered mutex key
+ @param socket descriptor
+ @param addr the socket ip address
+ @param addr_len length of socket ip address
+ @return an instrumented socket
+*/
+typedef struct PSI_socket* (*init_socket_v1_t)
+ (PSI_socket_key key, const my_socket *fd,
+ const struct sockaddr *addr, socklen_t addr_len);
+
+/**
+ socket instrumentation destruction API.
+ @param socket the socket to destroy
+*/
+typedef void (*destroy_socket_v1_t)(struct PSI_socket *socket);
+
+/**
+ Acquire a table share instrumentation.
+ @param temporary True for temporary tables
+ @param share The SQL layer table share
+ @return a table share instrumentation, or NULL
+*/
+typedef struct PSI_table_share* (*get_table_share_v1_t)
+ (my_bool temporary, struct TABLE_SHARE *share);
+
+/**
+ Release a table share.
+ @param info the table share to release
+*/
+typedef void (*release_table_share_v1_t)(struct PSI_table_share *share);
+
+/**
+ Drop a table share.
+ @param temporary True for temporary tables
+ @param schema_name the table schema name
+ @param schema_name_length the table schema name length
+ @param table_name the table name
+ @param table_name_length the table name length
+*/
+typedef void (*drop_table_share_v1_t)
+ (my_bool temporary, const char *schema_name, int schema_name_length,
+ const char *table_name, int table_name_length);
+
+/**
+ Open an instrumentation table handle.
+ @param share the table to open
+ @param identity table handle identity
+ @return a table handle, or NULL
+*/
+typedef struct PSI_table* (*open_table_v1_t)
+ (struct PSI_table_share *share, const void *identity);
+
+/**
+ Unbind a table handle from the current thread.
+ This operation happens when an opened table is added to the open table cache.
+ @param table the table to unbind
+*/
+typedef void (*unbind_table_v1_t)
+ (struct PSI_table *table);
+
+/**
+ Rebind a table handle to the current thread.
+ This operation happens when a table from the open table cache
+ is reused for a thread.
+ @param table the table to unbind
+*/
+typedef PSI_table* (*rebind_table_v1_t)
+ (PSI_table_share *share, const void *identity, PSI_table *table);
+
+/**
+ Close an instrumentation table handle.
+ Note that the table handle is invalid after this call.
+ @param table the table handle to close
+*/
+typedef void (*close_table_v1_t)(struct TABLE_SHARE *server_share,
+ struct PSI_table *table);
+
+/**
+ Create a file instrumentation for a created file.
+ This method does not create the file itself, but is used to notify the
+ instrumentation interface that a file was just created.
+ @param key the file instrumentation key for this file
+ @param name the file name
+ @param file the file handle
+*/
+typedef void (*create_file_v1_t)(PSI_file_key key, const char *name,
+ File file);
+
+/**
+ Spawn a thread.
+ This method creates a new thread, with instrumentation.
+ @param key the instrumentation key for this thread
+ @param thread the resulting thread
+ @param attr the thread attributes
+ @param start_routine the thread start routine
+ @param arg the thread start routine argument
+*/
+typedef int (*spawn_thread_v1_t)(PSI_thread_key key,
+ pthread_t *thread,
+ const pthread_attr_t *attr,
+ void *(*start_routine)(void*), void *arg);
+
+/**
+ Create instrumentation for a thread.
+ @param key the registered key
+ @param identity an address typical of the thread
+ @return an instrumented thread
+*/
+typedef struct PSI_thread* (*new_thread_v1_t)
+ (PSI_thread_key key, const void *identity, ulonglong thread_id);
+
+/**
+ Assign a THD to an instrumented thread.
+ @param thread the instrumented thread
+ @param THD the sql layer THD to assign
+*/
+typedef void (*set_thread_THD_v1_t)(struct PSI_thread *thread,
+ THD *thd);
+
+/**
+ Assign an id to an instrumented thread.
+ @param thread the instrumented thread
+ @param id the id to assign
+*/
+typedef void (*set_thread_id_v1_t)(struct PSI_thread *thread,
+ ulonglong id);
+
+/**
+ Assign the current operating system thread id to an instrumented thread.
+ The operating system task id is obtained from @c gettid()
+ @param thread the instrumented thread
+*/
+typedef void (*set_thread_os_id_v1_t)(struct PSI_thread *thread);
+
+/**
+ Get the instrumentation for the running thread.
+ For this function to return a result,
+ the thread instrumentation must have been attached to the
+ running thread using @c set_thread()
+ @return the instrumentation for the running thread
+*/
+typedef struct PSI_thread* (*get_thread_v1_t)(void);
+
+/**
+ Assign a user name to the instrumented thread.
+ @param user the user name
+ @param user_len the user name length
+*/
+typedef void (*set_thread_user_v1_t)(const char *user, int user_len);
+
+/**
+ Assign a user name and host name to the instrumented thread.
+ @param user the user name
+ @param user_len the user name length
+ @param host the host name
+ @param host_len the host name length
+*/
+typedef void (*set_thread_account_v1_t)(const char *user, int user_len,
+ const char *host, int host_len);
+
+/**
+ Assign a current database to the instrumented thread.
+ @param db the database name
+ @param db_len the database name length
+*/
+typedef void (*set_thread_db_v1_t)(const char* db, int db_len);
+
+/**
+ Assign a current command to the instrumented thread.
+ @param command the current command
+*/
+typedef void (*set_thread_command_v1_t)(int command);
+
+/**
+ Assign a connection type to the instrumented thread.
+ @param conn_type the connection type
+*/
+typedef void (*set_connection_type_v1_t)(opaque_vio_type conn_type);
+
+
+/**
+ Assign a start time to the instrumented thread.
+ @param start_time the thread start time
+*/
+typedef void (*set_thread_start_time_v1_t)(time_t start_time);
+
+/**
+ Assign a state to the instrumented thread.
+ @param state the thread state
+*/
+typedef void (*set_thread_state_v1_t)(const char* state);
+
+/**
+ Assign a process info to the instrumented thread.
+ @param info the process into string
+ @param info_len the process into string length
+*/
+typedef void (*set_thread_info_v1_t)(const char* info, uint info_len);
+
+/**
+ Attach a thread instrumentation to the running thread.
+ In case of thread pools, this method should be called when
+ a worker thread picks a work item and runs it.
+ Also, this method should be called if the instrumented code does not
+ keep the pointer returned by @c new_thread() and relies on @c get_thread()
+ instead.
+ @param thread the thread instrumentation
+*/
+typedef void (*set_thread_v1_t)(struct PSI_thread *thread);
+
+/** Delete the current thread instrumentation. */
+typedef void (*delete_current_thread_v1_t)(void);
+
+/** Delete a thread instrumentation. */
+typedef void (*delete_thread_v1_t)(struct PSI_thread *thread);
+
+/**
+ Get a file instrumentation locker, for opening or creating a file.
+ @param state data storage for the locker
+ @param key the file instrumentation key
+ @param op the operation to perform
+ @param name the file name
+ @param identity a pointer representative of this file.
+ @return a file locker, or NULL
+*/
+typedef struct PSI_file_locker* (*get_thread_file_name_locker_v1_t)
+ (struct PSI_file_locker_state_v1 *state,
+ PSI_file_key key, enum PSI_file_operation op, const char *name,
+ const void *identity);
+
+/**
+ Get a file stream instrumentation locker.
+ @param state data storage for the locker
+ @param file the file stream to access
+ @param op the operation to perform
+ @return a file locker, or NULL
+*/
+typedef struct PSI_file_locker* (*get_thread_file_stream_locker_v1_t)
+ (struct PSI_file_locker_state_v1 *state,
+ struct PSI_file *file, enum PSI_file_operation op);
+
+/**
+ Get a file instrumentation locker.
+ @param state data storage for the locker
+ @param file the file descriptor to access
+ @param op the operation to perform
+ @return a file locker, or NULL
+*/
+typedef struct PSI_file_locker* (*get_thread_file_descriptor_locker_v1_t)
+ (struct PSI_file_locker_state_v1 *state,
+ File file, enum PSI_file_operation op);
+
+/**
+ Record a mutex instrumentation unlock event.
+ @param mutex the mutex instrumentation
+*/
+typedef void (*unlock_mutex_v1_t)
+ (struct PSI_mutex *mutex);
+
+/**
+ Record a rwlock instrumentation unlock event.
+ @param rwlock the rwlock instrumentation
+*/
+typedef void (*unlock_rwlock_v1_t)
+ (struct PSI_rwlock *rwlock);
+
+/**
+ Record a condition instrumentation signal event.
+ @param cond the cond instrumentation
+*/
+typedef void (*signal_cond_v1_t)
+ (struct PSI_cond *cond);
+
+/**
+ Record a condition instrumentation broadcast event.
+ @param cond the cond instrumentation
+*/
+typedef void (*broadcast_cond_v1_t)
+ (struct PSI_cond *cond);
+
+/**
+ Record an idle instrumentation wait start event.
+ @param state data storage for the locker
+ @param file the source file name
+ @param line the source line number
+ @return an idle locker, or NULL
+*/
+typedef struct PSI_idle_locker* (*start_idle_wait_v1_t)
+ (struct PSI_idle_locker_state_v1 *state, const char *src_file, uint src_line);
+
+/**
+ Record an idle instrumentation wait end event.
+ @param locker a thread locker for the running thread
+*/
+typedef void (*end_idle_wait_v1_t)
+ (struct PSI_idle_locker *locker);
+
+/**
+ Record a mutex instrumentation wait start event.
+ @param state data storage for the locker
+ @param mutex the instrumented mutex to lock
+ @param op the operation to perform
+ @param file the source file name
+ @param line the source line number
+ @return a mutex locker, or NULL
+*/
+typedef struct PSI_mutex_locker* (*start_mutex_wait_v1_t)
+ (struct PSI_mutex_locker_state_v1 *state,
+ struct PSI_mutex *mutex,
+ enum PSI_mutex_operation op,
+ const char *src_file, uint src_line);
+
+/**
+ Record a mutex instrumentation wait end event.
+ @param locker a thread locker for the running thread
+ @param rc the wait operation return code
+*/
+typedef void (*end_mutex_wait_v1_t)
+ (struct PSI_mutex_locker *locker, int rc);
+
+/**
+ Record a rwlock instrumentation read wait start event.
+ @param locker a thread locker for the running thread
+ @param must must block: 1 for lock, 0 for trylock
+*/
+typedef struct PSI_rwlock_locker* (*start_rwlock_rdwait_v1_t)
+ (struct PSI_rwlock_locker_state_v1 *state,
+ struct PSI_rwlock *rwlock,
+ enum PSI_rwlock_operation op,
+ const char *src_file, uint src_line);
+
+/**
+ Record a rwlock instrumentation read wait end event.
+ @param locker a thread locker for the running thread
+ @param rc the wait operation return code
+*/
+typedef void (*end_rwlock_rdwait_v1_t)
+ (struct PSI_rwlock_locker *locker, int rc);
+
+/**
+ Record a rwlock instrumentation write wait start event.
+ @param locker a thread locker for the running thread
+ @param must must block: 1 for lock, 0 for trylock
+*/
+typedef struct PSI_rwlock_locker* (*start_rwlock_wrwait_v1_t)
+ (struct PSI_rwlock_locker_state_v1 *state,
+ struct PSI_rwlock *rwlock,
+ enum PSI_rwlock_operation op,
+ const char *src_file, uint src_line);
+
+/**
+ Record a rwlock instrumentation write wait end event.
+ @param locker a thread locker for the running thread
+ @param rc the wait operation return code
+*/
+typedef void (*end_rwlock_wrwait_v1_t)
+ (struct PSI_rwlock_locker *locker, int rc);
+
+/**
+ Record a condition instrumentation wait start event.
+ @param locker a thread locker for the running thread
+ @param must must block: 1 for wait, 0 for timedwait
+*/
+typedef struct PSI_cond_locker* (*start_cond_wait_v1_t)
+ (struct PSI_cond_locker_state_v1 *state,
+ struct PSI_cond *cond,
+ struct PSI_mutex *mutex,
+ enum PSI_cond_operation op,
+ const char *src_file, uint src_line);
+
+/**
+ Record a condition instrumentation wait end event.
+ @param locker a thread locker for the running thread
+ @param rc the wait operation return code
+*/
+typedef void (*end_cond_wait_v1_t)
+ (struct PSI_cond_locker *locker, int rc);
+
+/**
+ Record a table instrumentation io wait start event.
+ @param locker a table locker for the running thread
+ @param file the source file name
+ @param line the source line number
+*/
+typedef struct PSI_table_locker* (*start_table_io_wait_v1_t)
+ (struct PSI_table_locker_state *state,
+ struct PSI_table *table,
+ enum PSI_table_io_operation op,
+ uint index,
+ const char *src_file, uint src_line);
+
+/**
+ Record a table instrumentation io wait end event.
+ @param locker a table locker for the running thread
+ @param numrows the number of rows involved in io
+*/
+typedef void (*end_table_io_wait_v1_t)
+ (struct PSI_table_locker *locker,
+ ulonglong numrows);
+
+/**
+ Record a table instrumentation lock wait start event.
+ @param locker a table locker for the running thread
+ @param file the source file name
+ @param line the source line number
+*/
+typedef struct PSI_table_locker* (*start_table_lock_wait_v1_t)
+ (struct PSI_table_locker_state *state,
+ struct PSI_table *table,
+ enum PSI_table_lock_operation op,
+ ulong flags,
+ const char *src_file, uint src_line);
+
+/**
+ Record a table instrumentation lock wait end event.
+ @param locker a table locker for the running thread
+*/
+typedef void (*end_table_lock_wait_v1_t)(struct PSI_table_locker *locker);
+
+typedef void (*unlock_table_v1_t)(struct PSI_table *table);
+
+/**
+ Start a file instrumentation open operation.
+ @param locker the file locker
+ @param op the operation to perform
+ @param src_file the source file name
+ @param src_line the source line number
+*/
+typedef void (*start_file_open_wait_v1_t)
+ (struct PSI_file_locker *locker, const char *src_file, uint src_line);
+
+/**
+ End a file instrumentation open operation, for file streams.
+ @param locker the file locker.
+ @param result the opened file (NULL indicates failure, non NULL success).
+ @return an instrumented file handle
+*/
+typedef struct PSI_file* (*end_file_open_wait_v1_t)
+ (struct PSI_file_locker *locker, void *result);
+
+/**
+ End a file instrumentation open operation, for non stream files.
+ @param locker the file locker.
+ @param file the file number assigned by open() or create() for this file.
+*/
+typedef void (*end_file_open_wait_and_bind_to_descriptor_v1_t)
+ (struct PSI_file_locker *locker, File file);
+
+/**
+ End a file instrumentation open operation, for non stream temporary files.
+ @param locker the file locker.
+ @param file the file number assigned by open() or create() for this file.
+ @param filename the file name generated during temporary file creation.
+*/
+typedef void (*end_temp_file_open_wait_and_bind_to_descriptor_v1_t)
+ (struct PSI_file_locker *locker, File file, const char *filename);
+
+/**
+ Record a file instrumentation start event.
+ @param locker a file locker for the running thread
+ @param op file operation to be performed
+ @param count the number of bytes requested, or 0 if not applicable
+ @param src_file the source file name
+ @param src_line the source line number
+*/
+typedef void (*start_file_wait_v1_t)
+ (struct PSI_file_locker *locker, size_t count,
+ const char *src_file, uint src_line);
+
+/**
+ Record a file instrumentation end event.
+ Note that for file close operations, the instrumented file handle
+ associated with the file (which was provided to obtain a locker)
+ is invalid after this call.
+ @param locker a file locker for the running thread
+ @param count the number of bytes actually used in the operation,
+ or 0 if not applicable, or -1 if the operation failed
+ @sa get_thread_file_name_locker
+ @sa get_thread_file_stream_locker
+ @sa get_thread_file_descriptor_locker
+*/
+typedef void (*end_file_wait_v1_t)
+ (struct PSI_file_locker *locker, size_t count);
+
+/**
+ Start a file instrumentation close operation.
+ @param locker the file locker
+ @param op the operation to perform
+ @param src_file the source file name
+ @param src_line the source line number
+*/
+typedef void (*start_file_close_wait_v1_t)
+ (struct PSI_file_locker *locker, const char *src_file, uint src_line);
+
+/**
+ End a file instrumentation close operation.
+ @param locker the file locker.
+ @param rc the close operation return code (0 for success).
+ @return an instrumented file handle
+*/
+typedef void (*end_file_close_wait_v1_t)
+ (struct PSI_file_locker *locker, int rc);
+
+/**
+ Rename a file instrumentation close operation.
+ @param locker the file locker.
+ @param old_name name of the file to be renamed.
+ @param new_name name of the file after rename.
+ @param rc the rename operation return code (0 for success).
+*/
+typedef void (*end_file_rename_wait_v1_t)
+ (struct PSI_file_locker *locker, const char *old_name,
+ const char *new_name, int rc);
+
+/**
+ Start a new stage, and implicitly end the previous stage.
+ @param key the key of the new stage
+ @param src_file the source file name
+ @param src_line the source line number
+ @return the new stage progress
+*/
+typedef PSI_stage_progress* (*start_stage_v1_t)
+ (PSI_stage_key key, const char *src_file, int src_line);
+
+typedef PSI_stage_progress* (*get_current_stage_progress_v1_t)(void);
+
+/** End the current stage. */
+typedef void (*end_stage_v1_t) (void);
+
+/**
+ Get a statement instrumentation locker.
+ @param state data storage for the locker
+ @param key the statement instrumentation key
+ @param charset client character set
+ @return a statement locker, or NULL
+*/
+typedef struct PSI_statement_locker* (*get_thread_statement_locker_v1_t)
+ (struct PSI_statement_locker_state_v1 *state,
+ PSI_statement_key key, const void *charset, PSI_sp_share *sp_share);
+
+/**
+ Refine a statement locker to a more specific key.
+ Note that only events declared mutable can be refined.
+ @param the statement locker for the current event
+ @param key the new key for the event
+ @sa PSI_FLAG_MUTABLE
+*/
+typedef struct PSI_statement_locker* (*refine_statement_v1_t)
+ (struct PSI_statement_locker *locker,
+ PSI_statement_key key);
+
+/**
+ Start a new statement event.
+ @param locker the statement locker for this event
+ @param db the active database name for this statement
+ @param db_length the active database name length for this statement
+ @param src_file source file name
+ @param src_line source line number
+*/
+typedef void (*start_statement_v1_t)
+ (struct PSI_statement_locker *locker,
+ const char *db, uint db_length,
+ const char *src_file, uint src_line);
+
+/**
+ Set the statement text for a statement event.
+ @param locker the current statement locker
+ @param text the statement text
+ @param text_len the statement text length
+*/
+typedef void (*set_statement_text_v1_t)
+ (struct PSI_statement_locker *locker,
+ const char *text, uint text_len);
+
+/**
+ Set a statement event lock time.
+ @param locker the statement locker
+ @param lock_time the locked time, in microseconds
+*/
+typedef void (*set_statement_lock_time_t)
+ (struct PSI_statement_locker *locker, ulonglong lock_time);
+
+/**
+ Set a statement event rows sent metric.
+ @param locker the statement locker
+ @param count the number of rows sent
+*/
+typedef void (*set_statement_rows_sent_t)
+ (struct PSI_statement_locker *locker, ulonglong count);
+
+/**
+ Set a statement event rows examined metric.
+ @param locker the statement locker
+ @param count the number of rows examined
+*/
+typedef void (*set_statement_rows_examined_t)
+ (struct PSI_statement_locker *locker, ulonglong count);
+
+/**
+ Increment a statement event "created tmp disk tables" metric.
+ @param locker the statement locker
+ @param count the metric increment value
+*/
+typedef void (*inc_statement_created_tmp_disk_tables_t)
+ (struct PSI_statement_locker *locker, ulong count);
+
+/**
+ Increment a statement event "created tmp tables" metric.
+ @param locker the statement locker
+ @param count the metric increment value
+*/
+typedef void (*inc_statement_created_tmp_tables_t)
+ (struct PSI_statement_locker *locker, ulong count);
+
+/**
+ Increment a statement event "select full join" metric.
+ @param locker the statement locker
+ @param count the metric increment value
+*/
+typedef void (*inc_statement_select_full_join_t)
+ (struct PSI_statement_locker *locker, ulong count);
+
+/**
+ Increment a statement event "select full range join" metric.
+ @param locker the statement locker
+ @param count the metric increment value
+*/
+typedef void (*inc_statement_select_full_range_join_t)
+ (struct PSI_statement_locker *locker, ulong count);
+
+/**
+ Increment a statement event "select range join" metric.
+ @param locker the statement locker
+ @param count the metric increment value
+*/
+typedef void (*inc_statement_select_range_t)
+ (struct PSI_statement_locker *locker, ulong count);
+
+/**
+ Increment a statement event "select range check" metric.
+ @param locker the statement locker
+ @param count the metric increment value
+*/
+typedef void (*inc_statement_select_range_check_t)
+ (struct PSI_statement_locker *locker, ulong count);
+
+/**
+ Increment a statement event "select scan" metric.
+ @param locker the statement locker
+ @param count the metric increment value
+*/
+typedef void (*inc_statement_select_scan_t)
+ (struct PSI_statement_locker *locker, ulong count);
+
+/**
+ Increment a statement event "sort merge passes" metric.
+ @param locker the statement locker
+ @param count the metric increment value
+*/
+typedef void (*inc_statement_sort_merge_passes_t)
+ (struct PSI_statement_locker *locker, ulong count);
+
+/**
+ Increment a statement event "sort range" metric.
+ @param locker the statement locker
+ @param count the metric increment value
+*/
+typedef void (*inc_statement_sort_range_t)
+ (struct PSI_statement_locker *locker, ulong count);
+
+/**
+ Increment a statement event "sort rows" metric.
+ @param locker the statement locker
+ @param count the metric increment value
+*/
+typedef void (*inc_statement_sort_rows_t)
+ (struct PSI_statement_locker *locker, ulong count);
+
+/**
+ Increment a statement event "sort scan" metric.
+ @param locker the statement locker
+ @param count the metric increment value
+*/
+typedef void (*inc_statement_sort_scan_t)
+ (struct PSI_statement_locker *locker, ulong count);
+
+/**
+ Set a statement event "no index used" metric.
+ @param locker the statement locker
+ @param count the metric value
+*/
+typedef void (*set_statement_no_index_used_t)
+ (struct PSI_statement_locker *locker);
+
+/**
+ Set a statement event "no good index used" metric.
+ @param locker the statement locker
+ @param count the metric value
+*/
+typedef void (*set_statement_no_good_index_used_t)
+ (struct PSI_statement_locker *locker);
+
+/**
+ End a statement event.
+ @param locker the statement locker
+ @param stmt_da the statement diagnostics area.
+ @sa Diagnostics_area
+*/
+typedef void (*end_statement_v1_t)
+ (struct PSI_statement_locker *locker, void *stmt_da);
+
+/**
+ Get a transaction instrumentation locker.
+ @param state data storage for the locker
+ @param xid the xid for this transaction
+ @param trxid the InnoDB transaction id
+ @param iso_level isolation level for this transaction
+ @param read_only true if transaction access mode is read-only
+ @param autocommit true if transaction is autocommit
+ @return a transaction locker, or NULL
+*/
+typedef struct PSI_transaction_locker* (*get_thread_transaction_locker_v1_t)
+ (struct PSI_transaction_locker_state_v1 *state, const void *xid,
+ ulonglong trxid, int isolation_level, my_bool read_only,
+ my_bool autocommit);
+
+/**
+ Start a new transaction event.
+ @param locker the transaction locker for this event
+ @param src_file source file name
+ @param src_line source line number
+*/
+typedef void (*start_transaction_v1_t)
+ (struct PSI_transaction_locker *locker,
+ const char *src_file, uint src_line);
+
+/**
+ Set the transaction xid.
+ @param locker the transaction locker for this event
+ @param xid the id of the XA transaction
+ #param xa_state is the state of the XA transaction
+*/
+typedef void (*set_transaction_xid_v1_t)
+ (struct PSI_transaction_locker *locker,
+ const void *xid, int xa_state);
+
+/**
+ Set the state of the XA transaction.
+ @param locker the transaction locker for this event
+ @param xa_state the new state of the xa transaction
+*/
+typedef void (*set_transaction_xa_state_v1_t)
+ (struct PSI_transaction_locker *locker,
+ int xa_state);
+
+/**
+ Set the transaction gtid.
+ @param locker the transaction locker for this event
+ @param sid the source id for the transaction, mapped from sidno
+ @param gtid_spec the gtid specifier for the transaction
+*/
+typedef void (*set_transaction_gtid_v1_t)
+ (struct PSI_transaction_locker *locker,
+ const void *sid, const void *gtid_spec);
+
+/**
+ Set the transaction trx_id.
+ @param locker the transaction locker for this event
+ @param trxid the storage engine transaction ID
+*/
+typedef void (*set_transaction_trxid_v1_t)
+ (struct PSI_transaction_locker *locker,
+ const ulonglong *trxid);
+
+/**
+ Increment a transaction event savepoint count.
+ @param locker the transaction locker
+ @param count the increment value
+*/
+typedef void (*inc_transaction_savepoints_v1_t)
+ (struct PSI_transaction_locker *locker, ulong count);
+
+/**
+ Increment a transaction event rollback to savepoint count.
+ @param locker the transaction locker
+ @param count the increment value
+*/
+typedef void (*inc_transaction_rollback_to_savepoint_v1_t)
+ (struct PSI_transaction_locker *locker, ulong count);
+
+/**
+ Increment a transaction event release savepoint count.
+ @param locker the transaction locker
+ @param count the increment value
+*/
+typedef void (*inc_transaction_release_savepoint_v1_t)
+ (struct PSI_transaction_locker *locker, ulong count);
+
+/**
+ Commit or rollback the transaction.
+ @param locker the transaction locker for this event
+ @param commit true if transaction was committed, false if rolled back
+*/
+typedef void (*end_transaction_v1_t)
+ (struct PSI_transaction_locker *locker,
+ my_bool commit);
+
+/**
+ Record a socket instrumentation start event.
+ @param locker a socket locker for the running thread
+ @param op socket operation to be performed
+ @param count the number of bytes requested, or 0 if not applicable
+ @param src_file the source file name
+ @param src_line the source line number
+*/
+typedef struct PSI_socket_locker* (*start_socket_wait_v1_t)
+ (struct PSI_socket_locker_state_v1 *state,
+ struct PSI_socket *socket,
+ enum PSI_socket_operation op,
+ size_t count,
+ const char *src_file, uint src_line);
+
+/**
+ Record a socket instrumentation end event.
+ Note that for socket close operations, the instrumented socket handle
+ associated with the socket (which was provided to obtain a locker)
+ is invalid after this call.
+ @param locker a socket locker for the running thread
+ @param count the number of bytes actually used in the operation,
+ or 0 if not applicable, or -1 if the operation failed
+ @sa get_thread_socket_locker
+*/
+typedef void (*end_socket_wait_v1_t)
+ (struct PSI_socket_locker *locker, size_t count);
+
+/**
+ Set the socket state for an instrumented socket.
+ @param socket the instrumented socket
+ @param state socket state
+ */
+typedef void (*set_socket_state_v1_t)(struct PSI_socket *socket,
+ enum PSI_socket_state state);
+
+/**
+ Set the socket info for an instrumented socket.
+ @param socket the instrumented socket
+ @param fd the socket descriptor
+ @param addr the socket ip address
+ @param addr_len length of socket ip address
+ @param thread_id associated thread id
+*/
+typedef void (*set_socket_info_v1_t)(struct PSI_socket *socket,
+ const my_socket *fd,
+ const struct sockaddr *addr,
+ socklen_t addr_len);
+
+/**
+ Bind a socket to the thread that owns it.
+ @param socket instrumented socket
+*/
+typedef void (*set_socket_thread_owner_v1_t)(struct PSI_socket *socket);
+
+/**
+ Get a prepare statement.
+ @param locker a statement locker for the running thread.
+*/
+typedef PSI_prepared_stmt* (*create_prepared_stmt_v1_t)
+ (void *identity, uint stmt_id, PSI_statement_locker *locker,
+ const char *stmt_name, size_t stmt_name_length);
+
+/**
+ destroy a prepare statement.
+ @param prepared_stmt prepared statement.
+*/
+typedef void (*destroy_prepared_stmt_v1_t)
+ (PSI_prepared_stmt *prepared_stmt);
+
+/**
+ repreare a prepare statement.
+ @param prepared_stmt prepared statement.
+*/
+typedef void (*reprepare_prepared_stmt_v1_t)
+ (PSI_prepared_stmt *prepared_stmt);
+
+/**
+ Record a prepare statement instrumentation execute event.
+ @param locker a statement locker for the running thread.
+ @param prepared_stmt prepared statement.
+*/
+typedef void (*execute_prepared_stmt_v1_t)
+ (PSI_statement_locker *locker, PSI_prepared_stmt* prepared_stmt);
+
+/**
+ Set the statement text for a prepared statment event.
+ @param prepared_stmt prepared statement.
+ @param text the prepared statement text
+ @param text_len the prepared statement text length
+*/
+typedef void (*set_prepared_stmt_text_v1_t)(PSI_prepared_stmt *prepared_stmt,
+ const char *text,
+ uint text_len);
+/**
+ Get a digest locker for the current statement.
+ @param locker a statement locker for the running thread
+*/
+typedef struct PSI_digest_locker * (*digest_start_v1_t)
+ (struct PSI_statement_locker *locker);
+
+/**
+ Add a token to the current digest instrumentation.
+ @param locker a digest locker for the current statement
+ @param token the lexical token to add
+ @param yylval the lexical token attributes
+*/
+typedef void (*digest_end_v1_t)
+ (struct PSI_digest_locker *locker, const struct sql_digest_storage *digest);
+
+typedef PSI_sp_locker* (*start_sp_v1_t)
+ (struct PSI_sp_locker_state_v1 *state, struct PSI_sp_share* sp_share);
+
+typedef void (*end_sp_v1_t)
+ (struct PSI_sp_locker *locker);
+
+typedef void (*drop_sp_v1_t)
+ (uint object_type,
+ const char *schema_name, uint schema_name_length,
+ const char *object_name, uint object_name_length);
+
+/**
+ Acquire a sp share instrumentation.
+ @param type of stored program
+ @param schema name of stored program
+ @param name of stored program
+ @return a stored program share instrumentation, or NULL
+*/
+typedef struct PSI_sp_share* (*get_sp_share_v1_t)
+ (uint object_type,
+ const char *schema_name, uint schema_name_length,
+ const char *object_name, uint object_name_length);
+
+/**
+ Release a stored program share.
+ @param info the stored program share to release
+*/
+typedef void (*release_sp_share_v1_t)(struct PSI_sp_share *share);
+
+typedef PSI_metadata_lock* (*create_metadata_lock_v1_t)
+ (void *identity,
+ const MDL_key *key,
+ opaque_mdl_type mdl_type,
+ opaque_mdl_duration mdl_duration,
+ opaque_mdl_status mdl_status,
+ const char *src_file,
+ uint src_line);
+
+typedef void (*set_metadata_lock_status_v1_t)(PSI_metadata_lock *lock,
+ opaque_mdl_status mdl_status);
+
+typedef void (*destroy_metadata_lock_v1_t)(PSI_metadata_lock *lock);
+
+typedef struct PSI_metadata_locker* (*start_metadata_wait_v1_t)
+ (struct PSI_metadata_locker_state_v1 *state,
+ struct PSI_metadata_lock *mdl,
+ const char *src_file, uint src_line);
+
+typedef void (*end_metadata_wait_v1_t)
+ (struct PSI_metadata_locker *locker, int rc);
+
+/**
+ Stores an array of connection attributes
+ @param buffer char array of length encoded connection attributes
+ in network format
+ @param length length of the data in buffer
+ @param from_cs charset in which @c buffer is encoded
+ @return state
+ @retval non_0 attributes truncated
+ @retval 0 stored the attribute
+*/
+typedef int (*set_thread_connect_attrs_v1_t)(const char *buffer, uint length,
+ const void *from_cs);
+
+/**
+ Performance Schema Interface, version 1.
+ @since PSI_VERSION_1
+*/
+struct PSI_v1
+{
+ /** @sa register_mutex_v1_t. */
+ register_mutex_v1_t register_mutex;
+ /** @sa register_rwlock_v1_t. */
+ register_rwlock_v1_t register_rwlock;
+ /** @sa register_cond_v1_t. */
+ register_cond_v1_t register_cond;
+ /** @sa register_thread_v1_t. */
+ register_thread_v1_t register_thread;
+ /** @sa register_file_v1_t. */
+ register_file_v1_t register_file;
+ /** @sa register_stage_v1_t. */
+ register_stage_v1_t register_stage;
+ /** @sa register_statement_v1_t. */
+ register_statement_v1_t register_statement;
+ /** @sa register_socket_v1_t. */
+ register_socket_v1_t register_socket;
+ /** @sa init_mutex_v1_t. */
+ init_mutex_v1_t init_mutex;
+ /** @sa destroy_mutex_v1_t. */
+ destroy_mutex_v1_t destroy_mutex;
+ /** @sa init_rwlock_v1_t. */
+ init_rwlock_v1_t init_rwlock;
+ /** @sa destroy_rwlock_v1_t. */
+ destroy_rwlock_v1_t destroy_rwlock;
+ /** @sa init_cond_v1_t. */
+ init_cond_v1_t init_cond;
+ /** @sa destroy_cond_v1_t. */
+ destroy_cond_v1_t destroy_cond;
+ /** @sa init_socket_v1_t. */
+ init_socket_v1_t init_socket;
+ /** @sa destroy_socket_v1_t. */
+ destroy_socket_v1_t destroy_socket;
+
+ /** @sa get_table_share_v1_t. */
+ get_table_share_v1_t get_table_share;
+ /** @sa release_table_share_v1_t. */
+ release_table_share_v1_t release_table_share;
+ /** @sa drop_table_share_v1_t. */
+ drop_table_share_v1_t drop_table_share;
+ /** @sa open_table_v1_t. */
+ open_table_v1_t open_table;
+ /** @sa unbind_table_v1_t. */
+ unbind_table_v1_t unbind_table;
+ /** @sa rebind_table_v1_t. */
+ rebind_table_v1_t rebind_table;
+ /** @sa close_table_v1_t. */
+ close_table_v1_t close_table;
+ /** @sa create_file_v1_t. */
+ create_file_v1_t create_file;
+ /** @sa spawn_thread_v1_t. */
+ spawn_thread_v1_t spawn_thread;
+ /** @sa new_thread_v1_t. */
+ new_thread_v1_t new_thread;
+ /** @sa set_thread_id_v1_t. */
+ set_thread_id_v1_t set_thread_id;
+ /** @sa set_thread_THD_v1_t. */
+ set_thread_THD_v1_t set_thread_THD;
+ /** @sa set_thread_os_id_v1_t. */
+ set_thread_os_id_v1_t set_thread_os_id;
+ /** @sa get_thread_v1_t. */
+ get_thread_v1_t get_thread;
+ /** @sa set_thread_user_v1_t. */
+ set_thread_user_v1_t set_thread_user;
+ /** @sa set_thread_account_v1_t. */
+ set_thread_account_v1_t set_thread_account;
+ /** @sa set_thread_db_v1_t. */
+ set_thread_db_v1_t set_thread_db;
+ /** @sa set_thread_command_v1_t. */
+ set_thread_command_v1_t set_thread_command;
+ /** @sa set_connection_type_v1_t. */
+ set_connection_type_v1_t set_connection_type;
+ /** @sa set_thread_start_time_v1_t. */
+ set_thread_start_time_v1_t set_thread_start_time;
+ /** @sa set_thread_state_v1_t. */
+ set_thread_state_v1_t set_thread_state;
+ /** @sa set_thread_info_v1_t. */
+ set_thread_info_v1_t set_thread_info;
+ /** @sa set_thread_v1_t. */
+ set_thread_v1_t set_thread;
+ /** @sa delete_current_thread_v1_t. */
+ delete_current_thread_v1_t delete_current_thread;
+ /** @sa delete_thread_v1_t. */
+ delete_thread_v1_t delete_thread;
+ /** @sa get_thread_file_name_locker_v1_t. */
+ get_thread_file_name_locker_v1_t get_thread_file_name_locker;
+ /** @sa get_thread_file_stream_locker_v1_t. */
+ get_thread_file_stream_locker_v1_t get_thread_file_stream_locker;
+ /** @sa get_thread_file_descriptor_locker_v1_t. */
+ get_thread_file_descriptor_locker_v1_t get_thread_file_descriptor_locker;
+ /** @sa unlock_mutex_v1_t. */
+ unlock_mutex_v1_t unlock_mutex;
+ /** @sa unlock_rwlock_v1_t. */
+ unlock_rwlock_v1_t unlock_rwlock;
+ /** @sa signal_cond_v1_t. */
+ signal_cond_v1_t signal_cond;
+ /** @sa broadcast_cond_v1_t. */
+ broadcast_cond_v1_t broadcast_cond;
+ /** @sa start_idle_wait_v1_t. */
+ start_idle_wait_v1_t start_idle_wait;
+ /** @sa end_idle_wait_v1_t. */
+ end_idle_wait_v1_t end_idle_wait;
+ /** @sa start_mutex_wait_v1_t. */
+ start_mutex_wait_v1_t start_mutex_wait;
+ /** @sa end_mutex_wait_v1_t. */
+ end_mutex_wait_v1_t end_mutex_wait;
+ /** @sa start_rwlock_rdwait_v1_t. */
+ start_rwlock_rdwait_v1_t start_rwlock_rdwait;
+ /** @sa end_rwlock_rdwait_v1_t. */
+ end_rwlock_rdwait_v1_t end_rwlock_rdwait;
+ /** @sa start_rwlock_wrwait_v1_t. */
+ start_rwlock_wrwait_v1_t start_rwlock_wrwait;
+ /** @sa end_rwlock_wrwait_v1_t. */
+ end_rwlock_wrwait_v1_t end_rwlock_wrwait;
+ /** @sa start_cond_wait_v1_t. */
+ start_cond_wait_v1_t start_cond_wait;
+ /** @sa end_cond_wait_v1_t. */
+ end_cond_wait_v1_t end_cond_wait;
+ /** @sa start_table_io_wait_v1_t. */
+ start_table_io_wait_v1_t start_table_io_wait;
+ /** @sa end_table_io_wait_v1_t. */
+ end_table_io_wait_v1_t end_table_io_wait;
+ /** @sa start_table_lock_wait_v1_t. */
+ start_table_lock_wait_v1_t start_table_lock_wait;
+ /** @sa end_table_lock_wait_v1_t. */
+ end_table_lock_wait_v1_t end_table_lock_wait;
+ /** @sa start_file_open_wait_v1_t. */
+ start_file_open_wait_v1_t start_file_open_wait;
+ /** @sa end_file_open_wait_v1_t. */
+ end_file_open_wait_v1_t end_file_open_wait;
+ /** @sa end_file_open_wait_and_bind_to_descriptor_v1_t. */
+ end_file_open_wait_and_bind_to_descriptor_v1_t
+ end_file_open_wait_and_bind_to_descriptor;
+ /** @sa end_temp_file_open_wait_and_bind_to_descriptor_v1_t. */
+ end_temp_file_open_wait_and_bind_to_descriptor_v1_t
+ end_temp_file_open_wait_and_bind_to_descriptor;
+ /** @sa start_file_wait_v1_t. */
+ start_file_wait_v1_t start_file_wait;
+ /** @sa end_file_wait_v1_t. */
+ end_file_wait_v1_t end_file_wait;
+ /** @sa start_file_close_wait_v1_t. */
+ start_file_close_wait_v1_t start_file_close_wait;
+ /** @sa end_file_close_wait_v1_t. */
+ end_file_close_wait_v1_t end_file_close_wait;
+ /** @sa rename_file_close_wait_v1_t. */
+ end_file_rename_wait_v1_t end_file_rename_wait;
+ /** @sa start_stage_v1_t. */
+ start_stage_v1_t start_stage;
+ /** @sa get_current_stage_progress_v1_t. */
+ get_current_stage_progress_v1_t get_current_stage_progress;
+ /** @sa end_stage_v1_t. */
+ end_stage_v1_t end_stage;
+ /** @sa get_thread_statement_locker_v1_t. */
+ get_thread_statement_locker_v1_t get_thread_statement_locker;
+ /** @sa refine_statement_v1_t. */
+ refine_statement_v1_t refine_statement;
+ /** @sa start_statement_v1_t. */
+ start_statement_v1_t start_statement;
+ /** @sa set_statement_text_v1_t. */
+ set_statement_text_v1_t set_statement_text;
+ /** @sa set_statement_lock_time_t. */
+ set_statement_lock_time_t set_statement_lock_time;
+ /** @sa set_statement_rows_sent_t. */
+ set_statement_rows_sent_t set_statement_rows_sent;
+ /** @sa set_statement_rows_examined_t. */
+ set_statement_rows_examined_t set_statement_rows_examined;
+ /** @sa inc_statement_created_tmp_disk_tables. */
+ inc_statement_created_tmp_disk_tables_t inc_statement_created_tmp_disk_tables;
+ /** @sa inc_statement_created_tmp_tables. */
+ inc_statement_created_tmp_tables_t inc_statement_created_tmp_tables;
+ /** @sa inc_statement_select_full_join. */
+ inc_statement_select_full_join_t inc_statement_select_full_join;
+ /** @sa inc_statement_select_full_range_join. */
+ inc_statement_select_full_range_join_t inc_statement_select_full_range_join;
+ /** @sa inc_statement_select_range. */
+ inc_statement_select_range_t inc_statement_select_range;
+ /** @sa inc_statement_select_range_check. */
+ inc_statement_select_range_check_t inc_statement_select_range_check;
+ /** @sa inc_statement_select_scan. */
+ inc_statement_select_scan_t inc_statement_select_scan;
+ /** @sa inc_statement_sort_merge_passes. */
+ inc_statement_sort_merge_passes_t inc_statement_sort_merge_passes;
+ /** @sa inc_statement_sort_range. */
+ inc_statement_sort_range_t inc_statement_sort_range;
+ /** @sa inc_statement_sort_rows. */
+ inc_statement_sort_rows_t inc_statement_sort_rows;
+ /** @sa inc_statement_sort_scan. */
+ inc_statement_sort_scan_t inc_statement_sort_scan;
+ /** @sa set_statement_no_index_used. */
+ set_statement_no_index_used_t set_statement_no_index_used;
+ /** @sa set_statement_no_good_index_used. */
+ set_statement_no_good_index_used_t set_statement_no_good_index_used;
+ /** @sa end_statement_v1_t. */
+ end_statement_v1_t end_statement;
+ /** @sa get_thread_transaction_locker_v1_t. */
+ get_thread_transaction_locker_v1_t get_thread_transaction_locker;
+ /** @sa start_transaction_v1_t. */
+ start_transaction_v1_t start_transaction;
+ /** @sa set_transaction_xid_v1_t. */
+ set_transaction_xid_v1_t set_transaction_xid;
+ /** @sa set_transaction_xa_state_v1_t. */
+ set_transaction_xa_state_v1_t set_transaction_xa_state;
+ /** @sa set_transaction_gtid_v1_t. */
+ set_transaction_gtid_v1_t set_transaction_gtid;
+ /** @sa set_transaction_trxid_v1_t. */
+ set_transaction_trxid_v1_t set_transaction_trxid;
+ /** @sa inc_transaction_savepoints_v1_t. */
+ inc_transaction_savepoints_v1_t inc_transaction_savepoints;
+ /** @sa inc_transaction_rollback_to_savepoint_v1_t. */
+ inc_transaction_rollback_to_savepoint_v1_t inc_transaction_rollback_to_savepoint;
+ /** @sa inc_transaction_release_savepoint_v1_t. */
+ inc_transaction_release_savepoint_v1_t inc_transaction_release_savepoint;
+ /** @sa end_transaction_v1_t. */
+ end_transaction_v1_t end_transaction;
+ /** @sa start_socket_wait_v1_t. */
+ start_socket_wait_v1_t start_socket_wait;
+ /** @sa end_socket_wait_v1_t. */
+ end_socket_wait_v1_t end_socket_wait;
+ /** @sa set_socket_state_v1_t. */
+ set_socket_state_v1_t set_socket_state;
+ /** @sa set_socket_info_v1_t. */
+ set_socket_info_v1_t set_socket_info;
+ /** @sa set_socket_thread_owner_v1_t. */
+ set_socket_thread_owner_v1_t set_socket_thread_owner;
+ /** @sa create_prepared_stmt_v1_t. */
+ create_prepared_stmt_v1_t create_prepared_stmt;
+ /** @sa destroy_prepared_stmt_v1_t. */
+ destroy_prepared_stmt_v1_t destroy_prepared_stmt;
+ /** @sa reprepare_prepared_stmt_v1_t. */
+ reprepare_prepared_stmt_v1_t reprepare_prepared_stmt;
+ /** @sa execute_prepared_stmt_v1_t. */
+ execute_prepared_stmt_v1_t execute_prepared_stmt;
+ /** @sa set_prepared_stmt_text_v1_t. */
+ set_prepared_stmt_text_v1_t set_prepared_stmt_text;
+ /** @sa digest_start_v1_t. */
+ digest_start_v1_t digest_start;
+ /** @sa digest_end_v1_t. */
+ digest_end_v1_t digest_end;
+ /** @sa set_thread_connect_attrs_v1_t. */
+ set_thread_connect_attrs_v1_t set_thread_connect_attrs;
+ /** @sa start_sp_v1_t. */
+ start_sp_v1_t start_sp;
+ /** @sa start_sp_v1_t. */
+ end_sp_v1_t end_sp;
+ /** @sa drop_sp_v1_t. */
+ drop_sp_v1_t drop_sp;
+ /** @sa get_sp_share_v1_t. */
+ get_sp_share_v1_t get_sp_share;
+ /** @sa release_sp_share_v1_t. */
+ release_sp_share_v1_t release_sp_share;
+ /** @sa register_memory_v1_t. */
+ register_memory_v1_t register_memory;
+ /** @sa memory_alloc_v1_t. */
+ memory_alloc_v1_t memory_alloc;
+ /** @sa memory_realloc_v1_t. */
+ memory_realloc_v1_t memory_realloc;
+ /** @sa memory_claim_v1_t. */
+ memory_claim_v1_t memory_claim;
+ /** @sa memory_free_v1_t. */
+ memory_free_v1_t memory_free;
+
+ unlock_table_v1_t unlock_table;
+
+ create_metadata_lock_v1_t create_metadata_lock;
+ set_metadata_lock_status_v1_t set_metadata_lock_status;
+ destroy_metadata_lock_v1_t destroy_metadata_lock;
+
+ start_metadata_wait_v1_t start_metadata_wait;
+ end_metadata_wait_v1_t end_metadata_wait;
+};
+
+/** @} (end of group Group_PSI_v1) */
+
+#endif /* HAVE_PSI_1 */
+
+#ifdef USE_PSI_2
+#define HAVE_PSI_2
+#endif
+
+#ifdef HAVE_PSI_2
+
+/**
+ @defgroup Group_PSI_v2 Application Binary Interface, version 2
+ @ingroup Instrumentation_interface
+ @{
+*/
+
+/**
+ Performance Schema Interface, version 2.
+ This is a placeholder, this interface is not defined yet.
+ @since PSI_VERSION_2
+*/
+struct PSI_v2
+{
+ /** Placeholder */
+ int placeholder;
+ /* ... extended interface ... */
+};
+
+/** Placeholder */
+struct PSI_mutex_info_v2
+{
+ /** Placeholder */
+ int placeholder;
+};
+
+/** Placeholder */
+struct PSI_rwlock_info_v2
+{
+ /** Placeholder */
+ int placeholder;
+};
+
+/** Placeholder */
+struct PSI_cond_info_v2
+{
+ /** Placeholder */
+ int placeholder;
+};
+
+/** Placeholder */
+struct PSI_thread_info_v2
+{
+ /** Placeholder */
+ int placeholder;
+};
+
+/** Placeholder */
+struct PSI_file_info_v2
+{
+ /** Placeholder */
+ int placeholder;
+};
+
+/** Placeholder */
+struct PSI_stage_info_v2
+{
+ /** Placeholder */
+ int placeholder;
+};
+
+/** Placeholder */
+struct PSI_statement_info_v2
+{
+ /** Placeholder */
+ int placeholder;
+};
+
+/** Placeholder */
+struct PSI_transaction_info_v2
+{
+ /** Placeholder */
+ int placeholder;
+};
+
+/** Placeholder */
+struct PSI_idle_locker_state_v2
+{
+ /** Placeholder */
+ int placeholder;
+};
+
+/** Placeholder */
+struct PSI_mutex_locker_state_v2
+{
+ /** Placeholder */
+ int placeholder;
+};
+
+/** Placeholder */
+struct PSI_rwlock_locker_state_v2
+{
+ /** Placeholder */
+ int placeholder;
+};
+
+/** Placeholder */
+struct PSI_cond_locker_state_v2
+{
+ /** Placeholder */
+ int placeholder;
+};
+
+/** Placeholder */
+struct PSI_file_locker_state_v2
+{
+ /** Placeholder */
+ int placeholder;
+};
+
+/** Placeholder */
+struct PSI_statement_locker_state_v2
+{
+ /** Placeholder */
+ int placeholder;
+};
+
+/** Placeholder */
+struct PSI_transaction_locker_state_v2
+{
+ /** Placeholder */
+ int placeholder;
+};
+
+/** Placeholder */
+struct PSI_socket_locker_state_v2
+{
+ /** Placeholder */
+ int placeholder;
+};
+
+struct PSI_metadata_locker_state_v2
+{
+ int placeholder;
+};
+
+/** @} (end of group Group_PSI_v2) */
+
+#endif /* HAVE_PSI_2 */
+
+/**
+ @typedef PSI
+ The instrumentation interface for the current version.
+ @sa PSI_CURRENT_VERSION
+*/
+
+/**
+ @typedef PSI_mutex_info
+ The mutex information structure for the current version.
+*/
+
+/**
+ @typedef PSI_rwlock_info
+ The rwlock information structure for the current version.
+*/
+
+/**
+ @typedef PSI_cond_info
+ The cond information structure for the current version.
+*/
+
+/**
+ @typedef PSI_thread_info
+ The thread information structure for the current version.
+*/
+
+/**
+ @typedef PSI_file_info
+ The file information structure for the current version.
+*/
+
+/* Export the required version */
+#ifdef USE_PSI_1
+typedef struct PSI_v1 PSI;
+typedef struct PSI_mutex_info_v1 PSI_mutex_info;
+typedef struct PSI_rwlock_info_v1 PSI_rwlock_info;
+typedef struct PSI_cond_info_v1 PSI_cond_info;
+typedef struct PSI_thread_info_v1 PSI_thread_info;
+typedef struct PSI_file_info_v1 PSI_file_info;
+typedef struct PSI_stage_info_v1 PSI_stage_info;
+typedef struct PSI_statement_info_v1 PSI_statement_info;
+typedef struct PSI_transaction_info_v1 PSI_transaction_info;
+typedef struct PSI_socket_info_v1 PSI_socket_info;
+typedef struct PSI_idle_locker_state_v1 PSI_idle_locker_state;
+typedef struct PSI_mutex_locker_state_v1 PSI_mutex_locker_state;
+typedef struct PSI_rwlock_locker_state_v1 PSI_rwlock_locker_state;
+typedef struct PSI_cond_locker_state_v1 PSI_cond_locker_state;
+typedef struct PSI_file_locker_state_v1 PSI_file_locker_state;
+typedef struct PSI_statement_locker_state_v1 PSI_statement_locker_state;
+typedef struct PSI_transaction_locker_state_v1 PSI_transaction_locker_state;
+typedef struct PSI_socket_locker_state_v1 PSI_socket_locker_state;
+typedef struct PSI_sp_locker_state_v1 PSI_sp_locker_state;
+typedef struct PSI_metadata_locker_state_v1 PSI_metadata_locker_state;
+#endif
+
+#ifdef USE_PSI_2
+typedef struct PSI_v2 PSI;
+typedef struct PSI_mutex_info_v2 PSI_mutex_info;
+typedef struct PSI_rwlock_info_v2 PSI_rwlock_info;
+typedef struct PSI_cond_info_v2 PSI_cond_info;
+typedef struct PSI_thread_info_v2 PSI_thread_info;
+typedef struct PSI_file_info_v2 PSI_file_info;
+typedef struct PSI_stage_info_v2 PSI_stage_info;
+typedef struct PSI_statement_info_v2 PSI_statement_info;
+typedef struct PSI_transaction_info_v2 PSI_transaction_info;
+typedef struct PSI_socket_info_v2 PSI_socket_info;
+typedef struct PSI_idle_locker_state_v2 PSI_idle_locker_state;
+typedef struct PSI_mutex_locker_state_v2 PSI_mutex_locker_state;
+typedef struct PSI_rwlock_locker_state_v2 PSI_rwlock_locker_state;
+typedef struct PSI_cond_locker_state_v2 PSI_cond_locker_state;
+typedef struct PSI_file_locker_state_v2 PSI_file_locker_state;
+typedef struct PSI_statement_locker_state_v2 PSI_statement_locker_state;
+typedef struct PSI_transaction_locker_state_v2 PSI_transaction_locker_state;
+typedef struct PSI_socket_locker_state_v2 PSI_socket_locker_state;
+typedef struct PSI_sp_locker_state_v2 PSI_sp_locker_state;
+typedef struct PSI_metadata_locker_state_v2 PSI_metadata_locker_state;
+#endif
+
+#ifndef HAVE_PSI_INTERFACE
+
+/**
+ Dummy structure, used to declare PSI_server when no instrumentation
+ is available.
+ The content does not matter, since PSI_server will be NULL.
+*/
+struct PSI_none
+{
+ int opaque;
+};
+typedef struct PSI_none PSI;
+
+/**
+ Stage instrument information.
+ @since PSI_VERSION_1
+ This structure is used to register an instrumented stage.
+*/
+struct PSI_stage_info_none
+{
+ /** Unused stage key. */
+ unsigned int m_key;
+ /** The name of the stage instrument. */
+ const char *m_name;
+ /** Unused stage flags. */
+ int m_flags;
+};
+
+/**
+ The stage instrumentation has to co exist with the legacy
+ THD::set_proc_info instrumentation.
+ To avoid duplication of the instrumentation in the server,
+ the common PSI_stage_info structure is used,
+ so we export it here, even when not building
+ with HAVE_PSI_INTERFACE.
+*/
+typedef struct PSI_stage_info_none PSI_stage_info;
+typedef struct PSI_stage_info_none PSI_statement_info;
+typedef struct PSI_stage_info_none PSI_sp_locker_state;
+typedef struct PSI_stage_info_none PSI_metadata_locker_state;
+typedef struct PSI_stage_info_none PSI_metadata_locker;
+
+#endif /* HAVE_PSI_INTERFACE */
+
+extern MYSQL_PLUGIN_IMPORT PSI *PSI_server;
+
+/*
+ Allow to override PSI_XXX_CALL at compile time
+ with more efficient implementations, if available.
+ If nothing better is available,
+ make a dynamic call using the PSI_server function pointer.
+*/
+
+#define PSI_DYNAMIC_CALL(M) PSI_server->M
+
+/** @} */
+
+C_MODE_END
+#endif /* MYSQL_PERFORMANCE_SCHEMA_INTERFACE_H */
+
diff --git a/include/mysql/psi/psi_abi_v0.h b/include/mysql/psi/psi_abi_v0.h
new file mode 100644
index 00000000..5c879fb8
--- /dev/null
+++ b/include/mysql/psi/psi_abi_v0.h
@@ -0,0 +1,31 @@
+/* Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License, version 2.0, for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */
+
+/**
+ @file mysql/psi/psi_abi_v0.h
+ ABI check for mysql/psi/psi.h, when compiling without instrumentation.
+ This file is only used to automate detection of changes between versions.
+ Do not include this file, include mysql/psi/psi.h instead.
+*/
+#define MY_GLOBAL_INCLUDED
+#include "mysql/psi/psi.h"
+
diff --git a/include/mysql/psi/psi_abi_v0.h.pp b/include/mysql/psi/psi_abi_v0.h.pp
new file mode 100644
index 00000000..47dc72b7
--- /dev/null
+++ b/include/mysql/psi/psi_abi_v0.h.pp
@@ -0,0 +1,100 @@
+#include "mysql/psi/psi.h"
+#include "psi_base.h"
+#include "psi_memory.h"
+#include "psi_base.h"
+struct PSI_thread;
+typedef unsigned int PSI_memory_key;
+C_MODE_START
+struct MDL_key;
+typedef struct MDL_key MDL_key;
+typedef int opaque_mdl_type;
+typedef int opaque_mdl_duration;
+typedef int opaque_mdl_status;
+typedef int opaque_vio_type;
+struct TABLE_SHARE;
+struct sql_digest_storage;
+ struct opaque_THD
+ {
+ int dummy;
+ };
+ typedef struct opaque_THD THD;
+struct PSI_mutex;
+typedef struct PSI_mutex PSI_mutex;
+struct PSI_rwlock;
+typedef struct PSI_rwlock PSI_rwlock;
+struct PSI_cond;
+typedef struct PSI_cond PSI_cond;
+struct PSI_table_share;
+typedef struct PSI_table_share PSI_table_share;
+struct PSI_table;
+typedef struct PSI_table PSI_table;
+struct PSI_thread;
+typedef struct PSI_thread PSI_thread;
+struct PSI_file;
+typedef struct PSI_file PSI_file;
+struct PSI_socket;
+typedef struct PSI_socket PSI_socket;
+struct PSI_prepared_stmt;
+typedef struct PSI_prepared_stmt PSI_prepared_stmt;
+struct PSI_table_locker;
+typedef struct PSI_table_locker PSI_table_locker;
+struct PSI_statement_locker;
+typedef struct PSI_statement_locker PSI_statement_locker;
+struct PSI_transaction_locker;
+typedef struct PSI_transaction_locker PSI_transaction_locker;
+struct PSI_idle_locker;
+typedef struct PSI_idle_locker PSI_idle_locker;
+struct PSI_digest_locker;
+typedef struct PSI_digest_locker PSI_digest_locker;
+struct PSI_sp_share;
+typedef struct PSI_sp_share PSI_sp_share;
+struct PSI_sp_locker;
+typedef struct PSI_sp_locker PSI_sp_locker;
+struct PSI_metadata_lock;
+typedef struct PSI_metadata_lock PSI_metadata_lock;
+struct PSI_stage_progress
+{
+ ulonglong m_work_completed;
+ ulonglong m_work_estimated;
+};
+typedef struct PSI_stage_progress PSI_stage_progress;
+enum PSI_table_io_operation
+{
+ PSI_TABLE_FETCH_ROW= 0,
+ PSI_TABLE_WRITE_ROW= 1,
+ PSI_TABLE_UPDATE_ROW= 2,
+ PSI_TABLE_DELETE_ROW= 3
+};
+typedef enum PSI_table_io_operation PSI_table_io_operation;
+struct PSI_table_locker_state
+{
+ uint m_flags;
+ enum PSI_table_io_operation m_io_operation;
+ struct PSI_table *m_table;
+ struct PSI_table_share *m_table_share;
+ struct PSI_thread *m_thread;
+ ulonglong m_timer_start;
+ ulonglong (*m_timer)(void);
+ void *m_wait;
+ uint m_index;
+};
+typedef struct PSI_table_locker_state PSI_table_locker_state;
+struct PSI_bootstrap
+{
+ void* (*get_interface)(int version);
+};
+typedef struct PSI_bootstrap PSI_bootstrap;
+struct PSI_none
+{
+ int opaque;
+};
+typedef struct PSI_none PSI;
+struct PSI_stage_info_none
+{
+ unsigned int m_key;
+ const char *m_name;
+ int m_flags;
+};
+typedef struct PSI_stage_info_none PSI_stage_info;
+extern MYSQL_PLUGIN_IMPORT PSI *PSI_server;
+C_MODE_END
diff --git a/include/mysql/psi/psi_abi_v1.h b/include/mysql/psi/psi_abi_v1.h
new file mode 100644
index 00000000..488e832c
--- /dev/null
+++ b/include/mysql/psi/psi_abi_v1.h
@@ -0,0 +1,33 @@
+/* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License, version 2.0, for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */
+
+/**
+ @file mysql/psi/psi_abi_v1.h
+ ABI check for mysql/psi/psi.h, when using PSI_VERSION_1.
+ This file is only used to automate detection of changes between versions.
+ Do not include this file, include mysql/psi/psi.h instead.
+*/
+#define USE_PSI_1
+#define HAVE_PSI_INTERFACE
+#define MY_GLOBAL_INCLUDED
+#include "mysql/psi/psi.h"
+
diff --git a/include/mysql/psi/psi_abi_v1.h.pp b/include/mysql/psi/psi_abi_v1.h.pp
new file mode 100644
index 00000000..60a6a803
--- /dev/null
+++ b/include/mysql/psi/psi_abi_v1.h.pp
@@ -0,0 +1,854 @@
+extern "C" {
+}
+extern "C" {
+struct PSI_thread;
+typedef unsigned int PSI_memory_key;
+struct PSI_memory_info_v1
+{
+ PSI_memory_key *m_key;
+ const char *m_name;
+ int m_flags;
+};
+typedef struct PSI_memory_info_v1 PSI_memory_info_v1;
+typedef void (*register_memory_v1_t)
+ (const char *category, struct PSI_memory_info_v1 *info, int count);
+typedef PSI_memory_key (*memory_alloc_v1_t)
+ (PSI_memory_key key, size_t size, struct PSI_thread ** owner);
+typedef PSI_memory_key (*memory_realloc_v1_t)
+ (PSI_memory_key key, size_t old_size, size_t new_size, struct PSI_thread ** owner);
+typedef PSI_memory_key (*memory_claim_v1_t)
+ (PSI_memory_key key, size_t size, struct PSI_thread ** owner);
+typedef void (*memory_free_v1_t)
+ (PSI_memory_key key, size_t size, struct PSI_thread * owner);
+typedef struct PSI_memory_info_v1 PSI_memory_info;
+}
+C_MODE_START
+struct MDL_key;
+typedef struct MDL_key MDL_key;
+typedef int opaque_mdl_type;
+typedef int opaque_mdl_duration;
+typedef int opaque_mdl_status;
+typedef int opaque_vio_type;
+struct TABLE_SHARE;
+struct sql_digest_storage;
+ class THD;
+struct PSI_mutex;
+typedef struct PSI_mutex PSI_mutex;
+struct PSI_rwlock;
+typedef struct PSI_rwlock PSI_rwlock;
+struct PSI_cond;
+typedef struct PSI_cond PSI_cond;
+struct PSI_table_share;
+typedef struct PSI_table_share PSI_table_share;
+struct PSI_table;
+typedef struct PSI_table PSI_table;
+struct PSI_thread;
+typedef struct PSI_thread PSI_thread;
+struct PSI_file;
+typedef struct PSI_file PSI_file;
+struct PSI_socket;
+typedef struct PSI_socket PSI_socket;
+struct PSI_prepared_stmt;
+typedef struct PSI_prepared_stmt PSI_prepared_stmt;
+struct PSI_table_locker;
+typedef struct PSI_table_locker PSI_table_locker;
+struct PSI_statement_locker;
+typedef struct PSI_statement_locker PSI_statement_locker;
+struct PSI_transaction_locker;
+typedef struct PSI_transaction_locker PSI_transaction_locker;
+struct PSI_idle_locker;
+typedef struct PSI_idle_locker PSI_idle_locker;
+struct PSI_digest_locker;
+typedef struct PSI_digest_locker PSI_digest_locker;
+struct PSI_sp_share;
+typedef struct PSI_sp_share PSI_sp_share;
+struct PSI_sp_locker;
+typedef struct PSI_sp_locker PSI_sp_locker;
+struct PSI_metadata_lock;
+typedef struct PSI_metadata_lock PSI_metadata_lock;
+struct PSI_stage_progress
+{
+ ulonglong m_work_completed;
+ ulonglong m_work_estimated;
+};
+typedef struct PSI_stage_progress PSI_stage_progress;
+enum PSI_table_io_operation
+{
+ PSI_TABLE_FETCH_ROW= 0,
+ PSI_TABLE_WRITE_ROW= 1,
+ PSI_TABLE_UPDATE_ROW= 2,
+ PSI_TABLE_DELETE_ROW= 3
+};
+typedef enum PSI_table_io_operation PSI_table_io_operation;
+struct PSI_table_locker_state
+{
+ uint m_flags;
+ enum PSI_table_io_operation m_io_operation;
+ struct PSI_table *m_table;
+ struct PSI_table_share *m_table_share;
+ struct PSI_thread *m_thread;
+ ulonglong m_timer_start;
+ ulonglong (*m_timer)(void);
+ void *m_wait;
+ uint m_index;
+};
+typedef struct PSI_table_locker_state PSI_table_locker_state;
+struct PSI_bootstrap
+{
+ void* (*get_interface)(int version);
+};
+typedef struct PSI_bootstrap PSI_bootstrap;
+struct PSI_mutex_locker;
+typedef struct PSI_mutex_locker PSI_mutex_locker;
+struct PSI_rwlock_locker;
+typedef struct PSI_rwlock_locker PSI_rwlock_locker;
+struct PSI_cond_locker;
+typedef struct PSI_cond_locker PSI_cond_locker;
+struct PSI_file_locker;
+typedef struct PSI_file_locker PSI_file_locker;
+struct PSI_socket_locker;
+typedef struct PSI_socket_locker PSI_socket_locker;
+struct PSI_metadata_locker;
+typedef struct PSI_metadata_locker PSI_metadata_locker;
+enum PSI_mutex_operation
+{
+ PSI_MUTEX_LOCK= 0,
+ PSI_MUTEX_TRYLOCK= 1
+};
+typedef enum PSI_mutex_operation PSI_mutex_operation;
+enum PSI_rwlock_operation
+{
+ PSI_RWLOCK_READLOCK= 0,
+ PSI_RWLOCK_WRITELOCK= 1,
+ PSI_RWLOCK_TRYREADLOCK= 2,
+ PSI_RWLOCK_TRYWRITELOCK= 3,
+ PSI_RWLOCK_SHAREDLOCK= 4,
+ PSI_RWLOCK_SHAREDEXCLUSIVELOCK= 5,
+ PSI_RWLOCK_EXCLUSIVELOCK= 6,
+ PSI_RWLOCK_TRYSHAREDLOCK= 7,
+ PSI_RWLOCK_TRYSHAREDEXCLUSIVELOCK= 8,
+ PSI_RWLOCK_TRYEXCLUSIVELOCK= 9
+};
+typedef enum PSI_rwlock_operation PSI_rwlock_operation;
+enum PSI_cond_operation
+{
+ PSI_COND_WAIT= 0,
+ PSI_COND_TIMEDWAIT= 1
+};
+typedef enum PSI_cond_operation PSI_cond_operation;
+enum PSI_file_operation
+{
+ PSI_FILE_CREATE= 0,
+ PSI_FILE_CREATE_TMP= 1,
+ PSI_FILE_OPEN= 2,
+ PSI_FILE_STREAM_OPEN= 3,
+ PSI_FILE_CLOSE= 4,
+ PSI_FILE_STREAM_CLOSE= 5,
+ PSI_FILE_READ= 6,
+ PSI_FILE_WRITE= 7,
+ PSI_FILE_SEEK= 8,
+ PSI_FILE_TELL= 9,
+ PSI_FILE_FLUSH= 10,
+ PSI_FILE_STAT= 11,
+ PSI_FILE_FSTAT= 12,
+ PSI_FILE_CHSIZE= 13,
+ PSI_FILE_DELETE= 14,
+ PSI_FILE_RENAME= 15,
+ PSI_FILE_SYNC= 16
+};
+typedef enum PSI_file_operation PSI_file_operation;
+enum PSI_table_lock_operation
+{
+ PSI_TABLE_LOCK= 0,
+ PSI_TABLE_EXTERNAL_LOCK= 1
+};
+typedef enum PSI_table_lock_operation PSI_table_lock_operation;
+enum PSI_socket_state
+{
+ PSI_SOCKET_STATE_IDLE= 1,
+ PSI_SOCKET_STATE_ACTIVE= 2
+};
+typedef enum PSI_socket_state PSI_socket_state;
+enum PSI_socket_operation
+{
+ PSI_SOCKET_CREATE= 0,
+ PSI_SOCKET_CONNECT= 1,
+ PSI_SOCKET_BIND= 2,
+ PSI_SOCKET_CLOSE= 3,
+ PSI_SOCKET_SEND= 4,
+ PSI_SOCKET_RECV= 5,
+ PSI_SOCKET_SENDTO= 6,
+ PSI_SOCKET_RECVFROM= 7,
+ PSI_SOCKET_SENDMSG= 8,
+ PSI_SOCKET_RECVMSG= 9,
+ PSI_SOCKET_SEEK= 10,
+ PSI_SOCKET_OPT= 11,
+ PSI_SOCKET_STAT= 12,
+ PSI_SOCKET_SHUTDOWN= 13,
+ PSI_SOCKET_SELECT= 14
+};
+typedef enum PSI_socket_operation PSI_socket_operation;
+typedef unsigned int PSI_mutex_key;
+typedef unsigned int PSI_rwlock_key;
+typedef unsigned int PSI_cond_key;
+typedef unsigned int PSI_thread_key;
+typedef unsigned int PSI_file_key;
+typedef unsigned int PSI_stage_key;
+typedef unsigned int PSI_statement_key;
+typedef unsigned int PSI_socket_key;
+struct PSI_mutex_info_v1
+{
+ PSI_mutex_key *m_key;
+ const char *m_name;
+ int m_flags;
+};
+typedef struct PSI_mutex_info_v1 PSI_mutex_info_v1;
+struct PSI_rwlock_info_v1
+{
+ PSI_rwlock_key *m_key;
+ const char *m_name;
+ int m_flags;
+};
+typedef struct PSI_rwlock_info_v1 PSI_rwlock_info_v1;
+struct PSI_cond_info_v1
+{
+ PSI_cond_key *m_key;
+ const char *m_name;
+ int m_flags;
+};
+typedef struct PSI_cond_info_v1 PSI_cond_info_v1;
+struct PSI_thread_info_v1
+{
+ PSI_thread_key *m_key;
+ const char *m_name;
+ int m_flags;
+};
+typedef struct PSI_thread_info_v1 PSI_thread_info_v1;
+struct PSI_file_info_v1
+{
+ PSI_file_key *m_key;
+ const char *m_name;
+ int m_flags;
+};
+typedef struct PSI_file_info_v1 PSI_file_info_v1;
+struct PSI_stage_info_v1
+{
+ PSI_stage_key m_key;
+ const char *m_name;
+ int m_flags;
+};
+typedef struct PSI_stage_info_v1 PSI_stage_info_v1;
+struct PSI_statement_info_v1
+{
+ PSI_statement_key m_key;
+ const char *m_name;
+ int m_flags;
+};
+typedef struct PSI_statement_info_v1 PSI_statement_info_v1;
+struct PSI_socket_info_v1
+{
+ PSI_socket_key *m_key;
+ const char *m_name;
+ int m_flags;
+};
+typedef struct PSI_socket_info_v1 PSI_socket_info_v1;
+struct PSI_idle_locker_state_v1
+{
+ uint m_flags;
+ struct PSI_thread *m_thread;
+ ulonglong m_timer_start;
+ ulonglong (*m_timer)(void);
+ void *m_wait;
+};
+typedef struct PSI_idle_locker_state_v1 PSI_idle_locker_state_v1;
+struct PSI_mutex_locker_state_v1
+{
+ uint m_flags;
+ enum PSI_mutex_operation m_operation;
+ struct PSI_mutex *m_mutex;
+ struct PSI_thread *m_thread;
+ ulonglong m_timer_start;
+ ulonglong (*m_timer)(void);
+ void *m_wait;
+};
+typedef struct PSI_mutex_locker_state_v1 PSI_mutex_locker_state_v1;
+struct PSI_rwlock_locker_state_v1
+{
+ uint m_flags;
+ enum PSI_rwlock_operation m_operation;
+ struct PSI_rwlock *m_rwlock;
+ struct PSI_thread *m_thread;
+ ulonglong m_timer_start;
+ ulonglong (*m_timer)(void);
+ void *m_wait;
+};
+typedef struct PSI_rwlock_locker_state_v1 PSI_rwlock_locker_state_v1;
+struct PSI_cond_locker_state_v1
+{
+ uint m_flags;
+ enum PSI_cond_operation m_operation;
+ struct PSI_cond *m_cond;
+ struct PSI_mutex *m_mutex;
+ struct PSI_thread *m_thread;
+ ulonglong m_timer_start;
+ ulonglong (*m_timer)(void);
+ void *m_wait;
+};
+typedef struct PSI_cond_locker_state_v1 PSI_cond_locker_state_v1;
+struct PSI_file_locker_state_v1
+{
+ uint m_flags;
+ enum PSI_file_operation m_operation;
+ struct PSI_file *m_file;
+ const char *m_name;
+ void *m_class;
+ struct PSI_thread *m_thread;
+ size_t m_number_of_bytes;
+ ulonglong m_timer_start;
+ ulonglong (*m_timer)(void);
+ void *m_wait;
+};
+typedef struct PSI_file_locker_state_v1 PSI_file_locker_state_v1;
+struct PSI_metadata_locker_state_v1
+{
+ uint m_flags;
+ struct PSI_metadata_lock *m_metadata_lock;
+ struct PSI_thread *m_thread;
+ ulonglong m_timer_start;
+ ulonglong (*m_timer)(void);
+ void *m_wait;
+};
+typedef struct PSI_metadata_locker_state_v1 PSI_metadata_locker_state_v1;
+struct PSI_statement_locker_state_v1
+{
+ my_bool m_discarded;
+ my_bool m_in_prepare;
+ uchar m_no_index_used;
+ uchar m_no_good_index_used;
+ uint m_flags;
+ void *m_class;
+ struct PSI_thread *m_thread;
+ ulonglong m_timer_start;
+ ulonglong (*m_timer)(void);
+ void *m_statement;
+ ulonglong m_lock_time;
+ ulonglong m_rows_sent;
+ ulonglong m_rows_examined;
+ ulong m_created_tmp_disk_tables;
+ ulong m_created_tmp_tables;
+ ulong m_select_full_join;
+ ulong m_select_full_range_join;
+ ulong m_select_range;
+ ulong m_select_range_check;
+ ulong m_select_scan;
+ ulong m_sort_merge_passes;
+ ulong m_sort_range;
+ ulong m_sort_rows;
+ ulong m_sort_scan;
+ const struct sql_digest_storage *m_digest;
+ char m_schema_name[(64 * 3)];
+ uint m_schema_name_length;
+ uint m_cs_number;
+ PSI_sp_share *m_parent_sp_share;
+ PSI_prepared_stmt *m_parent_prepared_stmt;
+};
+typedef struct PSI_statement_locker_state_v1 PSI_statement_locker_state_v1;
+struct PSI_transaction_locker_state_v1
+{
+ uint m_flags;
+ void *m_class;
+ struct PSI_thread *m_thread;
+ ulonglong m_timer_start;
+ ulonglong (*m_timer)(void);
+ void *m_transaction;
+ my_bool m_read_only;
+ my_bool m_autocommit;
+ ulong m_statement_count;
+ ulong m_savepoint_count;
+ ulong m_rollback_to_savepoint_count;
+ ulong m_release_savepoint_count;
+};
+typedef struct PSI_transaction_locker_state_v1 PSI_transaction_locker_state_v1;
+struct PSI_socket_locker_state_v1
+{
+ uint m_flags;
+ struct PSI_socket *m_socket;
+ struct PSI_thread *m_thread;
+ size_t m_number_of_bytes;
+ ulonglong m_timer_start;
+ ulonglong (*m_timer)(void);
+ enum PSI_socket_operation m_operation;
+ const char* m_src_file;
+ int m_src_line;
+ void *m_wait;
+};
+typedef struct PSI_socket_locker_state_v1 PSI_socket_locker_state_v1;
+struct PSI_sp_locker_state_v1
+{
+ uint m_flags;
+ struct PSI_thread *m_thread;
+ ulonglong m_timer_start;
+ ulonglong (*m_timer)(void);
+ PSI_sp_share* m_sp_share;
+};
+typedef struct PSI_sp_locker_state_v1 PSI_sp_locker_state_v1;
+typedef void (*register_mutex_v1_t)
+ (const char *category, struct PSI_mutex_info_v1 *info, int count);
+typedef void (*register_rwlock_v1_t)
+ (const char *category, struct PSI_rwlock_info_v1 *info, int count);
+typedef void (*register_cond_v1_t)
+ (const char *category, struct PSI_cond_info_v1 *info, int count);
+typedef void (*register_thread_v1_t)
+ (const char *category, struct PSI_thread_info_v1 *info, int count);
+typedef void (*register_file_v1_t)
+ (const char *category, struct PSI_file_info_v1 *info, int count);
+typedef void (*register_stage_v1_t)
+ (const char *category, struct PSI_stage_info_v1 **info, int count);
+typedef void (*register_statement_v1_t)
+ (const char *category, struct PSI_statement_info_v1 *info, int count);
+typedef void (*register_socket_v1_t)
+ (const char *category, struct PSI_socket_info_v1 *info, int count);
+typedef struct PSI_mutex* (*init_mutex_v1_t)
+ (PSI_mutex_key key, const void *identity);
+typedef void (*destroy_mutex_v1_t)(struct PSI_mutex *mutex);
+typedef struct PSI_rwlock* (*init_rwlock_v1_t)
+ (PSI_rwlock_key key, const void *identity);
+typedef void (*destroy_rwlock_v1_t)(struct PSI_rwlock *rwlock);
+typedef struct PSI_cond* (*init_cond_v1_t)
+ (PSI_cond_key key, const void *identity);
+typedef void (*destroy_cond_v1_t)(struct PSI_cond *cond);
+typedef struct PSI_socket* (*init_socket_v1_t)
+ (PSI_socket_key key, const my_socket *fd,
+ const struct sockaddr *addr, socklen_t addr_len);
+typedef void (*destroy_socket_v1_t)(struct PSI_socket *socket);
+typedef struct PSI_table_share* (*get_table_share_v1_t)
+ (my_bool temporary, struct TABLE_SHARE *share);
+typedef void (*release_table_share_v1_t)(struct PSI_table_share *share);
+typedef void (*drop_table_share_v1_t)
+ (my_bool temporary, const char *schema_name, int schema_name_length,
+ const char *table_name, int table_name_length);
+typedef struct PSI_table* (*open_table_v1_t)
+ (struct PSI_table_share *share, const void *identity);
+typedef void (*unbind_table_v1_t)
+ (struct PSI_table *table);
+typedef PSI_table* (*rebind_table_v1_t)
+ (PSI_table_share *share, const void *identity, PSI_table *table);
+typedef void (*close_table_v1_t)(struct TABLE_SHARE *server_share,
+ struct PSI_table *table);
+typedef void (*create_file_v1_t)(PSI_file_key key, const char *name,
+ File file);
+typedef int (*spawn_thread_v1_t)(PSI_thread_key key,
+ pthread_t *thread,
+ const pthread_attr_t *attr,
+ void *(*start_routine)(void*), void *arg);
+typedef struct PSI_thread* (*new_thread_v1_t)
+ (PSI_thread_key key, const void *identity, ulonglong thread_id);
+typedef void (*set_thread_THD_v1_t)(struct PSI_thread *thread,
+ THD *thd);
+typedef void (*set_thread_id_v1_t)(struct PSI_thread *thread,
+ ulonglong id);
+typedef void (*set_thread_os_id_v1_t)(struct PSI_thread *thread);
+typedef struct PSI_thread* (*get_thread_v1_t)(void);
+typedef void (*set_thread_user_v1_t)(const char *user, int user_len);
+typedef void (*set_thread_account_v1_t)(const char *user, int user_len,
+ const char *host, int host_len);
+typedef void (*set_thread_db_v1_t)(const char* db, int db_len);
+typedef void (*set_thread_command_v1_t)(int command);
+typedef void (*set_connection_type_v1_t)(opaque_vio_type conn_type);
+typedef void (*set_thread_start_time_v1_t)(time_t start_time);
+typedef void (*set_thread_state_v1_t)(const char* state);
+typedef void (*set_thread_info_v1_t)(const char* info, uint info_len);
+typedef void (*set_thread_v1_t)(struct PSI_thread *thread);
+typedef void (*delete_current_thread_v1_t)(void);
+typedef void (*delete_thread_v1_t)(struct PSI_thread *thread);
+typedef struct PSI_file_locker* (*get_thread_file_name_locker_v1_t)
+ (struct PSI_file_locker_state_v1 *state,
+ PSI_file_key key, enum PSI_file_operation op, const char *name,
+ const void *identity);
+typedef struct PSI_file_locker* (*get_thread_file_stream_locker_v1_t)
+ (struct PSI_file_locker_state_v1 *state,
+ struct PSI_file *file, enum PSI_file_operation op);
+typedef struct PSI_file_locker* (*get_thread_file_descriptor_locker_v1_t)
+ (struct PSI_file_locker_state_v1 *state,
+ File file, enum PSI_file_operation op);
+typedef void (*unlock_mutex_v1_t)
+ (struct PSI_mutex *mutex);
+typedef void (*unlock_rwlock_v1_t)
+ (struct PSI_rwlock *rwlock);
+typedef void (*signal_cond_v1_t)
+ (struct PSI_cond *cond);
+typedef void (*broadcast_cond_v1_t)
+ (struct PSI_cond *cond);
+typedef struct PSI_idle_locker* (*start_idle_wait_v1_t)
+ (struct PSI_idle_locker_state_v1 *state, const char *src_file, uint src_line);
+typedef void (*end_idle_wait_v1_t)
+ (struct PSI_idle_locker *locker);
+typedef struct PSI_mutex_locker* (*start_mutex_wait_v1_t)
+ (struct PSI_mutex_locker_state_v1 *state,
+ struct PSI_mutex *mutex,
+ enum PSI_mutex_operation op,
+ const char *src_file, uint src_line);
+typedef void (*end_mutex_wait_v1_t)
+ (struct PSI_mutex_locker *locker, int rc);
+typedef struct PSI_rwlock_locker* (*start_rwlock_rdwait_v1_t)
+ (struct PSI_rwlock_locker_state_v1 *state,
+ struct PSI_rwlock *rwlock,
+ enum PSI_rwlock_operation op,
+ const char *src_file, uint src_line);
+typedef void (*end_rwlock_rdwait_v1_t)
+ (struct PSI_rwlock_locker *locker, int rc);
+typedef struct PSI_rwlock_locker* (*start_rwlock_wrwait_v1_t)
+ (struct PSI_rwlock_locker_state_v1 *state,
+ struct PSI_rwlock *rwlock,
+ enum PSI_rwlock_operation op,
+ const char *src_file, uint src_line);
+typedef void (*end_rwlock_wrwait_v1_t)
+ (struct PSI_rwlock_locker *locker, int rc);
+typedef struct PSI_cond_locker* (*start_cond_wait_v1_t)
+ (struct PSI_cond_locker_state_v1 *state,
+ struct PSI_cond *cond,
+ struct PSI_mutex *mutex,
+ enum PSI_cond_operation op,
+ const char *src_file, uint src_line);
+typedef void (*end_cond_wait_v1_t)
+ (struct PSI_cond_locker *locker, int rc);
+typedef struct PSI_table_locker* (*start_table_io_wait_v1_t)
+ (struct PSI_table_locker_state *state,
+ struct PSI_table *table,
+ enum PSI_table_io_operation op,
+ uint index,
+ const char *src_file, uint src_line);
+typedef void (*end_table_io_wait_v1_t)
+ (struct PSI_table_locker *locker,
+ ulonglong numrows);
+typedef struct PSI_table_locker* (*start_table_lock_wait_v1_t)
+ (struct PSI_table_locker_state *state,
+ struct PSI_table *table,
+ enum PSI_table_lock_operation op,
+ ulong flags,
+ const char *src_file, uint src_line);
+typedef void (*end_table_lock_wait_v1_t)(struct PSI_table_locker *locker);
+typedef void (*unlock_table_v1_t)(struct PSI_table *table);
+typedef void (*start_file_open_wait_v1_t)
+ (struct PSI_file_locker *locker, const char *src_file, uint src_line);
+typedef struct PSI_file* (*end_file_open_wait_v1_t)
+ (struct PSI_file_locker *locker, void *result);
+typedef void (*end_file_open_wait_and_bind_to_descriptor_v1_t)
+ (struct PSI_file_locker *locker, File file);
+typedef void (*end_temp_file_open_wait_and_bind_to_descriptor_v1_t)
+ (struct PSI_file_locker *locker, File file, const char *filename);
+typedef void (*start_file_wait_v1_t)
+ (struct PSI_file_locker *locker, size_t count,
+ const char *src_file, uint src_line);
+typedef void (*end_file_wait_v1_t)
+ (struct PSI_file_locker *locker, size_t count);
+typedef void (*start_file_close_wait_v1_t)
+ (struct PSI_file_locker *locker, const char *src_file, uint src_line);
+typedef void (*end_file_close_wait_v1_t)
+ (struct PSI_file_locker *locker, int rc);
+typedef void (*end_file_rename_wait_v1_t)
+ (struct PSI_file_locker *locker, const char *old_name,
+ const char *new_name, int rc);
+typedef PSI_stage_progress* (*start_stage_v1_t)
+ (PSI_stage_key key, const char *src_file, int src_line);
+typedef PSI_stage_progress* (*get_current_stage_progress_v1_t)(void);
+typedef void (*end_stage_v1_t) (void);
+typedef struct PSI_statement_locker* (*get_thread_statement_locker_v1_t)
+ (struct PSI_statement_locker_state_v1 *state,
+ PSI_statement_key key, const void *charset, PSI_sp_share *sp_share);
+typedef struct PSI_statement_locker* (*refine_statement_v1_t)
+ (struct PSI_statement_locker *locker,
+ PSI_statement_key key);
+typedef void (*start_statement_v1_t)
+ (struct PSI_statement_locker *locker,
+ const char *db, uint db_length,
+ const char *src_file, uint src_line);
+typedef void (*set_statement_text_v1_t)
+ (struct PSI_statement_locker *locker,
+ const char *text, uint text_len);
+typedef void (*set_statement_lock_time_t)
+ (struct PSI_statement_locker *locker, ulonglong lock_time);
+typedef void (*set_statement_rows_sent_t)
+ (struct PSI_statement_locker *locker, ulonglong count);
+typedef void (*set_statement_rows_examined_t)
+ (struct PSI_statement_locker *locker, ulonglong count);
+typedef void (*inc_statement_created_tmp_disk_tables_t)
+ (struct PSI_statement_locker *locker, ulong count);
+typedef void (*inc_statement_created_tmp_tables_t)
+ (struct PSI_statement_locker *locker, ulong count);
+typedef void (*inc_statement_select_full_join_t)
+ (struct PSI_statement_locker *locker, ulong count);
+typedef void (*inc_statement_select_full_range_join_t)
+ (struct PSI_statement_locker *locker, ulong count);
+typedef void (*inc_statement_select_range_t)
+ (struct PSI_statement_locker *locker, ulong count);
+typedef void (*inc_statement_select_range_check_t)
+ (struct PSI_statement_locker *locker, ulong count);
+typedef void (*inc_statement_select_scan_t)
+ (struct PSI_statement_locker *locker, ulong count);
+typedef void (*inc_statement_sort_merge_passes_t)
+ (struct PSI_statement_locker *locker, ulong count);
+typedef void (*inc_statement_sort_range_t)
+ (struct PSI_statement_locker *locker, ulong count);
+typedef void (*inc_statement_sort_rows_t)
+ (struct PSI_statement_locker *locker, ulong count);
+typedef void (*inc_statement_sort_scan_t)
+ (struct PSI_statement_locker *locker, ulong count);
+typedef void (*set_statement_no_index_used_t)
+ (struct PSI_statement_locker *locker);
+typedef void (*set_statement_no_good_index_used_t)
+ (struct PSI_statement_locker *locker);
+typedef void (*end_statement_v1_t)
+ (struct PSI_statement_locker *locker, void *stmt_da);
+typedef struct PSI_transaction_locker* (*get_thread_transaction_locker_v1_t)
+ (struct PSI_transaction_locker_state_v1 *state, const void *xid,
+ ulonglong trxid, int isolation_level, my_bool read_only,
+ my_bool autocommit);
+typedef void (*start_transaction_v1_t)
+ (struct PSI_transaction_locker *locker,
+ const char *src_file, uint src_line);
+typedef void (*set_transaction_xid_v1_t)
+ (struct PSI_transaction_locker *locker,
+ const void *xid, int xa_state);
+typedef void (*set_transaction_xa_state_v1_t)
+ (struct PSI_transaction_locker *locker,
+ int xa_state);
+typedef void (*set_transaction_gtid_v1_t)
+ (struct PSI_transaction_locker *locker,
+ const void *sid, const void *gtid_spec);
+typedef void (*set_transaction_trxid_v1_t)
+ (struct PSI_transaction_locker *locker,
+ const ulonglong *trxid);
+typedef void (*inc_transaction_savepoints_v1_t)
+ (struct PSI_transaction_locker *locker, ulong count);
+typedef void (*inc_transaction_rollback_to_savepoint_v1_t)
+ (struct PSI_transaction_locker *locker, ulong count);
+typedef void (*inc_transaction_release_savepoint_v1_t)
+ (struct PSI_transaction_locker *locker, ulong count);
+typedef void (*end_transaction_v1_t)
+ (struct PSI_transaction_locker *locker,
+ my_bool commit);
+typedef struct PSI_socket_locker* (*start_socket_wait_v1_t)
+ (struct PSI_socket_locker_state_v1 *state,
+ struct PSI_socket *socket,
+ enum PSI_socket_operation op,
+ size_t count,
+ const char *src_file, uint src_line);
+typedef void (*end_socket_wait_v1_t)
+ (struct PSI_socket_locker *locker, size_t count);
+typedef void (*set_socket_state_v1_t)(struct PSI_socket *socket,
+ enum PSI_socket_state state);
+typedef void (*set_socket_info_v1_t)(struct PSI_socket *socket,
+ const my_socket *fd,
+ const struct sockaddr *addr,
+ socklen_t addr_len);
+typedef void (*set_socket_thread_owner_v1_t)(struct PSI_socket *socket);
+typedef PSI_prepared_stmt* (*create_prepared_stmt_v1_t)
+ (void *identity, uint stmt_id, PSI_statement_locker *locker,
+ const char *stmt_name, size_t stmt_name_length);
+typedef void (*destroy_prepared_stmt_v1_t)
+ (PSI_prepared_stmt *prepared_stmt);
+typedef void (*reprepare_prepared_stmt_v1_t)
+ (PSI_prepared_stmt *prepared_stmt);
+typedef void (*execute_prepared_stmt_v1_t)
+ (PSI_statement_locker *locker, PSI_prepared_stmt* prepared_stmt);
+typedef void (*set_prepared_stmt_text_v1_t)(PSI_prepared_stmt *prepared_stmt,
+ const char *text,
+ uint text_len);
+typedef struct PSI_digest_locker * (*digest_start_v1_t)
+ (struct PSI_statement_locker *locker);
+typedef void (*digest_end_v1_t)
+ (struct PSI_digest_locker *locker, const struct sql_digest_storage *digest);
+typedef PSI_sp_locker* (*start_sp_v1_t)
+ (struct PSI_sp_locker_state_v1 *state, struct PSI_sp_share* sp_share);
+typedef void (*end_sp_v1_t)
+ (struct PSI_sp_locker *locker);
+typedef void (*drop_sp_v1_t)
+ (uint object_type,
+ const char *schema_name, uint schema_name_length,
+ const char *object_name, uint object_name_length);
+typedef struct PSI_sp_share* (*get_sp_share_v1_t)
+ (uint object_type,
+ const char *schema_name, uint schema_name_length,
+ const char *object_name, uint object_name_length);
+typedef void (*release_sp_share_v1_t)(struct PSI_sp_share *share);
+typedef PSI_metadata_lock* (*create_metadata_lock_v1_t)
+ (void *identity,
+ const MDL_key *key,
+ opaque_mdl_type mdl_type,
+ opaque_mdl_duration mdl_duration,
+ opaque_mdl_status mdl_status,
+ const char *src_file,
+ uint src_line);
+typedef void (*set_metadata_lock_status_v1_t)(PSI_metadata_lock *lock,
+ opaque_mdl_status mdl_status);
+typedef void (*destroy_metadata_lock_v1_t)(PSI_metadata_lock *lock);
+typedef struct PSI_metadata_locker* (*start_metadata_wait_v1_t)
+ (struct PSI_metadata_locker_state_v1 *state,
+ struct PSI_metadata_lock *mdl,
+ const char *src_file, uint src_line);
+typedef void (*end_metadata_wait_v1_t)
+ (struct PSI_metadata_locker *locker, int rc);
+typedef int (*set_thread_connect_attrs_v1_t)(const char *buffer, uint length,
+ const void *from_cs);
+struct PSI_v1
+{
+ register_mutex_v1_t register_mutex;
+ register_rwlock_v1_t register_rwlock;
+ register_cond_v1_t register_cond;
+ register_thread_v1_t register_thread;
+ register_file_v1_t register_file;
+ register_stage_v1_t register_stage;
+ register_statement_v1_t register_statement;
+ register_socket_v1_t register_socket;
+ init_mutex_v1_t init_mutex;
+ destroy_mutex_v1_t destroy_mutex;
+ init_rwlock_v1_t init_rwlock;
+ destroy_rwlock_v1_t destroy_rwlock;
+ init_cond_v1_t init_cond;
+ destroy_cond_v1_t destroy_cond;
+ init_socket_v1_t init_socket;
+ destroy_socket_v1_t destroy_socket;
+ get_table_share_v1_t get_table_share;
+ release_table_share_v1_t release_table_share;
+ drop_table_share_v1_t drop_table_share;
+ open_table_v1_t open_table;
+ unbind_table_v1_t unbind_table;
+ rebind_table_v1_t rebind_table;
+ close_table_v1_t close_table;
+ create_file_v1_t create_file;
+ spawn_thread_v1_t spawn_thread;
+ new_thread_v1_t new_thread;
+ set_thread_id_v1_t set_thread_id;
+ set_thread_THD_v1_t set_thread_THD;
+ set_thread_os_id_v1_t set_thread_os_id;
+ get_thread_v1_t get_thread;
+ set_thread_user_v1_t set_thread_user;
+ set_thread_account_v1_t set_thread_account;
+ set_thread_db_v1_t set_thread_db;
+ set_thread_command_v1_t set_thread_command;
+ set_connection_type_v1_t set_connection_type;
+ set_thread_start_time_v1_t set_thread_start_time;
+ set_thread_state_v1_t set_thread_state;
+ set_thread_info_v1_t set_thread_info;
+ set_thread_v1_t set_thread;
+ delete_current_thread_v1_t delete_current_thread;
+ delete_thread_v1_t delete_thread;
+ get_thread_file_name_locker_v1_t get_thread_file_name_locker;
+ get_thread_file_stream_locker_v1_t get_thread_file_stream_locker;
+ get_thread_file_descriptor_locker_v1_t get_thread_file_descriptor_locker;
+ unlock_mutex_v1_t unlock_mutex;
+ unlock_rwlock_v1_t unlock_rwlock;
+ signal_cond_v1_t signal_cond;
+ broadcast_cond_v1_t broadcast_cond;
+ start_idle_wait_v1_t start_idle_wait;
+ end_idle_wait_v1_t end_idle_wait;
+ start_mutex_wait_v1_t start_mutex_wait;
+ end_mutex_wait_v1_t end_mutex_wait;
+ start_rwlock_rdwait_v1_t start_rwlock_rdwait;
+ end_rwlock_rdwait_v1_t end_rwlock_rdwait;
+ start_rwlock_wrwait_v1_t start_rwlock_wrwait;
+ end_rwlock_wrwait_v1_t end_rwlock_wrwait;
+ start_cond_wait_v1_t start_cond_wait;
+ end_cond_wait_v1_t end_cond_wait;
+ start_table_io_wait_v1_t start_table_io_wait;
+ end_table_io_wait_v1_t end_table_io_wait;
+ start_table_lock_wait_v1_t start_table_lock_wait;
+ end_table_lock_wait_v1_t end_table_lock_wait;
+ start_file_open_wait_v1_t start_file_open_wait;
+ end_file_open_wait_v1_t end_file_open_wait;
+ end_file_open_wait_and_bind_to_descriptor_v1_t
+ end_file_open_wait_and_bind_to_descriptor;
+ end_temp_file_open_wait_and_bind_to_descriptor_v1_t
+ end_temp_file_open_wait_and_bind_to_descriptor;
+ start_file_wait_v1_t start_file_wait;
+ end_file_wait_v1_t end_file_wait;
+ start_file_close_wait_v1_t start_file_close_wait;
+ end_file_close_wait_v1_t end_file_close_wait;
+ end_file_rename_wait_v1_t end_file_rename_wait;
+ start_stage_v1_t start_stage;
+ get_current_stage_progress_v1_t get_current_stage_progress;
+ end_stage_v1_t end_stage;
+ get_thread_statement_locker_v1_t get_thread_statement_locker;
+ refine_statement_v1_t refine_statement;
+ start_statement_v1_t start_statement;
+ set_statement_text_v1_t set_statement_text;
+ set_statement_lock_time_t set_statement_lock_time;
+ set_statement_rows_sent_t set_statement_rows_sent;
+ set_statement_rows_examined_t set_statement_rows_examined;
+ inc_statement_created_tmp_disk_tables_t inc_statement_created_tmp_disk_tables;
+ inc_statement_created_tmp_tables_t inc_statement_created_tmp_tables;
+ inc_statement_select_full_join_t inc_statement_select_full_join;
+ inc_statement_select_full_range_join_t inc_statement_select_full_range_join;
+ inc_statement_select_range_t inc_statement_select_range;
+ inc_statement_select_range_check_t inc_statement_select_range_check;
+ inc_statement_select_scan_t inc_statement_select_scan;
+ inc_statement_sort_merge_passes_t inc_statement_sort_merge_passes;
+ inc_statement_sort_range_t inc_statement_sort_range;
+ inc_statement_sort_rows_t inc_statement_sort_rows;
+ inc_statement_sort_scan_t inc_statement_sort_scan;
+ set_statement_no_index_used_t set_statement_no_index_used;
+ set_statement_no_good_index_used_t set_statement_no_good_index_used;
+ end_statement_v1_t end_statement;
+ get_thread_transaction_locker_v1_t get_thread_transaction_locker;
+ start_transaction_v1_t start_transaction;
+ set_transaction_xid_v1_t set_transaction_xid;
+ set_transaction_xa_state_v1_t set_transaction_xa_state;
+ set_transaction_gtid_v1_t set_transaction_gtid;
+ set_transaction_trxid_v1_t set_transaction_trxid;
+ inc_transaction_savepoints_v1_t inc_transaction_savepoints;
+ inc_transaction_rollback_to_savepoint_v1_t inc_transaction_rollback_to_savepoint;
+ inc_transaction_release_savepoint_v1_t inc_transaction_release_savepoint;
+ end_transaction_v1_t end_transaction;
+ start_socket_wait_v1_t start_socket_wait;
+ end_socket_wait_v1_t end_socket_wait;
+ set_socket_state_v1_t set_socket_state;
+ set_socket_info_v1_t set_socket_info;
+ set_socket_thread_owner_v1_t set_socket_thread_owner;
+ create_prepared_stmt_v1_t create_prepared_stmt;
+ destroy_prepared_stmt_v1_t destroy_prepared_stmt;
+ reprepare_prepared_stmt_v1_t reprepare_prepared_stmt;
+ execute_prepared_stmt_v1_t execute_prepared_stmt;
+ set_prepared_stmt_text_v1_t set_prepared_stmt_text;
+ digest_start_v1_t digest_start;
+ digest_end_v1_t digest_end;
+ set_thread_connect_attrs_v1_t set_thread_connect_attrs;
+ start_sp_v1_t start_sp;
+ end_sp_v1_t end_sp;
+ drop_sp_v1_t drop_sp;
+ get_sp_share_v1_t get_sp_share;
+ release_sp_share_v1_t release_sp_share;
+ register_memory_v1_t register_memory;
+ memory_alloc_v1_t memory_alloc;
+ memory_realloc_v1_t memory_realloc;
+ memory_claim_v1_t memory_claim;
+ memory_free_v1_t memory_free;
+ unlock_table_v1_t unlock_table;
+ create_metadata_lock_v1_t create_metadata_lock;
+ set_metadata_lock_status_v1_t set_metadata_lock_status;
+ destroy_metadata_lock_v1_t destroy_metadata_lock;
+ start_metadata_wait_v1_t start_metadata_wait;
+ end_metadata_wait_v1_t end_metadata_wait;
+};
+typedef struct PSI_v1 PSI;
+typedef struct PSI_mutex_info_v1 PSI_mutex_info;
+typedef struct PSI_rwlock_info_v1 PSI_rwlock_info;
+typedef struct PSI_cond_info_v1 PSI_cond_info;
+typedef struct PSI_thread_info_v1 PSI_thread_info;
+typedef struct PSI_file_info_v1 PSI_file_info;
+typedef struct PSI_stage_info_v1 PSI_stage_info;
+typedef struct PSI_statement_info_v1 PSI_statement_info;
+typedef struct PSI_transaction_info_v1 PSI_transaction_info;
+typedef struct PSI_socket_info_v1 PSI_socket_info;
+typedef struct PSI_idle_locker_state_v1 PSI_idle_locker_state;
+typedef struct PSI_mutex_locker_state_v1 PSI_mutex_locker_state;
+typedef struct PSI_rwlock_locker_state_v1 PSI_rwlock_locker_state;
+typedef struct PSI_cond_locker_state_v1 PSI_cond_locker_state;
+typedef struct PSI_file_locker_state_v1 PSI_file_locker_state;
+typedef struct PSI_statement_locker_state_v1 PSI_statement_locker_state;
+typedef struct PSI_transaction_locker_state_v1 PSI_transaction_locker_state;
+typedef struct PSI_socket_locker_state_v1 PSI_socket_locker_state;
+typedef struct PSI_sp_locker_state_v1 PSI_sp_locker_state;
+typedef struct PSI_metadata_locker_state_v1 PSI_metadata_locker_state;
+extern MYSQL_PLUGIN_IMPORT PSI *PSI_server;
+C_MODE_END
diff --git a/include/mysql/psi/psi_abi_v2.h b/include/mysql/psi/psi_abi_v2.h
new file mode 100644
index 00000000..3495d618
--- /dev/null
+++ b/include/mysql/psi/psi_abi_v2.h
@@ -0,0 +1,33 @@
+/* Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License, version 2.0, for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */
+
+/**
+ @file mysql/psi/psi_abi_v1.h
+ ABI check for mysql/psi/psi.h, when using PSI_VERSION_2.
+ This file is only used to automate detection of changes between versions.
+ Do not include this file, include mysql/psi/psi.h instead.
+*/
+#define USE_PSI_2
+#define HAVE_PSI_INTERFACE
+#define MY_GLOBAL_INCLUDED
+#include "mysql/psi/psi.h"
+
diff --git a/include/mysql/psi/psi_abi_v2.h.pp b/include/mysql/psi/psi_abi_v2.h.pp
new file mode 100644
index 00000000..a670e53a
--- /dev/null
+++ b/include/mysql/psi/psi_abi_v2.h.pp
@@ -0,0 +1,279 @@
+extern "C" {
+}
+extern "C" {
+struct PSI_thread;
+typedef unsigned int PSI_memory_key;
+struct PSI_memory_info_v2
+{
+ int placeholder;
+};
+typedef struct PSI_memory_info_v2 PSI_memory_info;
+}
+C_MODE_START
+struct MDL_key;
+typedef struct MDL_key MDL_key;
+typedef int opaque_mdl_type;
+typedef int opaque_mdl_duration;
+typedef int opaque_mdl_status;
+typedef int opaque_vio_type;
+struct TABLE_SHARE;
+struct sql_digest_storage;
+ class THD;
+struct PSI_mutex;
+typedef struct PSI_mutex PSI_mutex;
+struct PSI_rwlock;
+typedef struct PSI_rwlock PSI_rwlock;
+struct PSI_cond;
+typedef struct PSI_cond PSI_cond;
+struct PSI_table_share;
+typedef struct PSI_table_share PSI_table_share;
+struct PSI_table;
+typedef struct PSI_table PSI_table;
+struct PSI_thread;
+typedef struct PSI_thread PSI_thread;
+struct PSI_file;
+typedef struct PSI_file PSI_file;
+struct PSI_socket;
+typedef struct PSI_socket PSI_socket;
+struct PSI_prepared_stmt;
+typedef struct PSI_prepared_stmt PSI_prepared_stmt;
+struct PSI_table_locker;
+typedef struct PSI_table_locker PSI_table_locker;
+struct PSI_statement_locker;
+typedef struct PSI_statement_locker PSI_statement_locker;
+struct PSI_transaction_locker;
+typedef struct PSI_transaction_locker PSI_transaction_locker;
+struct PSI_idle_locker;
+typedef struct PSI_idle_locker PSI_idle_locker;
+struct PSI_digest_locker;
+typedef struct PSI_digest_locker PSI_digest_locker;
+struct PSI_sp_share;
+typedef struct PSI_sp_share PSI_sp_share;
+struct PSI_sp_locker;
+typedef struct PSI_sp_locker PSI_sp_locker;
+struct PSI_metadata_lock;
+typedef struct PSI_metadata_lock PSI_metadata_lock;
+struct PSI_stage_progress
+{
+ ulonglong m_work_completed;
+ ulonglong m_work_estimated;
+};
+typedef struct PSI_stage_progress PSI_stage_progress;
+enum PSI_table_io_operation
+{
+ PSI_TABLE_FETCH_ROW= 0,
+ PSI_TABLE_WRITE_ROW= 1,
+ PSI_TABLE_UPDATE_ROW= 2,
+ PSI_TABLE_DELETE_ROW= 3
+};
+typedef enum PSI_table_io_operation PSI_table_io_operation;
+struct PSI_table_locker_state
+{
+ uint m_flags;
+ enum PSI_table_io_operation m_io_operation;
+ struct PSI_table *m_table;
+ struct PSI_table_share *m_table_share;
+ struct PSI_thread *m_thread;
+ ulonglong m_timer_start;
+ ulonglong (*m_timer)(void);
+ void *m_wait;
+ uint m_index;
+};
+typedef struct PSI_table_locker_state PSI_table_locker_state;
+struct PSI_bootstrap
+{
+ void* (*get_interface)(int version);
+};
+typedef struct PSI_bootstrap PSI_bootstrap;
+struct PSI_mutex_locker;
+typedef struct PSI_mutex_locker PSI_mutex_locker;
+struct PSI_rwlock_locker;
+typedef struct PSI_rwlock_locker PSI_rwlock_locker;
+struct PSI_cond_locker;
+typedef struct PSI_cond_locker PSI_cond_locker;
+struct PSI_file_locker;
+typedef struct PSI_file_locker PSI_file_locker;
+struct PSI_socket_locker;
+typedef struct PSI_socket_locker PSI_socket_locker;
+struct PSI_metadata_locker;
+typedef struct PSI_metadata_locker PSI_metadata_locker;
+enum PSI_mutex_operation
+{
+ PSI_MUTEX_LOCK= 0,
+ PSI_MUTEX_TRYLOCK= 1
+};
+typedef enum PSI_mutex_operation PSI_mutex_operation;
+enum PSI_rwlock_operation
+{
+ PSI_RWLOCK_READLOCK= 0,
+ PSI_RWLOCK_WRITELOCK= 1,
+ PSI_RWLOCK_TRYREADLOCK= 2,
+ PSI_RWLOCK_TRYWRITELOCK= 3,
+ PSI_RWLOCK_SHAREDLOCK= 4,
+ PSI_RWLOCK_SHAREDEXCLUSIVELOCK= 5,
+ PSI_RWLOCK_EXCLUSIVELOCK= 6,
+ PSI_RWLOCK_TRYSHAREDLOCK= 7,
+ PSI_RWLOCK_TRYSHAREDEXCLUSIVELOCK= 8,
+ PSI_RWLOCK_TRYEXCLUSIVELOCK= 9
+};
+typedef enum PSI_rwlock_operation PSI_rwlock_operation;
+enum PSI_cond_operation
+{
+ PSI_COND_WAIT= 0,
+ PSI_COND_TIMEDWAIT= 1
+};
+typedef enum PSI_cond_operation PSI_cond_operation;
+enum PSI_file_operation
+{
+ PSI_FILE_CREATE= 0,
+ PSI_FILE_CREATE_TMP= 1,
+ PSI_FILE_OPEN= 2,
+ PSI_FILE_STREAM_OPEN= 3,
+ PSI_FILE_CLOSE= 4,
+ PSI_FILE_STREAM_CLOSE= 5,
+ PSI_FILE_READ= 6,
+ PSI_FILE_WRITE= 7,
+ PSI_FILE_SEEK= 8,
+ PSI_FILE_TELL= 9,
+ PSI_FILE_FLUSH= 10,
+ PSI_FILE_STAT= 11,
+ PSI_FILE_FSTAT= 12,
+ PSI_FILE_CHSIZE= 13,
+ PSI_FILE_DELETE= 14,
+ PSI_FILE_RENAME= 15,
+ PSI_FILE_SYNC= 16
+};
+typedef enum PSI_file_operation PSI_file_operation;
+enum PSI_table_lock_operation
+{
+ PSI_TABLE_LOCK= 0,
+ PSI_TABLE_EXTERNAL_LOCK= 1
+};
+typedef enum PSI_table_lock_operation PSI_table_lock_operation;
+enum PSI_socket_state
+{
+ PSI_SOCKET_STATE_IDLE= 1,
+ PSI_SOCKET_STATE_ACTIVE= 2
+};
+typedef enum PSI_socket_state PSI_socket_state;
+enum PSI_socket_operation
+{
+ PSI_SOCKET_CREATE= 0,
+ PSI_SOCKET_CONNECT= 1,
+ PSI_SOCKET_BIND= 2,
+ PSI_SOCKET_CLOSE= 3,
+ PSI_SOCKET_SEND= 4,
+ PSI_SOCKET_RECV= 5,
+ PSI_SOCKET_SENDTO= 6,
+ PSI_SOCKET_RECVFROM= 7,
+ PSI_SOCKET_SENDMSG= 8,
+ PSI_SOCKET_RECVMSG= 9,
+ PSI_SOCKET_SEEK= 10,
+ PSI_SOCKET_OPT= 11,
+ PSI_SOCKET_STAT= 12,
+ PSI_SOCKET_SHUTDOWN= 13,
+ PSI_SOCKET_SELECT= 14
+};
+typedef enum PSI_socket_operation PSI_socket_operation;
+typedef unsigned int PSI_mutex_key;
+typedef unsigned int PSI_rwlock_key;
+typedef unsigned int PSI_cond_key;
+typedef unsigned int PSI_thread_key;
+typedef unsigned int PSI_file_key;
+typedef unsigned int PSI_stage_key;
+typedef unsigned int PSI_statement_key;
+typedef unsigned int PSI_socket_key;
+struct PSI_v2
+{
+ int placeholder;
+};
+struct PSI_mutex_info_v2
+{
+ int placeholder;
+};
+struct PSI_rwlock_info_v2
+{
+ int placeholder;
+};
+struct PSI_cond_info_v2
+{
+ int placeholder;
+};
+struct PSI_thread_info_v2
+{
+ int placeholder;
+};
+struct PSI_file_info_v2
+{
+ int placeholder;
+};
+struct PSI_stage_info_v2
+{
+ int placeholder;
+};
+struct PSI_statement_info_v2
+{
+ int placeholder;
+};
+struct PSI_transaction_info_v2
+{
+ int placeholder;
+};
+struct PSI_idle_locker_state_v2
+{
+ int placeholder;
+};
+struct PSI_mutex_locker_state_v2
+{
+ int placeholder;
+};
+struct PSI_rwlock_locker_state_v2
+{
+ int placeholder;
+};
+struct PSI_cond_locker_state_v2
+{
+ int placeholder;
+};
+struct PSI_file_locker_state_v2
+{
+ int placeholder;
+};
+struct PSI_statement_locker_state_v2
+{
+ int placeholder;
+};
+struct PSI_transaction_locker_state_v2
+{
+ int placeholder;
+};
+struct PSI_socket_locker_state_v2
+{
+ int placeholder;
+};
+struct PSI_metadata_locker_state_v2
+{
+ int placeholder;
+};
+typedef struct PSI_v2 PSI;
+typedef struct PSI_mutex_info_v2 PSI_mutex_info;
+typedef struct PSI_rwlock_info_v2 PSI_rwlock_info;
+typedef struct PSI_cond_info_v2 PSI_cond_info;
+typedef struct PSI_thread_info_v2 PSI_thread_info;
+typedef struct PSI_file_info_v2 PSI_file_info;
+typedef struct PSI_stage_info_v2 PSI_stage_info;
+typedef struct PSI_statement_info_v2 PSI_statement_info;
+typedef struct PSI_transaction_info_v2 PSI_transaction_info;
+typedef struct PSI_socket_info_v2 PSI_socket_info;
+typedef struct PSI_idle_locker_state_v2 PSI_idle_locker_state;
+typedef struct PSI_mutex_locker_state_v2 PSI_mutex_locker_state;
+typedef struct PSI_rwlock_locker_state_v2 PSI_rwlock_locker_state;
+typedef struct PSI_cond_locker_state_v2 PSI_cond_locker_state;
+typedef struct PSI_file_locker_state_v2 PSI_file_locker_state;
+typedef struct PSI_statement_locker_state_v2 PSI_statement_locker_state;
+typedef struct PSI_transaction_locker_state_v2 PSI_transaction_locker_state;
+typedef struct PSI_socket_locker_state_v2 PSI_socket_locker_state;
+typedef struct PSI_sp_locker_state_v2 PSI_sp_locker_state;
+typedef struct PSI_metadata_locker_state_v2 PSI_metadata_locker_state;
+extern MYSQL_PLUGIN_IMPORT PSI *PSI_server;
+C_MODE_END
diff --git a/include/mysql/psi/psi_base.h b/include/mysql/psi/psi_base.h
new file mode 100644
index 00000000..f365e262
--- /dev/null
+++ b/include/mysql/psi/psi_base.h
@@ -0,0 +1,172 @@
+/* Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
+
+ Without limiting anything contained in the foregoing, this file,
+ which is part of C Driver for MySQL (Connector/C), is also subject to the
+ Universal FOSS Exception, version 1.0, a copy of which can be found at
+ http://oss.oracle.com/licenses/universal-foss-exception.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License, version 2.0, for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */
+
+#ifndef MYSQL_PSI_BASE_H
+#define MYSQL_PSI_BASE_H
+
+#ifdef EMBEDDED_LIBRARY
+#define DISABLE_ALL_PSI
+#endif /* EMBEDDED_LIBRARY */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ @file mysql/psi/psi_base.h
+ Performance schema instrumentation interface.
+
+ @defgroup Instrumentation_interface Instrumentation Interface
+ @ingroup Performance_schema
+ @{
+*/
+
+#define PSI_INSTRUMENT_ME 0
+#define PSI_INSTRUMENT_MEM ((PSI_memory_key)0)
+
+#define PSI_NOT_INSTRUMENTED 0
+
+/**
+ Global flag.
+ This flag indicate that an instrumentation point is a global variable,
+ or a singleton.
+*/
+#define PSI_FLAG_GLOBAL (1 << 0)
+
+/**
+ Mutable flag.
+ This flag indicate that an instrumentation point is a general placeholder,
+ that can mutate into a more specific instrumentation point.
+*/
+#define PSI_FLAG_MUTABLE (1 << 1)
+
+#define PSI_FLAG_THREAD (1 << 2)
+
+/**
+ Stage progress flag.
+ This flag apply to the stage instruments only.
+ It indicates the instrumentation provides progress data.
+*/
+#define PSI_FLAG_STAGE_PROGRESS (1 << 3)
+
+/**
+ Shared Exclusive flag.
+ Indicates that rwlock support the shared exclusive state.
+*/
+#define PSI_RWLOCK_FLAG_SX (1 << 4)
+
+/**
+ Transferable flag.
+ This flag indicate that an instrumented object can
+ be created by a thread and destroyed by another thread.
+*/
+#define PSI_FLAG_TRANSFER (1 << 5)
+
+/**
+ Volatility flag.
+ This flag indicate that an instrumented object
+ has a volatility (life cycle) comparable
+ to the volatility of a session.
+*/
+#define PSI_FLAG_VOLATILITY_SESSION (1 << 6)
+
+#ifdef HAVE_PSI_INTERFACE
+
+/**
+ @def PSI_VERSION_1
+ Performance Schema Interface number for version 1.
+ This version is supported.
+*/
+#define PSI_VERSION_1 1
+
+/**
+ @def PSI_VERSION_2
+ Performance Schema Interface number for version 2.
+ This version is not implemented, it's a placeholder.
+*/
+#define PSI_VERSION_2 2
+
+/**
+ @def PSI_CURRENT_VERSION
+ Performance Schema Interface number for the most recent version.
+ The most current version is @c PSI_VERSION_1
+*/
+#define PSI_CURRENT_VERSION 1
+
+/**
+ @def USE_PSI_1
+ Define USE_PSI_1 to use the interface version 1.
+*/
+
+/**
+ @def USE_PSI_2
+ Define USE_PSI_2 to use the interface version 2.
+*/
+
+/**
+ @def HAVE_PSI_1
+ Define HAVE_PSI_1 if the interface version 1 needs to be compiled in.
+*/
+
+/**
+ @def HAVE_PSI_2
+ Define HAVE_PSI_2 if the interface version 2 needs to be compiled in.
+*/
+
+#ifndef USE_PSI_2
+#ifndef USE_PSI_1
+#define USE_PSI_1
+#endif
+#endif
+
+#ifdef USE_PSI_1
+#define HAVE_PSI_1
+#endif
+
+#ifdef USE_PSI_2
+#define HAVE_PSI_2
+#endif
+
+/*
+ Allow to override PSI_XXX_CALL at compile time
+ with more efficient implementations, if available.
+ If nothing better is available,
+ make a dynamic call using the PSI_server function pointer.
+*/
+
+#define PSI_DYNAMIC_CALL(M) PSI_server->M
+
+#endif /* HAVE_PSI_INTERFACE */
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MYSQL_PSI_BASE_H */
+
diff --git a/include/mysql/psi/psi_memory.h b/include/mysql/psi/psi_memory.h
new file mode 100644
index 00000000..c019c9cd
--- /dev/null
+++ b/include/mysql/psi/psi_memory.h
@@ -0,0 +1,171 @@
+/* Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
+
+ Without limiting anything contained in the foregoing, this file,
+ which is part of C Driver for MySQL (Connector/C), is also subject to the
+ Universal FOSS Exception, version 1.0, a copy of which can be found at
+ http://oss.oracle.com/licenses/universal-foss-exception.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License, version 2.0, for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */
+
+#ifndef MYSQL_PSI_MEMORY_H
+#define MYSQL_PSI_MEMORY_H
+
+#include "psi_base.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ @file mysql/psi/psi_memory.h
+ Performance schema instrumentation interface.
+
+ @defgroup Instrumentation_interface Instrumentation Interface
+ @ingroup Performance_schema
+ @{
+*/
+
+#ifdef HAVE_PSI_INTERFACE
+#ifndef DISABLE_ALL_PSI
+#ifndef DISABLE_PSI_MEMORY
+#define HAVE_PSI_MEMORY_INTERFACE
+#endif /* DISABLE_PSI_MEMORY */
+#endif /* DISABLE_ALL_PSI */
+#endif /* HAVE_PSI_INTERFACE */
+
+struct PSI_thread;
+
+/**
+ Instrumented memory key.
+ To instrument memory, a memory key must be obtained using @c register_memory.
+ Using a zero key always disable the instrumentation.
+*/
+typedef unsigned int PSI_memory_key;
+
+#ifdef HAVE_PSI_1
+
+/**
+ @defgroup Group_PSI_v1 Application Binary Interface, version 1
+ @ingroup Instrumentation_interface
+ @{
+*/
+
+/**
+ Memory instrument information.
+ @since PSI_VERSION_1
+ This structure is used to register instrumented memory.
+*/
+struct PSI_memory_info_v1
+{
+ /** Pointer to the key assigned to the registered memory. */
+ PSI_memory_key *m_key;
+ /** The name of the memory instrument to register. */
+ const char *m_name;
+ /**
+ The flags of the socket instrument to register.
+ @sa PSI_FLAG_GLOBAL
+ */
+ int m_flags;
+};
+typedef struct PSI_memory_info_v1 PSI_memory_info_v1;
+
+/**
+ Memory registration API.
+ @param category a category name (typically a plugin name)
+ @param info an array of memory info to register
+ @param count the size of the info array
+*/
+typedef void (*register_memory_v1_t)
+ (const char *category, struct PSI_memory_info_v1 *info, int count);
+
+/**
+ Instrument memory allocation.
+ @param key the memory instrument key
+ @param size the size of memory allocated
+ @param[out] owner the memory owner
+ @return the effective memory instrument key
+*/
+typedef PSI_memory_key (*memory_alloc_v1_t)
+ (PSI_memory_key key, size_t size, struct PSI_thread ** owner);
+
+/**
+ Instrument memory re allocation.
+ @param key the memory instrument key
+ @param old_size the size of memory previously allocated
+ @param new_size the size of memory re allocated
+ @param[in, out] owner the memory owner
+ @return the effective memory instrument key
+*/
+typedef PSI_memory_key (*memory_realloc_v1_t)
+ (PSI_memory_key key, size_t old_size, size_t new_size, struct PSI_thread ** owner);
+
+/**
+ Instrument memory claim.
+ @param key the memory instrument key
+ @param size the size of memory allocated
+ @param[in, out] owner the memory owner
+ @return the effective memory instrument key
+*/
+typedef PSI_memory_key (*memory_claim_v1_t)
+ (PSI_memory_key key, size_t size, struct PSI_thread ** owner);
+
+/**
+ Instrument memory free.
+ @param key the memory instrument key
+ @param size the size of memory allocated
+ @param owner the memory owner
+*/
+typedef void (*memory_free_v1_t)
+ (PSI_memory_key key, size_t size, struct PSI_thread * owner);
+
+/** @} (end of group Group_PSI_v1) */
+
+#ifdef _AIX
+PSI_memory_key key_memory_log_event;
+#endif
+
+#endif /* HAVE_PSI_1 */
+
+#ifdef HAVE_PSI_2
+struct PSI_memory_info_v2
+{
+ int placeholder;
+};
+
+#endif /* HAVE_PSI_2 */
+
+#ifdef USE_PSI_1
+typedef struct PSI_memory_info_v1 PSI_memory_info;
+#endif
+
+#ifdef USE_PSI_2
+typedef struct PSI_memory_info_v2 PSI_memory_info;
+#endif
+
+/** @} (end of group Instrumentation_interface) */
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* MYSQL_PSI_MEMORY_H */
+
diff --git a/include/mysql/service_base64.h b/include/mysql/service_base64.h
new file mode 100644
index 00000000..43b5ba32
--- /dev/null
+++ b/include/mysql/service_base64.h
@@ -0,0 +1,82 @@
+#ifndef MYSQL_SERVICE_BASE64_INCLUDED
+/* Copyright (c) 2017, MariaDB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */
+
+/**
+ @file
+ my base64 service
+
+ Functions for base64 en- and decoding
+*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef MYSQL_ABI_CHECK
+#include <stdlib.h>
+#endif
+
+/* Allow multuple chunks 'AAA= AA== AA==', binlog uses this */
+#define MY_BASE64_DECODE_ALLOW_MULTIPLE_CHUNKS 1
+
+extern struct base64_service_st {
+ int (*base64_needed_encoded_length_ptr)(int length_of_data);
+ int (*base64_encode_max_arg_length_ptr)(void);
+ int (*base64_needed_decoded_length_ptr)(int length_of_encoded_data);
+ int (*base64_decode_max_arg_length_ptr)();
+ int (*base64_encode_ptr)(const void *src, size_t src_len, char *dst);
+ int (*base64_decode_ptr)(const char *src, size_t src_len,
+ void *dst, const char **end_ptr, int flags);
+} *base64_service;
+
+#ifdef MYSQL_DYNAMIC_PLUGIN
+
+#define my_base64_needed_encoded_length(A) base64_service->base64_needed_encoded_length_ptr(A)
+#define my_base64_encode_max_arg_length() base64_service->base64_encode_max_arg_length_ptr()
+#define my_base64_needed_decoded_length(A) base64_service->base64_needed_decoded_length_ptr(A)
+#define my_base64_decode_max_arg_length() base64_service->base64_decode_max_arg_length_ptr()
+#define my_base64_encode(A,B,C) base64_service->base64_encode_ptr(A,B,C)
+#define my_base64_decode(A,B,C,D,E) base64_service->base64_decode_ptr(A,B,C,D,E)
+
+#else
+
+/* Calculate how much memory needed for dst of my_base64_encode() */
+int my_base64_needed_encoded_length(int length_of_data);
+
+/* Maximum length my_base64_encode_needed_length() can accept with no overflow. */
+int my_base64_encode_max_arg_length(void);
+
+/* Calculate how much memory needed for dst of my_base64_decode() */
+int my_base64_needed_decoded_length(int length_of_encoded_data);
+
+/* Maximum length my_base64_decode_needed_length() can accept with no overflow. */
+int my_base64_decode_max_arg_length();
+
+/* Encode data as a my_base64 string */
+int my_base64_encode(const void *src, size_t src_len, char *dst);
+
+/* Decode a my_base64 string into data */
+int my_base64_decode(const char *src, size_t src_len,
+ void *dst, const char **end_ptr, int flags);
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#define MYSQL_SERVICE_BASE64_INCLUDED
+#endif
diff --git a/include/mysql/service_debug_sync.h b/include/mysql/service_debug_sync.h
new file mode 100644
index 00000000..0bd49a13
--- /dev/null
+++ b/include/mysql/service_debug_sync.h
@@ -0,0 +1,361 @@
+#ifndef MYSQL_SERVICE_DEBUG_SYNC_INCLUDED
+/* Copyright (c) 2009, 2010, Oracle and/or its affiliates.
+ Copyright (c) 2012, Monty Program Ab
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */
+
+/**
+ @file
+ == Debug Sync Facility ==
+
+ The Debug Sync Facility allows placement of synchronization points in
+ the server code by using the DEBUG_SYNC macro:
+
+ open_tables(...)
+
+ DEBUG_SYNC(thd, "after_open_tables");
+
+ lock_tables(...)
+
+ When activated, a sync point can
+
+ - Emit a signal and/or
+ - Wait for a signal
+
+ Nomenclature:
+
+ - signal: A value of a global variable that persists
+ until overwritten by a new signal. The global
+ variable can also be seen as a "signal post"
+ or "flag mast". Then the signal is what is
+ attached to the "signal post" or "flag mast".
+
+ - emit a signal: Assign the value (the signal) to the global
+ variable ("set a flag") and broadcast a
+ global condition to wake those waiting for
+ a signal.
+
+ - wait for a signal: Loop over waiting for the global condition until
+ the global value matches the wait-for signal.
+
+ By default, all sync points are inactive. They do nothing (except to
+ burn a couple of CPU cycles for checking if they are active).
+
+ A sync point becomes active when an action is requested for it.
+ To do so, put a line like this in the test case file:
+
+ SET DEBUG_SYNC= 'after_open_tables SIGNAL opened WAIT_FOR flushed';
+
+ This activates the sync point 'after_open_tables'. It requests it to
+ emit the signal 'opened' and wait for another thread to emit the signal
+ 'flushed' when the thread's execution runs through the sync point.
+
+ For every sync point there can be one action per thread only. Every
+ thread can request multiple actions, but only one per sync point. In
+ other words, a thread can activate multiple sync points.
+
+ Here is an example how to activate and use the sync points:
+
+ --connection conn1
+ SET DEBUG_SYNC= 'after_open_tables SIGNAL opened WAIT_FOR flushed';
+ send INSERT INTO t1 VALUES(1);
+ --connection conn2
+ SET DEBUG_SYNC= 'now WAIT_FOR opened';
+ SET DEBUG_SYNC= 'after_abort_locks SIGNAL flushed';
+ FLUSH TABLE t1;
+
+ When conn1 runs through the INSERT statement, it hits the sync point
+ 'after_open_tables'. It notices that it is active and executes its
+ action. It emits the signal 'opened' and waits for another thread to
+ emit the signal 'flushed'.
+
+ conn2 waits immediately at the special sync point 'now' for another
+ thread to emit the 'opened' signal.
+
+ A signal remains in effect until it is overwritten. If conn1 signals
+ 'opened' before conn2 reaches 'now', conn2 will still find the 'opened'
+ signal. It does not wait in this case.
+
+ When conn2 reaches 'after_abort_locks', it signals 'flushed', which lets
+ conn1 awake.
+
+ Normally the activation of a sync point is cleared when it has been
+ executed. Sometimes it is necessary to keep the sync point active for
+ another execution. You can add an execute count to the action:
+
+ SET DEBUG_SYNC= 'name SIGNAL sig EXECUTE 3';
+
+ This sets the signal point's activation counter to 3. Each execution
+ decrements the counter. After the third execution the sync point
+ becomes inactive.
+
+ One of the primary goals of this facility is to eliminate sleeps from
+ the test suite. In most cases it should be possible to rewrite test
+ cases so that they do not need to sleep. (But this facility cannot
+ synchronize multiple processes.) However, to support test development,
+ and as a last resort, sync point waiting times out. There is a default
+ timeout, but it can be overridden:
+
+ SET DEBUG_SYNC= 'name WAIT_FOR sig TIMEOUT 10 EXECUTE 2';
+
+ TIMEOUT 0 is special: If the signal is not present, the wait times out
+ immediately.
+
+ When a wait timed out (even on TIMEOUT 0), a warning is generated so
+ that it shows up in the test result.
+
+ You can throw an error message and kill the query when a synchronization
+ point is hit a certain number of times:
+
+ SET DEBUG_SYNC= 'name HIT_LIMIT 3';
+
+ Or combine it with signal and/or wait:
+
+ SET DEBUG_SYNC= 'name SIGNAL sig EXECUTE 2 HIT_LIMIT 3';
+
+ Here the first two hits emit the signal, the third hit returns the error
+ message and kills the query.
+
+ For cases where you are not sure that an action is taken and thus
+ cleared in any case, you can force to clear (deactivate) a sync point:
+
+ SET DEBUG_SYNC= 'name CLEAR';
+
+ If you want to clear all actions and clear the global signal, use:
+
+ SET DEBUG_SYNC= 'RESET';
+
+ This is the only way to reset the global signal to an empty string.
+
+ For testing of the facility itself you can execute a sync point just
+ as if it had been hit:
+
+ SET DEBUG_SYNC= 'name TEST';
+
+
+ === Formal Syntax ===
+
+ The string to "assign" to the DEBUG_SYNC variable can contain:
+
+ {RESET |
+ <sync point name> TEST |
+ <sync point name> CLEAR |
+ <sync point name> {{SIGNAL <signal name> |
+ WAIT_FOR <signal name> [TIMEOUT <seconds>]}
+ [EXECUTE <count>] &| HIT_LIMIT <count>}
+
+ Here '&|' means 'and/or'. This means that one of the sections
+ separated by '&|' must be present or both of them.
+
+
+ === Activation/Deactivation ===
+
+ The facility is an optional part of the MySQL server.
+ It is enabled in a debug server by default.
+
+ ./configure --enable-debug-sync
+
+ The Debug Sync Facility, when compiled in, is disabled by default. It
+ can be enabled by a mysqld command line option:
+
+ --debug-sync-timeout[=default_wait_timeout_value_in_seconds]
+
+ 'default_wait_timeout_value_in_seconds' is the default timeout for the
+ WAIT_FOR action. If set to zero, the facility stays disabled.
+
+ The facility is enabled by default in the test suite, but can be
+ disabled with:
+
+ mysql-test-run.pl ... --debug-sync-timeout=0 ...
+
+ Likewise the default wait timeout can be set:
+
+ mysql-test-run.pl ... --debug-sync-timeout=10 ...
+
+ The command line option influences the readable value of the system
+ variable 'debug_sync'.
+
+ * If the facility is not compiled in, the system variable does not exist.
+
+ * If --debug-sync-timeout=0 the value of the variable reads as "OFF".
+
+ * Otherwise the value reads as "ON - current signal: " followed by the
+ current signal string, which can be empty.
+
+ The readable variable value is the same, regardless if read as global
+ or session value.
+
+ Setting the 'debug-sync' system variable requires 'SUPER' privilege.
+ You can never read back the string that you assigned to the variable,
+ unless you assign the value that the variable does already have. But
+ that would give a parse error. A syntactically correct string is
+ parsed into a debug sync action and stored apart from the variable value.
+
+
+ === Implementation ===
+
+ Pseudo code for a sync point:
+
+ #define DEBUG_SYNC(thd, sync_point_name)
+ if (unlikely(opt_debug_sync_timeout))
+ debug_sync(thd, STRING_WITH_LEN(sync_point_name))
+
+ The sync point performs a binary search in a sorted array of actions
+ for this thread.
+
+ The SET DEBUG_SYNC statement adds a requested action to the array or
+ overwrites an existing action for the same sync point. When it adds a
+ new action, the array is sorted again.
+
+
+ === A typical synchronization pattern ===
+
+ There are quite a few places in MySQL, where we use a synchronization
+ pattern like this:
+
+ mysql_mutex_lock(&mutex);
+ thd->enter_cond(&condition_variable, &mutex, new_message);
+ #if defined(ENABLE_DEBUG_SYNC)
+ if (!thd->killed && !end_of_wait_condition)
+ DEBUG_SYNC(thd, "sync_point_name");
+ #endif
+ while (!thd->killed && !end_of_wait_condition)
+ mysql_cond_wait(&condition_variable, &mutex);
+ thd->exit_cond(old_message);
+
+ Here some explanations:
+
+ thd->enter_cond() is used to register the condition variable and the
+ mutex in thd->mysys_var. This is done to allow the thread to be
+ interrupted (killed) from its sleep. Another thread can find the
+ condition variable to signal and mutex to use for synchronization in
+ this thread's THD::mysys_var.
+
+ thd->enter_cond() requires the mutex to be acquired in advance.
+
+ thd->exit_cond() unregisters the condition variable and mutex and
+ releases the mutex.
+
+ If you want to have a Debug Sync point with the wait, please place it
+ behind enter_cond(). Only then you can safely decide, if the wait will
+ be taken. Also you will have THD::proc_info correct when the sync
+ point emits a signal. DEBUG_SYNC sets its own proc_info, but restores
+ the previous one before releasing its internal mutex. As soon as
+ another thread sees the signal, it does also see the proc_info from
+ before entering the sync point. In this case it will be "new_message",
+ which is associated with the wait that is to be synchronized.
+
+ In the example above, the wait condition is repeated before the sync
+ point. This is done to skip the sync point, if no wait takes place.
+ The sync point is before the loop (not inside the loop) to have it hit
+ once only. It is possible that the condition variable is signaled
+ multiple times without the wait condition to be true.
+
+ A bit off-topic: At some places, the loop is taken around the whole
+ synchronization pattern:
+
+ while (!thd->killed && !end_of_wait_condition)
+ {
+ mysql_mutex_lock(&mutex);
+ thd->enter_cond(&condition_variable, &mutex, new_message);
+ if (!thd->killed [&& !end_of_wait_condition])
+ {
+ [DEBUG_SYNC(thd, "sync_point_name");]
+ mysql_cond_wait(&condition_variable, &mutex);
+ }
+ thd->exit_cond(old_message);
+ }
+
+ Note that it is important to repeat the test for thd->killed after
+ enter_cond(). Otherwise the killing thread may kill this thread after
+ it tested thd->killed in the loop condition and before it registered
+ the condition variable and mutex in enter_cond(). In this case, the
+ killing thread does not know that this thread is going to wait on a
+ condition variable. It would just set THD::killed. But if we would not
+ test it again, we would go asleep though we are killed. If the killing
+ thread would kill us when we are after the second test, but still
+ before sleeping, we hold the mutex, which is registered in mysys_var.
+ The killing thread would try to acquire the mutex before signaling
+ the condition variable. Since the mutex is only released implicitly in
+ mysql_cond_wait(), the signaling happens at the right place. We
+ have a safe synchronization.
+
+ === Co-work with the DBUG facility ===
+
+ When running the MySQL test suite with the --debug-dbug command line
+ option, the Debug Sync Facility writes trace messages to the DBUG
+ trace. The following shell commands proved very useful in extracting
+ relevant information:
+
+ egrep 'query:|debug_sync_exec:' mysql-test/var/log/mysqld.1.trace
+
+ It shows all executed SQL statements and all actions executed by
+ synchronization points.
+
+ Sometimes it is also useful to see, which synchronization points have
+ been run through (hit) with or without executing actions. Then add
+ "|debug_sync_point:" to the egrep pattern.
+
+ === Further reading ===
+
+ For a discussion of other methods to synchronize threads see
+ http://forge.mysql.com/wiki/MySQL_Internals_Test_Synchronization
+
+ For complete syntax tests, functional tests, and examples see the test
+ case debug_sync.test.
+
+ See also http://forge.mysql.com/worklog/task.php?id=4259
+*/
+
+#ifndef MYSQL_ABI_CHECK
+#include <stdlib.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef MYSQL_DYNAMIC_PLUGIN
+extern void (*debug_sync_service)(MYSQL_THD, const char *, size_t);
+#else
+#define debug_sync_service debug_sync_C_callback_ptr
+extern void (*debug_sync_C_callback_ptr)(MYSQL_THD, const char *, size_t);
+#endif
+
+#ifdef ENABLED_DEBUG_SYNC
+#define DEBUG_SYNC(thd, name) \
+ do { \
+ if (debug_sync_service) \
+ debug_sync_service(thd, STRING_WITH_LEN(name)); \
+ } while(0)
+
+#define DEBUG_SYNC_C_IF_THD(thd, name) \
+ do { \
+ if (debug_sync_service && thd) \
+ debug_sync_service((MYSQL_THD) thd, STRING_WITH_LEN(name)); \
+ } while(0)
+#else
+#define DEBUG_SYNC(thd,name) do { } while(0)
+#define DEBUG_SYNC_C_IF_THD(thd, _sync_point_name_) do { } while(0)
+#endif /* defined(ENABLED_DEBUG_SYNC) */
+
+/* compatibility macro */
+#define DEBUG_SYNC_C(name) DEBUG_SYNC(NULL, name)
+
+#ifdef __cplusplus
+}
+#endif
+
+#define MYSQL_SERVICE_DEBUG_SYNC_INCLUDED
+#endif
diff --git a/include/mysql/service_encryption.h b/include/mysql/service_encryption.h
new file mode 100644
index 00000000..a4e908f9
--- /dev/null
+++ b/include/mysql/service_encryption.h
@@ -0,0 +1,131 @@
+#ifndef MYSQL_SERVICE_ENCRYPTION_INCLUDED
+/* Copyright (c) 2015, MariaDB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */
+
+/**
+ @file
+ encryption service
+
+ Functions to support data encryption and encryption key management.
+ They are normally implemented in an encryption plugin, so this service
+ connects encryption *consumers* (e.g. storage engines) to the encryption
+ *provider* (encryption plugin).
+*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef MYSQL_ABI_CHECK
+#ifdef _WIN32
+#include <malloc.h>
+#ifndef __cplusplus
+#define inline __inline
+#endif
+#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__)
+#include <stdlib.h>
+#else
+#include <alloca.h>
+#endif
+#endif
+
+/* returned from encryption_key_get_latest_version() */
+#define ENCRYPTION_KEY_VERSION_INVALID (~(unsigned int)0)
+#define ENCRYPTION_KEY_NOT_ENCRYPTED (0)
+
+#define ENCRYPTION_KEY_SYSTEM_DATA 1
+#define ENCRYPTION_KEY_TEMPORARY_DATA 2
+
+/* returned from encryption_key_get() */
+#define ENCRYPTION_KEY_BUFFER_TOO_SMALL (100)
+
+#define ENCRYPTION_FLAG_DECRYPT 0
+#define ENCRYPTION_FLAG_ENCRYPT 1
+#define ENCRYPTION_FLAG_NOPAD 2
+
+struct encryption_service_st {
+ unsigned int (*encryption_key_get_latest_version_func)(unsigned int key_id);
+ unsigned int (*encryption_key_get_func)(unsigned int key_id, unsigned int key_version,
+ unsigned char* buffer, unsigned int* length);
+ unsigned int (*encryption_ctx_size_func)(unsigned int key_id, unsigned int key_version);
+ int (*encryption_ctx_init_func)(void *ctx, const unsigned char* key, unsigned int klen,
+ const unsigned char* iv, unsigned int ivlen,
+ int flags, unsigned int key_id,
+ unsigned int key_version);
+ int (*encryption_ctx_update_func)(void *ctx, const unsigned char* src, unsigned int slen,
+ unsigned char* dst, unsigned int* dlen);
+ int (*encryption_ctx_finish_func)(void *ctx, unsigned char* dst, unsigned int* dlen);
+ unsigned int (*encryption_encrypted_length_func)(unsigned int slen, unsigned int key_id, unsigned int key_version);
+};
+
+#ifdef MYSQL_DYNAMIC_PLUGIN
+
+extern struct encryption_service_st *encryption_service;
+
+#define encryption_key_get_latest_version(KI) encryption_service->encryption_key_get_latest_version_func(KI)
+#define encryption_key_get(KI,KV,K,S) encryption_service->encryption_key_get_func((KI),(KV),(K),(S))
+#define encryption_ctx_size(KI,KV) encryption_service->encryption_ctx_size_func((KI),(KV))
+#define encryption_ctx_init(CTX,K,KL,IV,IVL,F,KI,KV) encryption_service->encryption_ctx_init_func((CTX),(K),(KL),(IV),(IVL),(F),(KI),(KV))
+#define encryption_ctx_update(CTX,S,SL,D,DL) encryption_service->encryption_ctx_update_func((CTX),(S),(SL),(D),(DL))
+#define encryption_ctx_finish(CTX,D,DL) encryption_service->encryption_ctx_finish_func((CTX),(D),(DL))
+#define encryption_encrypted_length(SL,KI,KV) encryption_service->encryption_encrypted_length_func((SL),(KI),(KV))
+#else
+
+extern struct encryption_service_st encryption_handler;
+
+#define encryption_key_get_latest_version(KI) encryption_handler.encryption_key_get_latest_version_func(KI)
+#define encryption_key_get(KI,KV,K,S) encryption_handler.encryption_key_get_func((KI),(KV),(K),(S))
+#define encryption_ctx_size(KI,KV) encryption_handler.encryption_ctx_size_func((KI),(KV))
+#define encryption_ctx_init(CTX,K,KL,IV,IVL,F,KI,KV) encryption_handler.encryption_ctx_init_func((CTX),(K),(KL),(IV),(IVL),(F),(KI),(KV))
+#define encryption_ctx_update(CTX,S,SL,D,DL) encryption_handler.encryption_ctx_update_func((CTX),(S),(SL),(D),(DL))
+#define encryption_ctx_finish(CTX,D,DL) encryption_handler.encryption_ctx_finish_func((CTX),(D),(DL))
+#define encryption_encrypted_length(SL,KI,KV) encryption_handler.encryption_encrypted_length_func((SL),(KI),(KV))
+#endif
+
+static inline unsigned int encryption_key_id_exists(unsigned int id)
+{
+ return encryption_key_get_latest_version(id) != ENCRYPTION_KEY_VERSION_INVALID;
+}
+
+static inline unsigned int encryption_key_version_exists(unsigned int id, unsigned int version)
+{
+ unsigned int unused;
+ return encryption_key_get(id, version, NULL, &unused) != ENCRYPTION_KEY_VERSION_INVALID;
+}
+
+static inline int encryption_crypt(const unsigned char* src, unsigned int slen,
+ unsigned char* dst, unsigned int* dlen,
+ const unsigned char* key, unsigned int klen,
+ const unsigned char* iv, unsigned int ivlen,
+ int flags, unsigned int key_id, unsigned int key_version)
+{
+ void *ctx= alloca(encryption_ctx_size(key_id, key_version));
+ int res1, res2;
+ unsigned int d1, d2;
+ if ((res1= encryption_ctx_init(ctx, key, klen, iv, ivlen, flags, key_id, key_version)))
+ return res1;
+ res1= encryption_ctx_update(ctx, src, slen, dst, &d1);
+ res2= encryption_ctx_finish(ctx, dst + d1, &d2);
+ *dlen= d1 + d2;
+ return res1 ? res1 : res2;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#define MYSQL_SERVICE_ENCRYPTION_INCLUDED
+#endif
+
diff --git a/include/mysql/service_encryption_scheme.h b/include/mysql/service_encryption_scheme.h
new file mode 100644
index 00000000..bcd4d646
--- /dev/null
+++ b/include/mysql/service_encryption_scheme.h
@@ -0,0 +1,133 @@
+#ifndef MYSQL_SERVICE_ENCRYPTION_SCHEME_INCLUDED
+/* Copyright (c) 2015, MariaDB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */
+
+/**
+ @file
+ encryption scheme service
+
+ A higher-level access to encryption service.
+
+ This is a helper service that storage engines use to encrypt tables on disk.
+ It requests keys from the plugin, generates temporary or local keys
+ from the global (as returned by the plugin) keys, etc.
+
+ To use the service:
+
+ * st_encryption_scheme object is created per space. A "space" can be
+ a table space in XtraDB/InnoDB, a file in Aria, etc. The whole
+ space is encrypted with the one key id.
+
+ * The service does not take the key and the IV as parameters for
+ encryption or decryption. Instead it takes two 32-bit integers and
+ one 64-bit integer (and requests the key from an encryption
+ plugin, if needed).
+
+ * The service requests the global key from the encryption plugin
+ automatically as needed. Three last keys are cached in the
+ st_encryption_scheme. Number of key requests (number of cache
+ misses) are counted in st_encryption_scheme::keyserver_requests
+
+ * If an st_encryption_scheme can be used concurrently by different
+ threads, it needs to be able to lock itself when accessing the key
+ cache. Set the st_encryption_scheme::locker appropriately. If
+ non-zero, it will be invoked by encrypt/decrypt functions to lock
+ and unlock the scheme when needed.
+
+ * Implementation details (in particular, key derivation) are defined
+ by the scheme type. Currently only schema type 1 is supported.
+
+ In the schema type 1, every "space" (table space in XtraDB/InnoDB,
+ file in Aria) is encrypted with a different space-local key:
+
+ * Every space has a 16-byte unique identifier (typically it's
+ generated randomly and stored in the space). The caller should
+ put it into st_encryption_scheme::iv.
+
+ * Space-local key is generated by encrypting this identifier with
+ the global encryption key (of the given id and version) using AES_ECB.
+
+ * Encryption/decryption parameters for a page are typically the
+ 4-byte space id, 4-byte page position (offset, page number, etc),
+ and the 8-byte LSN. This guarantees that they'll be different for
+ any two pages (of the same or different tablespaces) and also that
+ they'll change for the same page when it's modified. They don't need
+ to be secret (they create the IV, not the encryption key).
+*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ENCRYPTION_SCHEME_KEY_INVALID -1
+#define ENCRYPTION_SCHEME_BLOCK_LENGTH 16
+
+struct st_encryption_scheme_key {
+ unsigned int version;
+ unsigned char key[ENCRYPTION_SCHEME_BLOCK_LENGTH];
+};
+
+struct st_encryption_scheme {
+ unsigned char iv[ENCRYPTION_SCHEME_BLOCK_LENGTH];
+ struct st_encryption_scheme_key key[3];
+ unsigned int keyserver_requests;
+ unsigned int key_id;
+ unsigned int type;
+
+ void (*locker)(struct st_encryption_scheme *self, int release);
+};
+
+extern struct encryption_scheme_service_st {
+ int (*encryption_scheme_encrypt_func)
+ (const unsigned char* src, unsigned int slen,
+ unsigned char* dst, unsigned int* dlen,
+ struct st_encryption_scheme *scheme,
+ unsigned int key_version, unsigned int i32_1,
+ unsigned int i32_2, unsigned long long i64);
+ int (*encryption_scheme_decrypt_func)
+ (const unsigned char* src, unsigned int slen,
+ unsigned char* dst, unsigned int* dlen,
+ struct st_encryption_scheme *scheme,
+ unsigned int key_version, unsigned int i32_1,
+ unsigned int i32_2, unsigned long long i64);
+} *encryption_scheme_service;
+
+#ifdef MYSQL_DYNAMIC_PLUGIN
+
+#define encryption_scheme_encrypt(S,SL,D,DL,SCH,KV,I32,J32,I64) encryption_scheme_service->encryption_scheme_encrypt_func(S,SL,D,DL,SCH,KV,I32,J32,I64)
+#define encryption_scheme_decrypt(S,SL,D,DL,SCH,KV,I32,J32,I64) encryption_scheme_service->encryption_scheme_decrypt_func(S,SL,D,DL,SCH,KV,I32,J32,I64)
+
+#else
+
+int encryption_scheme_encrypt(const unsigned char* src, unsigned int slen,
+ unsigned char* dst, unsigned int* dlen,
+ struct st_encryption_scheme *scheme,
+ unsigned int key_version, unsigned int i32_1,
+ unsigned int i32_2, unsigned long long i64);
+int encryption_scheme_decrypt(const unsigned char* src, unsigned int slen,
+ unsigned char* dst, unsigned int* dlen,
+ struct st_encryption_scheme *scheme,
+ unsigned int key_version, unsigned int i32_1,
+ unsigned int i32_2, unsigned long long i64);
+
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#define MYSQL_SERVICE_ENCRYPTION_SCHEME_INCLUDED
+#endif
diff --git a/include/mysql/service_json.h b/include/mysql/service_json.h
new file mode 100644
index 00000000..cb748c0c
--- /dev/null
+++ b/include/mysql/service_json.h
@@ -0,0 +1,119 @@
+/* Copyright (C) 2018 MariaDB Corporation
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */
+
+#ifndef MYSQL_SERVICE_JSON
+#define MYSQL_SERVICE_JSON
+
+/**
+ @file
+ json service
+
+ Exports JSON parsing methods for plugins to use.
+
+ Functions of the service:
+ json_type - returns the type of the JSON argument,
+ and the parsed value if it's scalar (not object or array)
+
+ json_get_array_item - expects JSON array as an argument,
+ and returns the type of the element at index `n_item`.
+ Returns JSV_NOTHING type if the array is shorter
+ than n_item and the actual length of the array in value_len.
+ If successful, then `value` up till `value[value_len]` contains the array
+ element at the desired index (n_item).
+
+ json_get_object_key - expects JSON object as an argument,
+ searches for a key in the object, return it's type and stores its value in `value`.
+ JSV_NOTHING if no such key found, the number of keys
+ in v_len.
+
+ json_get_object_nkey - expects JSON object as an argument.
+ finds n_key's key in the object, returns it's name, type and value.
+ JSV_NOTHING if object has less keys than n_key.
+*/
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum json_types
+{
+ JSV_BAD_JSON=-1,
+ JSV_NOTHING=0,
+ JSV_OBJECT=1,
+ JSV_ARRAY=2,
+ JSV_STRING=3,
+ JSV_NUMBER=4,
+ JSV_TRUE=5,
+ JSV_FALSE=6,
+ JSV_NULL=7
+};
+
+extern struct json_service_st {
+ enum json_types (*json_type)(const char *js, const char *js_end,
+ const char **value, int *value_len);
+ enum json_types (*json_get_array_item)(const char *js, const char *js_end,
+ int n_item,
+ const char **value, int *value_len);
+ enum json_types (*json_get_object_key)(const char *js, const char *js_end,
+ const char *key,
+ const char **value, int *value_len);
+ enum json_types (*json_get_object_nkey)(const char *js,const char *js_end,
+ int nkey,
+ const char **keyname, const char **keyname_end,
+ const char **value, int *value_len);
+ int (*json_escape_string)(const char *str,const char *str_end,
+ char *json, char *json_end);
+ int (*json_unescape_json)(const char *json_str, const char *json_end,
+ char *res, char *res_end);
+} *json_service;
+
+#ifdef MYSQL_DYNAMIC_PLUGIN
+
+#define json_type json_service->json_type
+#define json_get_array_item json_service->json_get_array_item
+#define json_get_object_key json_service->json_get_object_key
+#define json_get_object_nkey json_service->json_get_object_nkey
+#define json_escape_string json_service->json_escape_string
+#define json_unescape_json json_service->json_unescape_json
+
+#else
+
+enum json_types json_type(const char *js, const char *js_end,
+ const char **value, int *value_len);
+enum json_types json_get_array_item(const char *js, const char *js_end,
+ int n_item,
+ const char **value, int *value_len);
+enum json_types json_get_object_key(const char *js, const char *js_end,
+ const char *key,
+ const char **value, int *value_len);
+enum json_types json_get_object_nkey(const char *js,const char *js_end, int nkey,
+ const char **keyname, const char **keyname_end,
+ const char **value, int *value_len);
+int json_escape_string(const char *str,const char *str_end,
+ char *json, char *json_end);
+int json_unescape_json(const char *json_str, const char *json_end,
+ char *res, char *res_end);
+
+#endif /*MYSQL_DYNAMIC_PLUGIN*/
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*MYSQL_SERVICE_JSON */
+
+
diff --git a/include/mysql/service_kill_statement.h b/include/mysql/service_kill_statement.h
new file mode 100644
index 00000000..9f3415a7
--- /dev/null
+++ b/include/mysql/service_kill_statement.h
@@ -0,0 +1,71 @@
+/* Copyright (c) 2013, 2018, MariaDB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */
+
+#ifndef MYSQL_SERVICE_KILL_STATEMENT_INCLUDED
+#define MYSQL_SERVICE_KILL_STATEMENT_INCLUDED
+
+/**
+ @file
+ This service provides functions that allow plugins to support
+ the KILL statement.
+
+ In MySQL support for the KILL statement is cooperative. The KILL
+ statement only sets a "killed" flag. This function returns the value
+ of that flag. A thread should check it often, especially inside
+ time-consuming loops, and gracefully abort the operation if it is
+ non-zero.
+
+ thd_killed(thd)
+ @return 0 - no KILL statement was issued, continue normally
+ @return 1 - there was a KILL statement, abort the execution.
+
+ thd_kill_level(thd)
+ @return thd_kill_levels_enum values
+*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum thd_kill_levels {
+ THD_IS_NOT_KILLED=0,
+ THD_ABORT_SOFTLY=50, /**< abort when possible, don't leave tables corrupted */
+ THD_ABORT_ASAP=100, /**< abort asap */
+};
+
+extern struct kill_statement_service_st {
+ enum thd_kill_levels (*thd_kill_level_func)(const MYSQL_THD);
+} *thd_kill_statement_service;
+
+/* backward compatibility helper */
+#define thd_killed(THD) (thd_kill_level(THD) == THD_ABORT_ASAP)
+
+#ifdef MYSQL_DYNAMIC_PLUGIN
+
+#define thd_kill_level(THD) \
+ thd_kill_statement_service->thd_kill_level_func(THD)
+
+#else
+
+enum thd_kill_levels thd_kill_level(const MYSQL_THD);
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/include/mysql/service_logger.h b/include/mysql/service_logger.h
new file mode 100644
index 00000000..5979901b
--- /dev/null
+++ b/include/mysql/service_logger.h
@@ -0,0 +1,105 @@
+/* Copyright (C) 2012 Monty Program Ab
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */
+
+#ifndef MYSQL_SERVICE_LOGGER_INCLUDED
+#define MYSQL_SERVICE_LOGGER_INCLUDED
+
+#ifndef MYSQL_ABI_CHECK
+#include <stdarg.h>
+#endif
+
+/**
+ @file
+ logger service
+
+ Log file with rotation implementation.
+
+ This service implements logging with possible rotation
+ of the log files. Interface intentionally tries to be similar to FILE*
+ related functions.
+
+ So that one can open the log with logger_open(), specifying
+ the limit on the logfile size and the rotations number.
+
+ Then it's possible to write messages to the log with
+ logger_printf or logger_vprintf functions.
+
+ As the size of the logfile grows over the specified limit,
+ it is renamed to 'logfile.1'. The former 'logfile.1' becomes
+ 'logfile.2', etc. The file 'logfile.rotations' is removed.
+ That's how the rotation works.
+
+ The rotation can be forced with the logger_rotate() call.
+
+ Finally the log should be closed with logger_close().
+
+@notes:
+ Implementation checks the size of the log file before it starts new
+ printf into it. So the size of the file gets over the limit when it rotates.
+
+ The access is secured with the mutex, so the log is threadsafe.
+*/
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct logger_handle_st LOGGER_HANDLE;
+
+extern struct logger_service_st {
+ void (*logger_init_mutexes)();
+ LOGGER_HANDLE* (*open)(const char *path,
+ unsigned long long size_limit,
+ unsigned int rotations);
+ int (*close)(LOGGER_HANDLE *log);
+ int (*vprintf)(LOGGER_HANDLE *log, const char *fmt, va_list argptr);
+ int (*printf)(LOGGER_HANDLE *log, const char *fmt, ...);
+ int (*write)(LOGGER_HANDLE *log, const char *buffer, size_t size);
+ int (*rotate)(LOGGER_HANDLE *log);
+} *logger_service;
+
+#ifdef MYSQL_DYNAMIC_PLUGIN
+
+#define logger_init_mutexes logger_service->logger_init_mutexes
+#define logger_open(path, size_limit, rotations) \
+ (logger_service->open(path, size_limit, rotations))
+#define logger_close(log) (logger_service->close(log))
+#define logger_rotate(log) (logger_service->rotate(log))
+#define logger_vprintf(log, fmt, argptr) (logger_service->\
+ vprintf(log, fmt, argptr))
+#define logger_printf (*logger_service->printf)
+#define logger_write(log, buffer, size) \
+ (logger_service->write(log, buffer, size))
+#else
+
+ void logger_init_mutexes();
+ LOGGER_HANDLE *logger_open(const char *path,
+ unsigned long long size_limit,
+ unsigned int rotations);
+ int logger_close(LOGGER_HANDLE *log);
+ int logger_vprintf(LOGGER_HANDLE *log, const char *fmt, va_list argptr);
+ int logger_printf(LOGGER_HANDLE *log, const char *fmt, ...);
+ int logger_write(LOGGER_HANDLE *log, const char *buffer, size_t size);
+ int logger_rotate(LOGGER_HANDLE *log);
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*MYSQL_SERVICE_LOGGER_INCLUDED*/
+
diff --git a/include/mysql/service_md5.h b/include/mysql/service_md5.h
new file mode 100644
index 00000000..336cf70f
--- /dev/null
+++ b/include/mysql/service_md5.h
@@ -0,0 +1,69 @@
+#ifndef MYSQL_SERVICE_MD5_INCLUDED
+/* Copyright (c) 2014, Monty Program Ab
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */
+
+/**
+ @file
+ my md5 service
+
+ Functions to calculate MD5 hash from a memory buffer
+*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef MYSQL_ABI_CHECK
+#include <stdlib.h>
+#endif
+
+#define MY_MD5_HASH_SIZE 16 /* Hash size in bytes */
+
+extern struct my_md5_service_st {
+ void (*my_md5_type)(unsigned char*, const char*, size_t);
+ void (*my_md5_multi_type)(unsigned char*, ...);
+ size_t (*my_md5_context_size_type)();
+ void (*my_md5_init_type)(void *);
+ void (*my_md5_input_type)(void *, const unsigned char *, size_t);
+ void (*my_md5_result_type)(void *, unsigned char *);
+} *my_md5_service;
+
+#ifdef MYSQL_DYNAMIC_PLUGIN
+
+#define my_md5(A,B,C) my_md5_service->my_md5_type(A,B,C)
+#define my_md5_multi my_md5_service->my_md5_multi_type
+#define my_md5_context_size() my_md5_service->my_md5_context_size_type()
+#define my_md5_init(A) my_md5_service->my_md5_init_type(A)
+#define my_md5_input(A,B,C) my_md5_service->my_md5_input_type(A,B,C)
+#define my_md5_result(A,B) my_md5_service->my_md5_result_type(A,B)
+
+#else
+
+void my_md5(unsigned char*, const char*, size_t);
+void my_md5_multi(unsigned char*, ...);
+size_t my_md5_context_size();
+void my_md5_init(void *context);
+void my_md5_input(void *context, const unsigned char *buf, size_t len);
+void my_md5_result(void *context, unsigned char *digest);
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#define MYSQL_SERVICE_MD5_INCLUDED
+#endif
+
diff --git a/include/mysql/service_my_crypt.h b/include/mysql/service_my_crypt.h
new file mode 100644
index 00000000..2a232117
--- /dev/null
+++ b/include/mysql/service_my_crypt.h
@@ -0,0 +1,120 @@
+#ifndef MYSQL_SERVICE_MY_CRYPT_INCLUDED
+#define MYSQL_SERVICE_MY_CRYPT_INCLUDED
+
+/*
+ Copyright (c) 2014 Google Inc.
+ Copyright (c) 2014, 2015 MariaDB Corporation
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */
+
+/**
+ @file
+ my crypt service
+
+ AES encryption functions, and a function to generate random bytes.
+
+ Include my_config.h before this file to use CTR and GCM modes
+ (they only work if server was compiled with openssl).
+*/
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* return values from my_aes_encrypt/my_aes_decrypt functions */
+#define MY_AES_OK 0
+#define MY_AES_BAD_DATA -100
+#define MY_AES_OPENSSL_ERROR -101
+#define MY_AES_BAD_KEYSIZE -102
+
+/* The block size for all supported algorithms */
+#define MY_AES_BLOCK_SIZE 16
+
+/* The max key length of all supported algorithms */
+#define MY_AES_MAX_KEY_LENGTH 32
+
+#define MY_AES_CTX_SIZE 656
+
+enum my_aes_mode {
+ MY_AES_ECB, MY_AES_CBC
+#ifdef HAVE_EncryptAes128Ctr
+ , MY_AES_CTR
+#endif
+#ifdef HAVE_EncryptAes128Gcm
+ , MY_AES_GCM
+#endif
+};
+
+extern struct my_crypt_service_st {
+ int (*my_aes_crypt_init)(void *ctx, enum my_aes_mode mode, int flags,
+ const unsigned char* key, unsigned int klen,
+ const unsigned char* iv, unsigned int ivlen);
+ int (*my_aes_crypt_update)(void *ctx, const unsigned char *src, unsigned int slen,
+ unsigned char *dst, unsigned int *dlen);
+ int (*my_aes_crypt_finish)(void *ctx, unsigned char *dst, unsigned int *dlen);
+ int (*my_aes_crypt)(enum my_aes_mode mode, int flags,
+ const unsigned char *src, unsigned int slen, unsigned char *dst, unsigned int *dlen,
+ const unsigned char *key, unsigned int klen, const unsigned char *iv, unsigned int ivlen);
+ unsigned int (*my_aes_get_size)(enum my_aes_mode mode, unsigned int source_length);
+ unsigned int (*my_aes_ctx_size)(enum my_aes_mode mode);
+ int (*my_random_bytes)(unsigned char* buf, int num);
+} *my_crypt_service;
+
+#ifdef MYSQL_DYNAMIC_PLUGIN
+
+#define my_aes_crypt_init(A,B,C,D,E,F,G) \
+ my_crypt_service->my_aes_crypt_init(A,B,C,D,E,F,G)
+
+#define my_aes_crypt_update(A,B,C,D,E) \
+ my_crypt_service->my_aes_crypt_update(A,B,C,D,E)
+
+#define my_aes_crypt_finish(A,B,C) \
+ my_crypt_service->my_aes_crypt_finish(A,B,C)
+
+#define my_aes_crypt(A,B,C,D,E,F,G,H,I,J) \
+ my_crypt_service->my_aes_crypt(A,B,C,D,E,F,G,H,I,J)
+
+#define my_aes_get_size(A,B)\
+ my_crypt_service->my_aes_get_size(A,B)
+
+#define my_aes_ctx_size(A)\
+ my_crypt_service->my_aes_ctx_size(A)
+
+#define my_random_bytes(A,B)\
+ my_crypt_service->my_random_bytes(A,B)
+
+#else
+
+int my_aes_crypt_init(void *ctx, enum my_aes_mode mode, int flags,
+ const unsigned char* key, unsigned int klen,
+ const unsigned char* iv, unsigned int ivlen);
+int my_aes_crypt_update(void *ctx, const unsigned char *src, unsigned int slen,
+ unsigned char *dst, unsigned int *dlen);
+int my_aes_crypt_finish(void *ctx, unsigned char *dst, unsigned int *dlen);
+int my_aes_crypt(enum my_aes_mode mode, int flags,
+ const unsigned char *src, unsigned int slen, unsigned char *dst, unsigned int *dlen,
+ const unsigned char *key, unsigned int klen, const unsigned char *iv, unsigned int ivlen);
+
+int my_random_bytes(unsigned char* buf, int num);
+unsigned int my_aes_get_size(enum my_aes_mode mode, unsigned int source_length);
+unsigned int my_aes_ctx_size(enum my_aes_mode mode);
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MYSQL_SERVICE_MY_CRYPT_INCLUDED */
diff --git a/include/mysql/service_my_print_error.h b/include/mysql/service_my_print_error.h
new file mode 100644
index 00000000..74ba6a2a
--- /dev/null
+++ b/include/mysql/service_my_print_error.h
@@ -0,0 +1,64 @@
+/* Copyright (c) 2016, MariaDB
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; version 2 of the License.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */
+
+#ifndef MYSQL_SERVICE_MY_PRINT_ERROR_INCLUDED
+#define MYSQL_SERVICE_MY_PRINT_ERROR_INCLUDED
+
+/**
+ @file include/mysql/service_my_print_error.h
+
+ This service provides functions for plugins to report
+ errors to client (without client, the errors are written to the error log).
+
+*/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef MYSQL_ABI_CHECK
+#include <stdarg.h>
+#include <stdlib.h>
+#endif
+
+#define ME_ERROR_LOG 64 /* Write the message to the error log */
+#define ME_ERROR_LOG_ONLY 128 /* Write the error message to error log only */
+#define ME_NOTE 1024 /* Not an error, just a note */
+#define ME_WARNING 2048 /* Not an error, just a warning */
+#define ME_FATAL 4096 /* Fatal statement error */
+
+extern struct my_print_error_service_st {
+ void (*my_error_func)(unsigned int nr, unsigned long MyFlags, ...);
+ void (*my_printf_error_func)(unsigned int nr, const char *fmt, unsigned long MyFlags,...);
+ void (*my_printv_error_func)(unsigned int error, const char *format, unsigned long MyFlags, va_list ap);
+} *my_print_error_service;
+
+#ifdef MYSQL_DYNAMIC_PLUGIN
+
+#define my_error my_print_error_service->my_error_func
+#define my_printf_error my_print_error_service->my_printf_error_func
+#define my_printv_error(A,B,C,D) my_print_error_service->my_printv_error_func(A,B,C,D)
+
+#else
+extern void my_error(unsigned int nr, unsigned long MyFlags, ...);
+extern void my_printf_error(unsigned int my_err, const char *format, unsigned long MyFlags, ...);
+extern void my_printv_error(unsigned int error, const char *format, unsigned long MyFlags,va_list ap);
+#endif /* MYSQL_DYNAMIC_PLUGIN */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/include/mysql/service_my_snprintf.h b/include/mysql/service_my_snprintf.h
new file mode 100644
index 00000000..6757a658
--- /dev/null
+++ b/include/mysql/service_my_snprintf.h
@@ -0,0 +1,110 @@
+#ifndef MYSQL_SERVICE_MY_SNPRINTF_INCLUDED
+/* Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */
+
+/**
+ @file
+ my_snprintf service
+
+ Portable and limited vsnprintf() implementation.
+
+ This is a portable, limited vsnprintf() implementation, with some
+ extra features. "Portable" means that it'll produce identical result
+ on all platforms (for example, on Windows and Linux system printf %e
+ formats the exponent differently, on different systems %p either
+ prints leading 0x or not, %s may accept null pointer or crash on
+ it). "Limited" means that it does not support all the C89 features.
+ But it supports few extensions, not in any standard.
+
+ my_vsnprintf(to, n, fmt, ap)
+
+ @param[out] to A buffer to store the result in
+ @param[in] n Store up to n-1 characters, followed by an end 0
+ @param[in] fmt printf-like format string
+ @param[in] ap Arguments
+
+ @return a number of bytes written to a buffer *excluding* terminating '\0'
+
+ @post
+ The syntax of a format string is generally the same:
+ % <flag> <width> <precision> <length modifier> <format>
+ where everithing but the format is optional.
+
+ Three one-character flags are recognized:
+ '0' has the standard zero-padding semantics;
+ '-' is parsed, but silently ignored;
+ '`' (backtick) is only supported for strings (%s) and means that the
+ string will be quoted according to MySQL identifier quoting rules.
+
+ Both <width> and <precision> can be specified as numbers or '*'.
+ If an asterisk is used, an argument of type int is consumed.
+
+ <length modifier> can be 'l', 'll', or 'z'.
+
+ Supported formats are 's' (null pointer is accepted, printed as
+ "(null)"), 'b' (extension, see below), 'c', 'd', 'i', 'u', 'x', 'o',
+ 'X', 'p' (works as 0x%x), 'f', 'g', 'M' (extension, see below),
+ 'T' (extension, see below).
+
+ Standard syntax for positional arguments $n is supported.
+
+ Extensions:
+
+ Flag '`' (backtick): see above.
+
+ Format 'b': binary buffer, prints exactly <precision> bytes from the
+ argument, without stopping at '\0'.
+
+ Format 'M': takes one integer, prints this integer, space, double quote
+ error message, double quote. In other words
+ printf("%M", n) === printf("%d \"%s\"", n, strerror(n))
+
+ Format 'T': takes string and print it like s but if the strints should be
+ truncated puts "..." at the end.
+*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef MYSQL_ABI_CHECK
+#include <stdarg.h>
+#include <stdlib.h>
+#endif
+
+extern struct my_snprintf_service_st {
+ size_t (*my_snprintf_type)(char*, size_t, const char*, ...);
+ size_t (*my_vsnprintf_type)(char *, size_t, const char*, va_list);
+} *my_snprintf_service;
+
+#ifdef MYSQL_DYNAMIC_PLUGIN
+
+#define my_vsnprintf my_snprintf_service->my_vsnprintf_type
+#define my_snprintf my_snprintf_service->my_snprintf_type
+
+#else
+
+size_t my_snprintf(char* to, size_t n, const char* fmt, ...);
+size_t my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap);
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#define MYSQL_SERVICE_MY_SNPRINTF_INCLUDED
+#endif
+
diff --git a/include/mysql/service_progress_report.h b/include/mysql/service_progress_report.h
new file mode 100644
index 00000000..11fc24dc
--- /dev/null
+++ b/include/mysql/service_progress_report.h
@@ -0,0 +1,82 @@
+#ifndef MYSQL_SERVICE_PROGRESS_REPORT_INCLUDED
+/* Copyright (C) 2011 Monty Program Ab
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */
+
+/**
+ @file
+ This service allows plugins to report progress of long running operations
+ to the server. The progress report is visible in SHOW PROCESSLIST,
+ INFORMATION_SCHEMA.PROCESSLIST, and is sent to the client
+ if requested.
+
+ The functions are documented at
+ https://mariadb.com/kb/en/progress-reporting/#how-to-add-support-for-progress-reporting-to-a-storage-engine
+*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define thd_proc_info(thd, msg) set_thd_proc_info(thd, msg, \
+ __func__, __FILE__, __LINE__)
+
+extern struct progress_report_service_st {
+ void (*thd_progress_init_func)(MYSQL_THD thd, unsigned int max_stage);
+ void (*thd_progress_report_func)(MYSQL_THD thd,
+ unsigned long long progress,
+ unsigned long long max_progress);
+ void (*thd_progress_next_stage_func)(MYSQL_THD thd);
+ void (*thd_progress_end_func)(MYSQL_THD thd);
+ const char *(*set_thd_proc_info_func)(MYSQL_THD, const char *info,
+ const char *func,
+ const char *file,
+ unsigned int line);
+} *progress_report_service;
+
+#ifdef MYSQL_DYNAMIC_PLUGIN
+
+#define thd_progress_init(thd,max_stage) (progress_report_service->thd_progress_init_func((thd),(max_stage)))
+#define thd_progress_report(thd, progress, max_progress) (progress_report_service->thd_progress_report_func((thd), (progress), (max_progress)))
+#define thd_progress_next_stage(thd) (progress_report_service->thd_progress_next_stage_func(thd))
+#define thd_progress_end(thd) (progress_report_service->thd_progress_end_func(thd))
+#define set_thd_proc_info(thd,info,func,file,line) (progress_report_service->set_thd_proc_info_func((thd),(info),(func),(file),(line)))
+
+#else
+
+/**
+ Report progress for long running operations
+
+ @param thd User thread connection handle
+ @param progress Where we are now
+ @param max_progress Progress will continue up to this
+*/
+void thd_progress_init(MYSQL_THD thd, unsigned int max_stage);
+void thd_progress_report(MYSQL_THD thd,
+ unsigned long long progress,
+ unsigned long long max_progress);
+void thd_progress_next_stage(MYSQL_THD thd);
+void thd_progress_end(MYSQL_THD thd);
+const char *set_thd_proc_info(MYSQL_THD, const char * info, const char *func,
+ const char *file, unsigned int line);
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#define MYSQL_SERVICE_PROGRESS_REPORT_INCLUDED
+#endif
+
diff --git a/include/mysql/service_sha1.h b/include/mysql/service_sha1.h
new file mode 100644
index 00000000..d864e23f
--- /dev/null
+++ b/include/mysql/service_sha1.h
@@ -0,0 +1,69 @@
+#ifndef MYSQL_SERVICE_SHA1_INCLUDED
+/* Copyright (c) 2013, 2014, Monty Program Ab
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */
+
+/**
+ @file
+ my sha1 service
+
+ Functions to calculate SHA1 hash from a memory buffer
+*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef MYSQL_ABI_CHECK
+#include <stdlib.h>
+#endif
+
+#define MY_SHA1_HASH_SIZE 20 /* Hash size in bytes */
+
+extern struct my_sha1_service_st {
+ void (*my_sha1_type)(unsigned char*, const char*, size_t);
+ void (*my_sha1_multi_type)(unsigned char*, ...);
+ size_t (*my_sha1_context_size_type)();
+ void (*my_sha1_init_type)(void *);
+ void (*my_sha1_input_type)(void *, const unsigned char *, size_t);
+ void (*my_sha1_result_type)(void *, unsigned char *);
+} *my_sha1_service;
+
+#ifdef MYSQL_DYNAMIC_PLUGIN
+
+#define my_sha1(A,B,C) my_sha1_service->my_sha1_type(A,B,C)
+#define my_sha1_multi my_sha1_service->my_sha1_multi_type
+#define my_sha1_context_size() my_sha1_service->my_sha1_context_size_type()
+#define my_sha1_init(A) my_sha1_service->my_sha1_init_type(A)
+#define my_sha1_input(A,B,C) my_sha1_service->my_sha1_input_type(A,B,C)
+#define my_sha1_result(A,B) my_sha1_service->my_sha1_result_type(A,B)
+
+#else
+
+void my_sha1(unsigned char*, const char*, size_t);
+void my_sha1_multi(unsigned char*, ...);
+size_t my_sha1_context_size();
+void my_sha1_init(void *context);
+void my_sha1_input(void *context, const unsigned char *buf, size_t len);
+void my_sha1_result(void *context, unsigned char *digest);
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#define MYSQL_SERVICE_SHA1_INCLUDED
+#endif
+
diff --git a/include/mysql/service_sha2.h b/include/mysql/service_sha2.h
new file mode 100644
index 00000000..00834a9b
--- /dev/null
+++ b/include/mysql/service_sha2.h
@@ -0,0 +1,130 @@
+#ifndef MYSQL_SERVICE_SHA2_INCLUDED
+/* Copyright (c) 2017, MariaDB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */
+
+/**
+ @file
+ my sha2 service
+
+ Functions to calculate SHA2 hash from a memory buffer
+*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef MYSQL_ABI_CHECK
+#include <stdlib.h>
+#endif
+
+extern struct my_sha2_service_st {
+ void (*my_sha224_type)(unsigned char*, const char*, size_t);
+ void (*my_sha224_multi_type)(unsigned char*, ...);
+ size_t (*my_sha224_context_size_type)();
+ void (*my_sha224_init_type)(void *);
+ void (*my_sha224_input_type)(void *, const unsigned char *, size_t);
+ void (*my_sha224_result_type)(void *, unsigned char *);
+
+ void (*my_sha256_type)(unsigned char*, const char*, size_t);
+ void (*my_sha256_multi_type)(unsigned char*, ...);
+ size_t (*my_sha256_context_size_type)();
+ void (*my_sha256_init_type)(void *);
+ void (*my_sha256_input_type)(void *, const unsigned char *, size_t);
+ void (*my_sha256_result_type)(void *, unsigned char *);
+
+ void (*my_sha384_type)(unsigned char*, const char*, size_t);
+ void (*my_sha384_multi_type)(unsigned char*, ...);
+ size_t (*my_sha384_context_size_type)();
+ void (*my_sha384_init_type)(void *);
+ void (*my_sha384_input_type)(void *, const unsigned char *, size_t);
+ void (*my_sha384_result_type)(void *, unsigned char *);
+
+ void (*my_sha512_type)(unsigned char*, const char*, size_t);
+ void (*my_sha512_multi_type)(unsigned char*, ...);
+ size_t (*my_sha512_context_size_type)();
+ void (*my_sha512_init_type)(void *);
+ void (*my_sha512_input_type)(void *, const unsigned char *, size_t);
+ void (*my_sha512_result_type)(void *, unsigned char *);
+} *my_sha2_service;
+
+#ifdef MYSQL_DYNAMIC_PLUGIN
+
+#define my_sha224(A,B,C) my_sha2_service->my_sha224_type(A,B,C)
+#define my_sha224_multi my_sha2_service->my_sha224_multi_type
+#define my_sha224_context_size() my_sha2_service->my_sha224_context_size_type()
+#define my_sha224_init(A) my_sha2_service->my_sha224_init_type(A)
+#define my_sha224_input(A,B,C) my_sha2_service->my_sha224_input_type(A,B,C)
+#define my_sha224_result(A,B) my_sha2_service->my_sha224_result_type(A,B)
+
+#define my_sha256(A,B,C) my_sha2_service->my_sha256_type(A,B,C)
+#define my_sha256_multi my_sha2_service->my_sha256_multi_type
+#define my_sha256_context_size() my_sha2_service->my_sha256_context_size_type()
+#define my_sha256_init(A) my_sha2_service->my_sha256_init_type(A)
+#define my_sha256_input(A,B,C) my_sha2_service->my_sha256_input_type(A,B,C)
+#define my_sha256_result(A,B) my_sha2_service->my_sha256_result_type(A,B)
+
+#define my_sha384(A,B,C) my_sha2_service->my_sha384_type(A,B,C)
+#define my_sha384_multi my_sha2_service->my_sha384_multi_type
+#define my_sha384_context_size() my_sha2_service->my_sha384_context_size_type()
+#define my_sha384_init(A) my_sha2_service->my_sha384_init_type(A)
+#define my_sha384_input(A,B,C) my_sha2_service->my_sha384_input_type(A,B,C)
+#define my_sha384_result(A,B) my_sha2_service->my_sha384_result_type(A,B)
+
+#define my_sha512(A,B,C) my_sha2_service->my_sha512_type(A,B,C)
+#define my_sha512_multi my_sha2_service->my_sha512_multi_type
+#define my_sha512_context_size() my_sha2_service->my_sha512_context_size_type()
+#define my_sha512_init(A) my_sha2_service->my_sha512_init_type(A)
+#define my_sha512_input(A,B,C) my_sha2_service->my_sha512_input_type(A,B,C)
+#define my_sha512_result(A,B) my_sha2_service->my_sha512_result_type(A,B)
+
+#else
+
+void my_sha224(unsigned char*, const char*, size_t);
+void my_sha224_multi(unsigned char*, ...);
+size_t my_sha224_context_size();
+void my_sha224_init(void *context);
+void my_sha224_input(void *context, const unsigned char *buf, size_t len);
+void my_sha224_result(void *context, unsigned char *digest);
+
+void my_sha256(unsigned char*, const char*, size_t);
+void my_sha256_multi(unsigned char*, ...);
+size_t my_sha256_context_size();
+void my_sha256_init(void *context);
+void my_sha256_input(void *context, const unsigned char *buf, size_t len);
+void my_sha256_result(void *context, unsigned char *digest);
+
+void my_sha384(unsigned char*, const char*, size_t);
+void my_sha384_multi(unsigned char*, ...);
+size_t my_sha384_context_size();
+void my_sha384_init(void *context);
+void my_sha384_input(void *context, const unsigned char *buf, size_t len);
+void my_sha384_result(void *context, unsigned char *digest);
+
+void my_sha512(unsigned char*, const char*, size_t);
+void my_sha512_multi(unsigned char*, ...);
+size_t my_sha512_context_size();
+void my_sha512_init(void *context);
+void my_sha512_input(void *context, const unsigned char *buf, size_t len);
+void my_sha512_result(void *context, unsigned char *digest);
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#define MYSQL_SERVICE_SHA2_INCLUDED
+#endif
+
diff --git a/include/mysql/service_thd_alloc.h b/include/mysql/service_thd_alloc.h
new file mode 100644
index 00000000..0be4687b
--- /dev/null
+++ b/include/mysql/service_thd_alloc.h
@@ -0,0 +1,139 @@
+#ifndef MYSQL_SERVICE_THD_ALLOC_INCLUDED
+/* Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */
+
+/**
+ @file
+ This service provides functions to allocate memory in a connection local
+ memory pool. The memory allocated there will be automatically freed at the
+ end of the statement, don't use it for allocations that should live longer
+ than that. For short living allocations this is more efficient than
+ using my_malloc and friends, and automatic "garbage collection" allows not
+ to think about memory leaks.
+
+ The pool is best for small to medium objects, don't use it for large
+ allocations - they are better served with my_malloc.
+*/
+
+#ifndef MYSQL_ABI_CHECK
+#include <stdlib.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct st_mysql_lex_string
+{
+ char *str;
+ size_t length;
+};
+typedef struct st_mysql_lex_string MYSQL_LEX_STRING;
+
+struct st_mysql_const_lex_string
+{
+ const char *str;
+ size_t length;
+};
+typedef struct st_mysql_const_lex_string MYSQL_CONST_LEX_STRING;
+
+extern struct thd_alloc_service_st {
+ void *(*thd_alloc_func)(MYSQL_THD, size_t);
+ void *(*thd_calloc_func)(MYSQL_THD, size_t);
+ char *(*thd_strdup_func)(MYSQL_THD, const char *);
+ char *(*thd_strmake_func)(MYSQL_THD, const char *, size_t);
+ void *(*thd_memdup_func)(MYSQL_THD, const void*, size_t);
+ MYSQL_CONST_LEX_STRING *(*thd_make_lex_string_func)(MYSQL_THD,
+ MYSQL_CONST_LEX_STRING *,
+ const char *, size_t, int);
+} *thd_alloc_service;
+
+#ifdef MYSQL_DYNAMIC_PLUGIN
+
+#define thd_alloc(thd,size) (thd_alloc_service->thd_alloc_func((thd), (size)))
+
+#define thd_calloc(thd,size) (thd_alloc_service->thd_calloc_func((thd), (size)))
+
+#define thd_strdup(thd,str) (thd_alloc_service->thd_strdup_func((thd), (str)))
+
+#define thd_strmake(thd,str,size) \
+ (thd_alloc_service->thd_strmake_func((thd), (str), (size)))
+
+#define thd_memdup(thd,str,size) \
+ (thd_alloc_service->thd_memdup_func((thd), (str), (size)))
+
+#define thd_make_lex_string(thd, lex_str, str, size, allocate_lex_string) \
+ (thd_alloc_service->thd_make_lex_string_func((thd), (lex_str), (str), \
+ (size), (allocate_lex_string)))
+
+#else
+
+/**
+ Allocate memory in the connection's local memory pool
+
+ @details
+ When properly used in place of @c my_malloc(), this can significantly
+ improve concurrency. Don't use this or related functions to allocate
+ large chunks of memory. Use for temporary storage only. The memory
+ will be freed automatically at the end of the statement; no explicit
+ code is required to prevent memory leaks.
+
+ @see alloc_root()
+*/
+void *thd_alloc(MYSQL_THD thd, size_t size);
+/**
+ @see thd_alloc()
+*/
+void *thd_calloc(MYSQL_THD thd, size_t size);
+/**
+ @see thd_alloc()
+*/
+char *thd_strdup(MYSQL_THD thd, const char *str);
+/**
+ @see thd_alloc()
+*/
+char *thd_strmake(MYSQL_THD thd, const char *str, size_t size);
+/**
+ @see thd_alloc()
+*/
+void *thd_memdup(MYSQL_THD thd, const void* str, size_t size);
+
+/**
+ Create a LEX_STRING in this connection's local memory pool
+
+ @param thd user thread connection handle
+ @param lex_str pointer to LEX_STRING object to be initialized
+ @param str initializer to be copied into lex_str
+ @param size length of str, in bytes
+ @param allocate_lex_string flag: if TRUE, allocate new LEX_STRING object,
+ instead of using lex_str value
+ @return NULL on failure, or pointer to the LEX_STRING object
+
+ @see thd_alloc()
+*/
+MYSQL_CONST_LEX_STRING
+*thd_make_lex_string(MYSQL_THD thd, MYSQL_CONST_LEX_STRING *lex_str,
+ const char *str, size_t size,
+ int allocate_lex_string);
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#define MYSQL_SERVICE_THD_ALLOC_INCLUDED
+#endif
+
diff --git a/include/mysql/service_thd_autoinc.h b/include/mysql/service_thd_autoinc.h
new file mode 100644
index 00000000..28bd2bb1
--- /dev/null
+++ b/include/mysql/service_thd_autoinc.h
@@ -0,0 +1,53 @@
+#ifndef MYSQL_SERVICE_THD_AUTOINC_INCLUDED
+/* Copyright (C) 2013 MariaDB Foundation.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */
+
+/**
+ @file
+ This service provides access to the auto_increment related system variables:
+
+ @@auto_increment_offset
+ @@auto_increment_increment
+*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern struct thd_autoinc_service_st {
+ void (*thd_get_autoinc_func)(const MYSQL_THD thd,
+ unsigned long* off, unsigned long* inc);
+} *thd_autoinc_service;
+
+#ifdef MYSQL_DYNAMIC_PLUGIN
+#define thd_get_autoinc(thd, off, inc) \
+ (thd_autoinc_service->thd_get_autoinc_func((thd), (off), (inc)))
+#else
+/**
+ Return autoincrement system variables
+ @param IN thd user thread connection handle
+ @param OUT off the value of @@SESSION.auto_increment_offset
+ @param OUT inc the value of @@SESSION.auto_increment_increment
+*/
+void thd_get_autoinc(const MYSQL_THD thd,
+ unsigned long* off, unsigned long* inc);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#define MYSQL_SERVICE_THD_AUTOINC_INCLUDED
+#endif
diff --git a/include/mysql/service_thd_error_context.h b/include/mysql/service_thd_error_context.h
new file mode 100644
index 00000000..0b9082dd
--- /dev/null
+++ b/include/mysql/service_thd_error_context.h
@@ -0,0 +1,93 @@
+#ifndef MYSQL_SERVICE_THD_STMT_DA_INCLUDED
+/* Copyright (C) 2013 MariaDB Foundation.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */
+
+/**
+ @file
+ This service provides access to the statement diagnostics area:
+ - error message
+ - error number
+ - row for warning (e.g. for multi-row INSERT statements)
+*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+extern struct thd_error_context_service_st {
+ const char *(*thd_get_error_message_func)(const MYSQL_THD thd);
+ unsigned int (*thd_get_error_number_func)(const MYSQL_THD thd);
+ unsigned long (*thd_get_error_row_func)(const MYSQL_THD thd);
+ void (*thd_inc_error_row_func)(MYSQL_THD thd);
+ char *(*thd_get_error_context_description_func)(MYSQL_THD thd,
+ char *buffer,
+ unsigned int length,
+ unsigned int max_query_length);
+} *thd_error_context_service;
+
+#ifdef MYSQL_DYNAMIC_PLUGIN
+#define thd_get_error_message(thd) \
+ (thd_error_context_service->thd_get_error_message_func((thd)))
+#define thd_get_error_number(thd) \
+ (thd_error_context_service->thd_get_error_number_func((thd)))
+#define thd_get_error_row(thd) \
+ (thd_error_context_service->thd_get_error_row_func((thd)))
+#define thd_inc_error_row(thd) \
+ (thd_error_context_service->thd_inc_error_row_func((thd)))
+#define thd_get_error_context_description(thd, buffer, length, max_query_len) \
+ (thd_error_context_service->thd_get_error_context_description_func((thd), \
+ (buffer), \
+ (length), \
+ (max_query_len)))
+#else
+/**
+ Return error message
+ @param thd user thread connection handle
+ @return error text
+*/
+const char *thd_get_error_message(const MYSQL_THD thd);
+/**
+ Return error number
+ @param thd user thread connection handle
+ @return error number
+*/
+unsigned int thd_get_error_number(const MYSQL_THD thd);
+/**
+ Return the current row number (i.e. in a multiple INSERT statement)
+ @param thd user thread connection handle
+ @return row number
+*/
+unsigned long thd_get_error_row(const MYSQL_THD thd);
+/**
+ Increment the current row number
+ @param thd user thread connection handle
+*/
+void thd_inc_error_row(MYSQL_THD thd);
+/**
+ Return a text description of a thread, its security context (user,host)
+ and the current query.
+*/
+char *thd_get_error_context_description(MYSQL_THD thd,
+ char *buffer, unsigned int length,
+ unsigned int max_query_length);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#define MYSQL_SERVICE_THD_STMT_DA_INCLUDED
+#endif
diff --git a/include/mysql/service_thd_mdl.h b/include/mysql/service_thd_mdl.h
new file mode 100644
index 00000000..19b04769
--- /dev/null
+++ b/include/mysql/service_thd_mdl.h
@@ -0,0 +1,46 @@
+/* Copyright (c) 2019, MariaDB Corporation.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */
+
+#pragma once
+
+/**
+ @file include/mysql/service_thd_mdl.h
+ This service provides functions for plugins and storage engines to access
+ metadata locks.
+*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+extern struct thd_mdl_service_st {
+ void *(*thd_mdl_context)(MYSQL_THD);
+} *thd_mdl_service;
+
+#ifdef MYSQL_DYNAMIC_PLUGIN
+# define thd_mdl_context(_THD) thd_mdl_service->thd_mdl_context(_THD)
+#else
+/**
+ MDL_context accessor
+ @param thd the current session
+ @return pointer to thd->mdl_context
+*/
+void *thd_mdl_context(MYSQL_THD thd);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/include/mysql/service_thd_rnd.h b/include/mysql/service_thd_rnd.h
new file mode 100644
index 00000000..8761077e
--- /dev/null
+++ b/include/mysql/service_thd_rnd.h
@@ -0,0 +1,62 @@
+#ifndef MYSQL_SERVICE_THD_RND_INCLUDED
+/* Copyright (C) 2017 MariaDB Corporation
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */
+
+/**
+ @file
+ This service provides access to the thd-local random number generator.
+
+ It's preferable over the global one, because concurrent threads
+ can generate random numbers without fighting each other over the access
+ to the shared rnd state.
+*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef MYSQL_ABI_CHECK
+#include <stdlib.h>
+#endif
+
+extern struct thd_rnd_service_st {
+ double (*thd_rnd_ptr)(MYSQL_THD thd);
+ void (*thd_c_r_p_ptr)(MYSQL_THD thd, char *to, size_t length);
+} *thd_rnd_service;
+
+#ifdef MYSQL_DYNAMIC_PLUGIN
+#define thd_rnd(A) thd_rnd_service->thd_rnd_ptr(A)
+#define thd_create_random_password(A,B,C) thd_rnd_service->thd_c_r_p_ptr(A,B,C)
+#else
+
+double thd_rnd(MYSQL_THD thd);
+
+/**
+ Generate string of printable random characters of requested length.
+
+ @param to[out] Buffer for generation; must be at least length+1 bytes
+ long; result string is always null-terminated
+ @param length[in] How many random characters to put in buffer
+*/
+void thd_create_random_password(MYSQL_THD thd, char *to, size_t length);
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#define MYSQL_SERVICE_THD_RND_INCLUDED
+#endif
diff --git a/include/mysql/service_thd_specifics.h b/include/mysql/service_thd_specifics.h
new file mode 100644
index 00000000..a4078bd5
--- /dev/null
+++ b/include/mysql/service_thd_specifics.h
@@ -0,0 +1,110 @@
+#ifndef MYSQL_SERVICE_THD_SPECIFICS_INCLUDED
+/* Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */
+
+/**
+ @file
+
+ THD specific for plugin(s)
+
+ This API provides pthread_getspecific like functionality to plugin authors.
+ This is a functional alternative to the declarative MYSQL_THDVAR
+
+ A plugin should at init call thd_key_create that create a key that
+ will have storage in each THD. The key should be used by all threads
+ and can be used concurrently from all threads.
+
+ A plugin should at deinit call thd_key_delete.
+
+ Alternatively, a plugin can use thd_key_create_from_var(K,V) to create
+ a key that corresponds to a named MYSQL_THDVAR variable.
+
+ This API is also safe when using pool-of-threads in which case
+ pthread_getspecific is not, because the actual OS thread may change.
+
+ @note
+
+ Normally one should prefer MYSQL_THDVAR declarative API.
+
+ The benefits are:
+
+ - It supports typed variables (int, char*, enum, etc), not only void*.
+ - The memory allocated for MYSQL_THDVAR is free'd automatically
+ (if PLUGIN_VAR_MEMALLOC is specified).
+ - Continuous loading and unloading of the same plugin does not allocate
+ memory for same variables over and over again.
+
+ An example of using MYSQL_THDVAR for a thd local storage:
+
+ MYSQL_THDVAR_STR(my_tls,
+ PLUGIN_VAR_MEMALLOC | PLUGIN_VAR_NOSYSVAR | PLUGIN_VAR_NOCMDOPT,
+ "thd local storage example", 0, 0, 0);
+*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef int MYSQL_THD_KEY_T;
+
+extern struct thd_specifics_service_st {
+ int (*thd_key_create_func)(MYSQL_THD_KEY_T *key);
+ void (*thd_key_delete_func)(MYSQL_THD_KEY_T *key);
+ void *(*thd_getspecific_func)(MYSQL_THD thd, MYSQL_THD_KEY_T key);
+ int (*thd_setspecific_func)(MYSQL_THD thd, MYSQL_THD_KEY_T key, void *value);
+} *thd_specifics_service;
+
+#define thd_key_create_from_var(K, V) do { *(K)= MYSQL_SYSVAR_NAME(V).offset; } while(0)
+
+#ifdef MYSQL_DYNAMIC_PLUGIN
+
+#define thd_key_create(K) (thd_specifics_service->thd_key_create_func(K))
+#define thd_key_delete(K) (thd_specifics_service->thd_key_delete_func(K))
+#define thd_getspecific(T, K) (thd_specifics_service->thd_getspecific_func(T, K))
+#define thd_setspecific(T, K, V) (thd_specifics_service->thd_setspecific_func(T, K, V))
+
+#else
+
+/**
+ * create THD specific storage
+ * @return 0 on success
+ * else errno is returned
+ */
+int thd_key_create(MYSQL_THD_KEY_T *key);
+
+/**
+ * delete THD specific storage
+ */
+void thd_key_delete(MYSQL_THD_KEY_T *key);
+
+/**
+ * get/set thd specific storage
+ * - first time this is called from a thread it will return 0
+ * - this call is thread-safe in that different threads may call this
+ * simultaneously if operating on different THDs.
+ * - this call acquires no mutexes and is implemented as an array lookup
+ */
+void* thd_getspecific(MYSQL_THD thd, MYSQL_THD_KEY_T key);
+int thd_setspecific(MYSQL_THD thd, MYSQL_THD_KEY_T key, void *value);
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#define MYSQL_SERVICE_THD_SPECIFICS_INCLUDED
+#endif
+
diff --git a/include/mysql/service_thd_timezone.h b/include/mysql/service_thd_timezone.h
new file mode 100644
index 00000000..89e75274
--- /dev/null
+++ b/include/mysql/service_thd_timezone.h
@@ -0,0 +1,73 @@
+#ifndef MYSQL_SERVICE_THD_TIMEZONE_INCLUDED
+/* Copyright (C) 2013 MariaDB Foundation.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */
+
+/**
+ @file
+ This service provdes functions to convert between my_time_t and
+ MYSQL_TIME taking into account the current value of the time_zone
+ session variable.
+
+ The values of the my_time_t type are in Unix timestamp format,
+ i.e. the number of seconds since "1970-01-01 00:00:00 UTC".
+
+ The values of the MYSQL_TIME type are in the current time zone,
+ according to thd->variables.time_zone.
+
+ If the MYSQL_THD parameter is NULL, then global_system_variables.time_zone
+ is used for conversion.
+*/
+
+#ifndef MYSQL_ABI_CHECK
+/*
+ This service currently does not depend on any system headers.
+ If it needs system headers in the future, make sure to put
+ them inside this ifndef.
+*/
+#endif
+
+#include "mysql_time.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+extern struct thd_timezone_service_st {
+ my_time_t (*thd_TIME_to_gmt_sec)(MYSQL_THD thd, const MYSQL_TIME *ltime, unsigned int *errcode);
+ void (*thd_gmt_sec_to_TIME)(MYSQL_THD thd, MYSQL_TIME *ltime, my_time_t t);
+} *thd_timezone_service;
+
+#ifdef MYSQL_DYNAMIC_PLUGIN
+
+#define thd_TIME_to_gmt_sec(thd, ltime, errcode) \
+ (thd_timezone_service->thd_TIME_to_gmt_sec((thd), (ltime), (errcode)))
+
+#define thd_gmt_sec_to_TIME(thd, ltime, t) \
+ (thd_timezone_service->thd_gmt_sec_to_TIME((thd), (ltime), (t)))
+
+#else
+
+my_time_t thd_TIME_to_gmt_sec(MYSQL_THD thd, const MYSQL_TIME *ltime, unsigned int *errcode);
+void thd_gmt_sec_to_TIME(MYSQL_THD thd, MYSQL_TIME *ltime, my_time_t t);
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#define MYSQL_SERVICE_THD_TIMEZONE_INCLUDED
+#endif
diff --git a/include/mysql/service_thd_wait.h b/include/mysql/service_thd_wait.h
new file mode 100644
index 00000000..c20878fd
--- /dev/null
+++ b/include/mysql/service_thd_wait.h
@@ -0,0 +1,104 @@
+/* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */
+
+#ifndef MYSQL_SERVICE_THD_WAIT_INCLUDED
+#define MYSQL_SERVICE_THD_WAIT_INCLUDED
+
+/**
+ @file include/mysql/service_thd_wait.h
+ This service provides functions for plugins and storage engines to report
+ when they are going to sleep/stall.
+
+ SYNOPSIS
+ thd_wait_begin() - call just before a wait begins
+ thd Thread object
+ Use NULL if the thd is NOT known.
+ wait_type Type of wait
+ 1 -- short wait (e.g. for mutex)
+ 2 -- medium wait (e.g. for disk io)
+ 3 -- large wait (e.g. for locked row/table)
+ NOTES
+ This is used by the threadpool to have better knowledge of which
+ threads that currently are actively running on CPUs. When a thread
+ reports that it's going to sleep/stall, the threadpool scheduler is
+ free to start another thread in the pool most likely. The expected wait
+ time is simply an indication of how long the wait is expected to
+ become, the real wait time could be very different.
+
+ thd_wait_end() called immediately after the wait is complete
+
+ thd_wait_end() MUST be called if thd_wait_begin() was called.
+
+ Using thd_wait_...() service is optional but recommended. Using it will
+ improve performance as the thread pool will be more active at managing the
+ thread workload.
+*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ One should only report wait events that could potentially block for a
+ long time. A mutex wait is too short of an event to report. The reason
+ is that an event which is reported leads to a new thread starts
+ executing a query and this has a negative impact of usage of CPU caches
+ and thus the expected gain of starting a new thread must be higher than
+ the expected cost of lost performance due to starting a new thread.
+
+ Good examples of events that should be reported are waiting for row locks
+ that could easily be for many milliseconds or even seconds and the same
+ holds true for global read locks, table locks and other meta data locks.
+ Another event of interest is going to sleep for an extended time.
+*/
+typedef enum _thd_wait_type_e {
+ THD_WAIT_SLEEP= 1,
+ THD_WAIT_DISKIO= 2,
+ THD_WAIT_ROW_LOCK= 3,
+ THD_WAIT_GLOBAL_LOCK= 4,
+ THD_WAIT_META_DATA_LOCK= 5,
+ THD_WAIT_TABLE_LOCK= 6,
+ THD_WAIT_USER_LOCK= 7,
+ THD_WAIT_BINLOG= 8,
+ THD_WAIT_GROUP_COMMIT= 9,
+ THD_WAIT_SYNC= 10,
+ THD_WAIT_NET= 11,
+ THD_WAIT_LAST= 12
+} thd_wait_type;
+
+extern struct thd_wait_service_st {
+ void (*thd_wait_begin_func)(MYSQL_THD, int);
+ void (*thd_wait_end_func)(MYSQL_THD);
+} *thd_wait_service;
+
+#ifdef MYSQL_DYNAMIC_PLUGIN
+
+#define thd_wait_begin(_THD, _WAIT_TYPE) \
+ thd_wait_service->thd_wait_begin_func(_THD, _WAIT_TYPE)
+#define thd_wait_end(_THD) thd_wait_service->thd_wait_end_func(_THD)
+
+#else
+
+void thd_wait_begin(MYSQL_THD thd, int wait_type);
+void thd_wait_end(MYSQL_THD thd);
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/include/mysql/service_wsrep.h b/include/mysql/service_wsrep.h
new file mode 100644
index 00000000..0831326a
--- /dev/null
+++ b/include/mysql/service_wsrep.h
@@ -0,0 +1,242 @@
+#ifndef MYSQL_SERVICE_WSREP_INCLUDED
+#define MYSQL_SERVICE_WSREP_INCLUDED
+
+enum Wsrep_service_key_type
+{
+ WSREP_SERVICE_KEY_SHARED,
+ WSREP_SERVICE_KEY_REFERENCE,
+ WSREP_SERVICE_KEY_UPDATE,
+ WSREP_SERVICE_KEY_EXCLUSIVE
+};
+
+#if (defined (MYSQL_DYNAMIC_PLUGIN) && defined(MYSQL_SERVICE_WSREP_DYNAMIC_INCLUDED)) || (!defined(MYSQL_DYNAMIC_PLUGIN) && defined(MYSQL_SERVICE_WSREP_STATIC_INCLUDED))
+
+#else
+
+/* Copyright (c) 2015, 2020, MariaDB Corporation Ab
+ 2018 Codership Oy <info@codership.com>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */
+
+/**
+ @file
+ wsrep service
+
+ Interface to WSREP functionality in the server.
+ For engines that want to support galera.
+*/
+#include <my_pthread.h>
+#ifdef __cplusplus
+#endif
+
+struct xid_t;
+struct wsrep_ws_handle;
+struct wsrep_buf;
+
+/* Must match to definition in sql/mysqld.h */
+typedef int64 query_id_t;
+
+
+extern struct wsrep_service_st {
+ my_bool (*get_wsrep_recovery_func)();
+ bool (*wsrep_consistency_check_func)(MYSQL_THD thd);
+ int (*wsrep_is_wsrep_xid_func)(const void *xid);
+ long long (*wsrep_xid_seqno_func)(const struct xid_t *xid);
+ const unsigned char* (*wsrep_xid_uuid_func)(const struct xid_t *xid);
+ my_bool (*wsrep_on_func)(const MYSQL_THD thd);
+ bool (*wsrep_prepare_key_for_innodb_func)(MYSQL_THD thd, const unsigned char*, size_t, const unsigned char*, size_t, struct wsrep_buf*, size_t*);
+ void (*wsrep_thd_LOCK_func)(const MYSQL_THD thd);
+ void (*wsrep_thd_UNLOCK_func)(const MYSQL_THD thd);
+ const char * (*wsrep_thd_query_func)(const MYSQL_THD thd);
+ int (*wsrep_thd_retry_counter_func)(const MYSQL_THD thd);
+ bool (*wsrep_thd_ignore_table_func)(MYSQL_THD thd);
+ long long (*wsrep_thd_trx_seqno_func)(const MYSQL_THD thd);
+ my_bool (*wsrep_thd_is_aborting_func)(const MYSQL_THD thd);
+ void (*wsrep_set_data_home_dir_func)(const char *data_dir);
+ my_bool (*wsrep_thd_is_BF_func)(const MYSQL_THD thd, my_bool sync);
+ my_bool (*wsrep_thd_is_local_func)(const MYSQL_THD thd);
+ void (*wsrep_thd_self_abort_func)(MYSQL_THD thd);
+ int (*wsrep_thd_append_key_func)(MYSQL_THD thd, const struct wsrep_key* key,
+ int n_keys, enum Wsrep_service_key_type);
+ const char* (*wsrep_thd_client_state_str_func)(const MYSQL_THD thd);
+ const char* (*wsrep_thd_client_mode_str_func)(const MYSQL_THD thd);
+ const char* (*wsrep_thd_transaction_state_str_func)(const MYSQL_THD thd);
+ query_id_t (*wsrep_thd_transaction_id_func)(const MYSQL_THD thd);
+ my_bool (*wsrep_thd_bf_abort_func)(MYSQL_THD bf_thd,
+ MYSQL_THD victim_thd,
+ my_bool signal);
+ my_bool (*wsrep_thd_order_before_func)(const MYSQL_THD left, const MYSQL_THD right);
+ void (*wsrep_handle_SR_rollback_func)(MYSQL_THD BF_thd, MYSQL_THD victim_thd);
+ my_bool (*wsrep_thd_skip_locking_func)(const MYSQL_THD thd);
+ const char* (*wsrep_get_sr_table_name_func)();
+ my_bool (*wsrep_get_debug_func)();
+ void (*wsrep_commit_ordered_func)(MYSQL_THD thd);
+ my_bool (*wsrep_thd_is_applying_func)(const MYSQL_THD thd);
+ ulong (*wsrep_OSU_method_get_func)(const MYSQL_THD thd);
+ my_bool (*wsrep_thd_has_ignored_error_func)(const MYSQL_THD thd);
+ void (*wsrep_thd_set_ignored_error_func)(MYSQL_THD thd, my_bool val);
+ bool (*wsrep_thd_set_wsrep_aborter_func)(MYSQL_THD bf_thd, MYSQL_THD thd);
+ void (*wsrep_report_bf_lock_wait_func)(const MYSQL_THD thd,
+ unsigned long long trx_id);
+ void (*wsrep_thd_kill_LOCK_func)(const MYSQL_THD thd);
+ void (*wsrep_thd_kill_UNLOCK_func)(const MYSQL_THD thd);
+} *wsrep_service;
+
+#define MYSQL_SERVICE_WSREP_INCLUDED
+#endif
+
+#ifdef MYSQL_DYNAMIC_PLUGIN
+
+#define MYSQL_SERVICE_WSREP_DYNAMIC_INCLUDED
+#define get_wsrep_recovery() wsrep_service->get_wsrep_recovery_func()
+#define wsrep_consistency_check(T) wsrep_service->wsrep_consistency_check_func(T)
+#define wsrep_is_wsrep_xid(X) wsrep_service->wsrep_is_wsrep_xid_func(X)
+#define wsrep_xid_seqno(X) wsrep_service->wsrep_xid_seqno_func(X)
+#define wsrep_xid_uuid(X) wsrep_service->wsrep_xid_uuid_func(X)
+#define wsrep_on(thd) (thd) && WSREP_ON && wsrep_service->wsrep_on_func(thd)
+#define wsrep_prepare_key_for_innodb(A,B,C,D,E,F,G) wsrep_service->wsrep_prepare_key_for_innodb_func(A,B,C,D,E,F,G)
+#define wsrep_thd_LOCK(T) wsrep_service->wsrep_thd_LOCK_func(T)
+#define wsrep_thd_UNLOCK(T) wsrep_service->wsrep_thd_UNLOCK_func(T)
+#define wsrep_thd_kill_LOCK(T) wsrep_service->wsrep_thd_kill_LOCK_func(T)
+#define wsrep_thd_kill_UNLOCK(T) wsrep_service->wsrep_thd_kill_UNLOCK_func(T)
+#define wsrep_thd_query(T) wsrep_service->wsrep_thd_query_func(T)
+#define wsrep_thd_retry_counter(T) wsrep_service->wsrep_thd_retry_counter_func(T)
+#define wsrep_thd_ignore_table(T) wsrep_service->wsrep_thd_ignore_table_func(T)
+#define wsrep_thd_trx_seqno(T) wsrep_service->wsrep_thd_trx_seqno_func(T)
+#define wsrep_set_data_home_dir(A) wsrep_service->wsrep_set_data_home_dir_func(A)
+#define wsrep_thd_is_BF(T,S) wsrep_service->wsrep_thd_is_BF_func(T,S)
+#define wsrep_thd_is_aborting(T) wsrep_service->wsrep_thd_is_aborting_func(T)
+#define wsrep_thd_is_local(T) wsrep_service->wsrep_thd_is_local_func(T)
+#define wsrep_thd_self_abort(T) wsrep_service->wsrep_thd_self_abort_func(T)
+#define wsrep_thd_append_key(T,W,N,K) wsrep_service->wsrep_thd_append_key_func(T,W,N,K)
+#define wsrep_thd_client_state_str(T) wsrep_service->wsrep_thd_client_state_str_func(T)
+#define wsrep_thd_client_mode_str(T) wsrep_service->wsrep_thd_client_mode_str_func(T)
+#define wsrep_thd_transaction_state_str(T) wsrep_service->wsrep_thd_transaction_state_str_func(T)
+#define wsrep_thd_transaction_id(T) wsrep_service->wsrep_thd_transaction_id_func(T)
+#define wsrep_thd_bf_abort(T,T2,S) wsrep_service->wsrep_thd_bf_abort_func(T,T2,S)
+#define wsrep_thd_order_before(L,R) wsrep_service->wsrep_thd_order_before_func(L,R)
+#define wsrep_handle_SR_rollback(B,V) wsrep_service->wsrep_handle_SR_rollback_func(B,V)
+#define wsrep_thd_skip_locking(T) wsrep_service->wsrep_thd_skip_locking_func(T)
+#define wsrep_get_sr_table_name() wsrep_service->wsrep_get_sr_table_name_func()
+#define wsrep_get_debug() wsrep_service->wsrep_get_debug_func()
+#define wsrep_commit_ordered(T) wsrep_service->wsrep_commit_ordered_func(T)
+#define wsrep_thd_is_applying(T) wsrep_service->wsrep_thd_is_applying_func(T)
+#define wsrep_OSU_method_get(T) wsrep_service->wsrep_OSU_method_get_func(T)
+#define wsrep_thd_has_ignored_error(T) wsrep_service->wsrep_thd_has_ignored_error_func(T)
+#define wsrep_thd_set_ignored_error(T,V) wsrep_service->wsrep_thd_set_ignored_error_func(T,V)
+#define wsrep_thd_set_wsrep_aborter(T) wsrep_service->wsrep_thd_set_wsrep_aborter_func(T1, T2)
+#define wsrep_report_bf_lock_wait(T,I) wsrep_service->wsrep_report_bf_lock_wait(T,I)
+#else
+
+#define MYSQL_SERVICE_WSREP_STATIC_INCLUDED
+extern ulong wsrep_debug;
+extern my_bool wsrep_log_conflicts;
+extern my_bool wsrep_certify_nonPK;
+extern my_bool wsrep_load_data_splitting;
+extern my_bool wsrep_drupal_282555_workaround;
+extern my_bool wsrep_recovery;
+extern long wsrep_protocol_version;
+
+extern "C" bool wsrep_consistency_check(MYSQL_THD thd);
+bool wsrep_prepare_key_for_innodb(MYSQL_THD thd, const unsigned char* cache_key, size_t cache_key_len, const unsigned char* row_id, size_t row_id_len, struct wsrep_buf* key, size_t* key_len);
+extern "C" const char *wsrep_thd_query(const MYSQL_THD thd);
+extern "C" int wsrep_is_wsrep_xid(const void* xid);
+extern "C" long long wsrep_xid_seqno(const struct xid_t* xid);
+const unsigned char* wsrep_xid_uuid(const struct xid_t* xid);
+extern "C" long long wsrep_thd_trx_seqno(const MYSQL_THD thd);
+my_bool get_wsrep_recovery();
+bool wsrep_thd_ignore_table(MYSQL_THD thd);
+void wsrep_set_data_home_dir(const char *data_dir);
+
+/* from mysql wsrep-lib */
+#include "my_global.h"
+#include "my_pthread.h"
+
+/* Return true if wsrep is enabled for a thd. This means that
+ wsrep is enabled globally and the thd has wsrep on */
+extern "C" my_bool wsrep_on(const MYSQL_THD thd);
+/* Lock thd wsrep lock */
+extern "C" void wsrep_thd_LOCK(const MYSQL_THD thd);
+/* Unlock thd wsrep lock */
+extern "C" void wsrep_thd_UNLOCK(const MYSQL_THD thd);
+
+extern "C" void wsrep_thd_kill_LOCK(const MYSQL_THD thd);
+extern "C" void wsrep_thd_kill_UNLOCK(const MYSQL_THD thd);
+
+/* Return thd client state string */
+extern "C" const char* wsrep_thd_client_state_str(const MYSQL_THD thd);
+/* Return thd client mode string */
+extern "C" const char* wsrep_thd_client_mode_str(const MYSQL_THD thd);
+/* Return thd transaction state string */
+extern "C" const char* wsrep_thd_transaction_state_str(const MYSQL_THD thd);
+
+/* Return current transaction id */
+extern "C" query_id_t wsrep_thd_transaction_id(const MYSQL_THD thd);
+/* Mark thd own transaction as aborted */
+extern "C" void wsrep_thd_self_abort(MYSQL_THD thd);
+/* Return true if thd is in replicating mode */
+extern "C" my_bool wsrep_thd_is_local(const MYSQL_THD thd);
+/* Return true if thd is in high priority mode */
+/* todo: rename to is_high_priority() */
+extern "C" my_bool wsrep_thd_is_applying(const MYSQL_THD thd);
+/* set wsrep_aborter for the target THD */
+extern "C" bool wsrep_thd_set_wsrep_aborter(MYSQL_THD bf_thd, MYSQL_THD victim_thd);
+/* Return true if thd is in TOI mode */
+extern "C" my_bool wsrep_thd_is_toi(const MYSQL_THD thd);
+/* Return true if thd is in replicating TOI mode */
+extern "C" my_bool wsrep_thd_is_local_toi(const MYSQL_THD thd);
+/* Return true if thd is in RSU mode */
+extern "C" my_bool wsrep_thd_is_in_rsu(const MYSQL_THD thd);
+/* Return true if thd is in BF mode, either high_priority or TOI */
+extern "C" my_bool wsrep_thd_is_BF(const MYSQL_THD thd, my_bool sync);
+/* Return true if thd is streaming */
+extern "C" my_bool wsrep_thd_is_SR(const MYSQL_THD thd);
+extern "C" void wsrep_handle_SR_rollback(MYSQL_THD BF_thd, MYSQL_THD victim_thd);
+/* Return thd retry counter */
+extern "C" int wsrep_thd_retry_counter(const MYSQL_THD thd);
+/* BF abort victim_thd */
+extern "C" my_bool wsrep_thd_bf_abort(MYSQL_THD bf_thd,
+ MYSQL_THD victim_thd,
+ my_bool signal);
+/* Return true if left thd is ordered before right thd */
+extern "C" my_bool wsrep_thd_order_before(const MYSQL_THD left, const MYSQL_THD right);
+/* Return true if thd should skip locking. This means that the thd
+ is operating on shared resource inside commit order critical section. */
+extern "C" my_bool wsrep_thd_skip_locking(const MYSQL_THD thd);
+/* Return true if thd is aborting */
+extern "C" my_bool wsrep_thd_is_aborting(const MYSQL_THD thd);
+
+struct wsrep_key;
+struct wsrep_key_array;
+extern "C" int wsrep_thd_append_key(MYSQL_THD thd,
+ const struct wsrep_key* key,
+ int n_keys,
+ enum Wsrep_service_key_type);
+
+extern const char* wsrep_sr_table_name_full;
+
+extern "C" const char* wsrep_get_sr_table_name();
+
+extern "C" my_bool wsrep_get_debug();
+
+extern "C" void wsrep_commit_ordered(MYSQL_THD thd);
+extern "C" my_bool wsrep_thd_is_applying(const MYSQL_THD thd);
+extern "C" ulong wsrep_OSU_method_get(const MYSQL_THD thd);
+extern "C" my_bool wsrep_thd_has_ignored_error(const MYSQL_THD thd);
+extern "C" void wsrep_thd_set_ignored_error(MYSQL_THD thd, my_bool val);
+extern "C" bool wsrep_thd_set_wsrep_aborter(MYSQL_THD bf_thd, MYSQL_THD victim_thd);
+extern "C" void wsrep_report_bf_lock_wait(const THD *thd,
+ unsigned long long trx_id);
+#endif
+#endif /* MYSQL_SERVICE_WSREP_INCLUDED */
diff --git a/include/mysql/services.h b/include/mysql/services.h
new file mode 100644
index 00000000..2c3a0ae4
--- /dev/null
+++ b/include/mysql/services.h
@@ -0,0 +1,51 @@
+#ifndef MYSQL_SERVICES_INCLUDED
+/* Copyright (c) 2009, 2010, Oracle and/or its affiliates.
+ Copyright (c) 2012, 2017, MariaDB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <mysql/service_base64.h>
+#include <mysql/service_debug_sync.h>
+#include <mysql/service_encryption.h>
+#include <mysql/service_encryption_scheme.h>
+#include <mysql/service_kill_statement.h>
+#include <mysql/service_logger.h>
+#include <mysql/service_md5.h>
+#include <mysql/service_my_crypt.h>
+#include <mysql/service_my_print_error.h>
+#include <mysql/service_my_snprintf.h>
+#include <mysql/service_progress_report.h>
+#include <mysql/service_sha1.h>
+#include <mysql/service_sha2.h>
+#include <mysql/service_thd_alloc.h>
+#include <mysql/service_thd_autoinc.h>
+#include <mysql/service_thd_error_context.h>
+#include <mysql/service_thd_rnd.h>
+#include <mysql/service_thd_specifics.h>
+#include <mysql/service_thd_timezone.h>
+#include <mysql/service_thd_wait.h>
+#include <mysql/service_json.h>
+/*#include <mysql/service_wsrep.h>*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#define MYSQL_SERVICES_INCLUDED
+#endif
+