The document discusses user-defined functions (UDFs) in MariaDB. It provides background on UDFs, including their history and pros/cons. It then covers how to install, view, and call UDFs. The bulk of the document explains how to define a UDF in C, including the required API calls for initialization, execution, aggregation, and cleanup. It recommends a book for further reading on developing UDFs and other MariaDB plugins. Towards the end, it briefly discusses deploying a live UDF to solve the problem of matching hotel names from different sources.
2. About Andrew (LinuxJedi)
● Andrew Hutchings, aka “LinuxJedi”
● Lead Software Engineer for MariaDB’s ColumnStore
● Previous worked for:
○ NGINX - Senior Developer Advocate / Technical Product
Manager
○ HP - Principal Software Engineer (HP Cloud / ATG)
○ SkySQL - Senior Sustaining Engineer
○ Rackspace - Senior Software Engineer
○ Sun/Oracle - MySQL Senior Support Engineer
● Co-author of MySQL 5.1 Plugin Development
● IRC/Twitter: LinuxJedi
● EMail: linuxjedi@mariadb.com
3. About Sylvain
● Sylvain Arbaudie
● Principal consultant, senior trainer for MariaDB EMEA
● Previous worked for:
○ Airial conseil - Oracle Application performance
consultant
○ Karavel - MySQL/MariaDB/Oracle DBA
● EMail: sylvain.arbaudie@mariadb.com
4. What is a UDF?
● A plugin written in C
● Provides a new function call for SQL queries, for example:
SELECT my_function(b) FROM t1 WHERE a = 1000;
● Come in regular function or aggregate function form
● Very simple API
5. History of UDFs
● Appeared in MySQL 3.21.24
○ Roughly 21 years ago
○ Older that InnoDB or even transactions in MySQL
● External contribution by Alexis Mikhailov
● Aggregate functions came soon after (by version 3.23)
● A precursor to MySQL and MariaDB plugin APIs
● Not much has changed since
6. Pros and Cons
● Very easy to develop with a little
C knowledge
● Very rapid execution time
Pro
● If a UDF crashes it takes the
whole MariaDB server out with it
● Usually needs re-compiling with
every MariaDB point release
Con
13. API Calls
● name_init() - initialize at start of query
● name_deinit() - clean up at end of query
● name() - called on every row (or every group for aggregate)
● name_add() - called on every row of a group (Aggregate)
● name_clear() - called before the first row of a group (Aggregate)
● name_remove() - removes a row from a group (Aggregate Window Functions,
10.4 onwards)
15. Init Call
my_bool name_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
● initid - Supplies MariaDB with the return metadata
● args - MariaDB provides the argument metadata
● message - A pointer to add an error message, max MYSQL_ERRMSG_SIZE
bytes
● return - 0 for success, 1 for error
16. Deinit Call
void name_deinit(UDF_INIT *initid)
● initid - The metadata defined in the init call (contains an arbitrary pointer which
deinit can free)
17. Function Call
char *name(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long *length,
char *is_null, char *error)
long long name(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error)
double name(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error)
● initid - The init-time metadata object
● args - The input argument
● result - An optional pre-allocated 768 byte buffer to use
● length - The length of the result set
● is_null - Set to 1 if the result is NULL
● error - Set to 1 if an error occurred
● return - The return value for this row
18. Add / Remove Call
void name_add(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error)
void name_remove(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error)
● initid - The init-time metadata object
● args - The input argument
● is_null - Set to 1 if the result is NULL
● error - Set to 1 if an error occurred
19. Clear Call
void name_clear(UDF_INIT *initid, char *is_null, char *error)
● initid - The init-time metadata object
● is_null - Set to 1 if the result is NULL
● error - Set to 1 if an error occurred
20. Further Reading
● Contains chapters on how to write UDF
plugins as well as other plugins for MySQL
and MariaDB.
● Both the authors work for MariaDB and are
here this week. Come find us for more
information.
25. Finding the right tool : UDF
Since performances are not good enough, what other tool do we have to extend
MariaDB’s functionalities ?
Answer : User-Defined Functions
Example code on my personal github ad hoc repo :
https://github.com/SylvainA77/levenshtein-udf
31. 2nd step : Compiling
gcc -o /lib/levenshtein.so levenshtein.c `mysql_config --cflags` -shared -fPIC
Then you have to link the library into MariaDB plugin directory :
ln -s /lib/levenshtein.so /usr/lib64/mysql/plugin/
chmod 777 /lib/levenshtein.so
32. 3rd step : Creating the function
CREATE FUNCTION levesnhteinratio RETURNS REAL SONAME ‘levenshtein.so’;