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

22.3.3. Добавление Новой Собственной Функции

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

Если новая собственная функция будет упомянута в операторах, которые будут тиражированы в ведомые серверы, следует гарантировать, что каждый ведомый сервер также имеет функцию в наличии. Иначе, репликация перестанет работать на ведомых устройствах, когда они попытаются вызвать функцию.

Чтобы добавить новую собственную функцию, следуйте за этими шагами, чтобы изменить исходные файлы в sql каталог:

  1. Создайте подкласс для функции в item_create.cc:

    • Если функция берет постоянное число параметров, создайте подкласс Create_func_arg0, Create_func_arg1, Create_func_arg2, или Create_func_arg3, соответственно, в зависимости от того, берет ли функция нуль, один, два, или три параметра. Для примеров см. Create_func_uuid, Create_func_abs, Create_func_pow, и Create_func_lpad классы.

    • Если функция берет переменное число параметров, создайте подкласс Create_native_func. Для примера см. Create_func_concat.

  2. Чтобы обеспечить имя, которым функция может быть упомянута в SQL-операторах, зарегистрируйте имя в item_create.cc добавляя строку к этому массиву:

    static Native_func_registry func_array[]

    Можно зарегистрировать несколько имен для той же самой функции. Например, см. строки для "LCASE" и "LOWER", которые являются псевдонимами для Create_func_lcase.

  3. В item_func.h, объявите class, наследовавшийся от Item_num_func или Item_str_funcВ зависимости от того, возвращает ли Ваша функция число или строку.

  4. В item_func.cc, добавьте одно из следующих объявлений, в зависимости от того, определяете ли Вы числовую или строковую функцию:

    double   Item_func_newname::val()longlong Item_func_newname::val_int()String  *Item_func_newname::Str(String *str)

    Если Вы наследовали свой объект от какого-либо из стандартных элементов (как Item_num_func), вероятно, только необходимо определить одну из этих функций и позволить родительскому объекту заботиться о других функциях. Например, Item_str_func class определяет a val() функция, которая выполняется atof() на значении, возвращенном ::str().

  5. Если функция недетерминирована, включайте следующий оператор в конструктора элемента, чтобы указать, что функциональные результаты не должны кэшироваться:

    current_thd->lex->safe_to_cache_query=0;

    Функция недетерминирована, если, учитывая фиксированные значения для ее параметров, она может возвратить различные результаты для различных вызовов.

  6. Следует, вероятно, также определить следующую объектную функцию:

    void Item_func_newname::fix_length_and_dec()

    Эта функция должна, по крайней мере, вычислить max_length основанный на данных параметрах. max_length максимальное количество символов, которые может возвратить функция. Эта функция должна также установить maybe_null = 0 если основная функция не может возвратить a NULL значение. Функция может проверить, может ли какой-либо из аргументов функции возвратиться NULL проверяя параметры maybe_null переменная. Смотрите на Item_func_mod::fix_length_and_dec для типичного примера того, как сделать это.

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

Если Вы хотите возвратиться NULL от ::val(), ::val_int(), или ::str(), следует установить null_value к 1 и возврат 0.

Для ::str() возразите функциям, есть дополнительные соображения, чтобы знать: