我试图从用C编写的UDF中连接到本地主机上的MySQL数据库。我创建了一个用户定义的函数,将它作为插件文件夹中的共享对象提供给MySQL DB,并使UDF可用:
CREATE FUNCTION test_udf RETURNS INTEGER SONAME 'test_udf.so';这意味着我可以用:
SELECT test_udf();在调用test_udf()时,它应该连接到本地主机上的数据库、数据库中的SELECT数据、处理数据并返回一个整数值(如果成功)。
这在Mac下非常有效,但我没有机会在CentOS 7下工作。一旦UDF试图连接本地主机上的DB,我就会得到错误:
无法连接到“localhost”上的MySQL服务器
当然,我对my.cnf做了适当的设置,并负责防火墙设置。
有谁有主意吗?有人试过这样的东西吗?
这段代码使用gcc完美地在Mac和CentOS上编译。
gcc $(mysql_config —cflags —include —libs) -shared -fPIC -o test_udf.so test_udf.c/// DEBUG MODE FOR IDE (comment out if UDF need´s to be compiled using gcc from commandline) ///////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//#define DEBUG //<---------- COMMENT OUT IF COMPILATION AS SHARED OBJECT
//#define LINUX
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/***********************************************************************************************************************
* MySQL udf function prototypes
*
* for STRING functions:
* ++++++++++++++++++++++
* char *xxx(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long *length,char *is_null,
* char *error);
*
* for INTEGER functions:
* ++++++++++++++++++++++
* long long xxx(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error);
*
* for REAL functions:
* ++++++++++++++++++++++
* double xxx(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error);
*
* for DECIMAL functions:
* ++++++++++++++++++++++
* DECIMAL functions return string values and should be declared the same way as STRING functions.
* ROW functions are not implemented.
*
* Initialization / Deinitialization
* +++++++++++++++++++++++++++++++++
* The initialization and deinitialization functions are declared like this:
* my_bool xxx_init(UDF_INIT *initid, UDF_ARGS *args, char *message);
* void xxx_deinit(UDF_INIT *initid);
*
***********************************************************************************************************************/
/***********************************************************************************************************************
* UDF global defines (needed for debug & UDF BOTH!)
***********************************************************************************************************************/
#define QUERY_1 "SELECT * FROM test_table"
/***********************************************************************************************************************
* UDF global defines (needed for debug & UDF)
***********************************************************************************************************************/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#ifdef DEBUG
#define DEBUG_ON 1 // Debugging mode is on -> for testing in IDE
#else
/***********************************************************************************************************************
* automatic UDF function name generation
***********************************************************************************************************************/
#define DEBUG_ON 0 // Debugging mode is of when compiled as shared object
#define UDF_RETURN_TYPE my_ulonglong // the return value type <---------- TYPE IN RETURN VALUE TYPE
#define UDF_FCT_NAME test_udf // the UDF function name <---------- TYPE IN UDF FUNCTION NAME
#define INIT_FCT_NAME test_udf_init // the UDF init function name <---------- TYPE IN UDF INIT FUNCTION NAME
#define DEINIT_FCT_NAME test_udf_deinit // the UDF deinit function name <---------- TYPE IN UDF DEINIT FUNCTION NAME
#endif
/***********************************************************************************************************************
* Includes
***********************************************************************************************************************/
#ifdef DEBUG
#include <stdio.h>
#include <stdlib.h>
#ifndef LINUX
#include "include/mysql.h"
#else
#include "mysql/mysql.h"
#endif
#include <string.h>
#include "my_mysql_header.h"
#else
#include "my_mysql_header.h"
#ifdef STANDARD
/* STANDARD is defined, don't use any mysql functions */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#ifdef __WIN__
typedef unsigned __int64 ulonglong;/* Microsofts 64 bit types */
typedef __int64 longlong;
#else
typedef unsigned long long ulonglong;
typedef long long longlong;
#endif /*__WIN__*/
#else
#include <my_global.h>
#include <my_sys.h>
#if defined(MYSQL_SERVER)
#include <m_string.h>/* To get strmov() */
#else
/* when compiled as standalone */
#include <string.h>
#define strmov(a,b) stpcpy(a,b)
#define bzero(a,b) memset(a,0,b)
#define memcpy_fixed(a,b,c) memcpy(a,b,c)
#endif
#endif
#include <mysql.h>
#include <ctype.h>
#endif
//#endif
#ifndef DEBUG
/***********************************************************************************************************************
* MySQL UDF function prototypes
***********************************************************************************************************************/
my_bool INIT_FCT_NAME(UDF_INIT *initid, UDF_ARGS *args, char *message);
void DEINIT_FCT_NAME(UDF_INIT *initid __attribute__((unused)));
UDF_RETURN_TYPE UDF_FCT_NAME(UDF_INIT* initid,
UDF_ARGS* args __attribute__((unused)),
char* is_null __attribute__((unused)),
char* error __attribute__((unused)));
#endif
/***********************************************************************************************************************
* Other function prototypes
***********************************************************************************************************************/
/***********************************************************************************************************************
* Other functions
***********************************************************************************************************************/
int finish_with_error(MYSQL *con)
{
mysql_close(con);
return 1;
}
/***********************************************************************************************************************
* MySQL udf function definitions
***********************************************************************************************************************/
#ifdef DEBUG
int main ()
{
#else
my_bool INIT_FCT_NAME(UDF_INIT *initid, UDF_ARGS *args, char *message)
{
if(!(args->arg_count == 0)) {
strcpy(message, "No Arguments expected!");
return 1;
}
return 0;
}
void DEINIT_FCT_NAME(UDF_INIT *initid __attribute__((unused)))
{
}
UDF_RETURN_TYPE UDF_FCT_NAME(UDF_INIT* initid,
UDF_ARGS* args __attribute__((unused)),
char* is_null __attribute__((unused)),
char* error __attribute__((unused)))
{
#endif
MYSQL *con = mysql_init(NULL);
if (con == NULL)
{
fprintf(stderr, "%s\n", mysql_error(con));
exit(1);
}
if (mysql_real_connect(con, ADDRESS, USER, PASSWORD, DATABASE, 0, NULL, 0) == NULL)
{
finish_with_error(con);
}
if (mysql_query(con, QUERY_1))
{
finish_with_error(con);
}
MYSQL_RES *result = mysql_store_result(con);
if (result == NULL)
{
finish_with_error(con);
}
/*
* UDF CODE GOING HERE!
*/
mysql_free_result(result);
mysql_close(con);
return 0;
}发布于 2017-04-05 12:01:24
好吧,我终于想出了办法来解决这个问题。
1)在连接之前添加了mysql_options:
mysql_options(&mysql,MYSQL_READ_DEFAULT_GROUP,"client");2)由mysql_query改为mysql_real_query
mysql_real_query(&mysql, "select * from new_schema.new_table", 34);3)将my.cnf设置为:
[client]
port=3306
socket=/var/lib/mysql/mysql.sock4)在mysql_real_connect函数中使用127.0.0.1代替"localhost“,否则将不会使用配置好的套接字。
https://stackoverflow.com/questions/43210698
复制相似问题