Spec-Zone .ru
спецификации, руководства, описания, API

22.3.2. Добавление Новой Определяемой пользователем Функции

22.3.2.1. Вызывающие последовательности UDF для Простых Функций
22.3.2.2. Вызывающие последовательности UDF для Агрегатных функций
22.3.2.3. Обработка Параметра UDF
22.3.2.4. Возвращаемые значения UDF и Обработка ошибок
22.3.2.5. Компиляция и Установка Определяемых пользователем Функций
22.3.2.6. Определяемые пользователем Функциональные Предосторожности Безопасности

Для механизма UDF, чтобы работать, функции должны быть записаны в C или C++, и Ваша операционная система должна поддерживать динамическую загрузку. Исходные дистрибутивы MySQL включают файл sql/udf_example.c это определяет пять функций UDF. Консультируйтесь с этим файлом, чтобы видеть, как работают соглашения о вызовах UDF. include/mysql_com.h заголовочный файл определяет UDF-связанные символы и структуры данных, хотя Вы не должны включать этот заголовочный файл непосредственно; это включается mysql.h.

UDF содержит код, который становится частью рабочего сервера, так, когда Вы пишете UDF, Вы связываетесь любым и всеми ограничениями, которые применяются к записи серверного кода. Например, у Вас могут быть проблемы, если Вы пытаетесь использовать функции от libstdc++ библиотека. Эти ограничения могут измениться в будущих версиях сервера, таким образом, возможно, что обновления сервера потребуют версий UDFs, которые были первоначально записаны для более старых серверов. Для получения информации об этих ограничениях см. Раздел 2.9.4, "MySQL Source-Configuration Options", и Раздел 2.9.5, "Контакт с проблемным MySQL Compiling".

Чтобы быть в состоянии использовать UDFs, следует соединить mysqld динамически. Если Вы хотите использовать UDF, который должен получить доступ к символам от mysqld (например, metaphone функция в sql/udf_example.c использование default_charset_info), следует соединить программу с -rdynamic (см. man dlopen).

Для каждой функции, которую Вы хотите использовать в SQL-операторах, следует определить соответствующий C (или C++) функции. В следующем обсуждении имя "xxx" используется для имени функции в качестве примера. Различать SQL и использование C/C++, XXX() (верхний регистр) указывает на вызов функции SQL, и xxx() (нижний регистр) указывает на вызов функции C/C++.

Отметить

При использовании C++ можно инкапсулировать свои функции C в пределах:

extern "C" { ... }

Это гарантирует, что Ваши имена функций C++ остаются читаемыми в завершенном UDF.

Следующий список описывает функции C/C++, которые Вы пишете, чтобы реализовать интерфейс для названной функции XXX(). Основная функция, xxx(), требуется. Кроме того, UDF требует по крайней мере одной из других функций, описанных здесь, по причинам, обсужденным в Разделе 22.3.2.6, "Определяемые пользователем Функциональные Предосторожности Безопасности".

Когда SQL-оператор вызывает XXX(), MySQL вызывает функцию инициализации xxx_init() позволять этому выполнять любую необходимую установку, такую как проверка параметра или выделение памяти. Если xxx_init() возвращает ошибку, MySQL прерывает SQL-оператор с сообщением об ошибке и не вызывает функции deinitialization или основное. Иначе, MySQL вызывает основную функцию xxx() однажды для каждой строки. После того, как все строки были обработаны, MySQL вызывает deinitialization функцию xxx_deinit() так, чтобы это могло выполнить любую необходимую уборку.

Для агрегатных функций та работа как SUM(), следует также обеспечить следующие функции:

MySQL обрабатывает совокупный UDFs следующим образом:

  1. Вызвать xxx_init() чтобы позволить агрегатной функции выделять любую память, это нуждается для того, чтобы сохранить результаты.

  2. Сортируйте таблицу согласно GROUP BY выражение.

  3. Вызвать xxx_clear() для первой строки в каждой новой группе.

  4. Вызвать xxx_add() для каждой строки, которая принадлежит в той же самой группе.

  5. Вызвать xxx() чтобы получить результат для агрегата, когда группа изменяется или после, последняя строка была обработана.

  6. Повторите шаги 3 - 5, пока все строки не были обработаны

  7. Вызвать xxx_deinit() чтобы позволить свободному UDF любая память, это выделило.

Все функции должны быть ориентированы на многопотоковое исполнение. Это включает не только основную функцию, но и инициализацию и функции deinitialization также, и также дополнительные функции, требуемые агрегатными функциями. Последствие этого требования - то, что Вам не разрешают выделить глобальные или статические переменные то изменение! Если Вы нуждаетесь в памяти, следует выделить ее в xxx_init() и освободите это в xxx_deinit().