mysql udf返回字符串与数据重叠

kq0g1dla  于 2021-06-15  发布在  Mysql
关注(0)|答案(1)|浏览(373)

因为这是我第一次编写自定义项,所以我尝试编写简单的自定义项来返回传递给自定义项的相同参数。
代码如下:


# 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

如果我使用自定义项执行查询: SELECT get_arg(c_name) FROM tbl; 这将返回:


# get_arg(c_name)

amogh bharat shah
viraj bharat shah

看起来,当第二行的前5个字符被实际的行数据替换时,字符串的另一部分是第一行的垃圾。
为什么会这样?我应该怎样改变函数以避免字符串重叠?

67up9zun

67up9zun1#

传递给函数的字符串不一定以null结尾,从https://dev.mysql.com/doc/refman/8.0/en/udf-arguments.html:
不要假定字符串以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];

相关问题