#### 13.7.4.1 CREATE FUNCTION Statement for Loadable Functions

[]()[]()[]()[]()[]()

```
CREATE [AGGREGATE] FUNCTION [IF NOT EXISTS] 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 [Section 13.1.17, “CREATE PROCEDURE and CREATE FUNCTION Statements”](create-procedure.html).)

 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()`](mathematical-functions.html#function_abs) or [`CONCAT()`](string-functions.html#function_concat). See [Adding a Loadable Function](https://dev.mysql.com/doc/extending-mysql/8.0/en/adding-loadable-function.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.

`IF NOT EXISTS` prevents an error from occurring if there already exists a loadable function with the same name. It does *not* prevent an error from occurring if there already exists a built-in function having the same name. `IF NOT EXISTS` is supported for `CREATE FUNCTION` statements beginning with MySQL 8.0.29. See also [Function Name Resolution](function-resolution.html#function-name-resolution).

 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()`](aggregate-functions.html#function_sum) or [`COUNT()`](aggregate-functions.html#function_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`](server-system-variables.html#sysvar_plugin_dir) system variable. For more information, see [Section 5.7.1, “Installing and Uninstalling Loadable Functions”](function-loading.html).

[`CREATE FUNCTION`](create-function-loadable.html) requires the [`INSERT`](privileges-provided.html#priv_insert) privilege for the `mysql` system schema because it adds a row to the `mysql.func` system table to register the function.

[`CREATE FUNCTION`](create-function-loadable.html) also adds the function to the Performance Schema [`user_defined_functions`](performance-schema-user-defined-functions-table.html) table that provides runtime information about installed loadable functions. See [Section 27.12.21.8, “The user\_defined\_functions Table”](performance-schema-user-defined-functions-table.html).

Note

 Like the `mysql.func` system table, the Performance Schema [`user_defined_functions`](performance-schema-user-defined-functions-table.html) table lists loadable functions installed using [`CREATE FUNCTION`](create-function-loadable.html). Unlike the `mysql.func` table, the [`user_defined_functions`](performance-schema-user-defined-functions-table.html) table also lists loadable functions installed automatically by server components or plugins. This difference makes [`user_defined_functions`](performance-schema-user-defined-functions-table.html) preferable to `mysql.func` for checking which loadable functions are installed.

 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`](server-options.html#option_mysqld_skip-grant-tables) option, functions registered in the table are not loaded and are unavailable.

Note

 To upgrade the shared library associated with a loadable function, issue a [`DROP FUNCTION`](drop-function-loadable.html) statement, upgrade the shared library, and then issue a [`CREATE FUNCTION`](create-function-loadable.html) statement. If you upgrade the shared library first and then use [`DROP FUNCTION`](drop-function-loadable.html), the server may unexpectedly shut down.

