��������  ����Linux

mysql-logo.png (3082 bytes)MySQL���IJο��ֲ�

���룺����(yanzi)       ��ҳ��http://aosp.me


��һ��, ǰһ��, ��һ��, ���һ����Ŀ¼.


14 ΪMySQL�����º���

��2�ַ������º����ӵ�MySQL�У�

  • �����ͨ���û����庯��(UDF)�ӿڼ��뺯�����û����庯����CREATE FUNCTION��DROP FUNCTION��䶯̬�����Ӻ�ɾ������7.30 CREATE FUNCTION/DROP FUNCTION�䷨��
  • ����Լ��뺯����Ϊһ��ԭ����(���õ�)MySQL������ԭ�������������mysqld������������һ�����õĻ����Ͽɵõ���

ÿ�ַ��������ŵ��ȱ�㣺

  • ������дһ���û����庯��������밲װ�������⻹���Լ���װ�����ļ����������뺯�����������У��㲻��Ҫ��������
  • ���ܰ�UDF�ӵ�MySQL�����ƴ��뷢���С�ԭ������Ҫ�����޸�Դ����ַ���
  • ������������MySQL�ַ������ܼ���ʹ�������ǰ��װ��UDF������ԭ���������������ÿ������ʱ�ظ�����޸ġ�

������ʹ�����ַ��������º��������ǿ�����ԭ����������ABS()��SOUNDEX()����ʹ�á�

14.1 ����һ���µ��û����庯��

����UDF�Ĺ������ƣ�����������C��C++��д������IJ���ϵͳ����֧�ֶ�̬װ�ء�MySQLԴ����ַ�����һ���ļ���sql/udf_example.cc������������5���º������������ļ���UDF����Լ������������

