summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mariadb.com>2023-04-28 14:41:27 +0400
committerAlexander Barkov <bar@mariadb.com>2023-05-03 17:28:12 +0400
commit01ea779149a32f0dfd6fe8ea52c7ba51a69e1016 (patch)
treed4b9b34ab15ade535208814e38944310f60cc057
parent9b6f87b62afb32ea238e39b362b8e761f53e541c (diff)
downloadmariadb-git-01ea779149a32f0dfd6fe8ea52c7ba51a69e1016.tar.gz
MDEV-31174 New class Native_functions_hash
-rw-r--r--plugin/versioning/versioning.cc6
-rw-r--r--sql/item_create.cc78
-rw-r--r--sql/item_create.h57
-rw-r--r--sql/sql_lex.cc2
-rw-r--r--sql/sql_show.cc3
-rw-r--r--sql/sql_yacc.yy2
-rw-r--r--sql/sql_yacc_ora.yy2
7 files changed, 99 insertions, 51 deletions
diff --git a/plugin/versioning/versioning.cc b/plugin/versioning/versioning.cc
index e150e4e8465..8b9fb74e77b 100644
--- a/plugin/versioning/versioning.cc
+++ b/plugin/versioning/versioning.cc
@@ -140,7 +140,7 @@ Create_func_trt_trx_sees<X> Create_func_trt_trx_sees<X>::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_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");
// 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)
{
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)))
{
DBUG_ENTER("versioning_plugin_deinit");
- (void) item_create_remove(func_array);
+ (void) native_functions_hash.remove(func_array_vers);
DBUG_RETURN(0);
}
diff --git a/sql/item_create.cc b/sql/item_create.cc
index 616ba3a641a..a95d2ae4f9a 100644
--- a/sql/item_create.cc
+++ b/sql/item_create.cc
@@ -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
*/
-Native_func_registry func_array[] =
+const Native_func_registry func_array[] =
{
{ { STRING_WITH_LEN("ABS") }, BUILDER(Create_func_abs)},
{ { STRING_WITH_LEN("ACOS") }, BUILDER(Create_func_acos)},
@@ -7609,9 +7609,10 @@ Native_func_registry func_array[] =
{ {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*
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)
*/
-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,
- array_elements(func_array),
+ (ulong) count,
0,
0,
(my_hash_get_key) get_native_fct_hash_key,
NULL, /* Nothing to free */
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[])
+
+bool Native_functions_hash::append(const Native_func_registry array[])
{
- Native_func_registry *func;
+ const Native_func_registry *func;
- DBUG_ENTER("item_create_append");
+ DBUG_ENTER("Native_functions_hash::append");
for (func= array; func->builder != NULL; func++)
{
- if (my_hash_insert(& native_functions_hash, (uchar*) func))
- DBUG_RETURN(1);
+ if (my_hash_insert(this, (uchar*) func))
+ DBUG_RETURN(true);
}
#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",
func->name.str, (uint) func->name.length));
}
#endif
- DBUG_RETURN(0);
+ DBUG_RETURN(false);
}
-int item_create_remove(Native_func_registry array[])
+
+bool Native_functions_hash::remove(const Native_func_registry array[])
{
- Native_func_registry *func;
+ const Native_func_registry *func;
- DBUG_ENTER("item_create_remove");
+ DBUG_ENTER("Native_functions_hash::remove");
for (func= array; func->builder != NULL; func++)
{
- if (my_hash_delete(& native_functions_hash, (uchar*) func))
- DBUG_RETURN(1);
+ if (my_hash_delete(this, (uchar*) func))
+ DBUG_RETURN(true);
}
- DBUG_RETURN(0);
+ DBUG_RETURN(false);
}
+
/*
Empty the hash table for native functions.
Note: this code is not thread safe, and is intended to be used at server
shutdown only (after thread requests have been executed).
*/
-void item_create_cleanup()
+void Native_functions_hash::cleanup()
{
- DBUG_ENTER("item_create_cleanup");
- my_hash_free(& native_functions_hash);
+ DBUG_ENTER("Native_functions_hash::cleanup");
+ my_hash_free(this);
DBUG_VOID_RETURN;
}
+
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;
Create_func *builder= NULL;
/* Thread safe */
- func= (Native_func_registry*) my_hash_search(&native_functions_hash,
- (uchar*) name->str,
- name->length);
+ func= (Native_func_registry*) my_hash_search(this,
+ (uchar*) name.str,
+ name.length);
if (func)
{
@@ -7716,6 +7721,19 @@ find_native_function_builder(THD *thd, const LEX_CSTRING *name)
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 *
find_qualified_function_builder(THD *thd)
{
diff --git a/sql/item_create.h b/sql/item_create.h
index 8456644ff6d..60a757b95d8 100644
--- a/sql/item_create.h
+++ b/sql/item_create.h
@@ -145,16 +145,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.
@param thd The current thread
@return A function builder for qualified functions
@@ -200,9 +190,52 @@ struct Native_func_registry
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_append(Native_func_registry array[]);
-int item_create_remove(Native_func_registry array[]);
void item_create_cleanup();
Item *create_func_dyncol_create(THD *thd, List<DYNCALL_CREATE_DEF> &list);
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index f77b98f04f1..019377061a0 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -943,7 +943,7 @@ bool is_lex_native_function(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;
if (is_lex_native_function(name))
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 1ad20ac7593..a621c1de29a 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -76,9 +76,6 @@ extern size_t symbols_length;
extern SYMBOL sql_functions[];
extern size_t sql_functions_length;
-extern Native_func_registry func_array[];
-extern size_t func_array_length;
-
enum enum_i_s_events_fields
{
ISE_EVENT_CATALOG= 0,
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index cf3927ac30c..cdc04d93708 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -11485,7 +11485,7 @@ function_call_generic:
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)
{
item= builder->create_func(thd, &$1, $4);
diff --git a/sql/sql_yacc_ora.yy b/sql/sql_yacc_ora.yy
index 87f71d8332b..5b734a27f8c 100644
--- a/sql/sql_yacc_ora.yy
+++ b/sql/sql_yacc_ora.yy
@@ -11600,7 +11600,7 @@ function_call_generic:
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)
{
item= builder->create_func(thd, &$1, $4);