首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >PostgreSQL C函数: libpq不链接?

PostgreSQL C函数: libpq不链接?
EN

Stack Overflow用户
提问于 2019-09-10 12:28:44
回答 1查看 586关注 0票数 6

我想为PostgreSQL编写一个C函数。对于这个函数,我需要使用libpq查询一些数据,所以我首先编写了一个虚拟函数来测试这个部分:

代码语言:javascript
复制
#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中使用它时,它说:

代码语言:javascript
复制
ERROR:  could not load library "/usr/local/lib/postgresql/test.so": Error relocating /usr/local/lib/postgresql/test.so: PQexec: symbol not found

奇怪的是,PQsetdbLoginPQexec都在libpq-fe.h文件中,但只有第二个文件会导致错误。如果我注释PQexec行,那么PQsetdbLogin也会引发一个错误。

下面是我用来构建代码的Makefile:

代码语言:javascript
复制
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 --所以所有的东西都应该正常工作.但事实并非如此我也不知道为什么。

我在码头集装箱中使用PostgreSQL 9.6。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-09-10 13:08:50

如果您想要链接到外部库,则需要SHLIB_LINK,但只有在使用MODULE_big而不是MODULES时才有效。

一个有效的Makefile将是

代码语言:javascript
复制
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 *结果;char *c = PQgetvalue(res,0,0);VarChar* palloc(strlen(c) + VARHDRSZ);strncpy(VARDATA(结果),c,strlen(c));SET_VARSIZE(结果,strlen(c) + VARHDRSZ);
  • 在服务器函数中编写客户端代码通常是错误的。 如果只需在当前会话中运行查询,则使用服务器编程接口
  • 我想您的函数只是示例代码,但是您需要在后端终止之前关闭连接,否则会有连接泄漏。
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57871869

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档