MySQL UDF, возвращающий STRING, перекрывает данные

Поскольку я впервые пишу 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 символов второй строки заменяются фактическими данными строки, другая часть строки является мусором из первой строки.

Почему это происходит? и что я должен изменить в функции, чтобы избежать наложения строки?

0

Решение

Строки, передаваемые в вашу функцию, не обязательно заканчиваются нулем, от 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];
1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]