Добавление новых функций в MySQL

BLOB

BLOB (англ. Binary Large Object — двоичный большой объект) — массив двоичных данных.

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

Тип данных BLOB представляет собой двоичный объект большого размера, который может содержать переменное количество данных. Существуют 4 модификации этого типа - TINYBLOB, BLOB, MEDIUMBLOB и LONGBLOB, отличающиеся только максимальной длиной хранимых величин.

Тип данных TEXT также имеет 4 модификации - TINYTEXT, TEXT, MEDIUMTEXT и LONGTEXT, соответствующие упомянутым четырем типам BLOB и имеющие те же максимальную длину и требования к объему памяти. Единственное различие между типами BLOB и TEXT состоит в том, что сортировка и сравнение данных выполняются с учетом регистра для величин BLOB и без учета регистра для величин TEXT. Другими словами, TEXT - это независимый от регистра BLOB.

Если размер задаваемого в столбце BLOB или TEXT значения превосходит максимально допустимую длину столбца, то это значение соответствующим образом усекается.

В большинстве случаев столбец TEXT может рассматриваться как столбец VARCHAR неограниченного размера. И, аналогично, BLOB - как столбец типа VARCHAR BINARY. Различия при этом следующие:

-Столбцы типов BLOB и TEXT могут индексироваться в версии MySQL 3.23.2 и более новых. Более старые версии MySQL не поддерживают индексацию этих столбцов.

-В столбцах типов BLOB и TEXT не производится удаление концевых символов, как это делается для столбцов типа VARCHAR.

-Для столбцов BLOB и TEXT не может быть задан атрибут DEFAULT - значения величин по умолчанию.

В MyODBC величины типа BLOB определяются как LONGVARBINARY и величины типа TEXT - как LONGVARCHAR.

Так как величины типов BLOB и TEXT могут быть чрезмерно большими, при их использовании целесообразно предусмотреть некоторые ограничения:

Чтобы обеспечить возможность использования команд GROUP BY или ORDER BY в столбце типа BLOB или TEXT, необходимо преобразовать значение столбца в объект с фиксированной длиной. Обычно это делается с помощью функции SUBSTRING. Например:

mysql> SELECT comment FROM tbl_name,SUBSTRING(comment,20) AS substr

-> ORDER BY substr;

Если этого не сделать, то операция сортировки в столбце будет выполнена только для первых байтов, количество которых задается параметром max_sort_length. Значение по умолчанию величины max_sort_length равно 1024; это значение можно изменить, используя параметр -O сервера mysqld при его запуске. Группировка выражения, включающего в себя величины BLOB или TEXT, возможна при указании позиции столбца или использовании псевдонима:

mysql> SELECT id,SUBSTRING(blob_col,1,100) FROM tbl_name GROUP BY 2;

mysql> SELECT id,SUBSTRING(blob_col,1,100) AS b FROM tbl_name GROUP BY b;

Максимальный размер объекта типа BLOB или TEXT определяется его типом, но наибольшее значение, которое фактически может быть передано между клиентом и сервером, ограничено величиной доступной памяти и размером буферов связи. Можно изменить размер буфера блока передачи, но сделать это необходимо как на стороне сервера, так и на стороне клиента.

Следует учитывать, что внутренним представлением любой величины типа BLOB или TEXT является отдельно размещенный объект - в противоположность всем остальным типам столбцов, для которых память выделяется единовременно для столбца при открытии таблицы.

Обработка аргументов

Параметр args указывает на структуру UDF_ARGS, содержащую перечисленные ниже поля:

unsigned int arg_count

Количество аргументов. Это значение следует проверять в функции инициализации, если необходимо, чтобы функция вызывалась с определенным количеством аргументов. Например:

if (args->arg_count != 2)

{

strcpy(message,"XXX() requires two arguments");

return 1;

}

enum Item_result *arg_type

Тип для каждого аргумента. Возможные значения типа: STRING_RESULT, INT_RESULT и REAL_RESULT. Чтобы контролировать принадлежность аргументов к нужному типу и возвращать ошибку, если это не так, следует проверить массив arg_type в функции инициализации. Например:

