Для того чтобы работал механизм UDF, функции должны быть написаны на C или на C++, а используемая операционная система должна поддерживать динамическую загрузку. В поставку исходного кода входит файл `sql/udf_example.cc', в котором определены пять новых функций. К этому файлу следует обращаться, если нужно узнать, как работает соглашение о вызовах UDF.
Чтобы mysqld имел возможность использовать UDF-функции, необходимо
сконфигурировать MySQL с --with-mysqld-ldflags=-rdynamic. Причина здесь в
том, что на многих платформах (включая Linux) можно загружать динамическую
Для каждой функции, которую предполагается использовать в командах SQL, следует определять соответствующие функции C (или C++). В дальнейшем в качестве имени для примера функции мы будем использовать имя xxx. Чтобы различать применение в SQL и C/C++, для вызова SQL-функции мы будем использовать обозначение XXX() (прописными), а xxx() (строчными) - для вызова функции C/C++.
Для реализации интерфейса для XXX() требуются следующие функции C/C++:
Тип SQL | Тип C/C++ |
STRING | char * |
INTEGER | long long |
REAL | double |
При запуске SQL-команды XXX() MySQL вызывает функцию инициализации xxx_init(), чтобы дать ей возможность выполнить все необходимые установки, такие как проверка аргументов и распределение памяти. Если xxx_init() возвращает ошибку, то выполнение SQL-команды прерывается с сообщением об ошибке, а главная функция и функция деинициализации не вызываются. В противном случае для каждой строки вызывается главная функция xxx(). После того как будут обработаны все строки, вызывается функция деинициализации xxx_deinit(), чтобы выполнить необходимую очистку.
Для агрегатных функций (подобных SUM()) необходимо также подготовить следующие функции:
При использовании агрегатных UDF-функций MySQL работает следующим образом:
Все функции должны поддерживать многопоточность (не только главная, но также и функции инициализации и деинициализации). Это означает, что непозволительно распределять какие-либо глобальные или статические переменные с изменяющимися значениями! Если требуется память, то ее следует распределять в xxx_init() и освобождать в xxx_deinit().
9.2.1 Синтаксис CREATE FUNCTION/DROP FUNCTION | Оглавление | 9.2.2.1 Последовательность вызова UDF для простых функций |