SlideShare a Scribd company logo
Extending MARIADB
with user-defined
functions
Andrew Hutchings & Sylvain Arbaudie
MariaDB Corporation
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
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
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
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
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
Installing & Using
UDFs
Installing a UDF
CREATE [OR REPLACE] [AGGREGATE] FUNCTION [IF NOT EXISTS]
function_name
RETURNS {STRING|INTEGER|REAL|DECIMAL}
SONAME shared_library_name
Viewing Installed Plugins
MariaDB [test]> select * from mysql.func;
+-----------------------------+-----+------------------+-----------+
| name | ret | dl | type |
+-----------------------------+-----+------------------+-----------+
| calgetstats | 0 | libcalmysql.so | function |
| calsettrace | 2 | libcalmysql.so | function |
| calsetparms | 0 | libcalmysql.so | function |
| calflushcache | 2 | libcalmysql.so | function |
| calgettrace | 0 | libcalmysql.so | function |
| calgetversion | 0 | libcalmysql.so | function |
| calonlinealter | 2 | libcalmysql.so | function |
| calviewtablelock | 0 | libcalmysql.so | function |
| calcleartablelock | 0 | libcalmysql.so | function |
| caldisablepartitions | 0 | libcalmysql.so | function |
...
Calling Functions
MariaDB [test]> select my_example(my_ints) from my_tableG
+---------------------+
| my_example(my_ints) |
+---------------------+
| 99 |
| 27 |
+---------------------+
2 rows in set (0.00 sec)
Calling Functions
MariaDB [test]> select my_aggregate_example(my_ints) from my_tableG
+-------------------------------+
| my_aggregate_example(my_ints) |
+-------------------------------+
| 126 |
+-------------------------------+
1 row in set (0.00 sec)
Defining a UDF
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)
Execution Flow Chart
Start
name_init()
More
rows
?
name()
name_deinit()
End
Yes
No
Normal
Start
name_init()
More
groups
?
name_clear()
name_deinit()
End
Yes
No
Aggregate
More
rows
?
name_add()
name()
Yes
No
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
Deinit Call
void name_deinit(UDF_INIT *initid)
● initid - The metadata defined in the init call (contains an arbitrary pointer which
deinit can free)
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
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
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
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.
Deploying a UDF live
Need
Match hotel names in arabic and asian area from different sources
like : Riyad Marrakesch, Riad Marrakech and/or Ryad Marakesh
Stored procedure
Stored procedure works great but was too slow on MariaDB 10.0.12 : ~1 second/call
Prerequisites
GCC
MariaDB-devel packages
Basic C knowledge
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
1st step : Source code adaptation
Function headers :
my_bool levenshteinratio_init(UDF_INIT *initid, UDF_ARGS *args, char *message);
void levenshteinratio_deinit(UDF_INIT *initid);
double levenshteinratio(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error);
1st step : Source code adaptation
Functions code :
my_bool levenshteinratio_init(UDF_INIT *initid, UDF_ARGS *args, char *message) {
if ((args->arg_count != 2) ||
(args->arg_type[0] != STRING_RESULT || args->arg_type[1] != STRING_RESULT)) {
strcpy(message, "Function requires 2 arguments, (string, string)");
return 1;
}
1st step : Source code adaptation
Functions code :
//matrix for levenshtein calculations of size n+1 x m+1 (+1 for base values)
int *d = (int *) malloc(sizeof(int) * (args->lengths[0] + 1) * (args->lengths[1] + 1));
if (d == NULL) {
strcpy(message, "Failed to allocate memory");
return 1;
}
1st step : Source code adaptation
Functions code :
initid->ptr = (char*) d;
initid->max_length = LEVENSHTEIN_MAX;
initid->maybe_null = 0; //doesn't return null
return 0;
}
1st step : Source code adaptation
Functions code :
void levenshteinUDF_deinit(UDF_INIT *initid) {
if (initid->ptr != NULL) {
free(initid->ptr);
}
}
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
3rd step : Creating the function
CREATE FUNCTION levesnhteinratio RETURNS REAL SONAME ‘levenshtein.so’;
THANK YOU!

More Related Content

What's hot (20)

PDF
Learn O11y from Grafana ecosystem.
HungWei Chiu
 
PDF
Performance Monitoring: Understanding Your Scylla Cluster
ScyllaDB
 
PDF
Continuous Go Profiling & Observability
ScyllaDB
 
PDF
Apache Flink internals
Kostas Tzoumas
 