��ÿһ��������SQL�����ʹ�õĺ�������Ӧ�ö����Ӧ��C(�� C++)������������������У���xxx������һ�������������ӡ�Ϊ������SQL��C/C++�÷���XXX()(��д)����SQL�������ã���xxx()((Сд)����C/C++�������á�

���дʵ��XXX()�Ľӿڵ�C/C++�����ǣ�

xxx()������ģ�
�����������Ǽ��㺯������ĵط���SQL ���������C/C++�����������͵Ķ�Ӧ��ϵ���£�
SQL ���� C/C++ ����
STRING char *
INTEGER long long
REAL double
xxx_init()����ѡ��
Ϊxxx()�ij�ʼ���������������ڣ�
  • ��鴫��XXX()�IJ���������
  • ��������һ����������ͣ�������أ���������������ʱ������MySQL��Ϊ��ǿ�Ʋ���������Ҫ�����͡�
  • �����κ���������������ڴ档
  • ָ���������󳤶ȡ�
  • ָ��(��REAL����)С��λ�������Ŀ��
  • ָ������Ƿ�����NULL��
xxx_deinit()����ѡ��
Ϊxxx()�Ľ�����������Ӧ���ͷų�ʼ�����������˵��κ��ڴ档

��һ��SQL������XXX()ʱ��MySQL���ó�ʼ������xxx_init()������ִ���κ���������ã�������������ڴ���䡣���xxx_init()����һ������SQL�����һ��������Ϣ�����������������ͽ��������������ã�����Ϊÿ�е���������xxx()һ�Ρ��������б�������󣬽�������xxx_deinit()�����ã��������ִ���κα�Ҫ�������

���к��������̰߳�ȫ��(��ֻ�������������г�ʼ���ͽ�������)������ζ�ţ��㲻���������κθı��ȫ�ֻ�̬�������������Ҫ�ڴ棬��Ӧ����xxx_init()�ַ�����������xxx_deinit()���ͷ�����

14.1.1 UDF�ĵ���˳��

������Ӧ�����¶��塣ע�ⷵ�����ͺͲ�����ͬ��ȡ�������Ƿ���CREATE FUNCTION���������SQL����XXX()����STRING��INTEGER��REAL��

��STRING������

char *xxx(UDF_INIT *initid, UDF_ARGS *args,
              char *result, unsigned long *length,
              char *is_null, char *error);

��INTEGER������

long long xxx(UDF_INIT *initid, UDF_ARGS *args,
              char *is_null, char *error);

����REAL������

double xxx(UDF_INIT *initid, UDF_ARGS *args,
              char *is_null, char *error);

��ʼ���ͽ���������������������

my_bool xxx_init(UDF_INIT *initid, UDF_ARGS *args, char *message);

void xxx_deinit(UDF_INIT *initid);

initid��������������3����������ָ��һ��UDF_INIT�ṹ���������ں���֮�䴫����Ϣ��UDF_INIT�ṹ��Ա�������档��ʼ������Ӧ����д����Ҫ�ı���κγ�Ա������һ����Աʹ��ȱʡֵ�����ı�������

my_bool maybe_null
���xxx()�ܷ���NULL��xxx_init()Ӧ������maybe_nullΪ1������������κ�һ��������maybe_null��ȱʡֵ��1��
unsigned int decimals
С��λ��Ŀ��ȱʡֵ���ڱ������������IJ�����С��λ�������Ŀ�������磬�����������1.34��1.345��1.3��ȱʡֵ����3����Ϊ1.345��3��С��λ��
unsigned int max_length
�ַ����������󳤶ȡ�ȱʡֵ��ͬ��ȡ���ں����Ľ�����͡����ַ���������ȱʡ����IJ����ij��ȡ�������������ȱʡ��21λ����ʵ��������ȱʡ��13������initid->decimalsָ����С��λ�����������ֺ��������Ȱ����κη���λ��С�����ַ�����
char *ptr
������Ϊ���Լ���Ŀ��ʹ�õ�һ��ָ�롣���磬������ʹ��initid->ptr�ں���֮�䴫�ݷ�����ڴ档��xxx_init()�У������ڴ沢�����������ָ�룺
initid->ptr = allocated_memory;

��xxx()��xxx_deinit()�У�����initid->ptr��ʹ�û��ͷ��ڴ档

14.1.2 ��������

args����ָ��һ��UDF_ARGS��Ա����ṹ�������棺

unsigned int arg_count
�����������������Ҫ������һ���ض������IJ��������ã��ڳ�ʼ�������м�����ֵ�����磺
if (args->arg_count != 2)
{
    strcpy(message,"XXX() requires two arguments");
    return 1;
}
enum Item_result *arg_type
Ϊÿ�����������͡����ܵ�����ֵ��STRING_RESULT��INT_RESULT��REAL_RESULT��Ϊ��ȷ��������һ�ָ��������ͣ���������Dz��ǣ�����һ�������ڳ�ʼ�������м��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;
}

��Ϊ��һ��Ҫ����ĺ����IJ����������ض����͵�ѡ�������ʹ�ó�ʼ����������arg_type��Ա������Ҫ�����͡��⵼��MySQLΪÿ��xxx()����ǿ�Ʋ���Ϊ��Щ���ͣ����磬Ϊ��ָ��ͷ 2���������ַ�����������ǿ�ƣ���xxx_init()������Щ��

args->arg_type[0] = STRING_RESULT;
args->arg_type[1] = INT_RESULT;
char **args
args->args��������ĺ����������õIJ�����һ�����Ե���Ϣ���ݵ���ʼ����������һ����������i��args->args[i]ָ�����ֵ������������������ȷ��ȡֵ��ָ��) ��һ���dz����IJ�����args->args[i]��0��һ����������ֻ��ʹ�ó�����һ������ʽ������3��4*7-2��SI(3.14)��һ���dz������������ÿ���ÿ�в�ͬ��ֵ��һ������ʽ�����������ֻ��÷dz����������õĺ���������������ÿ�ε��ã�args->args�����Ե�ǰ���ڴ������������ݵ�ʵ�ʲ����������������µ�����һ������i��
  • һ��STRING_RESULT���͵IJ�����һ���ַ���ָ���һ�����ȸ�����������������ij��ȵĶ����Ƶ����ݻ����ݡ��ַ������ݿ���args->args[i]�õ������ַ���������args->lengths[i]���㲻Ӧ�ü����ַ������Կ�(null)�����ġ�
  • ����һ��INT_RESULT���͵IJ����������ǿ��ת��args->args[i]Ϊһ��long longֵ��
    long long int_val;
    int_val = *((long long*) args->args[i]);
    
  • ��һ��REAL_RESULT���͵IJ����������ǿ��ת��args->args[i]Ϊһ��doubleֵ��
    double    real_val;
    real_val = *((double*) args->args[i]);
    
    
