mysql 错误代码:2013错误代码:2013

8aqjt8rx  于 5个月前  发布在  Mysql
关注(0)|答案(1)|浏览(65)

我在MySQL中有以下查询:

SELECT FUNCTIONTEST(Column1, 27, 'SOMETHING', Column2) AS RANK1 FROM table1

字符串

  • Column1* 为varchar(100),Column2 为unsigned tinyint(3),默认值为0。不使用NULL。
  • FUNCTIONTEST* 是一个UDF函数,它以前工作得很好,但我想通过第四个参数来扩展它。

自定义项初始化函数清单:

bool FUNCTIONTEST_init(UDF_INIT *initid, UDF_ARGS *args, char *message) {
  if ((args->arg_count != 4) ||
      (args->arg_type[0] != STRING_RESULT || args->arg_type[1] != INT_RESULT || args->arg_type[2] != STRING_RESULT || args->arg_type[3] != INT_RESULT)) {
    strcpy(message, "Function requires 4 arguments, (string, int, string, int)");
    return 1;
  }
  const longlong abc = *((longlong*) args->args[1]);
  const long long def = *((long long*) args->args[3]);


当使用Column2时,最后一行会导致问题。它会生成错误:

  • 错误代码:2013。查询过程中与MySQL服务器失去连接 *

但是,如果我直接用一个数字调用query,而不是使用column,它就可以工作。

SELECT FUNCTIONTEST(Column1, 27, 'SOMETHING', 0) AS RANK1 FROM table1


有谁知道,可能是什么问题?
Column1是一个字符串,可以正常工作(不是代码片段的一部分)。我尝试将Column2改为varchar,但在UDF中将字符串转换为整数时遇到了麻烦。我还尝试在查询中使用 CAST
要复制,请在MySQL中创建以下表格:

SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
START TRANSACTION;
SET time_zone = "+00:00";

/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;

CREATE TABLE `stack` (
  `ID` int(11) NOT NULL,
  `Name` varchar(100) NOT NULL DEFAULT '',
  `Subtract` tinyint(3) UNSIGNED NOT NULL DEFAULT 0
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

INSERT INTO `stack` (`ID`, `Name`, `Subtract`) VALUES
(1, 'Test1 Test2 Test3', 0),
(2, 'Test4 Test5 Test6', 6);

ALTER TABLE `stack`
  ADD PRIMARY KEY (`ID`);

ALTER TABLE `stack`
  MODIFY `ID` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=3;
COMMIT;

/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;


名为levenshtein.c的UDF文件:

#ifdef STANDARD
/* STANDARD is defined, don't use any mysql functions */
#include <string.h>
#ifdef __WIN__
typedef unsigned __int64 ulonglong; /* Microsofts 64 bit types */
typedef __int64 longlong;
#else
#endif /*__WIN__*/
#else
//#include <my_global.h>
//#include <my_sys.h>
#if defined(MYSQL_SERVER)
#include <m_string.h>
#else
/* when compiled as standalone */
#include <string.h>
#endif
#endif

#include <mysql.h>
#include <ctype.h>
typedef unsigned long long ulonglong;
typedef long long longlong;

//#ifdef HAVE_DLOPEN

/* (Expected) maximum number of digits to return */
#define LEVENSHTEIN_MAX 3
#define INSERT_MULTIPLIER 5000
#define DELETE_MULTIPLIER 0
#define TRANSPOSITION_MULTIPLIER 2000

static inline int minimum(int a, int b, int c) {
  int min = a;
  if (b < min)
    min = b;
  if (c < min)
    min = c;
  return min;
}

#define min4(a,b,c,d) ((a)< (b) ? minimum((a),(c),(d)) : minimum((b),(c),(d)))

static inline int maximum(int a, int b) {
  if (a > b) return a;
  else return b;
}

#define min(x,y) ((x) < (y) ? (x) : (y))

bool  levenshtein2_init(UDF_INIT *initid, UDF_ARGS *args, char *message);
void     levenshtein2_deinit(UDF_INIT *initid);
longlong levenshtein2(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error);

bool levenshtein2_init(UDF_INIT *initid, UDF_ARGS *args, char *message) {
  if ((args->arg_count != 4) ||
      (args->arg_type[0] != STRING_RESULT || args->arg_type[1] != INT_RESULT || args->arg_type[2] != STRING_RESULT || args->arg_type[3] != INT_RESULT)) {
    strcpy(message, "Function requires 4 arguments, (string, int, string, int)");
    return 1;
  }
  const longlong sl = *((longlong*) args->args[1]);
  const long long subtract = *((long long*) args->args[3]);
  //const long long subtract = 3;
  if (sl <= 0) {
    strcpy(message, "Argument 1 must be greater than 0");
    return 1;
  }
  if (subtract < 0) {
    strcpy(message, "Argument 3 must be greater or equal to 0");
    return 1;
  }
  if (subtract > sl) {
    strcpy(message, "Argument 3 must be lower or greater to argument 1");
    return 1;
  }

  //matrix for levenshtein calculations of size 6 x n+2 x m+2 (+1 for base values and +1 for \0)
  
  int *d = (int *) malloc(sizeof(int) * 6 * (args->lengths[0] + 2) * (args->lengths[2] - subtract + 2));
  if (d == NULL) {
    strcpy(message, "Failed to allocate memory");
    return 1;
  }

  initid->ptr = (char*) d;
  initid->max_length = LEVENSHTEIN_MAX;
  initid->maybe_null = 0; //doesn't return null

  return 0;
}

void levenshtein2_deinit(UDF_INIT *initid) {
  if (initid->ptr != NULL)
    free(initid->ptr);
}

longlong levenshtein2(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error) {
  // Logic removed from example
  longlong bestDistance = 5;
    
  return (longlong) bestDistance;
}


编译为:

gcc -fPIC -o levenshtein.so -shared levenshtein.c `mysql_config --include`


创建函数:

CREATE FUNCTION levenshtein2 RETURNS INT SONAME 'levenshtein.so';


测试查询:

SELECT LEVENSHTEIN2(Name, 17, 'TEST1', Subtract) AS RANK1, stack.* FROM stack


当在levenshtein. c中注解第63行并取消注解第64行时,它可以工作。它也可以与第63行一起工作,它的查询是这样执行的:

SELECT LEVENSHTEIN2(Name, 17, 'TEST1', 3) AS RANK1, stack.* FROM stack

mi7gmzs6

mi7gmzs61#

我目前的解决方法是不验证和使用init函数中第四个参数的值,这意味着我分配了比我需要的更多的内存,但我可以接受,因为它与我以前使用这个函数没有什么不同。

bool levenshtein2_init(UDF_INIT *initid, UDF_ARGS *args, char *message) {
  if ((args->arg_count != 4) ||
      (args->arg_type[0] != STRING_RESULT || args->arg_type[1] != INT_RESULT || args->arg_type[2] != STRING_RESULT || args->arg_type[3] != INT_RESULT)) {
    strcpy(message, "Function requires 4 arguments, (string, int, string, int)");
    return 1;
  }
  const longlong sl = *((longlong*) args->args[1]);
  //const long long subtract = *((long long*) args->args[3]);
  if (sl <= 0) {
    strcpy(message, "Argument 1 must be greater than 0");
    return 1;
  }

  //matrix for levenshtein calculations of size 6 x n+2 x m+2 (+1 for base values and +1 for \0)
  
  int *d = (int *) malloc(sizeof(int) * 6 * (args->lengths[0] + 2) * (args->lengths[2] + 2));
  if (d == NULL) {
    strcpy(message, "Failed to allocate memory");
    return 1;
  }

  initid->ptr = (char*) d;
  initid->max_length = LEVENSHTEIN_MAX;
  initid->maybe_null = 0; //does not return null

  return 0;
}

longlong levenshtein2(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error) {
  longlong subtract = *((longlong*) args->args[3]);
  if (subtract < 0) {
    subtract = 0;
  }
  int sl = *((int*) args->args[1]);
  if (subtract > sl) {
    subtract = 0;
  }
  
  // Logic removed from example
  longlong bestDistance = subtract;
    
  return (longlong) bestDistance;
}

字符串
我仍然不明白,为什么longlong subtract = *((longlong*) args->args[3]);在init函数中不起作用。显然,来自DB的结果是整数,并且根据文档进行了转换。它在main函数中起作用。
如果提供了错误的参数值,我将 subtract 变量更改为0,而不是使函数失败。

相关问题