PPTX
Introduction to Kamailio (TADSummit 2020 Asia)
Fred Posner
 
PPTX
Révolution eBPF - un noyau dynamique
Raphaël PINSON
 
PDF
MMUG18 - MySQL Failover and Orchestrator
Simon J Mudd
 
PDF
Hyperspace for Delta Lake
Databricks
 
PPTX
What every data programmer needs to know about disks
iammutex
 
PDF
Apache Spark Overview
Vadim Y. Bichutskiy
 
PDF
Building a Data Pipeline from Scratch - Joe Crobak
Hakka Labs
 
PDF
Iceberg: A modern table format for big data (Strata NY 2018)
Ryan Blue
 
PDF
Designing Event-Driven Applications with Apache NiFi, Apache Flink, Apache Sp...
Timothy Spann
 
PPTX
HDFS Tiered Storage: Mounting Object Stores in HDFS
DataWorks Summit/Hadoop Summit
 
PPTX
Graylog Engineering - Design Your Architecture
Graylog
 
PDF
VictoriaMetrics: Welcome to the Virtual Meet Up March 2023
VictoriaMetrics
 
PDF
Cost-Based Optimizer Framework for Spark SQL: Spark Summit East talk by Ron H...
Spark Summit
 
PDF
Enabling Vectorized Engine in Apache Spark
Kazuaki Ishizaki
 
PDF
Graylog for open stack 3 steps to know why
Vietnam Open Infrastructure User Group
 
PPTX
History of intel microprocessors
SANJAYVERMA297
 
Learn O11y from Grafana ecosystem.
HungWei Chiu
 
Performance Monitoring: Understanding Your Scylla Cluster
ScyllaDB
 
Continuous Go Profiling & Observability
ScyllaDB
 
Apache Flink internals
Kostas Tzoumas
 
Introduction to Kamailio (TADSummit 2020 Asia)
Fred Posner
 
Révolution eBPF - un noyau dynamique
Raphaël PINSON
 
MMUG18 - MySQL Failover and Orchestrator
Simon J Mudd
 
Hyperspace for Delta Lake
Databricks
 
What every data programmer needs to know about disks
iammutex
 
Apache Spark Overview
Vadim Y. Bichutskiy
 
Building a Data Pipeline from Scratch - Joe Crobak
Hakka Labs
 
Iceberg: A modern table format for big data (Strata NY 2018)
Ryan Blue
 
Designing Event-Driven Applications with Apache NiFi, Apache Flink, Apache Sp...
Timothy Spann
 
HDFS Tiered Storage: Mounting Object Stores in HDFS
DataWorks Summit/Hadoop Summit
 
Graylog Engineering - Design Your Architecture
Graylog
 
VictoriaMetrics: Welcome to the Virtual Meet Up March 2023
VictoriaMetrics
 
Cost-Based Optimizer Framework for Spark SQL: Spark Summit East talk by Ron H...
Spark Summit
 
Enabling Vectorized Engine in Apache Spark
Kazuaki Ishizaki
 
Graylog for open stack 3 steps to know why
Vietnam Open Infrastructure User Group
 
History of intel microprocessors
SANJAYVERMA297
 

Similar to Extending MariaDB with user-defined functions (20)

ODP
Writing MySQL UDFs
Roland Bouman
 
PDF
Median-udf in mysql : Step By Step Installation And Problem Fixes For Install...
theGhost_k8
 
PPTX
ScyllaDB's Avi Kivity on UDF, UDA, and the Future
ScyllaDB
 
PPTX
Applying linear regression and predictive analytics
MariaDB plc
 
PDF
MariaDB stored procedures and why they should be improved
Federico Razzoli
 
PDF
Cassandra UDF and Materialized Views
Duyhai Doan
 
PDF
M|18 User Defined Functions
MariaDB plc
 
PDF
Modern solutions for modern database load: improvements in the latest MariaDB...
Sveta Smirnova
 
PDF
User defined-functions-cassandra-summit-eu-2014
Robert Stupp
 
PPTX
The Other HPC: High Productivity Computing in Polystore Environments
University of Washington
 
PPTX
How to add stuff to MySQL
Georgi Kodinov
 
PDF
Advanced MariaDB features that developers love.pdf
Federico Razzoli
 
PDF
Writing MySQL User-defined Functions in JavaScript
Roland Bouman
 
PDF
More on bpftrace for MariaDB DBAs and Developers - FOSDEM 2022 MariaDB Devroom
Valeriy Kravchuk
 
