PostgreSQL C风格的自定义函数FuncCallContext结构体描述及示例
来源:互联网 发布:莆田精仿鞋淘宝网店 编辑:程序博客网 时间:2024/06/17 20:05
1.FuncCallContext详细说明
/*------------------------------------------------------------------------- * 函数调用上下文struct(SRF为Set Returning Functions) *------------------------------------------------------------------------- * * 此结构保存设置返回函数的函数上下文。 * 使用fn_extra在调用之前保存一个指针 * 此struct适用于函数需要返回多行时使用 */typedef struct FuncCallContext{ /* * 函数以前调用过的次数 * call_cntr由SRF_FIRSTCALL_INIT()初始化为0 * 并在每次调用SRF_RETURN_NEXT()时递增 */ uint64 call_cntr; /* * [可选参数]最大调用数量 * max_calls只是为了方便起见设置它是可选的.如果没有设置 * 你必须提供替代方法来知道什么时候函数已经完成 * 这个值类似select中的limit */ uint64 max_calls; /* * 可选指针到插槽(已过时,不要再使用) * 已过时,只是为了兼容以前的版本 */ TupleTableSlot *slot; /* * [可选参数]用户提供的上下文指针 * uuser_fctx用作指向您自己定义的指针 * 以便在函数调用之间保留任意上下文信息 */ void *user_fctx; /* * [可选参数]指向包含属性类型输入元数据的struct的指针 * attinmeta用于返回元组(即复合数据类型) * 并且在返回基本数据类型时不使用 * 仅当您打算使用BuildTupleFromCStrings()创建返回元组时才需要 */ AttInMetadata *attinmeta; /* * 使用多次调用必须的structures内存上下文 * multi_call_memory_ctx在调用SRF_FIRSTCALL_INIT()时设置 * 并由SRF_RETURN_DONE()用于清理. * 对于要在SRF中多次调用中重用的内存来说这是最合适的内存上下文. */ MemoryContext multi_call_memory_ctx; /* * [可选参数]指向包含元组描述的struct的指针 * tuple_desc在返回元组(即复合数据类型)时使用 * 只有在要使用heap_form_tuple()而不是BuildTupleFromCStrings()构建元组时才需要使用 * 请注意,TupleDesc指针应该先运行BlessTupleDesc() */ TupleDesc tuple_desc;} FuncCallContext;
2.AttInMetadata示例,windows或Linux均可,如果不能编译,请添加必须的头文件
#include "postgres.h"#include "fmgr.h"#ifdef PG_MODULE_MAGICPG_MODULE_MAGIC;#endifPGDLLEXPORT Datum retcomposite(PG_FUNCTION_ARGS);PG_FUNCTION_INFO_V1(retcomposite);Datum retcomposite(PG_FUNCTION_ARGS) { FuncCallContext *funcctx; uint64 call_cntr, max_calls; TupleDesc tupdesc; AttInMetadata *attinmeta; /* stuff done only on the first call of the function */ if (SRF_IS_FIRSTCALL()) { MemoryContext oldcontext; /* create a function context for cross-call persistence*/ funcctx = SRF_FIRSTCALL_INIT(); /* switch to memory context appropriate for multiple function calls */ oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx); /*设置返回的记录集数量 */ funcctx->max_calls = PG_GETARG_UINT32(0); /* Build a tuple descriptor for our result type */ if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("function returning record called in context that cannot accept type record"))); /* generate attribute metadata needed later to produce tuples from raw C strings */ attinmeta = TupleDescGetAttInMetadata(tupdesc); funcctx->attinmeta = attinmeta; MemoryContextSwitchTo(oldcontext); //elog(NOTICE, "%d", 0); } //elog(NOTICE, "%s", "x"); /* stuff done on every call of the function */ funcctx = SRF_PERCALL_SETUP(); call_cntr = funcctx->call_cntr; max_calls = funcctx->max_calls; attinmeta = funcctx->attinmeta; if (call_cntr < max_calls) { /* do when there is more left to send */ char **values; HeapTuple tuple; Datum result; /* Prepare a values array for building the returned tuple. This should be an array of C strings which will be processed later by the type input functions. */ values = (char **)palloc(3 * sizeof(char *)); values[0] = (char *)palloc(16 * sizeof(char)); values[1] = (char *)palloc(16 * sizeof(char)); values[2] = (char *)palloc(16 * sizeof(char)); snprintf(values[0], 16, "%d", 1 * PG_GETARG_INT32(1)); snprintf(values[1], 16, "%d", 2 * PG_GETARG_INT32(1)); snprintf(values[2], 16, "%d", 3 * PG_GETARG_INT32(1)); /* build a tuple */ tuple = BuildTupleFromCStrings(attinmeta, values); /* make the tuple into a datum */ result = HeapTupleGetDatum(tuple); /* clean up (this is not really necessary) */ pfree(values[0]); pfree(values[1]); pfree(values[2]); pfree(values); SRF_RETURN_NEXT(funcctx, result); } else { /* do when there is no more left */ SRF_RETURN_DONE(funcctx); }}
3.函数定义
其中retcomposite的第1个参数是调用次数(返回的记录数量)
create type __retcomposite as (f1 integer, f2 integer, f3 integer);create function retcomposite(integer, integer) returns setof __retcompositeas 'pg_kmcb', 'retcomposite'language C immutable strict;
或者使用out参数
create function retcomposite(in integer, in integer,out f1 integer, out f2 integer, out f3 integer) returns setof recordas 'pg_kmcb', 'retcomposite'language C immutable strict;
注意:函数定义只能使用其中的一个
4.定义control,这里我编译的扩展是pg_kmcb.so或pg_kmcb.dll
comment = '自定义C风格的函数'default_version = '1.0'module_pathname = '$libdir/pg_kmcb'relocatable = true
5.创建扩展
以postgres用户连接到指定的数据库,然后运行
create extension pg_kmcb;
6.使用方法
返回100条一样的记录
select * from retcomposite(100,1);
阅读全文
0 0
- PostgreSQL C风格的自定义函数FuncCallContext结构体描述及示例
- C语言结构体及函数传递数组参数示例
- PostgreSQL C风格函数TEXT优化
- C风格struct结构体的对齐
- postgresql中自定义函数脚本的备份及恢复
- postgresql 多行变一行,C语言自定义函数
- 【C/C++】qt库结构及示例
- 【C/C++】qt库结构及示例
- Postgresql 窗口函数示例
- 自定义协议的注册及程序示例(C#)
- C连接PostgreSQL示例
- 结构体中指针赋值问题的分析及C代码示例
- 结构体中指针赋值问题的分析及C代码示例
- verilog的描述风格
- C语言的编码风格-文件描述(1)
- C语言结构体及typedef关键字定义结构体别名和函数指针的应用
- 关于set的自定义比较函数的使用及结构体的上下二分用法
- 使用C编写的动态链接库为PostgreSQL数据库添加自定义函数
- postgresql timestamp timestamptz 使用注意事项
- Eureka error "java.net.UnknownHostException: c1438e0d5866
- 清空postgresql shared_buffers
- postgresql10改进说明(翻译)
- PostgreSQL Windows简易安装
- PostgreSQL C风格的自定义函数FuncCallContext结构体描述及示例
- Spring核心类介绍
- PostgreSQL C风格函数TEXT优化
- 应用数据科学的现状:近期观察机器学习实际应用的趋势和对关键瓶颈的探讨
- [VS]VS2017 安装ReportDesigner/ReportViewer的方法
- Linux 虚拟机的安装与软件安装
- lightoj 1071
- 蓝桥杯--错误票据
- Android 中GreenDao3.0简单使用