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