为什么 MySQL UDF Returns 随机数据?
Why MySQL UDF Returns Random Data?
发生问题的系统信息:
OS:Debian 8.1 64 位 - MySQL 版本:5.5.44 - GCC:4.9.2
我正在创建一个简单的 UDF 函数,它将 return 字符串 Hello World。问题是它会 return Hello World, concat to it, 有一个很长的随机二进制字符串,带有可变大小的随机数据,每次执行都会改变。
hello_world.c
#ifdef STANDARD
/* STANDARD is defined,
don't use any mysql functions */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#ifdef __WIN__
typedef unsigned __int64 ulonglong; /* Microsofts 64 bit types */
typedef __int64 longlong;
#else
typedef unsigned long long ulonglong;
typedef long long longlong;
#endif /*__WIN__*/
#else
#include <my_global.h>
#include <my_sys.h>
#if defined(MYSQL_SERVER)
#include <m_string.h> /* To get strmov() */
#else
/* when compiled as standalone */
#include <string.h>
#define strmov(a,b) stpcpy(a,b)
#define bzero(a,b) memset(a,0,b)
#endif
#endif
#include <mysql.h>
#include <ctype.h>
#ifdef _WIN32
/* inet_aton needs winsock library */
#pragma comment(lib, "ws2_32")
#endif
#ifdef HAVE_DLOPEN
#if !defined(HAVE_GETHOSTBYADDR_R) || !defined(HAVE_SOLARIS_STYLE_GETHOST)
static pthread_mutex_t LOCK_hostname;
#endif
my_bool hello_world_init(UDF_INIT* initid, UDF_ARGS* args __attribute__((unused)),
char* is_null __attribute__((unused)), char* message __attribute__((unused)))
{
return 0;
}
void hello_world_deinit(UDF_INIT* initid, UDF_ARGS* args __attribute__((unused)),
char* is_null __attribute__((unused)), char* message __attribute__((unused)))
{}
char* hello_world(UDF_INIT *initid __attribute__((unused)),
UDF_ARGS *args, char *result, unsigned long *length,
char *is_null, char *message __attribute__((unused)))
{
char* hello = "Hello World";
return hello;
}
#endif /* HAVE_DLOPEN */
我曾尝试以两种不同的方式编译源代码,但输出相同:
gcc $(mysql_config --cflags) -shared -fPIC -o hello_world.so hello_world.c
gcc -shared -fPIC -o hello_world.so helloworld.c -I/usr/include/mysql
我将 UDF 共享库包含到 /usr/lib/mysql/plugin
并在 MySQL 中创建了函数:CREATE FUNCTION hello_world RETURNS STRING SONAME "hello_world.so";
一切都很顺利,函数执行时出现问题:
示例输出:
| Hello World ;, �� ����� x
� $ ���0 FJ
V � ?; D ��� A�C
d
Q �� �
���o |
可能是什么问题?
谢谢。
MySQL 不在 C 字符串中使用空终止符。 UDF 收到一个参数unsigned long *length
,你必须设置它。
*length = strlen(hello);
return hello;
您没有正确调用 UDF 调用。每 the documentation:
The return value of the main function xxx()
is the function value, for
long long and double functions. A string function should return a
pointer to the result and set *length to the length (in bytes) of the
return value. For example:
memcpy(result, "result string", 13);
*length = 13;
该文档还有很多内容。
发生问题的系统信息:
OS:Debian 8.1 64 位 - MySQL 版本:5.5.44 - GCC:4.9.2
我正在创建一个简单的 UDF 函数,它将 return 字符串 Hello World。问题是它会 return Hello World, concat to it, 有一个很长的随机二进制字符串,带有可变大小的随机数据,每次执行都会改变。
hello_world.c
#ifdef STANDARD
/* STANDARD is defined,
don't use any mysql functions */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#ifdef __WIN__
typedef unsigned __int64 ulonglong; /* Microsofts 64 bit types */
typedef __int64 longlong;
#else
typedef unsigned long long ulonglong;
typedef long long longlong;
#endif /*__WIN__*/
#else
#include <my_global.h>
#include <my_sys.h>
#if defined(MYSQL_SERVER)
#include <m_string.h> /* To get strmov() */
#else
/* when compiled as standalone */
#include <string.h>
#define strmov(a,b) stpcpy(a,b)
#define bzero(a,b) memset(a,0,b)
#endif
#endif
#include <mysql.h>
#include <ctype.h>
#ifdef _WIN32
/* inet_aton needs winsock library */
#pragma comment(lib, "ws2_32")
#endif
#ifdef HAVE_DLOPEN
#if !defined(HAVE_GETHOSTBYADDR_R) || !defined(HAVE_SOLARIS_STYLE_GETHOST)
static pthread_mutex_t LOCK_hostname;
#endif
my_bool hello_world_init(UDF_INIT* initid, UDF_ARGS* args __attribute__((unused)),
char* is_null __attribute__((unused)), char* message __attribute__((unused)))
{
return 0;
}
void hello_world_deinit(UDF_INIT* initid, UDF_ARGS* args __attribute__((unused)),
char* is_null __attribute__((unused)), char* message __attribute__((unused)))
{}
char* hello_world(UDF_INIT *initid __attribute__((unused)),
UDF_ARGS *args, char *result, unsigned long *length,
char *is_null, char *message __attribute__((unused)))
{
char* hello = "Hello World";
return hello;
}
#endif /* HAVE_DLOPEN */
我曾尝试以两种不同的方式编译源代码,但输出相同:
gcc $(mysql_config --cflags) -shared -fPIC -o hello_world.so hello_world.c
gcc -shared -fPIC -o hello_world.so helloworld.c -I/usr/include/mysql
我将 UDF 共享库包含到 /usr/lib/mysql/plugin
并在 MySQL 中创建了函数:CREATE FUNCTION hello_world RETURNS STRING SONAME "hello_world.so";
一切都很顺利,函数执行时出现问题:
示例输出:
| Hello World ;, �� ����� x
� $ ���0 FJ
V � ?; D ��� A�C
d
Q �� �
���o |
可能是什么问题?
谢谢。
MySQL 不在 C 字符串中使用空终止符。 UDF 收到一个参数unsigned long *length
,你必须设置它。
*length = strlen(hello);
return hello;
您没有正确调用 UDF 调用。每 the documentation:
The return value of the main function
xxx()
is the function value, for long long and double functions. A string function should return a pointer to the result and set *length to the length (in bytes) of the return value. For example:memcpy(result, "result string", 13); *length = 13;
该文档还有很多内容。