返回 STRING 的 MySQL UDF 与数据重叠

Posted

技术标签:

【中文标题】返回 STRING 的 MySQL UDF 与数据重叠【英文标题】:MySQL UDF returning STRING overlaps the data 【发布时间】:2019-05-20 02:04:20 【问题描述】:

因为这是我第一次编写 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 个字符被实际行数据替换时,字符串的其他部分是第一行的垃圾。

为什么会这样?我应该改变什么功能以避免字符串重叠?

【问题讨论】:

我将 C++ 标签添加到可能有助于获得答案的问题中。 【参考方案1】:

传递给您的函数的字符串不一定以 null 结尾,来自 https://dev.mysql.com/doc/refman/8.0/en/udf-arguments.html

不要假设字符串是空终止的。

从非空终止的字符串构造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];

【讨论】:

以上是关于返回 STRING 的 MySQL UDF 与数据重叠的主要内容,如果未能解决你的问题,请参考以下文章

MYSQL UDF 函数返回 XML

为啥 MySQL UDF 返回随机数据?

删除 initid->ptr、MySQL 聚合函数 (UDF) 时失去与 MySQL 服务器的连接

在 HIVE UDF 中返回 ArrayList<String>

udf spark Scala 返回案例类

pyspark 中的 UDF 能否返回与列不同的对象?