if (args->arg_type[0] != STRING_RESULT ||

args->arg_type[1] != INT_RESULT)

{

strcpy(message,"XXX() requires a string and an integer");

return 1;

}

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

args->arg_type[0] = STRING_RESULT;

args->arg_type[1] = INT_RESULT;

char **args

args->args передает в функцию инициализации информацию общего характера об аргументах, с которыми была вызвана функция. Для константного аргументаi args->args[i] указывает на значение аргумента (ниже приведены инструкции о том, как правильно получать доступ к значениям). Для неконстантого аргумента args->args[i] есть 0. Константный аргумент - это выражение, в котором используются только константы, вроде 3 или 4*7-2 или SIN(3.14). Неконстантный аргумент - это выражение, ссылающееся на значения, которые могут изменяться от строки к строке, такие как имена столбцов или обращения к функциям с неконстантными аргументами.

Для каждого вызова главной функции args->args содержит фактические аргументы, переданные для обрабатываемой в данный момент строки.

Функции могут ссылаться на аргумент i следующим образом:

Аргумент типа STRING_RESULT передается в виде указателя на строку плюс длина, чтобы обеспечить обработку двоичных данных или данных произвольной длины. Содержимое строки доступно посредством args->args[i], а длина строки представляет собой args->lengths[i]. Не следует исходить из предположения, что символ \0 отмечает конец строки.

Для аргумента типа INT_RESULT необходимо привести args->args[i] к значению типа long long:

long long int_val;

int_val = *((long long*) args->args[i]);

Для аргумента типа REAL_RESULT необходимо привести args->args[i] к значению типа double:

double real_val;

real_val = *((double*) args->args[i]);

unsigned long *lengths

Для функции инициализации массив lengths указывает максимальную длину строки для каждого аргумента. Изменять этот массив нельзя. При каждом вызове главной функции lengths содержит фактические длины всех строковых аргументов, переданных для обрабатываемой в текущий момент строки. Для типов аргументов INT_RESULT или REAL_RESULT lengths также содержит максимальную длину аргумента (как для функции инициализации).

BLOB

BLOB (англ. Binary Large Object — двоичный большой объект) — массив двоичных данных.

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

Тип данных BLOB представляет собой двоичный объект большого размера, который может содержать переменное количество данных. Существуют 4 модификации этого типа - TINYBLOB, BLOB, MEDIUMBLOB и LONGBLOB, отличающиеся только максимальной длиной хранимых величин.

Тип данных TEXT также имеет 4 модификации - TINYTEXT, TEXT, MEDIUMTEXT и LONGTEXT, соответствующие упомянутым четырем типам BLOB и имеющие те же максимальную длину и требования к объему памяти. Единственное различие между типами BLOB и TEXT состоит в том, что сортировка и сравнение данных выполняются с учетом регистра для величин BLOB и без учета регистра для величин TEXT. Другими словами, TEXT - это независимый от регистра BLOB.

Если размер задаваемого в столбце BLOB или TEXT значения превосходит максимально допустимую длину столбца, то это значение соответствующим образом усекается.

В большинстве случаев столбец TEXT может рассматриваться как столбец VARCHAR неограниченного размера. И, аналогично, BLOB - как столбец типа VARCHAR BINARY. Различия при этом следующие:

-Столбцы типов BLOB и TEXT могут индексироваться в версии MySQL 3.23.2 и более новых. Более старые версии MySQL не поддерживают индексацию этих столбцов.

-В столбцах типов BLOB и TEXT не производится удаление концевых символов, как это делается для столбцов типа VARCHAR.

-Для столбцов BLOB и TEXT не может быть задан атрибут DEFAULT - значения величин по умолчанию.

В MyODBC величины типа BLOB определяются как LONGVARBINARY и величины типа TEXT - как LONGVARCHAR.

Так как величины типов BLOB и TEXT могут быть чрезмерно большими, при их использовании целесообразно предусмотреть некоторые ограничения:

