一个使用mysql UDF编写mysql扩展函数的例子

13890阅读 0评论2013-09-25 playmud
分类:Mysql/postgreSQL

同事需要对一个表的不同字段进行处理,生成一些数据,使用shell处理比较慢,帮他写了一个mysql 的扩展函数,对UDF接口的资料做了一个了解,有需要的人可以看看,效率还是蛮高的。


点击(此处)折叠或打开

  1. #include <mysql.h>
  2. #include <string.h>
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <time.h>
  6. #include <sys/types.h>
  7. #include <sys/stat.h>
  8. #include <errno.h>
  9. #include <unistd.h>
  10. #include <stdint.h>

  11. /*资源分配*/
  12. my_bool myfun_init(UDF_INIT *initid, UDF_ARGS *args, char *message);

  13. /*自定义函数*/
  14. char *myfun(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long *length, char *is_null, char *error);

  15. /*资源回收*/
  16. void myfun_deinit(UDF_INIT *initid);

  17. /*
  18.   参数说明:
  19.          UDF_INT *initid
  20.            UDF_INIT 指针可以用于将分配好的资源传递给其他函数使用。

  21.          UDF_ARG *args
  22.            UDF_ARG 指针

  23.          char *message
  24.            出错信息指针

  25.   返回值 0 成功, 1 失败
  26.  
  27.  
  28. 针对UFD_INT和UDF_ARG的成员做一个简单说明。
  29. typedef struct st_udf_args
  30. {
  31.   unsigned int arg_count; 参数个数
  32.   enum Item_result *arg_type; 参数类型
  33.   char **args; 参数指针
  34.   unsigned long *lengths; 参数长度
  35.   char *maybe_null; 是否可以为空,1表示可以为空
  36.   char **attributes; 参数属性的指针
  37.   unsigned long *attribute_lengths; 参数属性的指针指向内容的长度
  38.   void *extension;                                            扩展指针
  39. } UDF_ARGS;


  40. typedef struct st_udf_init
  41. {
  42.   my_bool maybe_null; 1表示返回值可以为空
  43.   unsigned int decimals; 可以用来设置double类型小数点后的长度
  44.   unsigned long max_length; 自定义字符串函数返回结果的最大长度
  45.   char *ptr; 字符串指针 一般init里面分配的内存可以把地址给ptr,用于传递到其他函数,比如deinit里面释放分配的内存
  46.   my_bool const_item; 函数是否返回固定结果
  47.   void *extension;                         扩展指针
  48. } UDF_INIT;
  49. */

  50. /* init函数在myfun函数执行前调用*/
  51. my_bool myfun_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
  52. {
  53.   char *pstr;

  54.   if (args->arg_count != 1 || args->arg_type[0] != STRING_RESULT) {
  55.     /* 检测参数个数和参数类型 */
  56.     strncpy(message, " USAGE: myfun('').", MYSQL_ERRMSG_SIZE);
  57.     return 1;
  58.   }

  59.   pstr = malloc(sizeof(char) * 128);

  60.   /* 强制参数为指针类型 */
  61.   args->arg_type[0]= STRING_RESULT;

  62.   initid->ptr= (char *)total_bytes;

  63.   return 0;
  64. }

  65. /*
  66.   参数说明:
  67.          UDF_INT *initid
  68.            同init函数

  69.          UDF_ARG *args
  70.            用于读取穿进来参数的信息:传入的值,传入值的长度 ,类型等等,具体看上面结构体的说明

  71.         *result
  72.           保留参数

  73.         *length
  74.           用于设置返回值的长度

  75.         *is_null
  76.           是否为空

  77.         *error
  78.              如果设置为1自定义函数将不被再调用

  79.         RETURNS
  80.           字符串指针
  81. */
  82. char *myfun(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long *length, char *is_null, char *error)
  83. {
  84.   char *pstr= (char *)initid->ptr;
  85.     strcpy(pstr,"hello");
  86.     
  87.     memcpy(pstr+strlen(pstr),args->args[0],args->lengths[0]);
  88.     /*可以试试
  89.     
  90.     sprintf(pstr,“hello %s”, args->args[0]);
  91.     
  92.     可以深入理解args->lengths的作用了*/

  93.   return (result);
  94. }

  95. /* deinit函数在myfun函数执行完调用*/
  96. void myfun_deinit(UDF_INIT *initid)
  97. {
  98.   char *total_bytes= initid->ptr;

  99.   /* 释放内存*/
  100.   free(total_bytes);

  101.   return;
  102. }

上一篇:RPS和RFS实现分析
下一篇:linux内核模块之间互相调用对方模块的变量的问题