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(client)
|
||||||
ADD_SUBDIRECTORY(sql)
|
ADD_SUBDIRECTORY(sql)
|
||||||
ADD_SUBDIRECTORY(libmysql)
|
ADD_SUBDIRECTORY(libmysql)
|
||||||
|
ADD_SUBDIRECTORY(libservices)
|
||||||
ADD_SUBDIRECTORY(tests)
|
ADD_SUBDIRECTORY(tests)
|
||||||
IF(WITH_EMBEDDED_SERVER)
|
IF(WITH_EMBEDDED_SERVER)
|
||||||
ADD_SUBDIRECTORY(libmysqld)
|
ADD_SUBDIRECTORY(libmysqld)
|
||||||
|
@ -23,7 +23,7 @@ EXTRA_DIST = INSTALL-SOURCE INSTALL-WIN-SOURCE \
|
|||||||
|
|
||||||
SUBDIRS = . include @docs_dirs@ @zlib_dir@ \
|
SUBDIRS = . include @docs_dirs@ @zlib_dir@ \
|
||||||
@readline_topdir@ sql-common scripts \
|
@readline_topdir@ sql-common scripts \
|
||||||
@pstack_dir@ \
|
@pstack_dir@ libservices \
|
||||||
@sql_union_dirs@ unittest \
|
@sql_union_dirs@ unittest \
|
||||||
@sql_server@ @man_dirs@ tests \
|
@sql_server@ @man_dirs@ tests \
|
||||||
netware @libmysqld_dirs@ \
|
netware @libmysqld_dirs@ \
|
||||||
@ -32,7 +32,7 @@ SUBDIRS = . include @docs_dirs@ @zlib_dir@ \
|
|||||||
|
|
||||||
DIST_SUBDIRS = . include Docs zlib \
|
DIST_SUBDIRS = . include Docs zlib \
|
||||||
cmd-line-utils sql-common scripts \
|
cmd-line-utils sql-common scripts \
|
||||||
pstack \
|
pstack libservices \
|
||||||
strings mysys dbug extra regex libmysql libmysql_r client unittest storage plugin \
|
strings mysys dbug extra regex libmysql libmysql_r client unittest storage plugin \
|
||||||
vio sql man tests \
|
vio sql man tests \
|
||||||
netware libmysqld \
|
netware libmysqld \
|
||||||
|
@ -2946,7 +2946,7 @@ AC_CONFIG_FILES(Makefile extra/Makefile mysys/Makefile dnl
|
|||||||
man/Makefile BUILD/Makefile vio/Makefile dnl
|
man/Makefile BUILD/Makefile vio/Makefile dnl
|
||||||
libmysql/Makefile libmysql_r/Makefile client/Makefile dnl
|
libmysql/Makefile libmysql_r/Makefile client/Makefile dnl
|
||||||
sql/Makefile sql/share/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
|
dbug/Makefile scripts/Makefile include/Makefile dnl
|
||||||
tests/Makefile Docs/Makefile support-files/Makefile dnl
|
tests/Makefile Docs/Makefile support-files/Makefile dnl
|
||||||
support-files/MacOSX/Makefile support-files/RHEL4-SElinux/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 \
|
HEADERS_ABI = mysql.h mysql_com.h mysql_time.h \
|
||||||
my_list.h my_alloc.h typelib.h mysql/plugin.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 \
|
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 \
|
my_pthread.h my_no_pthread.h \
|
||||||
decimal.h errmsg.h my_global.h my_net.h \
|
decimal.h errmsg.h my_global.h my_net.h \
|
||||||
my_getopt.h sslopt-longopts.h my_dir.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_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 \
|
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 \
|
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 \
|
my_vle.h my_user.h my_atomic.h atomic/nolock.h \
|
||||||
atomic/rwlock.h atomic/x86-gcc.h atomic/x86-msvc.h \
|
atomic/rwlock.h atomic/x86-gcc.h atomic/x86-msvc.h \
|
||||||
atomic/solaris.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.
|
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
|
#include <mysql/plugin.h>
|
||||||
/* This definition must match the one given in mysql/plugin.h */
|
|
||||||
struct st_mysql_lex_string
|
|
||||||
{
|
|
||||||
char *str;
|
|
||||||
size_t length;
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
typedef struct st_mysql_lex_string LEX_STRING;
|
typedef struct st_mysql_lex_string LEX_STRING;
|
||||||
|
|
||||||
#define STRING_WITH_LEN(X) (X), ((size_t) (sizeof(X) - 1))
|
#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,
|
extern void my_printf_error _VARARGS((uint my_err, const char *format,
|
||||||
myf MyFlags, ...))
|
myf MyFlags, ...))
|
||||||
ATTRIBUTE_FORMAT(printf, 2, 4);
|
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) (),
|
extern int my_error_register(const char** (*get_errmsgs) (),
|
||||||
int first, int last);
|
int first, int last);
|
||||||
extern const char **my_error_unregister(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
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -16,12 +16,6 @@
|
|||||||
#ifndef _my_plugin_h
|
#ifndef _my_plugin_h
|
||||||
#define _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
|
On Windows, exports from DLL need to be declared
|
||||||
*/
|
*/
|
||||||
@ -39,15 +33,7 @@ class Item;
|
|||||||
#define MYSQL_THD void*
|
#define MYSQL_THD void*
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef _m_string_h
|
#include <mysql/services.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;
|
|
||||||
|
|
||||||
#define MYSQL_XIDDATASIZE 128
|
#define MYSQL_XIDDATASIZE 128
|
||||||
/**
|
/**
|
||||||
@ -70,7 +56,7 @@ typedef struct st_mysql_xid MYSQL_XID;
|
|||||||
Plugin API. Common for all plugin types.
|
Plugin API. Common for all plugin types.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define MYSQL_PLUGIN_INTERFACE_VERSION 0x0100
|
#define MYSQL_PLUGIN_INTERFACE_VERSION 0x0101
|
||||||
|
|
||||||
/*
|
/*
|
||||||
The allowable types of plugins
|
The allowable types of plugins
|
||||||
@ -126,7 +112,8 @@ enum enum_mysql_show_type
|
|||||||
{
|
{
|
||||||
SHOW_UNDEF, SHOW_BOOL, SHOW_INT, SHOW_LONG,
|
SHOW_UNDEF, SHOW_BOOL, SHOW_INT, SHOW_LONG,
|
||||||
SHOW_LONGLONG, SHOW_CHAR, SHOW_CHAR_PTR,
|
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 {
|
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);
|
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
|
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,
|
const char *key, unsigned int key_length,
|
||||||
int using_trx);
|
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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#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>
|
#include <stdlib.h>
|
||||||
typedef struct st_mysql MYSQL;
|
|
||||||
struct st_mysql_lex_string
|
struct st_mysql_lex_string
|
||||||
{
|
{
|
||||||
char *str;
|
char *str;
|
||||||
unsigned int length;
|
size_t length;
|
||||||
};
|
};
|
||||||
typedef struct st_mysql_lex_string MYSQL_LEX_STRING;
|
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 {
|
struct st_mysql_xid {
|
||||||
long formatID;
|
long formatID;
|
||||||
long gtrid_length;
|
long gtrid_length;
|
||||||
@ -17,7 +44,8 @@ enum enum_mysql_show_type
|
|||||||
{
|
{
|
||||||
SHOW_UNDEF, SHOW_BOOL, SHOW_INT, SHOW_LONG,
|
SHOW_UNDEF, SHOW_BOOL, SHOW_INT, SHOW_LONG,
|
||||||
SHOW_LONGLONG, SHOW_CHAR, SHOW_CHAR_PTR,
|
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 {
|
struct st_mysql_show_var {
|
||||||
const char *name;
|
const char *name;
|
||||||
@ -107,9 +135,9 @@ struct st_mysql_information_schema
|
|||||||
{
|
{
|
||||||
int interface_version;
|
int interface_version;
|
||||||
};
|
};
|
||||||
struct Mysql_replication {
|
struct Mysql_replication {
|
||||||
int interface_version;
|
int interface_version;
|
||||||
};
|
};
|
||||||
struct st_mysql_value
|
struct st_mysql_value
|
||||||
{
|
{
|
||||||
int (*value_type)(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 mysql_tmpfile(const char *prefix);
|
||||||
int thd_killed(const void* thd);
|
int thd_killed(const void* thd);
|
||||||
unsigned long thd_get_thread_id(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 thd_get_xid(const void* thd, MYSQL_XID *xid);
|
||||||
void mysql_query_cache_invalidate4(void* thd,
|
void mysql_query_cache_invalidate4(void* thd,
|
||||||
const char *key, unsigned int key_length,
|
const char *key, unsigned int key_length,
|
||||||
int using_trx);
|
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;
|
SELECT * FROM t1;
|
||||||
a
|
a
|
||||||
DROP TABLE t1;
|
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;
|
||||||
UNINSTALL PLUGIN EXAMPLE;
|
UNINSTALL PLUGIN EXAMPLE;
|
||||||
ERROR 42000: PLUGIN EXAMPLE does not exist
|
ERROR 42000: PLUGIN EXAMPLE does not exist
|
||||||
|
@ -22,6 +22,12 @@ SELECT * FROM t1;
|
|||||||
|
|
||||||
DROP TABLE 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;
|
UNINSTALL PLUGIN example;
|
||||||
--error 1305
|
--error 1305
|
||||||
UNINSTALL PLUGIN EXAMPLE;
|
UNINSTALL PLUGIN EXAMPLE;
|
||||||
|
@ -125,6 +125,29 @@ void my_printf_error(uint error, const char *format, myf MyFlags, ...)
|
|||||||
DBUG_VOID_RETURN;
|
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
|
Give message using error_handler_hook
|
||||||
|
|
||||||
|
@ -26,7 +26,8 @@ INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/include \
|
|||||||
|
|
||||||
EXTRA_LTLIBRARIES = libdaemon_example.la
|
EXTRA_LTLIBRARIES = libdaemon_example.la
|
||||||
pkgplugin_LTLIBRARIES = @plugin_daemon_example_shared_target@
|
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_CXXFLAGS= $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN
|
||||||
libdaemon_example_la_CFLAGS = $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN
|
libdaemon_example_la_CFLAGS = $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN
|
||||||
libdaemon_example_la_SOURCES = daemon_example.cc
|
libdaemon_example_la_SOURCES = daemon_example.cc
|
||||||
|
@ -45,7 +45,7 @@ SET (SQL_SOURCE
|
|||||||
discover.cc ../libmysql/errmsg.c field.cc field_conv.cc
|
discover.cc ../libmysql/errmsg.c field.cc field_conv.cc
|
||||||
filesort.cc gstream.cc
|
filesort.cc gstream.cc
|
||||||
ha_partition.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
|
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_create.cc item_func.cc item_geofunc.cc item_row.cc
|
||||||
item_strfunc.cc item_subselect.cc item_sum.cc item_timefunc.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 \
|
noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \
|
||||||
item_strfunc.h item_timefunc.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 \
|
item_create.h item_subselect.h item_row.h \
|
||||||
mysql_priv.h item_geofunc.h sql_bitmap.h \
|
mysql_priv.h item_geofunc.h sql_bitmap.h \
|
||||||
procedure.h sql_class.h sql_lex.h sql_list.h \
|
procedure.h sql_class.h sql_lex.h sql_list.h \
|
||||||
|
@ -28,6 +28,16 @@
|
|||||||
|
|
||||||
#ifndef MYSQL_CLIENT
|
#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 <my_global.h>
|
||||||
#include <mysql_version.h>
|
#include <mysql_version.h>
|
||||||
#include <mysql_embed.h>
|
#include <mysql_embed.h>
|
||||||
|
@ -16,6 +16,8 @@
|
|||||||
#ifndef REPLICATION_H
|
#ifndef REPLICATION_H
|
||||||
#define REPLICATION_H
|
#define REPLICATION_H
|
||||||
|
|
||||||
|
typedef struct st_mysql MYSQL;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#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);
|
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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -272,12 +272,7 @@ const char* thd_enter_cond(MYSQL_THD thd, pthread_cond_t *cond,
|
|||||||
if (!thd)
|
if (!thd)
|
||||||
thd= current_thd;
|
thd= current_thd;
|
||||||
|
|
||||||
const char* old_msg = thd->proc_info;
|
return thd->enter_cond(cond, mutex, msg);
|
||||||
safe_mutex_assert_owner(mutex);
|
|
||||||
thd->mysys_var->current_mutex = mutex;
|
|
||||||
thd->mysys_var->current_cond = cond;
|
|
||||||
thd->proc_info = msg;
|
|
||||||
return old_msg;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
@ -286,18 +281,7 @@ void thd_exit_cond(MYSQL_THD thd, const char *old_msg)
|
|||||||
if (!thd)
|
if (!thd)
|
||||||
thd= current_thd;
|
thd= current_thd;
|
||||||
|
|
||||||
/*
|
thd->exit_cond(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(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);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,7 +25,6 @@
|
|||||||
|
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "rpl_tblmap.h"
|
#include "rpl_tblmap.h"
|
||||||
#include "replication.h"
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
An interface that is used to take an action when
|
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,
|
inline const char* enter_cond(pthread_cond_t *cond, pthread_mutex_t* mutex,
|
||||||
const char* msg)
|
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)
|
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 time_t query_start() { query_start_used=1; return start_time; }
|
||||||
inline void set_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
|
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
|
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,
|
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
|
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 bool reap_needed= false;
|
||||||
static int plugin_array_version=0;
|
static int plugin_array_version=0;
|
||||||
|
|
||||||
|
static bool initialized= 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
write-lock on LOCK_system_variables_hash is required before modifying
|
write-lock on LOCK_system_variables_hash is required before modifying
|
||||||
the following variables/structures
|
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);
|
extern bool check_if_table_exists(THD *thd, TABLE_LIST *table, bool *exists);
|
||||||
#endif /* EMBEDDED_LIBRARY */
|
#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
|
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
|
#ifdef HAVE_DLOPEN
|
||||||
char dlpath[FN_REFLEN];
|
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;
|
struct st_plugin_dl *tmp, plugin_dl;
|
||||||
void *sym;
|
void *sym;
|
||||||
DBUG_ENTER("plugin_dl_add");
|
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) ||
|
system_charset_info, 1) ||
|
||||||
plugin_dir_len + dl->length + 1 >= FN_REFLEN)
|
plugin_dir_len + dl->length + 1 >= FN_REFLEN)
|
||||||
{
|
{
|
||||||
if (report & REPORT_TO_USER)
|
report_error(report, ER_UDF_NO_PATHS);
|
||||||
my_error(ER_UDF_NO_PATHS, MYF(0));
|
|
||||||
if (report & REPORT_TO_LOG)
|
|
||||||
sql_print_error("%s", ER_DEFAULT(ER_UDF_NO_PATHS));
|
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
/* If this dll is already loaded just increase ref_count. */
|
/* 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 (*errmsg == ' ') errmsg++;
|
if (*errmsg == ' ') errmsg++;
|
||||||
}
|
}
|
||||||
if (report & REPORT_TO_USER)
|
report_error(report, ER_CANT_OPEN_LIBRARY, dlpath, errno, errmsg);
|
||||||
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);
|
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
/* Determine interface version */
|
/* Determine interface version */
|
||||||
if (!(sym= dlsym(plugin_dl.handle, plugin_interface_version_sym)))
|
if (!(sym= dlsym(plugin_dl.handle, plugin_interface_version_sym)))
|
||||||
{
|
{
|
||||||
free_plugin_mem(&plugin_dl);
|
free_plugin_mem(&plugin_dl);
|
||||||
if (report & REPORT_TO_USER)
|
report_error(report, ER_CANT_FIND_DL_ENTRY, plugin_interface_version_sym);
|
||||||
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);
|
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
plugin_dl.version= *(int *)sym;
|
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))
|
(plugin_dl.version >> 8) > (MYSQL_PLUGIN_INTERFACE_VERSION >> 8))
|
||||||
{
|
{
|
||||||
free_plugin_mem(&plugin_dl);
|
free_plugin_mem(&plugin_dl);
|
||||||
if (report & REPORT_TO_USER)
|
report_error(report, ER_CANT_OPEN_LIBRARY, MYF(0), dlpath, 0,
|
||||||
my_error(ER_CANT_OPEN_LIBRARY, MYF(0), dlpath, 0,
|
"plugin interface version mismatch");
|
||||||
"plugin interface version mismatch");
|
|
||||||
if (report & REPORT_TO_LOG)
|
|
||||||
sql_print_error(ER_DEFAULT(ER_CANT_OPEN_LIBRARY), dlpath, 0,
|
|
||||||
"plugin interface version mismatch");
|
|
||||||
DBUG_RETURN(0);
|
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 */
|
/* Find plugin declarations */
|
||||||
if (!(sym= dlsym(plugin_dl.handle, plugin_declarations_sym)))
|
if (!(sym= dlsym(plugin_dl.handle, plugin_declarations_sym)))
|
||||||
{
|
{
|
||||||
free_plugin_mem(&plugin_dl);
|
free_plugin_mem(&plugin_dl);
|
||||||
if (report & REPORT_TO_USER)
|
report_error(report, ER_CANT_FIND_DL_ENTRY, MYF(0),
|
||||||
my_error(ER_CANT_FIND_DL_ENTRY, MYF(0), plugin_declarations_sym);
|
plugin_declarations_sym);
|
||||||
if (report & REPORT_TO_LOG)
|
|
||||||
sql_print_error(ER_DEFAULT(ER_CANT_FIND_DL_ENTRY),
|
|
||||||
plugin_declarations_sym);
|
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (plugin_dl.version != MYSQL_PLUGIN_INTERFACE_VERSION)
|
if (plugin_dl.version != MYSQL_PLUGIN_INTERFACE_VERSION)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
uint sizeof_st_plugin;
|
uint sizeof_st_plugin;
|
||||||
struct st_mysql_plugin *old, *cur;
|
struct st_mysql_plugin *old, *cur;
|
||||||
char *ptr= (char *)sym;
|
char *ptr= (char *)sym;
|
||||||
@ -443,11 +466,7 @@ static st_plugin_dl *plugin_dl_add(const LEX_STRING *dl, int report)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
#ifdef ERROR_ON_NO_SIZEOF_PLUGIN_SYMBOL
|
#ifdef ERROR_ON_NO_SIZEOF_PLUGIN_SYMBOL
|
||||||
free_plugin_mem(&plugin_dl);
|
report_error(report, ER_CANT_FIND_DL_ENTRY, sizeof_st_plugin_sym);
|
||||||
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);
|
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
#else
|
#else
|
||||||
/*
|
/*
|
||||||
@ -469,10 +488,7 @@ static st_plugin_dl *plugin_dl_add(const LEX_STRING *dl, int report)
|
|||||||
if (!cur)
|
if (!cur)
|
||||||
{
|
{
|
||||||
free_plugin_mem(&plugin_dl);
|
free_plugin_mem(&plugin_dl);
|
||||||
if (report & REPORT_TO_USER)
|
report_error(report, ER_OUTOFMEMORY, plugin_dl.dl.length);
|
||||||
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);
|
|
||||||
DBUG_RETURN(0);
|
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))))
|
if (! (plugin_dl.dl.str= (char*) my_malloc(plugin_dl.dl.length, MYF(0))))
|
||||||
{
|
{
|
||||||
free_plugin_mem(&plugin_dl);
|
free_plugin_mem(&plugin_dl);
|
||||||
if (report & REPORT_TO_USER)
|
report_error(report, ER_OUTOFMEMORY, plugin_dl.dl.length);
|
||||||
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);
|
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
plugin_dl.dl.length= copy_and_convert(plugin_dl.dl.str, plugin_dl.dl.length,
|
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)))
|
if (! (tmp= plugin_dl_insert_or_reuse(&plugin_dl)))
|
||||||
{
|
{
|
||||||
free_plugin_mem(&plugin_dl);
|
free_plugin_mem(&plugin_dl);
|
||||||
if (report & REPORT_TO_USER)
|
report_error(report, ER_OUTOFMEMORY, sizeof(struct st_plugin_dl));
|
||||||
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));
|
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
DBUG_RETURN(tmp);
|
DBUG_RETURN(tmp);
|
||||||
#else
|
#else
|
||||||
DBUG_ENTER("plugin_dl_add");
|
DBUG_ENTER("plugin_dl_add");
|
||||||
if (report & REPORT_TO_USER)
|
report_error(report, ER_FEATURE_DISABLED, "plugin", "HAVE_DLOPEN");
|
||||||
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");
|
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
#endif
|
#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
|
For debugging, we do an additional malloc which allows the
|
||||||
memory manager and/or valgrind to track locked references and
|
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))))
|
if (!(plugin= (plugin_ref) my_malloc_ci(sizeof(pi), MYF(MY_WME))))
|
||||||
DBUG_RETURN(NULL);
|
DBUG_RETURN(NULL);
|
||||||
@ -719,10 +726,7 @@ static bool plugin_add(MEM_ROOT *tmp_root,
|
|||||||
DBUG_ENTER("plugin_add");
|
DBUG_ENTER("plugin_add");
|
||||||
if (plugin_find_internal(name, MYSQL_ANY_PLUGIN))
|
if (plugin_find_internal(name, MYSQL_ANY_PLUGIN))
|
||||||
{
|
{
|
||||||
if (report & REPORT_TO_USER)
|
report_error(report, ER_UDF_EXISTS, name->str);
|
||||||
my_error(ER_UDF_EXISTS, MYF(0), name->str);
|
|
||||||
if (report & REPORT_TO_LOG)
|
|
||||||
sql_print_error(ER_DEFAULT(ER_UDF_EXISTS), name->str);
|
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
}
|
}
|
||||||
/* Clear the whole struct to catch future extensions. */
|
/* 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 ",
|
strxnmov(buf, sizeof(buf) - 1, "API version for ",
|
||||||
plugin_type_names[plugin->type].str,
|
plugin_type_names[plugin->type].str,
|
||||||
" plugin is too different", NullS);
|
" plugin is too different", NullS);
|
||||||
if (report & REPORT_TO_USER)
|
report_error(report, ER_CANT_OPEN_LIBRARY, dl->str, 0, buf);
|
||||||
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);
|
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
tmp.plugin= plugin;
|
tmp.plugin= plugin;
|
||||||
@ -781,10 +782,7 @@ static bool plugin_add(MEM_ROOT *tmp_root,
|
|||||||
DBUG_RETURN(FALSE);
|
DBUG_RETURN(FALSE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (report & REPORT_TO_USER)
|
report_error(report, ER_CANT_FIND_DL_ENTRY, name->str);
|
||||||
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);
|
|
||||||
err:
|
err:
|
||||||
plugin_dl_del(dl);
|
plugin_dl_del(dl);
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
|
@ -35,16 +35,6 @@ class sys_var;
|
|||||||
|
|
||||||
#define INITIAL_LEX_PLUGIN_LIST_SIZE 16
|
#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 enum enum_mysql_show_type SHOW_TYPE;
|
||||||
typedef struct st_mysql_show_var SHOW_VAR;
|
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
|
EXTRA_LTLIBRARIES = ha_example.la
|
||||||
pkgplugin_LTLIBRARIES = @plugin_example_shared_target@
|
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_CXXFLAGS= $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN
|
||||||
ha_example_la_CFLAGS = $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN
|
ha_example_la_CFLAGS = $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN
|
||||||
ha_example_la_SOURCES = ha_example.cc
|
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
|
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
|
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
|
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_declare_plugin(example)
|
||||||
{
|
{
|
||||||
MYSQL_STORAGE_ENGINE_PLUGIN,
|
MYSQL_STORAGE_ENGINE_PLUGIN,
|
||||||
@ -932,7 +950,7 @@ mysql_declare_plugin(example)
|
|||||||
example_init_func, /* Plugin Init */
|
example_init_func, /* Plugin Init */
|
||||||
example_done_func, /* Plugin Deinit */
|
example_done_func, /* Plugin Deinit */
|
||||||
0x0001 /* 0.1 */,
|
0x0001 /* 0.1 */,
|
||||||
NULL, /* status variables */
|
func_status, /* status variables */
|
||||||
example_system_variables, /* system variables */
|
example_system_variables, /* system variables */
|
||||||
NULL /* config options */
|
NULL /* config options */
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,7 @@ IF(NOT SOURCE_SUBLIBS)
|
|||||||
#The dll is linked to the mysqld executable
|
#The dll is linked to the mysqld executable
|
||||||
SET(dyn_libname ha_${libname})
|
SET(dyn_libname ha_${libname})
|
||||||
ADD_LIBRARY(${dyn_libname} SHARED ${${engine}_SOURCES})
|
ADD_LIBRARY(${dyn_libname} SHARED ${${engine}_SOURCES})
|
||||||
TARGET_LINK_LIBRARIES (${dyn_libname} mysqld)
|
TARGET_LINK_LIBRARIES (${dyn_libname} mysqlservices mysqld)
|
||||||
IF(${engine}_LIBS)
|
IF(${engine}_LIBS)
|
||||||
TARGET_LINK_LIBRARIES(${dyn_libname} ${${engine}_LIBS})
|
TARGET_LINK_LIBRARIES(${dyn_libname} ${${engine}_LIBS})
|
||||||
ENDIF(${engine}_LIBS)
|
ENDIF(${engine}_LIBS)
|
||||||
|
@ -472,6 +472,8 @@ start:
|
|||||||
/**
|
/**
|
||||||
Produces output string according to a format string
|
Produces output string according to a format string
|
||||||
|
|
||||||
|
See the detailed documentation around my_snprintf_service_st
|
||||||
|
|
||||||
@param cs string charset
|
@param cs string charset
|
||||||
@param to buffer where processed string will be place
|
@param to buffer where processed string will be place
|
||||||
@param n size of buffer
|
@param n size of buffer
|
||||||
|
Reference in New Issue
Block a user