unsigned long *lengths
�Գ�ʼ��������lengths����ָ��ÿ������������ַ������ȡ��������������ã�lengths����Ϊ��ǰ���ڱ��������д��ݵ��κ��ַ���������ʵ�ʳ��ȡ���INT_RESULT��REAL_RESULT���͵IJ�����lengths��Ȼ������������󳤶�(����Գ�ʼ������)��

14.1.3 ����ֵ�ͳ�������

���û�г��ִ��󣬳�ʼ������Ӧ�÷���0�����򷵻�1���������һ������xxx_init()Ӧ����message�����д洢һ�����ַ������Ĵ�����Ϣ����Ϣ�������ظ��ͻ�����Ϣ��������MYSQL_ERRMSG_SIZE���ַ�����������Ӧ�����ű�����Ϣ����80���ַ��Ա����ʺ�һ����׼�ն���Ļ�Ŀ��ȡ�

��long long��double������������xxx()�ķ���ֵ�Ǻ���ֵ�����ַ����������ַ�����result��length�����б����ء�result������255���ֽڳ���һ����������������ЩΪ����ֵ�����ݺͳ��ȡ����磺

memcpy(result, "result string", 13);
*length = 13;

�ַ�����������ֵҲͨ��ָ������

Ϊ�����������б���һ��NULL����ֵ���趨is_nullΪ1��

*is_null = 1; 

Ϊ���ں����б���һ�����󷵻أ��趨error����Ϊ1��

*error = 1; 

������κ���xxx()����*errorΪ1���Ե�ǰ�к���ֵ��NULL�������ڸ�����д����ĺ����У�XXX()�����á�(xxx()��������Ϊ�����б����á���ע�⣺��MySQL 3.22.10��ǰ�İ汾�У���Ӧ�ö�����*error��*is_null��

*error = 1;
*is_null = 1;

14.1.4 ���벢��װ�û����庯��

ʵ��UDF���ļ������ڷ��������е������ϱ����벢�Ұ�װ�������������������UDF�����ļ�������MySQLԴ����ַ�����udf_example.cc���У�����ļ��������к�����

  • metaphon()�����ַ���������һ������λ(metaphon)�ַ��������е���һ��soundex�ַ����������������Ӣ��������
  • myfunc_double()������������������ַ���ASCIIֵ�ĺͣ��������������֮�͡�
  • myfunc_int()�������������֮�͡�
  • lookup()���ض���������IP����
  • reverse_lookup()���ض�һ��IP����������������������һ���ַ���"xxx.xxx.xxx.xxx"��4λ���ֱ����á�

һ���ɶ�̬װ�ص��ļ�Ӧ�ñ���Ϊһ�������Ķ����ļ���ʹ�������������

shell> gcc -shared -o udf_example.so myfunc.cc

ͨ�����������MySQLԴ����������sql��Ŀ¼�µ�����������ܺ����׵��ҳ������ϵͳ��ȷ�ı�����ѡ�

shell> make udf_example.o

��Ӧ������һ��������make��ʾ�ı������������Ӧ��ɾ���ӽ��н�β��-cѡ��������������-o udf_example.so������һЩϵͳ�ϣ��������Ҫ�������ϱ���-c����

һ��������˰���UDF ��һ��������������밲װ�����Ұ�������MySQL������udf_example.cc������һ�������������һ������������udf_example.so�����ļ���׼ȷ�����ֿ�����ƽ̨��ͬ����ͬ)����������ļ�����ij��ldѰ�ҵ�Ŀ¼��������/usr/lib����������ϵͳ�ϣ������趨LD_LIBRARY��LD_LIBRARY_PATH����������ָ����UDF�����ļ���Ŀ¼��dopen�ֲ�ҳ��������Ӧ�������ϵͳ��ʹ���ĸ���������Ӧ����mysql.server��safe_mysqld����������������mysqld��

