mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
WL#4903 Plugin Service API part I
(mysql-next-mr backport)
This commit is contained in:
@ -311,6 +311,7 @@ ADD_SUBDIRECTORY(extra)
|
||||
ADD_SUBDIRECTORY(client)
|
||||
ADD_SUBDIRECTORY(sql)
|
||||
ADD_SUBDIRECTORY(libmysql)
|
||||
ADD_SUBDIRECTORY(libservices)
|
||||
ADD_SUBDIRECTORY(tests)
|
||||
IF(WITH_EMBEDDED_SERVER)
|
||||
ADD_SUBDIRECTORY(libmysqld)
|
||||
|
@ -23,7 +23,7 @@ EXTRA_DIST = INSTALL-SOURCE INSTALL-WIN-SOURCE \
|
||||
|
||||
SUBDIRS = . include @docs_dirs@ @zlib_dir@ \
|
||||
@readline_topdir@ sql-common scripts \
|
||||
@pstack_dir@ \
|
||||
@pstack_dir@ libservices \
|
||||
@sql_union_dirs@ unittest \
|
||||
@sql_server@ @man_dirs@ tests \
|
||||
netware @libmysqld_dirs@ \
|
||||
@ -32,7 +32,7 @@ SUBDIRS = . include @docs_dirs@ @zlib_dir@ \
|
||||
|
||||
DIST_SUBDIRS = . include Docs zlib \
|
||||
cmd-line-utils sql-common scripts \
|
||||
pstack \
|
||||
pstack libservices \
|
||||
strings mysys dbug extra regex libmysql libmysql_r client unittest storage plugin \
|
||||
vio sql man tests \
|
||||
netware libmysqld \
|
||||
|
@ -2946,7 +2946,7 @@ AC_CONFIG_FILES(Makefile extra/Makefile mysys/Makefile dnl
|
||||
man/Makefile BUILD/Makefile vio/Makefile dnl
|
||||
libmysql/Makefile libmysql_r/Makefile client/Makefile dnl
|
||||
sql/Makefile sql/share/Makefile dnl
|
||||
sql/sql_builtin.cc sql-common/Makefile dnl
|
||||
sql/sql_builtin.cc sql-common/Makefile libservices/Makefile dnl
|
||||
dbug/Makefile scripts/Makefile include/Makefile dnl
|
||||
tests/Makefile Docs/Makefile support-files/Makefile dnl
|
||||
support-files/MacOSX/Makefile support-files/RHEL4-SElinux/Makefile dnl
|
||||
|
@ -21,7 +21,8 @@ HEADERS_GEN_MAKE = my_config.h
|
||||
HEADERS_ABI = mysql.h mysql_com.h mysql_time.h \
|
||||
my_list.h my_alloc.h typelib.h mysql/plugin.h
|
||||
pkginclude_HEADERS = $(HEADERS_ABI) my_dbug.h m_string.h my_sys.h \
|
||||
my_xml.h mysql_embed.h \
|
||||
my_xml.h mysql_embed.h mysql/services.h \
|
||||
mysql/service_my_snprintf.h mysql/service_thd_alloc.h \
|
||||
my_pthread.h my_no_pthread.h \
|
||||
decimal.h errmsg.h my_global.h my_net.h \
|
||||
my_getopt.h sslopt-longopts.h my_dir.h \
|
||||
@ -36,7 +37,7 @@ noinst_HEADERS = config-win.h config-netware.h my_bit.h \
|
||||
my_nosys.h my_alarm.h queues.h rijndael.h sha1.h \
|
||||
my_aes.h my_tree.h my_trie.h hash.h thr_alarm.h \
|
||||
thr_lock.h t_ctype.h violite.h my_md5.h base64.h \
|
||||
my_handler.h my_time.h \
|
||||
my_handler.h my_time.h service_versions.h \
|
||||
my_vle.h my_user.h my_atomic.h atomic/nolock.h \
|
||||
atomic/rwlock.h atomic/x86-gcc.h atomic/x86-msvc.h \
|
||||
atomic/solaris.h \
|
||||
|
@ -250,16 +250,10 @@ extern size_t my_snprintf(char *to, size_t n, const char *fmt, ...)
|
||||
|
||||
/*
|
||||
LEX_STRING -- a pair of a C-string and its length.
|
||||
(it's part of the plugin API as a MYSQL_LEX_STRING)
|
||||
*/
|
||||
|
||||
#ifndef _my_plugin_h
|
||||
/* This definition must match the one given in mysql/plugin.h */
|
||||
struct st_mysql_lex_string
|
||||
{
|
||||
char *str;
|
||||
size_t length;
|
||||
};
|
||||
#endif
|
||||
#include <mysql/plugin.h>
|
||||
typedef struct st_mysql_lex_string LEX_STRING;
|
||||
|
||||
#define STRING_WITH_LEN(X) (X), ((size_t) (sizeof(X) - 1))
|
||||
|
@ -683,6 +683,8 @@ extern void my_error _VARARGS((int nr,myf MyFlags, ...));
|
||||
extern void my_printf_error _VARARGS((uint my_err, const char *format,
|
||||
myf MyFlags, ...))
|
||||
ATTRIBUTE_FORMAT(printf, 2, 4);
|
||||
extern void my_printv_error(uint error, const char *format, myf MyFlags,
|
||||
va_list ap);
|
||||
extern int my_error_register(const char** (*get_errmsgs) (),
|
||||
int first, int last);
|
||||
extern const char **my_error_unregister(int first, int last);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2005 MySQL AB
|
||||
/* Copyright (C) 2005 MySQL AB, 2009 Sun Microsystems, Inc.
|
||||
|
||||
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
|
||||
@ -16,12 +16,6 @@
|
||||
#ifndef _my_plugin_h
|
||||
#define _my_plugin_h
|
||||
|
||||
/* size_t */
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef struct st_mysql MYSQL;
|
||||
|
||||
|
||||
/*
|
||||
On Windows, exports from DLL need to be declared
|
||||
*/
|
||||
@ -39,15 +33,7 @@ class Item;
|
||||
#define MYSQL_THD void*
|
||||
#endif
|
||||
|
||||
#ifndef _m_string_h
|
||||
/* This definition must match the one given in m_string.h */
|
||||
struct st_mysql_lex_string
|
||||
{
|
||||
char *str;
|
||||
unsigned int length;
|
||||
};
|
||||
#endif /* _m_string_h */
|
||||
typedef struct st_mysql_lex_string MYSQL_LEX_STRING;
|
||||
#include <mysql/services.h>
|
||||
|
||||
#define MYSQL_XIDDATASIZE 128
|
||||
/**
|
||||
@ -70,7 +56,7 @@ typedef struct st_mysql_xid MYSQL_XID;
|
||||
Plugin API. Common for all plugin types.
|
||||
*/
|
||||
|
||||
#define MYSQL_PLUGIN_INTERFACE_VERSION 0x0100
|
||||
#define MYSQL_PLUGIN_INTERFACE_VERSION 0x0101
|
||||
|
||||
/*
|
||||
The allowable types of plugins
|
||||
@ -126,7 +112,8 @@ enum enum_mysql_show_type
|
||||
{
|
||||
SHOW_UNDEF, SHOW_BOOL, SHOW_INT, SHOW_LONG,
|
||||
SHOW_LONGLONG, SHOW_CHAR, SHOW_CHAR_PTR,
|
||||
SHOW_ARRAY, SHOW_FUNC, SHOW_DOUBLE
|
||||
SHOW_ARRAY, SHOW_FUNC, SHOW_DOUBLE,
|
||||
SHOW_always_last
|
||||
};
|
||||
|
||||
struct st_mysql_show_var {
|
||||
@ -750,54 +737,6 @@ int thd_killed(const MYSQL_THD thd);
|
||||
*/
|
||||
unsigned long thd_get_thread_id(const MYSQL_THD thd);
|
||||
|
||||
|
||||
/**
|
||||
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, unsigned int size);
|
||||
/**
|
||||
@see thd_alloc()
|
||||
*/
|
||||
void *thd_calloc(MYSQL_THD thd, unsigned int 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, unsigned int size);
|
||||
/**
|
||||
@see thd_alloc()
|
||||
*/
|
||||
void *thd_memdup(MYSQL_THD thd, const void* str, unsigned int 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_LEX_STRING *thd_make_lex_string(MYSQL_THD thd, MYSQL_LEX_STRING *lex_str,
|
||||
const char *str, unsigned int size,
|
||||
int allocate_lex_string);
|
||||
|
||||
/**
|
||||
Get the XID for this connection's transaction
|
||||
|
||||
@ -818,64 +757,6 @@ void mysql_query_cache_invalidate4(MYSQL_THD thd,
|
||||
const char *key, unsigned int key_length,
|
||||
int using_trx);
|
||||
|
||||
/**
|
||||
Get the value of user variable as an integer.
|
||||
|
||||
This function will return the value of variable @a name as an
|
||||
integer. If the original value of the variable is not an integer,
|
||||
the value will be converted into an integer.
|
||||
|
||||
@param name user variable name
|
||||
@param value pointer to return the value
|
||||
@param null_value if not NULL, the function will set it to true if
|
||||
the value of variable is null, set to false if not
|
||||
|
||||
@retval 0 Success
|
||||
@retval 1 Variable not found
|
||||
*/
|
||||
int get_user_var_int(const char *name,
|
||||
long long int *value, int *null_value);
|
||||
|
||||
/**
|
||||
Get the value of user variable as a double precision float number.
|
||||
|
||||
This function will return the value of variable @a name as real
|
||||
number. If the original value of the variable is not a real number,
|
||||
the value will be converted into a real number.
|
||||
|
||||
@param name user variable name
|
||||
@param value pointer to return the value
|
||||
@param null_value if not NULL, the function will set it to true if
|
||||
the value of variable is null, set to false if not
|
||||
|
||||
@retval 0 Success
|
||||
@retval 1 Variable not found
|
||||
*/
|
||||
int get_user_var_real(const char *name,
|
||||
double *value, int *null_value);
|
||||
|
||||
/**
|
||||
Get the value of user variable as a string.
|
||||
|
||||
This function will return the value of variable @a name as
|
||||
string. If the original value of the variable is not a string,
|
||||
the value will be converted into a string.
|
||||
|
||||
@param name user variable name
|
||||
@param value pointer to the value buffer
|
||||
@param len length of the value buffer
|
||||
@param precision precision of the value if it is a float number
|
||||
@param null_value if not NULL, the function will set it to true if
|
||||
the value of variable is null, set to false if not
|
||||
|
||||
@retval 0 Success
|
||||
@retval 1 Variable not found
|
||||
*/
|
||||
int get_user_var_str(const char *name,
|
||||
char *value, unsigned long len,
|
||||
unsigned int precision, int *null_value);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -1,11 +1,38 @@
|
||||
#include <mysql/services.h>
|
||||
#include <mysql/service_my_snprintf.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
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);
|
||||
#include <mysql/service_thd_alloc.h>
|
||||
#include <stdlib.h>
|
||||
typedef struct st_mysql MYSQL;
|
||||
struct st_mysql_lex_string
|
||||
{
|
||||
char *str;
|
||||
unsigned int length;
|
||||
size_t length;
|
||||
};
|
||||
typedef struct st_mysql_lex_string MYSQL_LEX_STRING;
|
||||
extern struct thd_alloc_service_st {
|
||||
void *(*thd_alloc_func)(void*, unsigned int);
|
||||
void *(*thd_calloc_func)(void*, unsigned int);
|
||||
char *(*thd_strdup_func)(void*, const char *);
|
||||
char *(*thd_strmake_func)(void*, const char *, unsigned int);
|
||||
void *(*thd_memdup_func)(void*, const void*, unsigned int);
|
||||
MYSQL_LEX_STRING *(*thd_make_lex_string_func)(void*, MYSQL_LEX_STRING *,
|
||||
const char *, unsigned int, int);
|
||||
} *thd_alloc_service;
|
||||
void *thd_alloc(void* thd, unsigned int size);
|
||||
void *thd_calloc(void* thd, unsigned int size);
|
||||
char *thd_strdup(void* thd, const char *str);
|
||||
char *thd_strmake(void* thd, const char *str, unsigned int size);
|
||||
void *thd_memdup(void* thd, const void* str, unsigned int size);
|
||||
MYSQL_LEX_STRING *thd_make_lex_string(void* thd, MYSQL_LEX_STRING *lex_str,
|
||||
const char *str, unsigned int size,
|
||||
int allocate_lex_string);
|
||||
struct st_mysql_xid {
|
||||
long formatID;
|
||||
long gtrid_length;
|
||||
@ -17,7 +44,8 @@ enum enum_mysql_show_type
|
||||
{
|
||||
SHOW_UNDEF, SHOW_BOOL, SHOW_INT, SHOW_LONG,
|
||||
SHOW_LONGLONG, SHOW_CHAR, SHOW_CHAR_PTR,
|
||||
SHOW_ARRAY, SHOW_FUNC, SHOW_DOUBLE
|
||||
SHOW_ARRAY, SHOW_FUNC, SHOW_DOUBLE,
|
||||
SHOW_always_last
|
||||
};
|
||||
struct st_mysql_show_var {
|
||||
const char *name;
|
||||
@ -107,9 +135,9 @@ struct st_mysql_information_schema
|
||||
{
|
||||
int interface_version;
|
||||
};
|
||||
struct Mysql_replication {
|
||||
int interface_version;
|
||||
};
|
||||
struct Mysql_replication {
|
||||
int interface_version;
|
||||
};
|
||||
struct st_mysql_value
|
||||
{
|
||||
int (*value_type)(struct st_mysql_value *);
|
||||
@ -130,22 +158,7 @@ void thd_inc_row_count(void* thd);
|
||||
int mysql_tmpfile(const char *prefix);
|
||||
int thd_killed(const void* thd);
|
||||
unsigned long thd_get_thread_id(const void* thd);
|
||||
void *thd_alloc(void* thd, unsigned int size);
|
||||
void *thd_calloc(void* thd, unsigned int size);
|
||||
char *thd_strdup(void* thd, const char *str);
|
||||
char *thd_strmake(void* thd, const char *str, unsigned int size);
|
||||
void *thd_memdup(void* thd, const void* str, unsigned int size);
|
||||
MYSQL_LEX_STRING *thd_make_lex_string(void* thd, MYSQL_LEX_STRING *lex_str,
|
||||
const char *str, unsigned int size,
|
||||
int allocate_lex_string);
|
||||
void thd_get_xid(const void* thd, MYSQL_XID *xid);
|
||||
void mysql_query_cache_invalidate4(void* thd,
|
||||
const char *key, unsigned int key_length,
|
||||
int using_trx);
|
||||
int get_user_var_int(const char *name,
|
||||
long long int *value, int *null_value);
|
||||
int get_user_var_real(const char *name,
|
||||
double *value, int *null_value);
|
||||
int get_user_var_str(const char *name,
|
||||
char *value, unsigned long len,
|
||||
unsigned int precision, int *null_value);
|
||||
|
98
include/mysql/service_my_snprintf.h
Normal file
98
include/mysql/service_my_snprintf.h
Normal file
@ -0,0 +1,98 @@
|
||||
#ifndef MYSQL_SERVICE_MY_SNPRINTF_INCLUDED
|
||||
/* Copyright (C) 2009 Sun Microsystems, Inc.
|
||||
|
||||
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 regognized:
|
||||
'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 '*'.
|
||||
|
||||
<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', 'u', 'x',
|
||||
'X', 'p' (works as 0x%x).
|
||||
|
||||
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'.
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
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
|
||||
|
128
include/mysql/service_thd_alloc.h
Normal file
128
include/mysql/service_thd_alloc.h
Normal file
@ -0,0 +1,128 @@
|
||||
#ifndef MYSQL_SERVICE_THD_ALLOC_INCLUDED
|
||||
/* Copyright (C) 2009 Sun Microsystems, Inc.
|
||||
|
||||
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
/**
|
||||
@file
|
||||
This service provdes 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.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct st_mysql_lex_string
|
||||
{
|
||||
char *str;
|
||||
size_t length;
|
||||
};
|
||||
typedef struct st_mysql_lex_string MYSQL_LEX_STRING;
|
||||
|
||||
extern struct thd_alloc_service_st {
|
||||
void *(*thd_alloc_func)(MYSQL_THD, unsigned int);
|
||||
void *(*thd_calloc_func)(MYSQL_THD, unsigned int);
|
||||
char *(*thd_strdup_func)(MYSQL_THD, const char *);
|
||||
char *(*thd_strmake_func)(MYSQL_THD, const char *, unsigned int);
|
||||
void *(*thd_memdup_func)(MYSQL_THD, const void*, unsigned int);
|
||||
MYSQL_LEX_STRING *(*thd_make_lex_string_func)(MYSQL_THD, MYSQL_LEX_STRING *,
|
||||
const char *, unsigned int, 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, unsigned int size);
|
||||
/**
|
||||
@see thd_alloc()
|
||||
*/
|
||||
void *thd_calloc(MYSQL_THD thd, unsigned int 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, unsigned int size);
|
||||
/**
|
||||
@see thd_alloc()
|
||||
*/
|
||||
void *thd_memdup(MYSQL_THD thd, const void* str, unsigned int 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_LEX_STRING *thd_make_lex_string(MYSQL_THD thd, MYSQL_LEX_STRING *lex_str,
|
||||
const char *str, unsigned int size,
|
||||
int allocate_lex_string);
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#define MYSQL_SERVICE_THD_ALLOC_INCLUDED
|
||||
#endif
|
||||
|
30
include/mysql/services.h
Normal file
30
include/mysql/services.h
Normal file
@ -0,0 +1,30 @@
|
||||
#ifndef MYSQL_SERVICES_INCLUDED
|
||||
/* Copyright (C) 2009 Sun Microsystems, Inc.
|
||||
|
||||
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <mysql/service_my_snprintf.h>
|
||||
#include <mysql/service_thd_alloc.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#define MYSQL_SERVICES_INCLUDED
|
||||
#endif
|
||||
|
24
include/service_versions.h
Normal file
24
include/service_versions.h
Normal file
@ -0,0 +1,24 @@
|
||||
/* Copyright (C) 2009 Sun Microsystems, Inc.
|
||||
|
||||
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#ifdef _WIN32
|
||||
#define SERVICE_VERSION __declspec(dllexport) void *
|
||||
#else
|
||||
#define SERVICE_VERSION void *
|
||||
#endif
|
||||
|
||||
#define VERSION_my_snprintf 0x0100
|
||||
#define VERSION_thd_alloc 0x0100
|
||||
|
20
libservices/CMakeLists.txt
Normal file
20
libservices/CMakeLists.txt
Normal file
@ -0,0 +1,20 @@
|
||||
# Copyright (C) 2006 MySQL 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-1301 USA
|
||||
|
||||
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include)
|
||||
|
||||
SET(MYSQLSERVICES_SOURCES my_snprintf_service.c thd_alloc_service.c)
|
||||
|
||||
ADD_LIBRARY(mysqlservices ${MYSQLSERVICES_SOURCES})
|
100
libservices/HOWTO
Normal file
100
libservices/HOWTO
Normal file
@ -0,0 +1,100 @@
|
||||
How to create a new service
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
A "service" is a set of C functions in a structure that a
|
||||
service dynamic linker uses when a dynamic plugin is loaded.
|
||||
|
||||
If you want to export C++ class you need to provide an
|
||||
extern "C" function that will create a new instance of your class,
|
||||
and put it in a service.
|
||||
|
||||
Data structures are not part of the service structure, but they are part
|
||||
of the API you create and usually need to be declared in the same
|
||||
service_*.h file.
|
||||
|
||||
To turn a set of functions (foo_func1, foo_func2)
|
||||
into a service "foo" you need to
|
||||
|
||||
1. create a new file include/mysql/service_foo.h
|
||||
|
||||
2. the template is
|
||||
==================================================================
|
||||
#ifndef MYSQL_SERVICE_FOO_INCLUDED
|
||||
/* standard GPL header */
|
||||
|
||||
/**
|
||||
@file
|
||||
*exhaustive* description of the interface you provide.
|
||||
This file is the main user documentation of the new service
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern struct foo_service_st {
|
||||
int (*foo_func1_type)(...); /* fix the prototype as appropriate */
|
||||
void (*foo_func2_type)(...); /* fix the prototype as appropriate */
|
||||
} *foo_service;
|
||||
|
||||
#ifdef MYSQL_DYNAMIC_PLUGIN
|
||||
|
||||
#define foo_func1(...) foo_service->foo_func1_type(...)
|
||||
#define foo_func2(...) foo_service->foo_func2_type(...)
|
||||
|
||||
#else
|
||||
|
||||
int foo_func1_type(...); /* fix the prototype as appropriate */
|
||||
void foo_func2_type(...); /* fix the prototype as appropriate */
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#define MYSQL_SERVICE_FOO_INCLUDED
|
||||
#endif
|
||||
==================================================================
|
||||
|
||||
the service_foo.h file should be self-contained, if it needs system headers -
|
||||
include them in it, e.g. if you use size_t - #include <stdlib.h>
|
||||
|
||||
it should also declare all the accompanying data structures, as necessary
|
||||
(e.g. thd_alloc_service declares MYSQL_LEX_STRING).
|
||||
|
||||
3. add the new file to include/Makefile.am (pkginclude_HEADERS)
|
||||
4. add the new file to include/mysql/services.h
|
||||
5. increase the minor plugin ABI version in include/mysql/plugin.h
|
||||
(MYSQL_PLUGIN_INTERFACE_VERSION = MYSQL_PLUGIN_INTERFACE_VERSION+1)
|
||||
6. add the version of your service to include/service_versions.h:
|
||||
==================================================================
|
||||
#define VERSION_foo 0x0100
|
||||
==================================================================
|
||||
|
||||
7. create a new file libservices/foo_service.h using the following template:
|
||||
==================================================================
|
||||
/* GPL header */
|
||||
#include <service_versions.h>
|
||||
SERVICE_VERSION *foo_service= (void*)VERSION_foo;
|
||||
==================================================================
|
||||
|
||||
8. add the new file to libservices/CMakeLists.txt (MYSQLSERVICES_SOURCES)
|
||||
9. add the new file to libservices/Makefile.am (libmysqlservices_a_SOURCES)
|
||||
10. and finally, register your service for dynamic linking in
|
||||
sql/sql_plugin_services.h
|
||||
10.1 fill in the service structure:
|
||||
==================================================================
|
||||
static struct foo_service_st foo_handler = {
|
||||
foo_func1,
|
||||
foo_func2
|
||||
}
|
||||
==================================================================
|
||||
|
||||
10.2 and add it to the list of services
|
||||
|
||||
==================================================================
|
||||
{ "foo_service", VERSION_foo, &foo_handler }
|
||||
==================================================================
|
||||
|
||||
that's all.
|
||||
|
19
libservices/Makefile.am
Normal file
19
libservices/Makefile.am
Normal file
@ -0,0 +1,19 @@
|
||||
# Copyright 2009 Sun Microsystems, Inc.
|
||||
#
|
||||
# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
AM_CPPFLAGS = -I$(top_srcdir)/include
|
||||
pkglib_LIBRARIES = libmysqlservices.a
|
||||
libmysqlservices_a_SOURCES = my_snprintf_service.c thd_alloc_service.c
|
||||
EXTRA_DIST = CMakeLists.txt
|
17
libservices/my_snprintf_service.c
Normal file
17
libservices/my_snprintf_service.c
Normal file
@ -0,0 +1,17 @@
|
||||
/* Copyright (C) 2009 Sun Microsystems, Inc.
|
||||
|
||||
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#include <service_versions.h>
|
||||
SERVICE_VERSION my_snprintf_service= (void*)VERSION_my_snprintf;
|
17
libservices/thd_alloc_service.c
Normal file
17
libservices/thd_alloc_service.c
Normal file
@ -0,0 +1,17 @@
|
||||
/* Copyright (C) 2009 Sun Microsystems, Inc.
|
||||
|
||||
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#include <service_versions.h>
|
||||
SERVICE_VERSION *thd_alloc_service= (void*)VERSION_thd_alloc;
|
@ -12,6 +12,15 @@ CREATE TABLE t1(a int) ENGINE=EXAMPLE;
|
||||
SELECT * FROM t1;
|
||||
a
|
||||
DROP TABLE t1;
|
||||
set global example_ulong_var=500;
|
||||
set global example_enum_var= e1;
|
||||
show status like 'example%';
|
||||
Variable_name Value
|
||||
example_func_example enum_var is 0, ulong_var is 500, really
|
||||
show variables like 'example%';
|
||||
Variable_name Value
|
||||
example_enum_var e1
|
||||
example_ulong_var 500
|
||||
UNINSTALL PLUGIN example;
|
||||
UNINSTALL PLUGIN EXAMPLE;
|
||||
ERROR 42000: PLUGIN EXAMPLE does not exist
|
||||
|
@ -22,6 +22,12 @@ SELECT * FROM t1;
|
||||
|
||||
DROP TABLE t1;
|
||||
|
||||
# a couple of tests for variables
|
||||
set global example_ulong_var=500;
|
||||
set global example_enum_var= e1;
|
||||
show status like 'example%';
|
||||
show variables like 'example%';
|
||||
|
||||
UNINSTALL PLUGIN example;
|
||||
--error 1305
|
||||
UNINSTALL PLUGIN EXAMPLE;
|
||||
|
@ -125,6 +125,29 @@ void my_printf_error(uint error, const char *format, myf MyFlags, ...)
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
/*
|
||||
Error with va_list
|
||||
|
||||
SYNOPSIS
|
||||
my_printv_error()
|
||||
error Errno
|
||||
format Format string
|
||||
MyFlags Flags
|
||||
... variable list
|
||||
*/
|
||||
|
||||
void my_printv_error(uint error, const char *format, myf MyFlags, va_list ap)
|
||||
{
|
||||
char ebuff[ERRMSGSIZE];
|
||||
DBUG_ENTER("my_printv_error");
|
||||
DBUG_PRINT("my", ("nr: %d MyFlags: %d errno: %d format: %s",
|
||||
error, MyFlags, errno, format));
|
||||
|
||||
(void) my_vsnprintf(ebuff, sizeof(ebuff), format, ap);
|
||||
(*error_handler_hook)(error, ebuff, MyFlags);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
/*
|
||||
Give message using error_handler_hook
|
||||
|
||||
|
@ -26,7 +26,8 @@ INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/include \
|
||||
|
||||
EXTRA_LTLIBRARIES = libdaemon_example.la
|
||||
pkgplugin_LTLIBRARIES = @plugin_daemon_example_shared_target@
|
||||
libdaemon_example_la_LDFLAGS = -module -rpath $(pkgplugindir)
|
||||
libdaemon_example_la_LDFLAGS = -module -rpath $(pkgplugindir) -L$(top_builddir)/libservices -lmysqlservices
|
||||
|
||||
libdaemon_example_la_CXXFLAGS= $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN
|
||||
libdaemon_example_la_CFLAGS = $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN
|
||||
libdaemon_example_la_SOURCES = daemon_example.cc
|
||||
|
@ -45,7 +45,7 @@ SET (SQL_SOURCE
|
||||
discover.cc ../libmysql/errmsg.c field.cc field_conv.cc
|
||||
filesort.cc gstream.cc
|
||||
ha_partition.cc
|
||||
handler.cc hash_filo.cc hash_filo.h
|
||||
handler.cc hash_filo.cc hash_filo.h sql_plugin_services.h
|
||||
hostname.cc init.cc item.cc item_buff.cc item_cmpfunc.cc
|
||||
item_create.cc item_func.cc item_geofunc.cc item_row.cc
|
||||
item_strfunc.cc item_subselect.cc item_sum.cc item_timefunc.cc
|
||||
|
@ -82,7 +82,7 @@ mysqld_LDADD = libndb.la \
|
||||
|
||||
noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \
|
||||
item_strfunc.h item_timefunc.h \
|
||||
item_xmlfunc.h \
|
||||
item_xmlfunc.h sql_plugin_services.h \
|
||||
item_create.h item_subselect.h item_row.h \
|
||||
mysql_priv.h item_geofunc.h sql_bitmap.h \
|
||||
procedure.h sql_class.h sql_lex.h sql_list.h \
|
||||
|
@ -28,6 +28,16 @@
|
||||
|
||||
#ifndef MYSQL_CLIENT
|
||||
|
||||
/*
|
||||
the following #define adds server-only members to enum_mysql_show_type,
|
||||
that is defined in mysql/plugin.h
|
||||
it has to be before mysql/plugin.h is included.
|
||||
*/
|
||||
#define SHOW_always_last SHOW_KEY_CACHE_LONG, \
|
||||
SHOW_KEY_CACHE_LONGLONG, SHOW_LONG_STATUS, SHOW_DOUBLE_STATUS, \
|
||||
SHOW_HAVE, SHOW_MY_BOOL, SHOW_HA_ROWS, SHOW_SYS, \
|
||||
SHOW_LONG_NOFLUSH, SHOW_LONGLONG_STATUS
|
||||
|
||||
#include <my_global.h>
|
||||
#include <mysql_version.h>
|
||||
#include <mysql_embed.h>
|
||||
|
@ -16,6 +16,8 @@
|
||||
#ifndef REPLICATION_H
|
||||
#define REPLICATION_H
|
||||
|
||||
typedef struct st_mysql MYSQL;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@ -483,6 +485,64 @@ const char* thd_enter_cond(MYSQL_THD thd, pthread_cond_t *cond,
|
||||
*/
|
||||
void thd_exit_cond(MYSQL_THD thd, const char *old_msg);
|
||||
|
||||
/**
|
||||
Get the value of user variable as an integer.
|
||||
|
||||
This function will return the value of variable @a name as an
|
||||
integer. If the original value of the variable is not an integer,
|
||||
the value will be converted into an integer.
|
||||
|
||||
@param name user variable name
|
||||
@param value pointer to return the value
|
||||
@param null_value if not NULL, the function will set it to true if
|
||||
the value of variable is null, set to false if not
|
||||
|
||||
@retval 0 Success
|
||||
@retval 1 Variable not found
|
||||
*/
|
||||
int get_user_var_int(const char *name,
|
||||
long long int *value, int *null_value);
|
||||
|
||||
/**
|
||||
Get the value of user variable as a double precision float number.
|
||||
|
||||
This function will return the value of variable @a name as real
|
||||
number. If the original value of the variable is not a real number,
|
||||
the value will be converted into a real number.
|
||||
|
||||
@param name user variable name
|
||||
@param value pointer to return the value
|
||||
@param null_value if not NULL, the function will set it to true if
|
||||
the value of variable is null, set to false if not
|
||||
|
||||
@retval 0 Success
|
||||
@retval 1 Variable not found
|
||||
*/
|
||||
int get_user_var_real(const char *name,
|
||||
double *value, int *null_value);
|
||||
|
||||
/**
|
||||
Get the value of user variable as a string.
|
||||
|
||||
This function will return the value of variable @a name as
|
||||
string. If the original value of the variable is not a string,
|
||||
the value will be converted into a string.
|
||||
|
||||
@param name user variable name
|
||||
@param value pointer to the value buffer
|
||||
@param len length of the value buffer
|
||||
@param precision precision of the value if it is a float number
|
||||
@param null_value if not NULL, the function will set it to true if
|
||||
the value of variable is null, set to false if not
|
||||
|
||||
@retval 0 Success
|
||||
@retval 1 Variable not found
|
||||
*/
|
||||
int get_user_var_str(const char *name,
|
||||
char *value, unsigned long len,
|
||||
unsigned int precision, int *null_value);
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -272,12 +272,7 @@ const char* thd_enter_cond(MYSQL_THD thd, pthread_cond_t *cond,
|
||||
if (!thd)
|
||||
thd= current_thd;
|
||||
|
||||
const char* old_msg = thd->proc_info;
|
||||
safe_mutex_assert_owner(mutex);
|
||||
thd->mysys_var->current_mutex = mutex;
|
||||
thd->mysys_var->current_cond = cond;
|
||||
thd->proc_info = msg;
|
||||
return old_msg;
|
||||
return thd->enter_cond(cond, mutex, msg);
|
||||
}
|
||||
|
||||
extern "C"
|
||||
@ -286,18 +281,7 @@ void thd_exit_cond(MYSQL_THD thd, const char *old_msg)
|
||||
if (!thd)
|
||||
thd= current_thd;
|
||||
|
||||
/*
|
||||
Putting the mutex unlock in thd_exit_cond() ensures that
|
||||
mysys_var->current_mutex is always unlocked _before_ mysys_var->mutex is
|
||||
locked (if that would not be the case, you'll get a deadlock if someone
|
||||
does a THD::awake() on you).
|
||||
*/
|
||||
pthread_mutex_unlock(thd->mysys_var->current_mutex);
|
||||
pthread_mutex_lock(&thd->mysys_var->mutex);
|
||||
thd->mysys_var->current_mutex = 0;
|
||||
thd->mysys_var->current_cond = 0;
|
||||
thd->proc_info = old_msg;
|
||||
pthread_mutex_unlock(&thd->mysys_var->mutex);
|
||||
thd->exit_cond(old_msg);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,6 @@
|
||||
|
||||
#include "log.h"
|
||||
#include "rpl_tblmap.h"
|
||||
#include "replication.h"
|
||||
|
||||
/**
|
||||
An interface that is used to take an action when
|
||||
@ -1886,11 +1885,28 @@ public:
|
||||
inline const char* enter_cond(pthread_cond_t *cond, pthread_mutex_t* mutex,
|
||||
const char* msg)
|
||||
{
|
||||
return thd_enter_cond(this, cond, mutex, msg);
|
||||
const char* old_msg = proc_info;
|
||||
safe_mutex_assert_owner(mutex);
|
||||
mysys_var->current_mutex = mutex;
|
||||
mysys_var->current_cond = cond;
|
||||
proc_info = msg;
|
||||
return old_msg;
|
||||
}
|
||||
inline void exit_cond(const char* old_msg)
|
||||
{
|
||||
thd_exit_cond(this, old_msg);
|
||||
/*
|
||||
Putting the mutex unlock in thd->exit_cond() ensures that
|
||||
mysys_var->current_mutex is always unlocked _before_ mysys_var->mutex is
|
||||
locked (if that would not be the case, you'll get a deadlock if someone
|
||||
does a THD::awake() on you).
|
||||
*/
|
||||
pthread_mutex_unlock(mysys_var->current_mutex);
|
||||
pthread_mutex_lock(&mysys_var->mutex);
|
||||
mysys_var->current_mutex = 0;
|
||||
mysys_var->current_cond = 0;
|
||||
proc_info = old_msg;
|
||||
pthread_mutex_unlock(&mysys_var->mutex);
|
||||
return;
|
||||
}
|
||||
inline time_t query_start() { query_start_used=1; return start_time; }
|
||||
inline void set_time()
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2005 MySQL AB
|
||||
/* Copyright (C) 2005 MySQL AB, 2009 Sun Microsystems, Inc.
|
||||
|
||||
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
|
||||
@ -99,7 +99,9 @@ static int cur_plugin_info_interface_version[MYSQL_MAX_PLUGIN_TYPE_NUM]=
|
||||
MYSQL_REPLICATION_INTERFACE_VERSION,
|
||||
};
|
||||
|
||||
static bool initialized= 0;
|
||||
/* support for Services */
|
||||
|
||||
#include "sql_plugin_services.h"
|
||||
|
||||
/*
|
||||
A mutex LOCK_plugin must be acquired before accessing the
|
||||
@ -113,6 +115,8 @@ static HASH plugin_hash[MYSQL_MAX_PLUGIN_TYPE_NUM];
|
||||
static bool reap_needed= false;
|
||||
static int plugin_array_version=0;
|
||||
|
||||
static bool initialized= 0;
|
||||
|
||||
/*
|
||||
write-lock on LOCK_system_variables_hash is required before modifying
|
||||
the following variables/structures
|
||||
@ -225,6 +229,22 @@ extern bool throw_bounds_warning(THD *thd, bool fixed, bool unsignd,
|
||||
extern bool check_if_table_exists(THD *thd, TABLE_LIST *table, bool *exists);
|
||||
#endif /* EMBEDDED_LIBRARY */
|
||||
|
||||
static void report_error(int where_to, uint error, ...)
|
||||
{
|
||||
va_list args;
|
||||
if (where_to & REPORT_TO_USER)
|
||||
{
|
||||
va_start(args, error);
|
||||
my_printv_error(error, ER(error), MYF(0), args);
|
||||
va_end(args);
|
||||
}
|
||||
if (where_to & REPORT_TO_LOG)
|
||||
{
|
||||
va_start(args, error);
|
||||
error_log_print(ERROR_LEVEL, ER(error), args);
|
||||
va_end(args);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Value type thunks, allows the C world to play in the C++ world
|
||||
@ -345,7 +365,7 @@ static st_plugin_dl *plugin_dl_add(const LEX_STRING *dl, int report)
|
||||
{
|
||||
#ifdef HAVE_DLOPEN
|
||||
char dlpath[FN_REFLEN];
|
||||
uint plugin_dir_len, dummy_errors, dlpathlen;
|
||||
uint plugin_dir_len, dummy_errors, dlpathlen, i;
|
||||
struct st_plugin_dl *tmp, plugin_dl;
|
||||
void *sym;
|
||||
DBUG_ENTER("plugin_dl_add");
|
||||
@ -360,10 +380,7 @@ static st_plugin_dl *plugin_dl_add(const LEX_STRING *dl, int report)
|
||||
system_charset_info, 1) ||
|
||||
plugin_dir_len + dl->length + 1 >= FN_REFLEN)
|
||||
{
|
||||
if (report & REPORT_TO_USER)
|
||||
my_error(ER_UDF_NO_PATHS, MYF(0));
|
||||
if (report & REPORT_TO_LOG)
|
||||
sql_print_error("%s", ER_DEFAULT(ER_UDF_NO_PATHS));
|
||||
report_error(report, ER_UDF_NO_PATHS);
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
/* If this dll is already loaded just increase ref_count. */
|
||||
@ -388,21 +405,14 @@ static st_plugin_dl *plugin_dl_add(const LEX_STRING *dl, int report)
|
||||
if (*errmsg == ':') errmsg++;
|
||||
if (*errmsg == ' ') errmsg++;
|
||||
}
|
||||
if (report & REPORT_TO_USER)
|
||||
my_error(ER_CANT_OPEN_LIBRARY, MYF(0), dlpath, errno, errmsg);
|
||||
if (report & REPORT_TO_LOG)
|
||||
sql_print_error(ER_DEFAULT(ER_CANT_OPEN_LIBRARY), dlpath, errno, errmsg);
|
||||
report_error(report, ER_CANT_OPEN_LIBRARY, dlpath, errno, errmsg);
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
/* Determine interface version */
|
||||
if (!(sym= dlsym(plugin_dl.handle, plugin_interface_version_sym)))
|
||||
{
|
||||
free_plugin_mem(&plugin_dl);
|
||||
if (report & REPORT_TO_USER)
|
||||
my_error(ER_CANT_FIND_DL_ENTRY, MYF(0), plugin_interface_version_sym);
|
||||
if (report & REPORT_TO_LOG)
|
||||
sql_print_error(ER_DEFAULT(ER_CANT_FIND_DL_ENTRY),
|
||||
plugin_interface_version_sym);
|
||||
report_error(report, ER_CANT_FIND_DL_ENTRY, plugin_interface_version_sym);
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
plugin_dl.version= *(int *)sym;
|
||||
@ -411,29 +421,42 @@ static st_plugin_dl *plugin_dl_add(const LEX_STRING *dl, int report)
|
||||
(plugin_dl.version >> 8) > (MYSQL_PLUGIN_INTERFACE_VERSION >> 8))
|
||||
{
|
||||
free_plugin_mem(&plugin_dl);
|
||||
if (report & REPORT_TO_USER)
|
||||
my_error(ER_CANT_OPEN_LIBRARY, MYF(0), dlpath, 0,
|
||||
"plugin interface version mismatch");
|
||||
if (report & REPORT_TO_LOG)
|
||||
sql_print_error(ER_DEFAULT(ER_CANT_OPEN_LIBRARY), dlpath, 0,
|
||||
"plugin interface version mismatch");
|
||||
report_error(report, ER_CANT_OPEN_LIBRARY, MYF(0), dlpath, 0,
|
||||
"plugin interface version mismatch");
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
/* link the services in */
|
||||
for (i= 0; i < array_elements(list_of_services); i++)
|
||||
{
|
||||
if ((sym= dlsym(plugin_dl.handle, list_of_services[i].name)))
|
||||
{
|
||||
uint ver= (uint)(intptr)*(void**)sym;
|
||||
if (ver > list_of_services[i].version ||
|
||||
(ver >> 8) < (list_of_services[i].version >> 8))
|
||||
{
|
||||
char buf[MYSQL_ERRMSG_SIZE];
|
||||
my_snprintf(buf, sizeof(buf),
|
||||
"service '%s' interface version mismatch",
|
||||
list_of_services[i].name);
|
||||
report_error(report, ER_CANT_OPEN_LIBRARY, dlpath, 0, buf);
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
*(void**)sym= list_of_services[i].service;
|
||||
}
|
||||
}
|
||||
|
||||
/* Find plugin declarations */
|
||||
if (!(sym= dlsym(plugin_dl.handle, plugin_declarations_sym)))
|
||||
{
|
||||
free_plugin_mem(&plugin_dl);
|
||||
if (report & REPORT_TO_USER)
|
||||
my_error(ER_CANT_FIND_DL_ENTRY, MYF(0), plugin_declarations_sym);
|
||||
if (report & REPORT_TO_LOG)
|
||||
sql_print_error(ER_DEFAULT(ER_CANT_FIND_DL_ENTRY),
|
||||
plugin_declarations_sym);
|
||||
report_error(report, ER_CANT_FIND_DL_ENTRY, MYF(0),
|
||||
plugin_declarations_sym);
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
if (plugin_dl.version != MYSQL_PLUGIN_INTERFACE_VERSION)
|
||||
{
|
||||
int i;
|
||||
uint sizeof_st_plugin;
|
||||
struct st_mysql_plugin *old, *cur;
|
||||
char *ptr= (char *)sym;
|
||||
@ -443,11 +466,7 @@ static st_plugin_dl *plugin_dl_add(const LEX_STRING *dl, int report)
|
||||
else
|
||||
{
|
||||
#ifdef ERROR_ON_NO_SIZEOF_PLUGIN_SYMBOL
|
||||
free_plugin_mem(&plugin_dl);
|
||||
if (report & REPORT_TO_USER)
|
||||
my_error(ER_CANT_FIND_DL_ENTRY, MYF(0), sizeof_st_plugin_sym);
|
||||
if (report & REPORT_TO_LOG)
|
||||
sql_print_error(ER_DEFAULT(ER_CANT_FIND_DL_ENTRY), sizeof_st_plugin_sym);
|
||||
report_error(report, ER_CANT_FIND_DL_ENTRY, sizeof_st_plugin_sym);
|
||||
DBUG_RETURN(0);
|
||||
#else
|
||||
/*
|
||||
@ -469,10 +488,7 @@ static st_plugin_dl *plugin_dl_add(const LEX_STRING *dl, int report)
|
||||
if (!cur)
|
||||
{
|
||||
free_plugin_mem(&plugin_dl);
|
||||
if (report & REPORT_TO_USER)
|
||||
my_error(ER_OUTOFMEMORY, MYF(0), plugin_dl.dl.length);
|
||||
if (report & REPORT_TO_LOG)
|
||||
sql_print_error(ER_DEFAULT(ER_OUTOFMEMORY), plugin_dl.dl.length);
|
||||
report_error(report, ER_OUTOFMEMORY, plugin_dl.dl.length);
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
/*
|
||||
@ -494,10 +510,7 @@ static st_plugin_dl *plugin_dl_add(const LEX_STRING *dl, int report)
|
||||
if (! (plugin_dl.dl.str= (char*) my_malloc(plugin_dl.dl.length, MYF(0))))
|
||||
{
|
||||
free_plugin_mem(&plugin_dl);
|
||||
if (report & REPORT_TO_USER)
|
||||
my_error(ER_OUTOFMEMORY, MYF(0), plugin_dl.dl.length);
|
||||
if (report & REPORT_TO_LOG)
|
||||
sql_print_error(ER_DEFAULT(ER_OUTOFMEMORY), plugin_dl.dl.length);
|
||||
report_error(report, ER_OUTOFMEMORY, plugin_dl.dl.length);
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
plugin_dl.dl.length= copy_and_convert(plugin_dl.dl.str, plugin_dl.dl.length,
|
||||
@ -508,19 +521,13 @@ static st_plugin_dl *plugin_dl_add(const LEX_STRING *dl, int report)
|
||||
if (! (tmp= plugin_dl_insert_or_reuse(&plugin_dl)))
|
||||
{
|
||||
free_plugin_mem(&plugin_dl);
|
||||
if (report & REPORT_TO_USER)
|
||||
my_error(ER_OUTOFMEMORY, MYF(0), sizeof(struct st_plugin_dl));
|
||||
if (report & REPORT_TO_LOG)
|
||||
sql_print_error(ER_DEFAULT(ER_OUTOFMEMORY), sizeof(struct st_plugin_dl));
|
||||
report_error(report, ER_OUTOFMEMORY, sizeof(struct st_plugin_dl));
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
DBUG_RETURN(tmp);
|
||||
#else
|
||||
DBUG_ENTER("plugin_dl_add");
|
||||
if (report & REPORT_TO_USER)
|
||||
my_error(ER_FEATURE_DISABLED, MYF(0), "plugin", "HAVE_DLOPEN");
|
||||
if (report & REPORT_TO_LOG)
|
||||
sql_print_error(ER_DEFAULT(ER_FEATURE_DISABLED), "plugin", "HAVE_DLOPEN");
|
||||
report_error(report, ER_FEATURE_DISABLED, "plugin", "HAVE_DLOPEN");
|
||||
DBUG_RETURN(0);
|
||||
#endif
|
||||
}
|
||||
@ -636,7 +643,7 @@ static plugin_ref intern_plugin_lock(LEX *lex, plugin_ref rc CALLER_INFO_PROTO)
|
||||
/*
|
||||
For debugging, we do an additional malloc which allows the
|
||||
memory manager and/or valgrind to track locked references and
|
||||
double unlocks to aid resolving reference counting.problems.
|
||||
double unlocks to aid resolving reference counting problems.
|
||||
*/
|
||||
if (!(plugin= (plugin_ref) my_malloc_ci(sizeof(pi), MYF(MY_WME))))
|
||||
DBUG_RETURN(NULL);
|
||||
@ -719,10 +726,7 @@ static bool plugin_add(MEM_ROOT *tmp_root,
|
||||
DBUG_ENTER("plugin_add");
|
||||
if (plugin_find_internal(name, MYSQL_ANY_PLUGIN))
|
||||
{
|
||||
if (report & REPORT_TO_USER)
|
||||
my_error(ER_UDF_EXISTS, MYF(0), name->str);
|
||||
if (report & REPORT_TO_LOG)
|
||||
sql_print_error(ER_DEFAULT(ER_UDF_EXISTS), name->str);
|
||||
report_error(report, ER_UDF_EXISTS, name->str);
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
/* Clear the whole struct to catch future extensions. */
|
||||
@ -749,10 +753,7 @@ static bool plugin_add(MEM_ROOT *tmp_root,
|
||||
strxnmov(buf, sizeof(buf) - 1, "API version for ",
|
||||
plugin_type_names[plugin->type].str,
|
||||
" plugin is too different", NullS);
|
||||
if (report & REPORT_TO_USER)
|
||||
my_error(ER_CANT_OPEN_LIBRARY, MYF(0), dl->str, 0, buf);
|
||||
if (report & REPORT_TO_LOG)
|
||||
sql_print_error(ER_DEFAULT(ER_CANT_OPEN_LIBRARY), dl->str, 0, buf);
|
||||
report_error(report, ER_CANT_OPEN_LIBRARY, dl->str, 0, buf);
|
||||
goto err;
|
||||
}
|
||||
tmp.plugin= plugin;
|
||||
@ -781,10 +782,7 @@ static bool plugin_add(MEM_ROOT *tmp_root,
|
||||
DBUG_RETURN(FALSE);
|
||||
}
|
||||
}
|
||||
if (report & REPORT_TO_USER)
|
||||
my_error(ER_CANT_FIND_DL_ENTRY, MYF(0), name->str);
|
||||
if (report & REPORT_TO_LOG)
|
||||
sql_print_error(ER_DEFAULT(ER_CANT_FIND_DL_ENTRY), name->str);
|
||||
report_error(report, ER_CANT_FIND_DL_ENTRY, name->str);
|
||||
err:
|
||||
plugin_dl_del(dl);
|
||||
DBUG_RETURN(TRUE);
|
||||
|
@ -35,16 +35,6 @@ class sys_var;
|
||||
|
||||
#define INITIAL_LEX_PLUGIN_LIST_SIZE 16
|
||||
|
||||
/*
|
||||
the following #define adds server-only members to enum_mysql_show_type,
|
||||
that is defined in plugin.h
|
||||
*/
|
||||
#define SHOW_FUNC SHOW_FUNC, SHOW_KEY_CACHE_LONG, SHOW_KEY_CACHE_LONGLONG, \
|
||||
SHOW_LONG_STATUS, SHOW_DOUBLE_STATUS, SHOW_HAVE, \
|
||||
SHOW_MY_BOOL, SHOW_HA_ROWS, SHOW_SYS, SHOW_LONG_NOFLUSH, \
|
||||
SHOW_LONGLONG_STATUS
|
||||
#include <mysql/plugin.h>
|
||||
#undef SHOW_FUNC
|
||||
typedef enum enum_mysql_show_type SHOW_TYPE;
|
||||
typedef struct st_mysql_show_var SHOW_VAR;
|
||||
|
||||
|
44
sql/sql_plugin_services.h
Normal file
44
sql/sql_plugin_services.h
Normal file
@ -0,0 +1,44 @@
|
||||
/* Copyright (C) 2009 Sun Microsystems, Inc.
|
||||
|
||||
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
/* support for Services */
|
||||
#include <service_versions.h>
|
||||
|
||||
struct st_service_ref {
|
||||
const char *name;
|
||||
uint version;
|
||||
void *service;
|
||||
};
|
||||
|
||||
static struct my_snprintf_service_st my_snprintf_handler = {
|
||||
my_snprintf,
|
||||
my_vsnprintf
|
||||
};
|
||||
|
||||
static struct thd_alloc_service_st thd_alloc_handler= {
|
||||
thd_alloc,
|
||||
thd_calloc,
|
||||
thd_strdup,
|
||||
thd_strmake,
|
||||
thd_memdup,
|
||||
thd_make_lex_string
|
||||
};
|
||||
|
||||
static struct st_service_ref list_of_services[]=
|
||||
{
|
||||
{ "my_snprintf_service", VERSION_my_snprintf, &my_snprintf_handler },
|
||||
{ "thd_alloc_service", VERSION_thd_alloc, &thd_alloc_handler }
|
||||
};
|
||||
|
@ -34,7 +34,7 @@ noinst_HEADERS = ha_example.h
|
||||
|
||||
EXTRA_LTLIBRARIES = ha_example.la
|
||||
pkgplugin_LTLIBRARIES = @plugin_example_shared_target@
|
||||
ha_example_la_LDFLAGS = -module -rpath $(pkgplugindir)
|
||||
ha_example_la_LDFLAGS = -module -rpath $(pkgplugindir) -L$(top_builddir)/libservices -lmysqlservices
|
||||
ha_example_la_CXXFLAGS= $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN
|
||||
ha_example_la_CFLAGS = $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN
|
||||
ha_example_la_SOURCES = ha_example.cc
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2003 MySQL AB
|
||||
/* Copyright (C) 2003 MySQL AB, 2009 Sun Microsystems, Inc.
|
||||
|
||||
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
|
||||
@ -921,6 +921,24 @@ static struct st_mysql_sys_var* example_system_variables[]= {
|
||||
NULL
|
||||
};
|
||||
|
||||
// this is an example of SHOW_FUNC and of my_snprintf() service
|
||||
static int show_func_example(MYSQL_THD thd, struct st_mysql_show_var *var,
|
||||
char *buf)
|
||||
{
|
||||
var->type= SHOW_CHAR;
|
||||
var->value= buf; // it's of SHOW_VAR_FUNC_BUFF_SIZE bytes
|
||||
my_snprintf(buf, SHOW_VAR_FUNC_BUFF_SIZE,
|
||||
"enum_var is %u, ulong_var is %lu, %.6b", // %b is MySQL extension
|
||||
srv_enum_var, srv_ulong_var, "really");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct st_mysql_show_var func_status[]=
|
||||
{
|
||||
{"example_func_example", (char *)show_func_example, SHOW_FUNC},
|
||||
{0,0,SHOW_UNDEF}
|
||||
};
|
||||
|
||||
mysql_declare_plugin(example)
|
||||
{
|
||||
MYSQL_STORAGE_ENGINE_PLUGIN,
|
||||
@ -932,7 +950,7 @@ mysql_declare_plugin(example)
|
||||
example_init_func, /* Plugin Init */
|
||||
example_done_func, /* Plugin Deinit */
|
||||
0x0001 /* 0.1 */,
|
||||
NULL, /* status variables */
|
||||
func_status, /* status variables */
|
||||
example_system_variables, /* system variables */
|
||||
NULL /* config options */
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ IF(NOT SOURCE_SUBLIBS)
|
||||
#The dll is linked to the mysqld executable
|
||||
SET(dyn_libname ha_${libname})
|
||||
ADD_LIBRARY(${dyn_libname} SHARED ${${engine}_SOURCES})
|
||||
TARGET_LINK_LIBRARIES (${dyn_libname} mysqld)
|
||||
TARGET_LINK_LIBRARIES (${dyn_libname} mysqlservices mysqld)
|
||||
IF(${engine}_LIBS)
|
||||
TARGET_LINK_LIBRARIES(${dyn_libname} ${${engine}_LIBS})
|
||||
ENDIF(${engine}_LIBS)
|
||||
|
@ -472,6 +472,8 @@ start:
|
||||
/**
|
||||
Produces output string according to a format string
|
||||
|
||||
See the detailed documentation around my_snprintf_service_st
|
||||
|
||||
@param cs string charset
|
||||
@param to buffer where processed string will be place
|
||||
@param n size of buffer
|
||||
|
Reference in New Issue
Block a user