Syntax:
CREATE [AGGREGATE] FUNCTION function_name
    RETURNS {STRING|INTEGER|REAL|DECIMAL}
    SONAME shared_library_name

This statement loads the loadable function named function_name. (CREATE
FUNCTION is also used to created stored functions; see [HELP CREATE
PROCEDURE].)

A loadable function is a way to extend MySQL with a new function that
works like a native (built-in) MySQL function such as ABS() or
CONCAT(). See Adding a Loadable Function
(https://dev.mysql.com/doc/extending-mysql/5.7/en/adding-loadable-funct
ion.html).

function_name is the name that should be used in SQL statements to
invoke the function. The RETURNS clause indicates the type of the
function's return value. DECIMAL is a legal value after RETURNS, but
currently DECIMAL functions return string values and should be written
like STRING functions.

The AGGREGATE keyword, if given, signifies that the function is an
aggregate (group) function. An aggregate function works exactly like a
native MySQL aggregate function such as SUM() or COUNT().

shared_library_name is the base name of the shared library file
containing the code that implements the function. The file must be
located in the plugin directory. This directory is given by the value
of the plugin_dir system variable. For more information, see
https://dev.mysql.com/doc/refman/5.7/en/function-loading.html.

CREATE FUNCTION requires the INSERT privilege for the mysql system
database because it adds a row to the mysql.func system table to
register the function.

During the normal startup sequence, the server loads functions
registered in the mysql.func table. If the server is started with the
--skip-grant-tables option, functions registered in the table are not
loaded and are unavailable.

URL: https://dev.mysql.com/doc/refman/5.7/en/create-function-loadable.html

