[英]PostgreSQL C function: libpq doesn't link?
我想为PostgreSQL编写一个C函数。 对于这个函数,我需要使用libpq查询一些数据,所以我开始编写一个虚函数来测试这个部分:
#define _XOPEN_SOURCE
#include <libpq-fe.h>
#include <postgres.h>
#include <fmgr.h>
#include <funcapi.h>
#include <executor/executor.h>
#include "test.h"
PG_FUNCTION_INFO_V1(getAnnotation);
Datum getAnnotation(PG_FUNCTION_ARGS) {
// Connection to the database
PGconn *conn = PQsetdbLogin("localhost",
"5432",
"",
"",
"postgres",
"postgres",
"password");
// Databases names
PGresult *res = PQexec (conn, "SELECT user FROM activity LIMIT 1;");
VarChar* i = PQgetvalue(res, 0, 0);
PG_RETURN_VARCHAR_P(i);
}
它应该返回我的一个表的第一行的第一列。 很简单吧? 好吧它不起作用。
当我尝试在psql中使用它时,它说:
ERROR: could not load library "/usr/local/lib/postgresql/test.so": Error relocating /usr/local/lib/postgresql/test.so: PQexec: symbol not found
奇怪的是, PQsetdbLogin
和PQexec
都在libpq-fe.h
文件中,但只有第二个导致错误。 如果我评论PQexec
行,那么PQsetdbLogin
也会引发错误。
这是我用来构建代码的Makefile:
PG_CPPFLAGS = -I$(libpq_srcdir)
LDFLAGS_INTERNAL = -L$(libdir)
SHLIB_LINK_INTERNAL = $(libpq)
SHLIB_PREREQS = submake-libpq
EXTENSION = test
DATA = test--0.1.sql
MODULES = test
# REGRESS = ... # Script for tests
PG_CONFIG = pg_config
PGXS := $(shell $(PG_CONFIG) --pgxs)
include $(PGXS)
正如你所看到的,我链接libpq所以一切都应该工作......但它没有,我不知道为什么。
我在docker容器中使用PostgreSQL 9.6。
如果要与外部库链接,则需要SHLIB_LINK
,但只有在使用MODULE_big
而不是MODULES
时才有效。
一个工作的Makefile
就是
PG_CPPFLAGS = -I$(libpq_srcdir)
SHLIB_LINK = $(libpq)
EXTENSION = test
DATA = test--0.1.sql
MODULE_big = test
OBJS = test.o
PG_CONFIG = pg_config
PGXS := $(shell $(PG_CONFIG) --pgxs)
include $(PGXS)
但是您的功能还有其他问题:
VarChar
是一个varlena
,但PQgetvalue
返回一个char *
。
您必须将值转换为varlena
,其代码类似于:
VarChar *result; char *c = PQgetvalue(res, 0, 0); result = (VarChar *) palloc(strlen(c) + VARHDRSZ); strncpy(VARDATA(result), c, strlen(c)); SET_VARSIZE(result, strlen(c) + VARHDRSZ);
在服务器函数中编写客户端代码通常是错误的想法。
如果您只需要在当前会话中运行查询,请使用服务器编程接口 。
我想你的函数只是示例代码,但是你需要在后端终止之前关闭连接,否则就会出现连接泄漏。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.