MySQL UDF 返回 STRING 与数据重叠
MySQL UDF returning STRING overlaps the data
因为这是我第一次编写 UDF,所以我尝试将简单的 UDF 编写为 return 传递给 UDF 的相同参数。
代码如下:
#include <stdlib.h>
#include <stdio.h>
#include <string>
#include <cstring>
#include <mysql.h>
#include <ctype.h>
#include <my_global.h>
#include <my_sys.h>
using namespace std;
extern "C" my_bool get_arg_init(UDF_INIT *initid, UDF_ARGS *args,
char *message)
{
if ( ( args->arg_count != 1 ) || ( args->arg_type[0] != STRING_RESULT ) )
{
strcpy( message, "Wrong argument type." );
return 1;
}
return 0;
}
extern "C" void get_arg_deinit(UDF_INIT *initid)
{
//nothing to free here
}
extern "C" char *get_arg(UDF_INIT *initid, UDF_ARGS *args,
char *result, unsigned long *length,
char *is_null, char *error)
{
std::string str = args->args[0]; // get the first argument passed
memcpy(result, str.c_str(), str.size()); // copy argument value into result buffer
*length = str.size(); // set length
return result;//return the same argument
}
我的 table 数据为;
SELECT c_name FROM tbl;
这将 return 数据作为:
# c_name
amogh bharat shah
viraj
如果我使用 UDF 执行查询:
SELECT get_arg(c_name) FROM tbl;
这个returns:
# get_arg(c_name)
amogh bharat shah
viraj bharat shah
看起来虽然第二行的前 5 个字符被替换为实际的行数据,但字符串的其他部分是第一行的垃圾。
为什么会这样?我应该改变什么功能来避免字符串重叠?
传递给您的函数的字符串不一定以 null 结尾,来自 https://dev.mysql.com/doc/refman/8.0/en/udf-arguments.html:
Do not assume that the string is null-terminated.
从非 null 终止的字符串构造 std::string
是未定义的行为,在这种情况下,我猜缓冲区最初是 0 填充的,因此字符串在有史以来最长的字符串的末尾结束放入缓冲区。
正确的代码是:
std::string str( args->args[0], args->lengths[0] );
或跳过在 std::string
中创建不必要的副本:
memcpy(result, args->args[0], args->lengths[0]);
*length = args->lengths[0];
因为这是我第一次编写 UDF,所以我尝试将简单的 UDF 编写为 return 传递给 UDF 的相同参数。
代码如下:
#include <stdlib.h>
#include <stdio.h>
#include <string>
#include <cstring>
#include <mysql.h>
#include <ctype.h>
#include <my_global.h>
#include <my_sys.h>
using namespace std;
extern "C" my_bool get_arg_init(UDF_INIT *initid, UDF_ARGS *args,
char *message)
{
if ( ( args->arg_count != 1 ) || ( args->arg_type[0] != STRING_RESULT ) )
{
strcpy( message, "Wrong argument type." );
return 1;
}
return 0;
}
extern "C" void get_arg_deinit(UDF_INIT *initid)
{
//nothing to free here
}
extern "C" char *get_arg(UDF_INIT *initid, UDF_ARGS *args,
char *result, unsigned long *length,
char *is_null, char *error)
{
std::string str = args->args[0]; // get the first argument passed
memcpy(result, str.c_str(), str.size()); // copy argument value into result buffer
*length = str.size(); // set length
return result;//return the same argument
}
我的 table 数据为;
SELECT c_name FROM tbl;
这将 return 数据作为:
# c_name
amogh bharat shah
viraj
如果我使用 UDF 执行查询:
SELECT get_arg(c_name) FROM tbl;
这个returns:
# get_arg(c_name)
amogh bharat shah
viraj bharat shah
看起来虽然第二行的前 5 个字符被替换为实际的行数据,但字符串的其他部分是第一行的垃圾。
为什么会这样?我应该改变什么功能来避免字符串重叠?
传递给您的函数的字符串不一定以 null 结尾,来自 https://dev.mysql.com/doc/refman/8.0/en/udf-arguments.html:
Do not assume that the string is null-terminated.
从非 null 终止的字符串构造 std::string
是未定义的行为,在这种情况下,我猜缓冲区最初是 0 填充的,因此字符串在有史以来最长的字符串的末尾结束放入缓冲区。
正确的代码是:
std::string str( args->args[0], args->lengths[0] );
或跳过在 std::string
中创建不必要的副本:
memcpy(result, args->args[0], args->lengths[0]);
*length = args->lengths[0];