�ڿⱻ��װ�Ժ�����Щ����֪ͨmysqld�й��µĺ�������Ϣ��

mysql> CREATE FUNCTION metaphon RETURNS STRING SONAME "udf_example.so";
mysql> CREATE FUNCTION myfunc_double RETURNS REAL SONAME "udf_example.so";
mysql> CREATE FUNCTION myfunc_int RETURNS INTEGER SONAME "udf_example.so";
mysql> CREATE FUNCTION lookup RETURNS STRING SONAME "udf_example.so";
mysql> CREATE FUNCTION reverse_lookup RETURNS STRING SONAME "udf_example.so";

������ʹ��DROP FUNCTIONɾ����

mysql> DROP FUNCTION metaphon;
mysql> DROP FUNCTION myfunc_double;
mysql> DROP FUNCTION myfunc_int;
mysql> DROP FUNCTION lookup;
mysql> DROP FUNCTION reverse_lookup;

CREATE FUNCTION��DROP FUNCTION�����mysql���ݿ��и���ϵͳ��func�������������ͺ͹��������������ڸñ��С�������ж�mysql��insert��deleteȨ���Դ���������������

�㲻Ӧ��ʹ��CREATE FUNCTION����һ���Ѿ��������ĺ������������Ҫ���°�װ��������Ӧ����DROP FUNCTIONɾ������Ȼ����CREATE FUNCTION���°�װ�����㽫��Ҫ�����������磬��������±�����ĺ�����һ���°汾���Ա�mysqld����°汾�����������������ʹ�þɰ汾��

��Ծ������ÿ�η���������ʱ�ٴ�װ�أ�������ʹ��--skip-grant-tablesѡ������mysqld������������£�UDF��ʼ������������UDF�����á�����Ծ������һ����CREATE FUNCTIONװ�ز���û����DROP FUNCTIONɾ���ĺ�����)

14.2 ����һ���µ�ԭ������

����һ���µ�ԭ�������Ĺ���������������ע�⣬�㲻����һ�������Ʒַ��м����º�������Ϊ�ù����漰�޸�MySQLԴ���롣������Դ����ַ����б���MySQL��ҲҪע�⣬�����Ǩ�Ƶ�MySQL�������汾�����磬��һ���°汾���ͷ�ʱ)���㽫��Ҫ���°汾�ظ��ù��̡�

Ϊ�˼���һ���µ�ԭ��MySQL��������ѭ��Щ���裺

  1. ����lex.h������1�У�����sql_functions[]�����ж��庯������
  2. ����sql_yacc.yy������2�С�һ��ָ��ʾyaccӦ�ö����Ԥ����������(��Ӧ�ü����ļ��Ŀ�ʼ)��Ȼ���庯���������ҽ�һ��������Щ��������Ŀ���ӵ�simple_expr�﷨���������С���һ�����ӣ��������sql_yacc.yy ���е�SOUNDEX���ֿ�����ʹ�������ġ�
  3. ����item_func.h���У�����һ���̳�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)
    
  5. ��Ҳ����Ӧ�ö������к�����
    void Item_func_newname::fix_length_and_dec()
    

    �����������Ӧ�û��ڸ����IJ�������max_length��max_length�Ǻ������Է��ص��ַ��������Ŀ��������������ܷ���һ��NULLֵ���������ҲӦ������maybe_null = 0����������ͨ����������maybe_null�����Ա��麯���������κ�һ���Ƿ��ܷ���NULL��

���к����������̰߳�ȫ�ģ�thread-safed����

���ַ�����������֪��һЩ����Ŀ��ǣ�

  • String *str�����ṩһ�������������������ַ�����������
  • ����Ӧ�÷��ر��������ַ�����
  • ���еĵ�ǰ�ַ���������ͼ��������κ��ڴ棬���Ǿ��Ա�Ҫ��

��һ��, ǰһ��, ��һ��, ���һ����Ŀ¼.

��������  ����Linux