c++ - 返回 STRING 的 MySQL UDF 与数据重叠

标签 c++ mysql mysql-udf

因为这是我第一次编写 UDF,所以我尝试编写简单的 UDF 以返回传递给 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
}

我的表有数据;

SELECT c_name FROM tbl;

这将返回数据为:

# c_name
amogh bharat shah
viraj

如果我使用 UDF 执行查询:

SELECT get_arg(c_name) FROM tbl;

返回:

# 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];

关于c++ - 返回 STRING 的 MySQL UDF 与数据重叠,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53853618/

相关文章:

MYSQL UDF 函数返回 XML

c++ - C++ 中的 MySQL 用户定义函数

c++ - 这种类型的初始化叫什么?

mysql - 如何将 'pre-formatted' 值转换为 float

mysql - 在大型更新时从 mysql 触发器向 gearman 发送作业

mysql - 无法使用 MAX_USER_CONNECTIONS 在 MariaDB 中创建用户

mysql + solr,或 solr 本身

c++ - 多模板化接口(interface)继承名称隐藏

c# - C++ 中的结构大小 & 转换为 C#

c++ - 为什么我的 OpenSSL C++ 代码会创建二进制加密输出?