我正在尝试为PostgreSQL编写一个小扩展名。
作为测试我的模块是否正确加载的一种方法,我在void _PG_init(void)
和void _PG_fini(void)
函数中的文件中写了一些东西。以下是这两个函数的代码:
#include "postgres.h"
#include "executor\executor.h"
#include "fmgr.h"
#include "funcapi.h"
#include <stdio.h>
PG_MODULE_MAGIC;
extern void _PG_init(void);
extern void _PG_fini(void);
static void myExecutorStart(QueryDesc *queryDesc, int eflags);
static void myExecutorRun(QueryDesc *queryDesc, ScanDirection direction, uint64 count);
static void myExecutorFinish(QueryDesc *queryDesc);
static void myExecutorEnd(QueryDesc *queryDesc);
static ExecutorStart_hook_type prevExecutorStart = NULL;
static ExecutorRun_hook_type prevExecutorRun = NULL;
static ExecutorFinish_hook_type prevExecutorFinish = NULL;
static ExecutorEnd_hook_type prevExecutorEnd = NULL;
void _PG_init(void) {
FILE *file = NULL;
file = fopen("F:\\init.txt", "a+");
fprintf(file, "Init started!\n");
fclose(file);
prevExecutorStart = ExecutorStart_hook;
ExecutorStart_hook = myExecutorStart;
prevExecutorRun = ExecutorRun_hook;
ExecutorRun_hook = myExecutorRun;
prevExecutorFinish = ExecutorFinish_hook;
ExecutorFinish_hook = myExecutorFinish;
prevExecutorEnd = ExecutorEnd_hook;
ExecutorEnd_hook = myExecutorEnd;
}
void _PG_fini(void) {
FILE *file = NULL;
file = fopen("F:\\fini.txt", "a+");
fprintf(file, "Fini started!\n");
fclose(file);
ExecutorStart_hook = prevExecutorStart;
ExecutorRun_hook = prevExecutorRun;
ExecutorFinish_hook = prevExecutorFinish;
ExecutorEnd_hook = prevExecutorEnd;
}
这些函数位于名为&#34; myextension.c&#34;的文件中,编译成&#34; myextension.dll&#34;。我在Visual Studio 2015中使用以下设置构建它:
在 myExecutorXXX 函数中,我检查是否有以前的 ExecutorXXX 函数,如果它们存在则调用它们,如果它们不调用 standard_ExecutorXXX < / strong>功能。以下是其中一个功能的示例:
static void myExecutorStart(QueryDesc *queryDesc, int eflags) {
if (prevExecutorStart) prevExecutorStart(queryDesc, eflags);
else standard_ExecutorStart(queryDesc, eflags);
FILE *file = NULL;
file = fopen("F:\\query.txt", "a+");
fprintf(file, "Query: %s started!\n", queryDesc->sourceText);
fclose(file);
}
我复制了&#34; myextension.dll&#34; in&#34; ../ PostgreSQL / 9.6 / lib&#34;目录,并添加了一个&#34; myextension.control&#34;和&#34; myextension - 1.0.sql&#34; to&#34; ../ PostgreSQL / 9.6 / share / extension&#34; 。目录
myextension.control:
# pg_extension extension
comment = 'myextension!!!'
default_version = '1.0'
myextension - 1.0.sql:
-- complain if script is sourced in psql, rather than via CREATE EXTENSION
\echo Use "CREATE EXTENSION myextension" to load this file. \quit
在&#34; postgresql.conf&#34;我添加了shared_preload_libraries =&#39; myextension&#39;。之后我连接到测试数据库并运行:CREATE EXTENSION myextension;,然后重新启动服务器。
如果有人知道可能导致这种情况的原因,请提供帮助。
答案 0 :(得分:1)
有几条评论可以帮助您走上正轨:
_PG_fini()
永远不会被调用,因为模块不会被卸载。 _PG_init()
会在加载模块时调用。您的主要问题似乎是为什么没有写入F:\init.txt
以及您用于记录的其他文件。
在Windows上,PostgreSQL通常作为服务运行。我怀疑操作系统用户没有写入这些文件的权限。我对Windows及其权限管理知之甚少,但我注意到你没有检查fopen()
的返回码,所以它可能会默默地失败。
我的建议是使用日志记录基础结构,例如与
elog(LOG, "Init started!");
这会将消息写入PostgreSQL服务器日志,并且更加舒适且不易出错。
还有两条评论:
创建扩展没有意义,因为您的代码不提供任何SQL功能。 CREATE EXTENSION myextension
是无操作。
更改shared_preload_libraries
后,不要忘记重启PostgreSQL服务器。