mirror of
https://github.com/MariaDB/server.git
synced 2025-05-29 21:42:28 +03:00
MDEV-31174 New class Native_functions_hash
This commit is contained in:
parent
9b6f87b62a
commit
01ea779149
@ -140,7 +140,7 @@ Create_func_trt_trx_sees<X> Create_func_trt_trx_sees<X>::s_singleton;
|
|||||||
|
|
||||||
#define BUILDER(F) & F::s_singleton
|
#define BUILDER(F) & F::s_singleton
|
||||||
|
|
||||||
static Native_func_registry func_array[] =
|
static const Native_func_registry func_array_vers[] =
|
||||||
{
|
{
|
||||||
{ { C_STRING_WITH_LEN("TRT_BEGIN_TS") }, BUILDER(Create_func_trt<TR_table::FLD_BEGIN_TS>)},
|
{ { C_STRING_WITH_LEN("TRT_BEGIN_TS") }, BUILDER(Create_func_trt<TR_table::FLD_BEGIN_TS>)},
|
||||||
{ { C_STRING_WITH_LEN("TRT_COMMIT_ID") }, BUILDER(Create_func_trt<TR_table::FLD_COMMIT_ID>)},
|
{ { C_STRING_WITH_LEN("TRT_COMMIT_ID") }, BUILDER(Create_func_trt<TR_table::FLD_COMMIT_ID>)},
|
||||||
@ -164,7 +164,7 @@ static int versioning_plugin_init(void *p __attribute__ ((unused)))
|
|||||||
{
|
{
|
||||||
DBUG_ENTER("versioning_plugin_init");
|
DBUG_ENTER("versioning_plugin_init");
|
||||||
// No need in locking since we so far single-threaded
|
// No need in locking since we so far single-threaded
|
||||||
int res= item_create_append(func_array);
|
int res= native_functions_hash.append(func_array_vers);
|
||||||
if (res)
|
if (res)
|
||||||
{
|
{
|
||||||
my_message(ER_PLUGIN_IS_NOT_LOADED, "Can't append function array" , MYF(0));
|
my_message(ER_PLUGIN_IS_NOT_LOADED, "Can't append function array" , MYF(0));
|
||||||
@ -177,7 +177,7 @@ static int versioning_plugin_init(void *p __attribute__ ((unused)))
|
|||||||
static int versioning_plugin_deinit(void *p __attribute__ ((unused)))
|
static int versioning_plugin_deinit(void *p __attribute__ ((unused)))
|
||||||
{
|
{
|
||||||
DBUG_ENTER("versioning_plugin_deinit");
|
DBUG_ENTER("versioning_plugin_deinit");
|
||||||
(void) item_create_remove(func_array);
|
(void) native_functions_hash.remove(func_array_vers);
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7249,7 +7249,7 @@ Create_func_year_week::create_native(THD *thd, const LEX_CSTRING *name,
|
|||||||
- keep 1 line per entry, it makes grep | sort easier
|
- keep 1 line per entry, it makes grep | sort easier
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Native_func_registry func_array[] =
|
const Native_func_registry func_array[] =
|
||||||
{
|
{
|
||||||
{ { STRING_WITH_LEN("ABS") }, BUILDER(Create_func_abs)},
|
{ { STRING_WITH_LEN("ABS") }, BUILDER(Create_func_abs)},
|
||||||
{ { STRING_WITH_LEN("ACOS") }, BUILDER(Create_func_acos)},
|
{ { STRING_WITH_LEN("ACOS") }, BUILDER(Create_func_acos)},
|
||||||
@ -7609,9 +7609,10 @@ Native_func_registry func_array[] =
|
|||||||
{ {0, 0}, NULL}
|
{ {0, 0}, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
size_t func_array_length= sizeof(func_array) / sizeof(Native_func_registry) - 1;
|
|
||||||
|
|
||||||
static HASH native_functions_hash;
|
const size_t func_array_length= sizeof(func_array) / sizeof(Native_func_registry) - 1;
|
||||||
|
|
||||||
|
Native_functions_hash native_functions_hash;
|
||||||
|
|
||||||
extern "C" uchar*
|
extern "C" uchar*
|
||||||
get_native_fct_hash_key(const uchar *buff, size_t *length,
|
get_native_fct_hash_key(const uchar *buff, size_t *length,
|
||||||
@ -7628,85 +7629,89 @@ get_native_fct_hash_key(const uchar *buff, size_t *length,
|
|||||||
startup only (before going multi-threaded)
|
startup only (before going multi-threaded)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int item_create_init()
|
bool Native_functions_hash::init(size_t count)
|
||||||
{
|
{
|
||||||
DBUG_ENTER("item_create_init");
|
DBUG_ENTER("Native_functions_hash::init");
|
||||||
|
|
||||||
if (my_hash_init(& native_functions_hash,
|
if (my_hash_init(this,
|
||||||
system_charset_info,
|
system_charset_info,
|
||||||
array_elements(func_array),
|
(ulong) count,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
(my_hash_get_key) get_native_fct_hash_key,
|
(my_hash_get_key) get_native_fct_hash_key,
|
||||||
NULL, /* Nothing to free */
|
NULL, /* Nothing to free */
|
||||||
MYF(0)))
|
MYF(0)))
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(true);
|
||||||
|
|
||||||
DBUG_RETURN(item_create_append(func_array));
|
DBUG_RETURN(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
int item_create_append(Native_func_registry array[])
|
|
||||||
{
|
|
||||||
Native_func_registry *func;
|
|
||||||
|
|
||||||
DBUG_ENTER("item_create_append");
|
bool Native_functions_hash::append(const Native_func_registry array[])
|
||||||
|
{
|
||||||
|
const Native_func_registry *func;
|
||||||
|
|
||||||
|
DBUG_ENTER("Native_functions_hash::append");
|
||||||
|
|
||||||
for (func= array; func->builder != NULL; func++)
|
for (func= array; func->builder != NULL; func++)
|
||||||
{
|
{
|
||||||
if (my_hash_insert(& native_functions_hash, (uchar*) func))
|
if (my_hash_insert(this, (uchar*) func))
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef DBUG_OFF
|
#ifndef DBUG_OFF
|
||||||
for (uint i=0 ; i < native_functions_hash.records ; i++)
|
for (uint i=0 ; i < records ; i++)
|
||||||
{
|
{
|
||||||
func= (Native_func_registry*) my_hash_element(& native_functions_hash, i);
|
func= (Native_func_registry*) my_hash_element(this, i);
|
||||||
DBUG_PRINT("info", ("native function: %s length: %u",
|
DBUG_PRINT("info", ("native function: %s length: %u",
|
||||||
func->name.str, (uint) func->name.length));
|
func->name.str, (uint) func->name.length));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
int item_create_remove(Native_func_registry array[])
|
|
||||||
{
|
|
||||||
Native_func_registry *func;
|
|
||||||
|
|
||||||
DBUG_ENTER("item_create_remove");
|
bool Native_functions_hash::remove(const Native_func_registry array[])
|
||||||
|
{
|
||||||
|
const Native_func_registry *func;
|
||||||
|
|
||||||
|
DBUG_ENTER("Native_functions_hash::remove");
|
||||||
|
|
||||||
for (func= array; func->builder != NULL; func++)
|
for (func= array; func->builder != NULL; func++)
|
||||||
{
|
{
|
||||||
if (my_hash_delete(& native_functions_hash, (uchar*) func))
|
if (my_hash_delete(this, (uchar*) func))
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Empty the hash table for native functions.
|
Empty the hash table for native functions.
|
||||||
Note: this code is not thread safe, and is intended to be used at server
|
Note: this code is not thread safe, and is intended to be used at server
|
||||||
shutdown only (after thread requests have been executed).
|
shutdown only (after thread requests have been executed).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void item_create_cleanup()
|
void Native_functions_hash::cleanup()
|
||||||
{
|
{
|
||||||
DBUG_ENTER("item_create_cleanup");
|
DBUG_ENTER("Native_functions_hash::cleanup");
|
||||||
my_hash_free(& native_functions_hash);
|
my_hash_free(this);
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Create_func *
|
Create_func *
|
||||||
find_native_function_builder(THD *thd, const LEX_CSTRING *name)
|
Native_functions_hash::find(THD *thd, const LEX_CSTRING &name) const
|
||||||
{
|
{
|
||||||
Native_func_registry *func;
|
Native_func_registry *func;
|
||||||
Create_func *builder= NULL;
|
Create_func *builder= NULL;
|
||||||
|
|
||||||
/* Thread safe */
|
/* Thread safe */
|
||||||
func= (Native_func_registry*) my_hash_search(&native_functions_hash,
|
func= (Native_func_registry*) my_hash_search(this,
|
||||||
(uchar*) name->str,
|
(uchar*) name.str,
|
||||||
name->length);
|
name.length);
|
||||||
|
|
||||||
if (func)
|
if (func)
|
||||||
{
|
{
|
||||||
@ -7716,6 +7721,19 @@ find_native_function_builder(THD *thd, const LEX_CSTRING *name)
|
|||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int item_create_init()
|
||||||
|
{
|
||||||
|
return native_functions_hash.init(func_array, array_elements(func_array));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void item_create_cleanup()
|
||||||
|
{
|
||||||
|
native_functions_hash.cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Create_qfunc *
|
Create_qfunc *
|
||||||
find_qualified_function_builder(THD *thd)
|
find_qualified_function_builder(THD *thd)
|
||||||
{
|
{
|
||||||
|
@ -144,16 +144,6 @@ protected:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Find the native function builder associated with a given function name.
|
|
||||||
@param thd The current thread
|
|
||||||
@param name The native function name
|
|
||||||
@return The native function builder associated with the name, or NULL
|
|
||||||
*/
|
|
||||||
extern Create_func *find_native_function_builder(THD *thd,
|
|
||||||
const LEX_CSTRING *name);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Find the function builder for qualified functions.
|
Find the function builder for qualified functions.
|
||||||
@param thd The current thread
|
@param thd The current thread
|
||||||
@ -200,9 +190,52 @@ struct Native_func_registry
|
|||||||
Create_func *builder;
|
Create_func *builder;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class Native_functions_hash: public HASH
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Native_functions_hash()
|
||||||
|
{
|
||||||
|
bzero(this, sizeof(*this));
|
||||||
|
}
|
||||||
|
~Native_functions_hash()
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
No automatic free because objects of this type
|
||||||
|
are expected to be declared statically.
|
||||||
|
The code in cleanup() calls my_hash_free() which may not work correctly
|
||||||
|
at the very end of mariadbd shutdown.
|
||||||
|
The the upper level code should call cleanup() explicitly.
|
||||||
|
|
||||||
|
Unfortunatelly, it's not possible to use DBUG_ASSERT(!records) here,
|
||||||
|
because the server terminates using exit() in some cases,
|
||||||
|
e.g. in the test main.named_pipe with the "Create named pipe failed"
|
||||||
|
error.
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
bool init(size_t count);
|
||||||
|
bool init(const Native_func_registry array[], size_t count)
|
||||||
|
{
|
||||||
|
return init(count) || append(array);
|
||||||
|
}
|
||||||
|
bool append(const Native_func_registry array[]);
|
||||||
|
bool remove(const Native_func_registry array[]);
|
||||||
|
void cleanup();
|
||||||
|
/**
|
||||||
|
Find the native function builder associated with a given function name.
|
||||||
|
@param thd The current thread
|
||||||
|
@param name The native function name
|
||||||
|
@return The native function builder associated with the name, or NULL
|
||||||
|
*/
|
||||||
|
Create_func *find(THD *thd, const LEX_CSTRING &name) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern MYSQL_PLUGIN_IMPORT Native_functions_hash native_functions_hash;
|
||||||
|
|
||||||
|
extern const Native_func_registry func_array[];
|
||||||
|
extern const size_t func_array_length;
|
||||||
|
|
||||||
int item_create_init();
|
int item_create_init();
|
||||||
int item_create_append(Native_func_registry array[]);
|
|
||||||
int item_create_remove(Native_func_registry array[]);
|
|
||||||
void item_create_cleanup();
|
void item_create_cleanup();
|
||||||
|
|
||||||
Item *create_func_dyncol_create(THD *thd, List<DYNCALL_CREATE_DEF> &list);
|
Item *create_func_dyncol_create(THD *thd, List<DYNCALL_CREATE_DEF> &list);
|
||||||
|
@ -943,7 +943,7 @@ bool is_lex_native_function(const LEX_CSTRING *name)
|
|||||||
|
|
||||||
bool is_native_function(THD *thd, const LEX_CSTRING *name)
|
bool is_native_function(THD *thd, const LEX_CSTRING *name)
|
||||||
{
|
{
|
||||||
if (find_native_function_builder(thd, name))
|
if (native_functions_hash.find(thd, *name))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (is_lex_native_function(name))
|
if (is_lex_native_function(name))
|
||||||
|
@ -76,9 +76,6 @@ extern size_t symbols_length;
|
|||||||
extern SYMBOL sql_functions[];
|
extern SYMBOL sql_functions[];
|
||||||
extern size_t sql_functions_length;
|
extern size_t sql_functions_length;
|
||||||
|
|
||||||
extern Native_func_registry func_array[];
|
|
||||||
extern size_t func_array_length;
|
|
||||||
|
|
||||||
enum enum_i_s_events_fields
|
enum enum_i_s_events_fields
|
||||||
{
|
{
|
||||||
ISE_EVENT_CATALOG= 0,
|
ISE_EVENT_CATALOG= 0,
|
||||||
|
@ -11485,7 +11485,7 @@ function_call_generic:
|
|||||||
|
|
||||||
This will be revised with WL#2128 (SQL PATH)
|
This will be revised with WL#2128 (SQL PATH)
|
||||||
*/
|
*/
|
||||||
builder= find_native_function_builder(thd, &$1);
|
builder= native_functions_hash.find(thd, $1);
|
||||||
if (builder)
|
if (builder)
|
||||||
{
|
{
|
||||||
item= builder->create_func(thd, &$1, $4);
|
item= builder->create_func(thd, &$1, $4);
|
||||||
|
@ -11600,7 +11600,7 @@ function_call_generic:
|
|||||||
|
|
||||||
This will be revised with WL#2128 (SQL PATH)
|
This will be revised with WL#2128 (SQL PATH)
|
||||||
*/
|
*/
|
||||||
builder= find_native_function_builder(thd, &$1);
|
builder= native_functions_hash.find(thd, $1);
|
||||||
if (builder)
|
if (builder)
|
||||||
{
|
{
|
||||||
item= builder->create_func(thd, &$1, $4);
|
item= builder->create_func(thd, &$1, $4);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user