WL#2936
"Server variables for plugins" Post review fixes. client/mysql.cc: wl2936 "Plugin server variables" post review fixes compile fix. app_type is now a void* and it isn't actually used here. include/my_getopt.h: wl2936 "Plugin server variables" post review fixes make app_type into a void*. This also required changes to client/mysql.cc and storage/ndb/src/mgmsrv/InitConfigFileParser.cpp in order to compile. include/my_global.h: wl2936 "Plugin server variables" post-review fixes declare compile_time_assert() macro. (provided by serg) include/mysql/plugin.h: wl2936 "Plugin server variables" post review fixes Add comments mysys/array.c: wl2936 "Plugin server variables" post review fixes mysys/typelib.c: wl2936 "Plugin server variables" post review fixes find_typeset() should not alter string sql/set_var.cc: wl2936 "Plugin server variables" post review fixes remove unnecessary code. sql/sql_class.cc: wl2936 "Plugin server variables" post review fixes explicitly declare export style for functions. sql/sql_lex.cc: wl2936 "Plugin server variables" post review fixes enforce that lex::plugins_static_buffer is declared immediately after lex::plugins. sql/sql_plugin.cc: wl2936 "Plugin Server variables" post review fixes sys_var_pluginvar does not need st_plugin_int at construction. remove debug code which was accidentially committed. add comments. fix mutex lock order. sql/sql_plugin.h: wl2936 "Plugin server variables" post review fixes add comment and macro to compare plugin_refs sql/table.cc: wl2936 "plugin server variables" post review fixes remove unneccessary unlock and variable. add checks for legacy type validity storage/ndb/src/mgmsrv/InitConfigFileParser.cpp: wl2936 "plugin server variables" post review fixes fix compile failure now that my_option::app_type is a void*
This commit is contained in:
parent
1fc7f2117b
commit
eac12b6587
@ -743,7 +743,7 @@ static struct my_option my_long_options[] =
|
||||
"Number of seconds before connection timeout.",
|
||||
(gptr*) &opt_connect_timeout,
|
||||
(gptr*) &opt_connect_timeout, 0, GET_ULONG, REQUIRED_ARG, 0, 0, 3600*12, 0,
|
||||
0, 1},
|
||||
0, 0},
|
||||
{"max_allowed_packet", OPT_MAX_ALLOWED_PACKET,
|
||||
"Max packet length to send to, or receive from server",
|
||||
(gptr*) &opt_max_allowed_packet, (gptr*) &opt_max_allowed_packet, 0, GET_ULONG,
|
||||
|
@ -54,7 +54,7 @@ struct my_option
|
||||
longlong max_value; /* Max allowed value */
|
||||
longlong sub_size; /* Subtract this from given value */
|
||||
long block_size; /* Value should be a mult. of this */
|
||||
long app_type; /* To be used by an application */
|
||||
void *app_type; /* To be used by an application */
|
||||
};
|
||||
|
||||
typedef my_bool (* my_get_one_option) (int, const struct my_option *, char * );
|
||||
|
@ -458,6 +458,14 @@ C_MODE_END
|
||||
*/
|
||||
#include <assert.h>
|
||||
|
||||
/* an assert that works at compile-time. only for constant expression */
|
||||
#define compile_time_assert(X) \
|
||||
do \
|
||||
{ \
|
||||
char compile_time_assert[(X) ? 1 : -1] \
|
||||
__attribute__ ((unused)); \
|
||||
} while(0)
|
||||
|
||||
/* Go around some bugs in different OS and compilers */
|
||||
#if defined (HPUX11) && defined(_LARGEFILE_SOURCE)
|
||||
#define _LARGEFILE64_SOURCE
|
||||
|
@ -122,9 +122,43 @@ typedef int (*mysql_show_var_func)(MYSQL_THD, struct st_mysql_show_var*, char *)
|
||||
struct st_mysql_sys_var;
|
||||
struct st_mysql_value;
|
||||
|
||||
/*
|
||||
SYNOPSIS
|
||||
(*mysql_var_check_func)()
|
||||
thd thread handle
|
||||
var dynamic variable being altered
|
||||
save pointer to temporary storage
|
||||
value user provided value
|
||||
RETURN
|
||||
0 user provided value is OK and the update func may be called.
|
||||
any other value indicates error.
|
||||
|
||||
This function should parse the user provided value and store in the
|
||||
provided temporary storage any data as required by the update func.
|
||||
There is sufficient space in the temporary storage to store a double.
|
||||
Note that the update func may not be called if any other error occurs
|
||||
so any memory allocated should be thread-local so that it may be freed
|
||||
automatically at the end of the statement.
|
||||
*/
|
||||
|
||||
typedef int (*mysql_var_check_func)(MYSQL_THD thd,
|
||||
struct st_mysql_sys_var *var,
|
||||
void *save, struct st_mysql_value *value);
|
||||
|
||||
/*
|
||||
SYNOPSIS
|
||||
(*mysql_var_update_func)()
|
||||
thd thread handle
|
||||
var dynamic variable being altered
|
||||
var_ptr pointer to dynamic variable
|
||||
save pointer to temporary storage
|
||||
RETURN
|
||||
NONE
|
||||
|
||||
This function should use the validated value stored in the temporary store
|
||||
and persist it in the provided pointer to the dynamic variable.
|
||||
For example, strings may require memory to be allocated.
|
||||
*/
|
||||
typedef void (*mysql_var_update_func)(MYSQL_THD thd,
|
||||
struct st_mysql_sys_var *var,
|
||||
void *var_ptr, void *save);
|
||||
@ -582,6 +616,10 @@ struct st_mysql_information_schema
|
||||
st_mysql_value struct for reading values from mysqld.
|
||||
Used by server variables framework to parse user-provided values.
|
||||
Will be used for arguments when implementing UDFs.
|
||||
|
||||
Note that val_str() returns a string in temporary memory
|
||||
that will be freed at the end of statement. Copy the string
|
||||
if you need it to persist.
|
||||
*/
|
||||
|
||||
#define MYSQL_VALUE_TYPE_STRING 0
|
||||
|
@ -57,9 +57,10 @@ my_bool init_dynamic_array2(DYNAMIC_ARRAY *array, uint element_size,
|
||||
}
|
||||
|
||||
if (!init_alloc)
|
||||
{
|
||||
init_alloc=alloc_increment;
|
||||
else
|
||||
init_buffer= 0;
|
||||
}
|
||||
array->elements=0;
|
||||
array->max_element=init_alloc;
|
||||
array->alloc_increment=alloc_increment;
|
||||
|
@ -20,6 +20,8 @@
|
||||
#include <m_ctype.h>
|
||||
|
||||
|
||||
static const char field_separator=',';
|
||||
|
||||
/*
|
||||
Search after a string in a list of strings. Endspace in x is not compared.
|
||||
|
||||
@ -31,6 +33,7 @@
|
||||
If & 1 accept only whole names
|
||||
If & 2 don't expand if half field
|
||||
If & 4 allow #number# as type
|
||||
If & 8 use ',' as string terminator
|
||||
|
||||
NOTES
|
||||
If part, uniq field is found and full_name == 0 then x is expanded
|
||||
@ -60,16 +63,18 @@ int find_type(my_string x, TYPELIB *typelib, uint full_name)
|
||||
for (pos=0 ; (j=typelib->type_names[pos]) ; pos++)
|
||||
{
|
||||
for (i=x ;
|
||||
*i && my_toupper(&my_charset_latin1,*i) ==
|
||||
*i && (!(full_name & 8) || *i != field_separator) &&
|
||||
my_toupper(&my_charset_latin1,*i) ==
|
||||
my_toupper(&my_charset_latin1,*j) ; i++, j++) ;
|
||||
if (! *j)
|
||||
{
|
||||
while (*i == ' ')
|
||||
i++; /* skip_end_space */
|
||||
if (! *i)
|
||||
if (! *i || ((full_name & 8) && *i == field_separator))
|
||||
DBUG_RETURN(pos+1);
|
||||
}
|
||||
if (! *i && (!*j || !(full_name & 1)))
|
||||
if ((!*i && (!(full_name & 8) || *i != field_separator)) &&
|
||||
(!*j || !(full_name & 1)))
|
||||
{
|
||||
find++;
|
||||
findpos=pos;
|
||||
@ -120,8 +125,6 @@ const char *get_type(TYPELIB *typelib, uint nr)
|
||||
}
|
||||
|
||||
|
||||
static const char field_separator=',';
|
||||
|
||||
/*
|
||||
Create an integer value to represent the supplied comma-seperated
|
||||
string where each string in the TYPELIB denotes a bit position.
|
||||
@ -157,9 +160,7 @@ my_ulonglong find_typeset(my_string x, TYPELIB *lib, int *err)
|
||||
(*err)++;
|
||||
i= x;
|
||||
while (*x && *x != field_separator) x++;
|
||||
if (*x)
|
||||
*x++= 0;
|
||||
if ((find= find_type(i, lib, 2) - 1) < 0)
|
||||
if ((find= find_type(i, lib, 2 | 8) - 1) < 0)
|
||||
DBUG_RETURN(0);
|
||||
result|= (ULL(1) << find);
|
||||
}
|
||||
|
@ -2838,7 +2838,6 @@ int set_var_init()
|
||||
|
||||
error:
|
||||
fprintf(stderr, "failed to initialize system variables");
|
||||
pthread_mutex_unlock(&LOCK_global_system_variables);
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
|
||||
|
@ -167,18 +167,25 @@ Open_tables_state::Open_tables_state(ulong version_arg)
|
||||
reset_open_tables_state();
|
||||
}
|
||||
|
||||
/*
|
||||
The following functions form part of the C plugin API
|
||||
*/
|
||||
|
||||
extern "C"
|
||||
int thd_in_lock_tables(const THD *thd)
|
||||
{
|
||||
return test(thd->in_lock_tables);
|
||||
}
|
||||
|
||||
|
||||
extern "C"
|
||||
int thd_tablespace_op(const THD *thd)
|
||||
{
|
||||
return test(thd->tablespace_op);
|
||||
}
|
||||
|
||||
|
||||
extern "C"
|
||||
const char *thd_proc_info(THD *thd, const char *info)
|
||||
{
|
||||
const char *old_info= thd->proc_info;
|
||||
@ -186,16 +193,19 @@ const char *thd_proc_info(THD *thd, const char *info)
|
||||
return old_info;
|
||||
}
|
||||
|
||||
extern "C"
|
||||
void **thd_ha_data(const THD *thd, const struct handlerton *hton)
|
||||
{
|
||||
return (void **) thd->ha_data + hton->slot;
|
||||
}
|
||||
|
||||
extern "C"
|
||||
long long thd_test_options(const THD *thd, long long test_options)
|
||||
{
|
||||
return thd->options & test_options;
|
||||
}
|
||||
|
||||
extern "C"
|
||||
int thd_sql_command(const THD *thd)
|
||||
{
|
||||
return (int) thd->lex->sql_command;
|
||||
@ -216,6 +226,7 @@ int thd_sql_command(const THD *thd)
|
||||
RETURN VALUES
|
||||
pointer to string
|
||||
*/
|
||||
extern "C"
|
||||
char *thd_security_context(THD *thd, char *buffer, int length,
|
||||
int max_query_len)
|
||||
{
|
||||
@ -268,6 +279,7 @@ char *thd_security_context(THD *thd, char *buffer, int length,
|
||||
return thd->strmake(str.ptr(), str.length());
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Pass nominal parameters to Statement constructor only to ensure that
|
||||
the destructor works OK in case of error. The main_mem_root will be
|
||||
|
@ -1745,6 +1745,9 @@ st_lex::st_lex()
|
||||
:result(0), yacc_yyss(0), yacc_yyvs(0),
|
||||
sql_command(SQLCOM_END)
|
||||
{
|
||||
/* Check that plugins_static_buffer is declared immediately after plugins */
|
||||
compile_time_assert((&plugins + 1) == (DYNAMIC_ARRAY*)plugins_static_buffer);
|
||||
|
||||
my_init_dynamic_array2(&plugins, sizeof(plugin_ref),
|
||||
plugins_static_buffer,
|
||||
INITIAL_LEX_PLUGIN_LIST_SIZE,
|
||||
|
@ -161,9 +161,8 @@ public:
|
||||
{ TRASH(ptr_arg, size); }
|
||||
|
||||
sys_var_pluginvar(const char *name_arg,
|
||||
struct st_plugin_int *plugin_arg,
|
||||
struct st_mysql_sys_var *plugin_var_arg)
|
||||
:sys_var(name_arg), plugin(plugin_arg), plugin_var(plugin_var_arg) {}
|
||||
:sys_var(name_arg), plugin_var(plugin_var_arg) {}
|
||||
sys_var_pluginvar *cast_pluginvar() { return this; }
|
||||
bool is_readonly() const { return plugin_var->flags & PLUGIN_VAR_READONLY; }
|
||||
bool check_type(enum_var_type type)
|
||||
@ -631,11 +630,6 @@ static plugin_ref intern_plugin_lock(LEX *lex, plugin_ref rc CALLER_INFO_PROTO)
|
||||
#else
|
||||
if (!(plugin= (plugin_ref) my_malloc_ci(sizeof(pi), MYF(MY_WME))))
|
||||
DBUG_RETURN(NULL);
|
||||
//if (0x4620a20L == (long) plugin)
|
||||
if (0x4656b10L == (long) plugin)
|
||||
{
|
||||
DBUG_PRINT("debug",("trap"));
|
||||
}
|
||||
|
||||
*plugin= pi;
|
||||
#endif
|
||||
@ -656,6 +650,10 @@ plugin_ref plugin_lock(THD *thd, plugin_ref *ptr CALLER_INFO_PROTO)
|
||||
LEX *lex= NULL;
|
||||
plugin_ref rc;
|
||||
DBUG_ENTER("plugin_lock");
|
||||
/*
|
||||
thd->lex may point to a nested LEX or a stored procedure LEX.
|
||||
main_lex is tightly coupled to the thread.
|
||||
*/
|
||||
if (thd)
|
||||
lex= !thd->lex ? &thd->main_lex : thd->lex;
|
||||
pthread_mutex_lock(&LOCK_plugin);
|
||||
@ -767,11 +765,9 @@ static bool plugin_add(MEM_ROOT *tmp_root,
|
||||
DBUG_RETURN(FALSE);
|
||||
}
|
||||
tmp_plugin_ptr->state= PLUGIN_IS_FREED;
|
||||
goto err;
|
||||
}
|
||||
mysql_del_sys_var_chain(tmp.system_vars);
|
||||
plugin_dl_del(dl);
|
||||
DBUG_RETURN(TRUE);
|
||||
goto err;
|
||||
}
|
||||
/* plugin was disabled */
|
||||
plugin_dl_del(dl);
|
||||
@ -939,7 +935,11 @@ static void intern_plugin_unlock(LEX *lex, plugin_ref plugin)
|
||||
pi->name.str, pi->ref_count));
|
||||
if (lex)
|
||||
{
|
||||
/* remove one instance of this plugin from the use list */
|
||||
/*
|
||||
Remove one instance of this plugin from the use list.
|
||||
We are searching backwards so that plugins locked last
|
||||
could be unlocked faster - optimizing for LIFO semantics.
|
||||
*/
|
||||
for (i= lex->plugins.elements - 1; i >= 0; i--)
|
||||
if (plugin == *dynamic_element(&lex->plugins, i, plugin_ref*))
|
||||
{
|
||||
@ -1283,6 +1283,7 @@ bool plugin_register_builtin(THD *thd, struct st_mysql_plugin *plugin)
|
||||
bzero(&tmp, sizeof(tmp));
|
||||
tmp.plugin= plugin;
|
||||
|
||||
pthread_mutex_lock(&LOCK_plugin);
|
||||
rw_wrlock(&LOCK_system_variables_hash);
|
||||
|
||||
if (test_plugin_options(thd->mem_root, &tmp, &dummy_argc, NULL, true))
|
||||
@ -1293,6 +1294,7 @@ bool plugin_register_builtin(THD *thd, struct st_mysql_plugin *plugin)
|
||||
|
||||
end:
|
||||
rw_unlock(&LOCK_system_variables_hash);
|
||||
pthread_mutex_unlock(&LOCK_plugin);
|
||||
|
||||
DBUG_RETURN(result);;
|
||||
}
|
||||
@ -1445,6 +1447,11 @@ void plugin_shutdown(void)
|
||||
{
|
||||
pthread_mutex_lock(&LOCK_plugin);
|
||||
|
||||
/*
|
||||
release any plugin references held but don't yet free
|
||||
memory for dynamic variables as some plugins may still
|
||||
want to reference their global variables.
|
||||
*/
|
||||
cleanup_variables(NULL, &global_system_variables, false);
|
||||
cleanup_variables(NULL, &max_system_variables, false);
|
||||
|
||||
@ -1470,6 +1477,9 @@ void plugin_shutdown(void)
|
||||
}
|
||||
reap_plugins();
|
||||
}
|
||||
|
||||
if (count > 0)
|
||||
sql_print_warning("Forcing shutdown of %d plugins", count);
|
||||
|
||||
plugins= (struct st_plugin_int **) my_alloca(sizeof(void*) * (count+1));
|
||||
|
||||
@ -1496,7 +1506,6 @@ void plugin_shutdown(void)
|
||||
plugin_deinitialize(plugins[i], false);
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&LOCK_plugin);
|
||||
|
||||
/*
|
||||
We defer checking ref_counts until after all plugins are deinitialized
|
||||
@ -1511,15 +1520,24 @@ void plugin_shutdown(void)
|
||||
if (plugins[i]->state & PLUGIN_IS_UNINITIALIZED)
|
||||
plugin_del(plugins[i]);
|
||||
|
||||
/*
|
||||
Now we can deallocate all memory.
|
||||
*/
|
||||
#if defined(SAFE_MUTEX) && !defined(DBUG_OFF)
|
||||
/* neccessary to avoid safe_mutex_assert_owner() trap */
|
||||
pthread_mutex_lock(&LOCK_plugin);
|
||||
#endif
|
||||
cleanup_variables(NULL, &global_system_variables, true);
|
||||
cleanup_variables(NULL, &max_system_variables, true);
|
||||
#if defined(SAFE_MUTEX) && !defined(DBUG_OFF)
|
||||
pthread_mutex_unlock(&LOCK_plugin);
|
||||
#endif
|
||||
|
||||
initialized= 0;
|
||||
pthread_mutex_unlock(&LOCK_plugin);
|
||||
pthread_mutex_destroy(&LOCK_plugin);
|
||||
|
||||
my_afree(plugins);
|
||||
}
|
||||
my_afree(plugins);
|
||||
|
||||
/* Dispose of the memory */
|
||||
|
||||
@ -2007,12 +2025,13 @@ sys_var *find_sys_var(THD *thd, const char *str, uint length)
|
||||
plugin_ref plugin;
|
||||
DBUG_ENTER("find_sys_var");
|
||||
|
||||
pthread_mutex_lock(&LOCK_plugin);
|
||||
rw_rdlock(&LOCK_system_variables_hash);
|
||||
if ((var= intern_find_sys_var(str, length, false)) &&
|
||||
(pi= var->cast_pluginvar()))
|
||||
{
|
||||
rw_unlock(&LOCK_system_variables_hash);
|
||||
LEX *lex= thd ? ( !thd->lex ? &thd->main_lex : thd->lex ) : NULL;
|
||||
pthread_mutex_lock(&LOCK_plugin);
|
||||
if (!(plugin= my_intern_plugin_lock(lex, plugin_int_to_ref(pi->plugin))))
|
||||
var= NULL; /* failed to lock it, it must be uninstalling */
|
||||
else
|
||||
@ -2022,9 +2041,10 @@ sys_var *find_sys_var(THD *thd, const char *str, uint length)
|
||||
var= NULL;
|
||||
intern_plugin_unlock(lex, plugin);
|
||||
}
|
||||
pthread_mutex_unlock(&LOCK_plugin);
|
||||
}
|
||||
rw_unlock(&LOCK_system_variables_hash);
|
||||
else
|
||||
rw_unlock(&LOCK_system_variables_hash);
|
||||
pthread_mutex_unlock(&LOCK_plugin);
|
||||
|
||||
/*
|
||||
If the variable exists but the plugin it is associated with is not ready
|
||||
@ -2183,7 +2203,7 @@ static byte *intern_sys_var_ptr(THD* thd, int offset, bool global_lock)
|
||||
return (byte*) global_system_variables.dynamic_variables_ptr + offset;
|
||||
|
||||
/*
|
||||
dynamic_variables_size points to the largest valid offset
|
||||
dynamic_variables_head points to the largest valid offset
|
||||
*/
|
||||
if (!thd->variables.dynamic_variables_ptr ||
|
||||
(uint)offset > thd->variables.dynamic_variables_head)
|
||||
@ -2208,8 +2228,6 @@ static byte *intern_sys_var_ptr(THD* thd, int offset, bool global_lock)
|
||||
thd->variables.dynamic_variables_size,
|
||||
global_system_variables.dynamic_variables_size -
|
||||
thd->variables.dynamic_variables_size);
|
||||
if (global_lock)
|
||||
pthread_mutex_unlock(&LOCK_global_system_variables);
|
||||
|
||||
/*
|
||||
now we need to iterate through any newly copied 'defaults'
|
||||
@ -2232,19 +2250,17 @@ static byte *intern_sys_var_ptr(THD* thd, int offset, bool global_lock)
|
||||
if ((pi->plugin_var->flags & PLUGIN_VAR_TYPEMASK) == PLUGIN_VAR_STR &&
|
||||
pi->plugin_var->flags & PLUGIN_VAR_MEMALLOC)
|
||||
{
|
||||
char **pp;
|
||||
if (global_lock)
|
||||
pthread_mutex_lock(&LOCK_global_system_variables);
|
||||
pp= (char**) (thd->variables.dynamic_variables_ptr +
|
||||
char **pp= (char**) (thd->variables.dynamic_variables_ptr +
|
||||
*(int*)(pi->plugin_var + 1));
|
||||
if ((*pp= *(char**) (global_system_variables.dynamic_variables_ptr +
|
||||
*(int*)(pi->plugin_var + 1))))
|
||||
*pp= my_strdup(*pp, MYF(MY_WME|MY_FAE));
|
||||
if (global_lock)
|
||||
pthread_mutex_unlock(&LOCK_global_system_variables);
|
||||
}
|
||||
}
|
||||
|
||||
if (global_lock)
|
||||
pthread_mutex_unlock(&LOCK_global_system_variables);
|
||||
|
||||
thd->variables.dynamic_variables_version=
|
||||
global_system_variables.dynamic_variables_version;
|
||||
thd->variables.dynamic_variables_head=
|
||||
@ -2817,7 +2833,7 @@ static int construct_options(MEM_ROOT *mem_root,
|
||||
|
||||
options->name= optname;
|
||||
options->comment= opt->comment;
|
||||
options->app_type= (long) opt;
|
||||
options->app_type= opt;
|
||||
options->id= (options-1)->id + 1;
|
||||
|
||||
if (opt->flags & PLUGIN_VAR_THDLOCAL)
|
||||
@ -2950,7 +2966,7 @@ static int test_plugin_options(MEM_ROOT *tmp_root, struct st_plugin_int *tmp,
|
||||
continue;
|
||||
|
||||
if ((var= find_bookmark(tmp->plugin->name, o->name, o->flags)))
|
||||
v= new (mem_root) sys_var_pluginvar(var->name + 1, tmp, o);
|
||||
v= new (mem_root) sys_var_pluginvar(var->name + 1, o);
|
||||
else
|
||||
{
|
||||
len= strlen(tmp->plugin->name) + strlen(o->name) + 2;
|
||||
@ -2962,10 +2978,15 @@ static int test_plugin_options(MEM_ROOT *tmp_root, struct st_plugin_int *tmp,
|
||||
if (*p == '-')
|
||||
*p= '_';
|
||||
|
||||
v= new (mem_root) sys_var_pluginvar(varname, tmp, o);
|
||||
v= new (mem_root) sys_var_pluginvar(varname, o);
|
||||
}
|
||||
DBUG_ASSERT(v); /* check that an object was actually constructed */
|
||||
|
||||
/*
|
||||
Add to the chain of variables.
|
||||
Done like this for easier debugging so that the
|
||||
pointer to v is not lost on optimized builds.
|
||||
*/
|
||||
v->chain_sys_var(&chain);
|
||||
}
|
||||
if (chain.first)
|
||||
|
@ -79,6 +79,11 @@ struct st_plugin_int
|
||||
sys_var *system_vars; /* server variables for this plugin */
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
See intern_plugin_lock() for the explanation for the
|
||||
conditionally defined plugin_ref type
|
||||
*/
|
||||
#ifdef DBUG_OFF
|
||||
typedef struct st_plugin_int *plugin_ref;
|
||||
#define plugin_decl(pi) ((pi)->plugin)
|
||||
@ -86,6 +91,7 @@ typedef struct st_plugin_int *plugin_ref;
|
||||
#define plugin_data(pi,cast) ((cast)((pi)->data))
|
||||
#define plugin_name(pi) (&((pi)->name))
|
||||
#define plugin_state(pi) ((pi)->state)
|
||||
#define plugin_equals(p1,p2) ((p1) == (p2))
|
||||
#else
|
||||
typedef struct st_plugin_int **plugin_ref;
|
||||
#define plugin_decl(pi) ((pi)[0]->plugin)
|
||||
@ -93,6 +99,7 @@ typedef struct st_plugin_int **plugin_ref;
|
||||
#define plugin_data(pi,cast) ((cast)((pi)[0]->data))
|
||||
#define plugin_name(pi) (&((pi)[0]->name))
|
||||
#define plugin_state(pi) ((pi)[0]->state)
|
||||
#define plugin_equals(p1,p2) ((p1) && (p2) && (p1)[0] == (p2)[0])
|
||||
#endif
|
||||
|
||||
typedef int (*plugin_type_init)(struct st_plugin_int *);
|
||||
|
26
sql/table.cc
26
sql/table.cc
@ -425,7 +425,6 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
|
||||
Field **field_ptr, *reg_field;
|
||||
const char **interval_array;
|
||||
enum legacy_db_type legacy_db_type;
|
||||
handlerton *hton;
|
||||
my_bitmap_map *bitmaps;
|
||||
DBUG_ENTER("open_binary_frm");
|
||||
|
||||
@ -456,11 +455,15 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
|
||||
DBUG_PRINT("info", ("default_part_db_type = %u", head[61]));
|
||||
#endif
|
||||
legacy_db_type= (enum legacy_db_type) (uint) *(head+3);
|
||||
if ((hton= ha_checktype(thd, legacy_db_type, 0, 0)) != share->db_type())
|
||||
{
|
||||
plugin_unlock(NULL, share->db_plugin);
|
||||
share->db_plugin= ha_lock_engine(NULL, hton);
|
||||
}
|
||||
DBUG_ASSERT(share->db_plugin == NULL);
|
||||
/*
|
||||
if the storage engine is dynamic, no point in resolving it by its
|
||||
dynamically allocated legacy_db_type. We will resolve it later by name.
|
||||
*/
|
||||
if (legacy_db_type > DB_TYPE_UNKNOWN &&
|
||||
legacy_db_type < DB_TYPE_FIRST_DYNAMIC)
|
||||
share->db_plugin= ha_lock_engine(NULL,
|
||||
ha_checktype(thd, legacy_db_type, 0, 0));
|
||||
share->db_create_options= db_create_options= uint2korr(head+30);
|
||||
share->db_options_in_use= share->db_create_options;
|
||||
share->mysql_version= uint4korr(head+51);
|
||||
@ -620,8 +623,17 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
|
||||
uint str_db_type_length= uint2korr(next_chunk);
|
||||
LEX_STRING name= { next_chunk + 2, str_db_type_length };
|
||||
plugin_ref tmp_plugin= ha_resolve_by_name(thd, &name);
|
||||
if (tmp_plugin != NULL)
|
||||
if (tmp_plugin != NULL && !plugin_equals(tmp_plugin, share->db_plugin))
|
||||
{
|
||||
if (legacy_db_type > DB_TYPE_UNKNOWN &&
|
||||
legacy_db_type < DB_TYPE_FIRST_DYNAMIC &&
|
||||
legacy_db_type != ha_legacy_type(
|
||||
plugin_data(tmp_plugin, handlerton *)))
|
||||
{
|
||||
/* bad file, legacy_db_type did not match the name */
|
||||
my_free(buff, MYF(0));
|
||||
goto err;
|
||||
}
|
||||
/*
|
||||
tmp_plugin is locked with a local lock.
|
||||
we unlock the old value of share->db_plugin before
|
||||
|
@ -612,10 +612,11 @@ static
|
||||
my_bool
|
||||
parse_mycnf_opt(int, const struct my_option * opt, char * value)
|
||||
{
|
||||
long *app_type= (long*) &opt->app_type;
|
||||
if(opt->comment)
|
||||
((struct my_option *)opt)->app_type++;
|
||||
(*app_type)++;
|
||||
else
|
||||
((struct my_option *)opt)->app_type = order++;
|
||||
*app_type = order++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -948,22 +949,6 @@ end:
|
||||
|
||||
template class Vector<struct my_option>;
|
||||
|
||||
#if 0
|
||||
struct my_option
|
||||
{
|
||||
const char *name; /* Name of the option */
|
||||
int id; /* unique id or short option */
|
||||
const char *comment; /* option comment, for autom. --help */
|
||||
gptr *value; /* The variable value */
|
||||
gptr *u_max_value; /* The user def. max variable value */
|
||||
const char **str_values; /* Pointer to possible values */
|
||||
ulong var_type;
|
||||
enum get_opt_arg_type arg_type;
|
||||
longlong def_value; /* Default value */
|
||||
longlong min_value; /* Min allowed value */
|
||||
longlong max_value; /* Max allowed value */
|
||||
longlong sub_size; /* Subtract this from given value */
|
||||
long block_size; /* Value should be a mult. of this */
|
||||
int app_type; /* To be used by an application */
|
||||
};
|
||||
#endif
|
||||
/*
|
||||
See include/my_getopt.h for the declaration of struct my_option
|
||||
*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user