Falls die MonetDB mit einer Funktion erweitert werden soll, die nicht aus den vorhandenen Funktionen hergeleitet werden kann, ist es notwendig, eine eigene UDF (User Defined Function) zu implementieren. Diese Seite baut auf den Informationen aus dem [[http://www.monetdb.org/Documentation/Cookbooks/SQLrecipes/UserDefinedFunction|Kochbuch]] auf.
Als Beispiel dient die Funktion bitcount. Diese ist wie folgt definiert:
unsigned int bitcount(unsigned int value)
Es sei darauf hingewiesen, dass die Funktion nur auf 32-Bit Werten definiert ist.
* Runterladen des Quellcodes von der [[http://www.monetdb.org/downloads/sources/Latest/MonetDB-11.15.17.zip|MonetDB-Webseite]]. Hinweis, dieser muss kompatibel mit der Version auf dem Server sein. Die magischen Schritte ''%%configure%%'' und ''%%make%%'' ausführen.
* Das Gerüst zum Erweitern der Funktionen findet sich in folgendem Verzeichnis: ''%%MonetDB-11.15.17/sql/backends/monet5/UDF%%''. Die Erweiterung besteht aus dem eigentlichen C-Code und einer Beschreibung der Erweiterung. Die Beschreibung wird in der ''%%udf.mal%%'' hinterlegt. Der C-Code in der Datei ''%%udf.c%%''
* Bauen der Erweiterung mittels eines einfachen ''%%make%%''. Die Erweiterungs-Bibliothek befindet sich dann in ''%%UDF/.libs/lib_udf.so%%''. Die Erweiterung besteht aus der udf.mal und der SO-Datei. Im Ideallfall könnte die Datei mittels ''%%make%%'' und dem Werkzeug ''%%bootstrap%%'' installiert werden, aber kopieren die Dateien direkt: ''%%cp -i udf.mal /usr/lib/monetdb5%%'' und ''%%cp -i .libs/lib_udf.so /usr/lib/monetdb5/%%''. Die alten Versionen werden dann überschrieben.
* Abschließend gilt es noch, die neue Funktion zu registrieren: ''%%create function bitcount(src int) returns int external name udf.bitcount;%%'' und den Server neuzustarten.
Test im mclient:
''%%$ select bitcount(7);%%''
sollte 3 zurückliefern. Es kann wie gewohnt auch mit der Funktion gerechnet werden:
''%%$ select bitcount(7)+1;%%''
sollte 4 zurückliefern.
Hinweis: Die erste Version ist langsamer, als eine direkte Implementierung in SQL. Hier gilt es noch zu evaluieren, wo der Bottleneck ist. Weiterhin führt der Datentyp 'wrd' scheinbar zu einem Überlauf.
Zeiten:
* in SQL: 500001 tuples 72.739ms
* als UDF: 500001 tuples 285.615ms