Чтобы обеспечить возможность использования команд GROUP BY или ORDER BY в столбце типа BLOB или TEXT, необходимо преобразовать значение столбца в объект с фиксированной длиной. Обычно это делается с помощью функции SUBSTRING. Например:

mysql> SELECT comment FROM tbl_name,SUBSTRING(comment,20) AS substr

-> ORDER BY substr;

Если этого не сделать, то операция сортировки в столбце будет выполнена только для первых байтов, количество которых задается параметром max_sort_length. Значение по умолчанию величины max_sort_length равно 1024; это значение можно изменить, используя параметр -O сервера mysqld при его запуске. Группировка выражения, включающего в себя величины BLOB или TEXT, возможна при указании позиции столбца или использовании псевдонима:

mysql> SELECT id,SUBSTRING(blob_col,1,100) FROM tbl_name GROUP BY 2;

mysql> SELECT id,SUBSTRING(blob_col,1,100) AS b FROM tbl_name GROUP BY b;

Максимальный размер объекта типа BLOB или TEXT определяется его типом, но наибольшее значение, которое фактически может быть передано между клиентом и сервером, ограничено величиной доступной памяти и размером буферов связи. Можно изменить размер буфера блока передачи, но сделать это необходимо как на стороне сервера, так и на стороне клиента.

Следует учитывать, что внутренним представлением любой величины типа BLOB или TEXT является отдельно размещенный объект - в противоположность всем остальным типам столбцов, для которых память выделяется единовременно для столбца при открытии таблицы.

Добавление новых функций в MySQL

Существует два способа добавления функций в MySQL:

Можно добавить функцию посредством интерфейса определяемых пользователем функций (user-definable function - UDF). Определяемые пользователем функции добавляются и удаляются динамически с помощью команд CREATE FUNCTION и DROP FUNCTION

Можно добавить функцию как ``родную'' (встроенную) функцию MySQL. ``Родные'' функции компилируются вместе с остальным кодом сервера mysqld и становятся постоянно доступными.

Каждый метод имеет преимущества и недостатки:

Если вы пишете определяемую пользователем функцию, то помимо сервера необходимо инсталлировать объектный файл. В этом нет необходимости при компиляции функции вместе с сервером.

UDFы можно добавить в бинарную поставку MySQL. Для ``родных'' функций необходимо изменять поставку исходного кода.

При обновлении поставки MySQL можно продолжать использовать ранее инсталлированные UDFы. Для ``родных функций нужно при каждом обновлении вносить изменения повторно.

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

Синтаксис CREATE FUNCTION/DROP FUNCTION

CREATE [AGGREGATE] FUNCTION function_name RETURNS {STRING|REAL|INTEGER}

SONAME shared_library_name

DROP FUNCTION function_name

Определяемая пользователем функция (UDF) - это средство, позволяющее расширить MySQL за счет новой функции, которая работает подобно ``родным'' (встроенным) функциям MySQL, таким как ABS() и CONCAT().

AGGREGATE - новая опция для версии MySQL 3.23. AGGREGATE - функция работает точно так же, как и ``родные'' GROUP-функции MySQL GROUP вроде SUM или COUNT().

CREATE FUNCTION сохраняет имя, тип и имя разделяемой библиотеки функции в системной таблице mysql.func. Чтобы создавать и удалять функции, необходимо обладать привилегиями INSERT и DELETE для базы данных mysql.

Все активные функции подгружаются при каждом запуске сервера, за исключением случая, когда mysqld запускается с опцией --skip-grant-tables. Тогда инициализация UDF пропускается и UDFы недоступны (активная функция - это функция, которая была загружена посредством CREATE FUNCTION и не удалена с помощью DROP FUNCTION).

Отметим, что для того, чтобы работала AGGREGATE, таблица mysql.func должна содержать столбец type. В противном случае следует запустить сценарийmysql_fix_privilege_tables, чтобы внести нужные исправления.

Наши рекомендации