PDF
Dynamic tracing of MariaDB on Linux - problems and solutions (MariaDB Server ...
Valeriy Kravchuk
 
PDF
External Language Stored Procedures for MySQL
Antony T Curtis
 
PDF
MariaDB workshop
Alex Chistyakov
 
PDF
Optimizing Apache Spark UDFs
Databricks
 
PDF
M|18 Understanding the Architecture of MariaDB ColumnStore
MariaDB plc
 
PPTX
User defined Function in SQL
baabtra.com - No. 1 supplier of quality freshers
 
Writing MySQL UDFs
Roland Bouman
 
Median-udf in mysql : Step By Step Installation And Problem Fixes For Install...
theGhost_k8
 
ScyllaDB's Avi Kivity on UDF, UDA, and the Future
ScyllaDB
 
Applying linear regression and predictive analytics
MariaDB plc
 
MariaDB stored procedures and why they should be improved
Federico Razzoli
 
Cassandra UDF and Materialized Views
Duyhai Doan
 
M|18 User Defined Functions
MariaDB plc
 
Modern solutions for modern database load: improvements in the latest MariaDB...
Sveta Smirnova
 
User defined-functions-cassandra-summit-eu-2014
Robert Stupp
 
The Other HPC: High Productivity Computing in Polystore Environments
University of Washington
 
How to add stuff to MySQL
Georgi Kodinov
 
Advanced MariaDB features that developers love.pdf
Federico Razzoli
 
Writing MySQL User-defined Functions in JavaScript
Roland Bouman
 
More on bpftrace for MariaDB DBAs and Developers - FOSDEM 2022 MariaDB Devroom
Valeriy Kravchuk
 
Dynamic tracing of MariaDB on Linux - problems and solutions (MariaDB Server ...
Valeriy Kravchuk
 
External Language Stored Procedures for MySQL
Antony T Curtis
 
MariaDB workshop
Alex Chistyakov
 
Optimizing Apache Spark UDFs
Databricks
 
M|18 Understanding the Architecture of MariaDB ColumnStore
MariaDB plc
 
Ad

More from MariaDB plc (20)

PDF
MariaDB Berlin Roadshow Slides - 8 April 2025
MariaDB plc
 
PDF
MariaDB München Roadshow - 24 September, 2024
MariaDB plc
 
PDF
MariaDB Paris Roadshow - 19 September 2024
MariaDB plc
 
PDF
MariaDB Amsterdam Roadshow: 19 September, 2024
MariaDB plc
 
PDF
MariaDB Paris Workshop 2023 - MaxScale 23.02.x
MariaDB plc
 
PDF
MariaDB Paris Workshop 2023 - Newpharma
MariaDB plc
 
PDF
MariaDB Paris Workshop 2023 - Cloud
MariaDB plc
 
PDF
MariaDB Paris Workshop 2023 - MariaDB Enterprise
MariaDB plc
 
PDF
MariaDB Paris Workshop 2023 - Performance Optimization
MariaDB plc
 
PDF
MariaDB Paris Workshop 2023 - MaxScale
MariaDB plc
 
PDF
MariaDB Paris Workshop 2023 - novadys presentation
MariaDB plc
 
PDF
MariaDB Paris Workshop 2023 - DARVA presentation
MariaDB plc
 
PDF
MariaDB Tech und Business Update Hamburg 2023 - MariaDB Enterprise Server
MariaDB plc
 
PDF
MariaDB SkySQL Autonome Skalierung, Observability, Cloud-Backup
MariaDB plc
 
PDF
Einführung : MariaDB Tech und Business Update Hamburg 2023
MariaDB plc
 
PDF
Hochverfügbarkeitslösungen mit MariaDB
MariaDB plc
 
PDF
Die Neuheiten in MariaDB Enterprise Server
MariaDB plc
 
PDF
Global Data Replication with Galera for Ansell Guardian®
MariaDB plc
 
PDF
Introducing workload analysis
MariaDB plc
 
PDF
Under the hood: SkySQL monitoring
MariaDB plc
 
MariaDB Berlin Roadshow Slides - 8 April 2025
MariaDB plc
 
MariaDB München Roadshow - 24 September, 2024
MariaDB plc
 
MariaDB Paris Roadshow - 19 September 2024
MariaDB plc
 
MariaDB Amsterdam Roadshow: 19 September, 2024
MariaDB plc
 
MariaDB Paris Workshop 2023 - MaxScale 23.02.x
MariaDB plc
 
MariaDB Paris Workshop 2023 - Newpharma
MariaDB plc
 
MariaDB Paris Workshop 2023 - Cloud
MariaDB plc
 
MariaDB Paris Workshop 2023 - MariaDB Enterprise
MariaDB plc
 
MariaDB Paris Workshop 2023 - Performance Optimization
MariaDB plc
 
MariaDB Paris Workshop 2023 - MaxScale
MariaDB plc
 
MariaDB Paris Workshop 2023 - novadys presentation
MariaDB plc
 
MariaDB Paris Workshop 2023 - DARVA presentation
MariaDB plc
 
MariaDB Tech und Business Update Hamburg 2023 - MariaDB Enterprise Server
MariaDB plc
 
MariaDB SkySQL Autonome Skalierung, Observability, Cloud-Backup
MariaDB plc
 
Einführung : MariaDB Tech und Business Update Hamburg 2023
MariaDB plc
 
Hochverfügbarkeitslösungen mit MariaDB
MariaDB plc
 
Die Neuheiten in MariaDB Enterprise Server
MariaDB plc
 
Global Data Replication with Galera for Ansell Guardian®
MariaDB plc
 
Introducing workload analysis
MariaDB plc
 
Under the hood: SkySQL monitoring
MariaDB plc
 
Ad

Recently uploaded (20)

PDF
Download Canva Pro 2025 PC Crack Full Latest Version
bashirkhan333g
 
PPTX
Agentic Automation Journey Session 1/5: Context Grounding and Autopilot for E...
klpathrudu
 
PDF
Wondershare PDFelement Pro Crack for MacOS New Version Latest 2025
bashirkhan333g
 
PPTX
AEM User Group: India Chapter Kickoff Meeting
jennaf3
 
PPTX
Tally_Basic_Operations_Presentation.pptx
AditiBansal54083
 
PDF
MiniTool Partition Wizard 12.8 Crack License Key LATEST
hashhshs786
 
PPTX
OpenChain @ OSS NA - In From the Cold: Open Source as Part of Mainstream Soft...
Shane Coughlan
 
PDF
vMix Pro 28.0.0.42 Download vMix Registration key Bundle
kulindacore
 
PDF
Build It, Buy It, or Already Got It? Make Smarter Martech Decisions
bbedford2
 
PDF
Top Agile Project Management Tools for Teams in 2025
Orangescrum
 
PDF
Unlock Efficiency with Insurance Policy Administration Systems
Insurance Tech Services
 
PPTX
Agentic Automation: Build & Deploy Your First UiPath Agent
klpathrudu
 
PDF
[Solution] Why Choose the VeryPDF DRM Protector Custom-Built Solution for You...
Lingwen1998
 
PDF
AI + DevOps = Smart Automation with devseccops.ai.pdf
Devseccops.ai
 
PPTX
Transforming Mining & Engineering Operations with Odoo ERP | Streamline Proje...
SatishKumar2651
 
PPTX
Home Care Tools: Benefits, features and more
Third Rock Techkno
 
PDF
The 5 Reasons for IT Maintenance - Arna Softech
Arna Softech
 
PDF
Open Chain Q2 Steering Committee Meeting - 2025-06-25
Shane Coughlan
 
PPTX
Empowering Asian Contributions: The Rise of Regional User Groups in Open Sour...
Shane Coughlan
 
PDF
Odoo CRM vs Zoho CRM: Honest Comparison 2025
Odiware Technologies Private Limited
 
Download Canva Pro 2025 PC Crack Full Latest Version
bashirkhan333g
 
Agentic Automation Journey Session 1/5: Context Grounding and Autopilot for E...
klpathrudu
 
Wondershare PDFelement Pro Crack for MacOS New Version Latest 2025
bashirkhan333g
 
AEM User Group: India Chapter Kickoff Meeting
jennaf3
 
Tally_Basic_Operations_Presentation.pptx
AditiBansal54083
 
MiniTool Partition Wizard 12.8 Crack License Key LATEST
hashhshs786
 
OpenChain @ OSS NA - In From the Cold: Open Source as Part of Mainstream Soft...
Shane Coughlan
 
vMix Pro 28.0.0.42 Download vMix Registration key Bundle
kulindacore
 
Build It, Buy It, or Already Got It? Make Smarter Martech Decisions
bbedford2
 
Top Agile Project Management Tools for Teams in 2025
Orangescrum
 
Unlock Efficiency with Insurance Policy Administration Systems
Insurance Tech Services
 
Agentic Automation: Build & Deploy Your First UiPath Agent
klpathrudu
 
[Solution] Why Choose the VeryPDF DRM Protector Custom-Built Solution for You...
Lingwen1998
 
AI + DevOps = Smart Automation with devseccops.ai.pdf
Devseccops.ai
 
Transforming Mining & Engineering Operations with Odoo ERP | Streamline Proje...
SatishKumar2651
 
Home Care Tools: Benefits, features and more
Third Rock Techkno
 
The 5 Reasons for IT Maintenance - Arna Softech
Arna Softech
 
Open Chain Q2 Steering Committee Meeting - 2025-06-25
Shane Coughlan
 
Empowering Asian Contributions: The Rise of Regional User Groups in Open Sour...
Shane Coughlan
 
Odoo CRM vs Zoho CRM: Honest Comparison 2025
Odiware Technologies Private Limited
 

Extending MariaDB with user-defined functions

  • 1. Extending MARIADB with user-defined functions Andrew Hutchings & Sylvain Arbaudie MariaDB Corporation
  • 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: [email protected]
  • 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: [email protected]
  • 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
  • 8. Installing a UDF CREATE [OR REPLACE] [AGGREGATE] FUNCTION [IF NOT EXISTS] function_name RETURNS {STRING|INTEGER|REAL|DECIMAL} SONAME shared_library_name
  • 9. Viewing Installed Plugins MariaDB [test]> select * from mysql.func; +-----------------------------+-----+------------------+-----------+ | name | ret | dl | type | +-----------------------------+-----+------------------+-----------+ | calgetstats | 0 | libcalmysql.so | function | | calsettrace | 2 | libcalmysql.so | function | | calsetparms | 0 | libcalmysql.so | function | | calflushcache | 2 | libcalmysql.so | function | | calgettrace | 0 | libcalmysql.so | function | | calgetversion | 0 | libcalmysql.so | function | | calonlinealter | 2 | libcalmysql.so | function | | calviewtablelock | 0 | libcalmysql.so | function | | calcleartablelock | 0 | libcalmysql.so | function | | caldisablepartitions | 0 | libcalmysql.so | function | ...
  • 10. Calling Functions MariaDB [test]> select my_example(my_ints) from my_tableG +---------------------+ | my_example(my_ints) | +---------------------+ | 99 | | 27 | +---------------------+ 2 rows in set (0.00 sec)
  • 11. Calling Functions MariaDB [test]> select my_aggregate_example(my_ints) from my_tableG +-------------------------------+ | my_aggregate_example(my_ints) | +-------------------------------+ | 126 | +-------------------------------+ 1 row in set (0.00 sec)
  • 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.
  • 22. Need Match hotel names in arabic and asian area from different sources like : Riyad Marrakesch, Riad Marrakech and/or Ryad Marakesh
  • 23. Stored procedure Stored procedure works great but was too slow on MariaDB 10.0.12 : ~1 second/call
  • 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
  • 26. 1st step : Source code adaptation Function headers : my_bool levenshteinratio_init(UDF_INIT *initid, UDF_ARGS *args, char *message); void levenshteinratio_deinit(UDF_INIT *initid); double levenshteinratio(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error);
  • 27. 1st step : Source code adaptation Functions code : my_bool levenshteinratio_init(UDF_INIT *initid, UDF_ARGS *args, char *message) { if ((args->arg_count != 2) || (args->arg_type[0] != STRING_RESULT || args->arg_type[1] != STRING_RESULT)) { strcpy(message, "Function requires 2 arguments, (string, string)"); return 1; }
  • 28. 1st step : Source code adaptation Functions code : //matrix for levenshtein calculations of size n+1 x m+1 (+1 for base values) int *d = (int *) malloc(sizeof(int) * (args->lengths[0] + 1) * (args->lengths[1] + 1)); if (d == NULL) { strcpy(message, "Failed to allocate memory"); return 1; }
  • 29. 1st step : Source code adaptation Functions code : initid->ptr = (char*) d; initid->max_length = LEVENSHTEIN_MAX; initid->maybe_null = 0; //doesn't return null return 0; }
  • 30. 1st step : Source code adaptation Functions code : void levenshteinUDF_deinit(UDF_INIT *initid) { if (initid->ptr != NULL) { free(initid->ptr); } }
  • 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’;