PostgreSQL extend function - C example
2015-10-14 20:46
295 查看
Postgres2015全国用户大会将于11月20至21日在北京丽亭华苑酒店召开。本次大会嘉宾阵容强大,国内顶级PostgreSQL数据库专家将悉数到场,并特邀欧洲、俄罗斯、日本、美国等国家和地区的数据库方面专家助阵:
Postgres-XC项目的发起人铃木市一(SUZUKI Koichi)
Postgres-XL的项目发起人Mason Sharp
pgpool的作者石井达夫(Tatsuo Ishii)
PG-Strom的作者海外浩平(Kaigai Kohei)
Greenplum研发总监姚延栋
周正中(德哥), PostgreSQL中国用户会创始人之一
汪洋,平安科技数据库技术部经理
……
2015年度PG大象会报名地址:http://postgres2015.eventdove.com/PostgreSQL中国社区: http://postgres.cn/PostgreSQL专业1群: 3336901(已满)PostgreSQL专业2群: 100910388PostgreSQL专业3群: 150657323 |
其中一些来自PostgreSQL的contrib, 还有一些来自PostgreSQL自身的adt函数。
当然你还可以去pgfoundry和pgxn还有github上找到很多例子。
以PostgreSQL自己提供的函数为例,看看如何找到自己需要的例子,例如我要写返回record类型的函数
查找这些例子
postgres=# select proname from pg_proc where prorettype='record'::regtype and not proretset; proname ------------------------------------- pg_sequence_parameters pg_stat_get_archiver pg_identify_object pg_xlogfile_name_offset pg_stat_file record_in record_recv json_to_record jsonb_to_record pg_create_physical_replication_slot pg_create_logical_replication_slot get_rcv_replication_stat(12 rows)
如果我要写返回多条记录的函数,可以查找这些例子
postgres=# select proname from pg_proc where prorettype='record'::regtype and proretset; proname ------------------------------------- aclexplode pg_get_keywords pg_options_to_table pg_stat_get_activity pg_stat_get_wal_senders pg_show_all_settings pg_lock_status pg_prepared_xact pg_get_multixact_members pg_prepared_statement pg_cursor pg_timezone_abbrevs pg_timezone_names json_each json_each_text json_to_recordset ts_stat ts_stat ts_token_type ts_token_type ts_parse ts_parse jsonb_each jsonb_each_text jsonb_to_recordset pg_available_extensions pg_available_extension_versions pg_extension_update_paths pg_get_replication_slots pg_event_trigger_dropped_objects ts_debug ts_debug pg_logical_slot_get_changes pg_logical_slot_peek_changes pg_logical_slot_get_binary_changes pg_logical_slot_peek_binary_changes _pg_expandarray(37 rows)
例如 :
postgres=# \df+ pg_stat_get_archiver List of functions Schema | Name | Result data type | Argument data types | Type | Security | Volatility | Owner | Language | Source code | Description ------------+----------------------+------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------+----------+------------+----------+----------+----------------------+-------------------------------------------- pg_catalog | pg_stat_get_archiver | record | OUT archived_count bigint, OUT last_archived_wal text, OUT last_archived_time timestamp with time zone, OUT failed_count bigint, OUT last_failed_wal text, OUT last_failed_time timestamp with time zone, OUT stats_reset timestamp with time zone | normal | invoker | stable | postgres | internal | pg_stat_get_archiver | statistics: information about WAL archiver(1 row)
对应的代码在,你可以学到如何构造一条返回记录。
src/backend/utils/adt/pgstatfuncs.c
Datumpg_stat_get_archiver(PG_FUNCTION_ARGS){ TupleDesc tupdesc; Datum values[7]; bool nulls[7]; PgStat_ArchiverStats *archiver_stats;
/* Initialise values and NULL flags arrays */ MemSet(values, 0, sizeof(values)); MemSet(nulls, 0, sizeof(nulls));
/* Initialise attributes information in the tuple descriptor */ tupdesc = CreateTemplateTupleDesc(7, false); TupleDescInitEntry(tupdesc, (AttrNumber) 1, "archived_count", INT8OID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 2, "last_archived_wal", TEXTOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 3, "last_archived_time", TIMESTAMPTZOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 4, "failed_count", INT8OID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 5, "last_failed_wal", TEXTOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 6, "last_failed_time", TIMESTAMPTZOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 7, "stats_reset", TIMESTAMPTZOID, -1, 0);
BlessTupleDesc(tupdesc);
/* Get statistics about the archiver process */ archiver_stats = pgstat_fetch_stat_archiver();
/* Fill values and NULLs */ values[0] = Int64GetDatum(archiver_stats->archived_count); if (*(archiver_stats->last_archived_wal) == '\0') nulls[1] = true; else values[1] = CStringGetTextDatum(archiver_stats->last_archived_wal);
if (archiver_stats->last_archived_timestamp == 0) nulls[2] = true; else values[2] = TimestampTzGetDatum(archiver_stats->last_archived_timestamp);
values[3] = Int64GetDatum(archiver_stats->failed_count); if (*(archiver_stats->last_failed_wal) == '\0') nulls[4] = true; else values[4] = CStringGetTextDatum(archiver_stats->last_failed_wal);
if (archiver_stats->last_failed_timestamp == 0) nulls[5] = true; else values[5] = TimestampTzGetDatum(archiver_stats->last_failed_timestamp);
if (archiver_stats->stat_reset_timestamp == 0) nulls[6] = true; else values[6] = TimestampTzGetDatum(archiver_stats->stat_reset_timestamp);
/* Returns the record as Datum */ PG_RETURN_DATUM(HeapTupleGetDatum( heap_form_tuple(tupdesc, values, nulls)));}
[参考]
1. http://www.postgresql.org/docs/9.5/static/xfunc-c.html
2. http://www.postgresql.org/docs/9.5/static/spi.html
3. http://pgfoundry.org/
4. http://pgxn.org/
相关文章推荐
- Android之获取手机上的图片和视频缩略图thumbnails
- android 代码实现控件之间的间距
- 神器SystemTap
- [Android]在代码里运行另一个程序的方法
- 数据库链接字符串查询网站
- 肯特·贝克:改变人生的代码整理魔法
- DB2实例管理
- DB2实例管理
- 保障MySQL数据安全的14个最佳方法
- mysql问答汇集
- 网页恶意代码的预防
- 创建一个空的IBM DB2 ECO数据库的方法
- Access 2000 数据库 80 万记录通用快速分页类
- 开通一个数据库失败的原因的和解决办法
- 一个简单的asp数据库操作类
- 高手写的Tracer-Flash代码调试类代码下载
- CentOS下DB2数据库安装过程详解
- PostgreSQL新手入门教程