热门关键字:  ubuntu  分区  Fedora  linux系统进程  函数

PostgreSQL 8.3文档-V 服务器编程-扩展SQL-C 语言函数

来源: 作者: 时间:2008-05-21 Tag: 点击:

在 SQL 里声明这个函数的一个方法是:

CREATE TYPE __retcomposite AS (f1 integer, f2 integer, f3 integer);

CREATE OR REPLACE FUNCTION retcomposite(integer, integer)
    RETURNS SETOF __retcomposite
    AS 'filename', 'retcomposite'
    LANGUAGE C IMMUTABLE STRICT;

另外一个方法是使用 OUT 参数:

CREATE OR REPLACE FUNCTION retcomposite(IN integer, IN integer,
    OUT f1 integer, OUT f2 integer, OUT f3 integer)
    RETURNS SETOF record
    AS 'filename', 'retcomposite'
    LANGUAGE C IMMUTABLE STRICT;

请注意在这个方法里,函数的输出类型实际上是匿名的 record 类型。

参阅源码发布包里的 contrib/tablefunc 获取更多有关返回集合的函数的例子。

 多态参数和返回类型

C 语言函数可以声明为接受和返回多态的类型 anyelement,anyarray,anynonarray 和 anyenum。参阅 Section 34.2.5 获取有关多态函数的更详细的解释。如果函数参数或者返回类型定义为多态类型,那么函数的作者就无法预先知道他将收到的参数,以及需要返回的数据。在 fmgr.h 里有两个过程,可以让版本-1的 C 函数知道它的参数的确切数据类型以及它需要返回的数据类型。这两个过程叫 get_fn_expr_rettype(FmgrInfo *flinfo) 和 get_fn_expr_argtype(FmgrInfo *flinfo, int argnum)。它们返回结果或者参数的类型 OID,如果这些信息不可获取,则返回 InvalidOid。结构 flinfo 通常是以 fcinfo->flinfo 进行访问的。参数 argnum 是以 0 为基的。get_call_result_type 也可以用做 get_fn_expr_rettype 替换。

比如,假设我们想写一个函数接受任意类型的一个元素,并且返回该类型的一个一维数组:

PG_FUNCTION_INFO_V1(make_array);
Datum
make_array(PG_FUNCTION_ARGS)
{
    ArrayType  *result;
    Oid         element_type = get_fn_expr_argtype(fcinfo->flinfo, 0);
    Datum       element;
    int16       typlen;
    bool        typbyval;
    char        typalign;
    int         ndims;
    int         dims[MAXDIM];
    int         lbs[MAXDIM];

    if (!OidIsValid(element_type))
        elog(ERROR, "could not determine data type of input");

    /* 获取提供的元素 */
    element = PG_GETARG_DATUM(0);

    /* 我们的维数是 1 */
    ndims = 1;
    /* 有一个元素 */
    dims[0] = 1;
    /* 数组下界是 1*/
    lbs[0] = 1;

    /* 获取有关元素类型需要的信息 */
    get_typlenbyvalalign(element_type, &typlen, &typbyval, &typalign);

    /* 然后制作数组 */
    result = construct_md_array(&element, ndims, dims, lbs,
                                element_type, typlen, typbyval, typalign);

    PG_RETURN_ARRAYTYPE_P(result);
}

下面的命令用 SQL 声明函数 make_array:

CREATE FUNCTION make_array(anyelement) RETURNS anyarray
    AS 'DIRECTORY/funcs', 'make_array'
    LANGUAGE C STRICT;

请注意使用 STRICT;这一点非常重要,因为代码没有认真测试空输入。

 共享内存和 LWLocks

附加模块可以在服务器启动的时候保留 LWLocks 和分配一篇共享内存。附加模块的共享库必须通过在 shared_preload_libraries 里面声明来预装载。共享内存是通过在你的 _PG_init 函数里面调用:

  void RequestAddinShmemSpace(int size)

来保留的。

LWLocks 是通过在 _PG_init 里调用:

  void RequestAddinLWLocks(int n)

来保留的。

为了避免可能的冲突条件,在访问每个后端并且初始化其分配的共享内存的时候,每个后端都应该使用 LWLock AddinShmemInitLock,如下所示:

        static mystruct *ptr = NULL;

        if (!ptr)
        {
                bool    found;

                LWLockAcquire(AddinShmemInitLock, LW_EXCLUSIVE);
                ptr = ShmemInitStruct("my struct name", size, &found);
                if (!ptr)
                        elog(ERROR, "out of shared memory");
                if (!found)
                {
                        初始化 shmem 区域的内容
                        使用下面一行请求任何需要的 LWLocks:
                        ptr->mylockid = LWLockAssign();
                }
                LWLockRelease(AddinShmemInitLock);
        }



相关文章:
pgSQL 集群过程
PL/SQL学习笔记:游标
Pgbouncer 管理员手册
Pgbouncer 用户手册
Pgbouncer 介绍
使用dbi-link在PG里访问异构数据库
PostgreSQL查看数据库表的大小
PostgreSQL设置默认的search path(schema)
PostgreSQL如何让数据按照中文排序
PostgreSQL利用用户定制的聚集函数选取每个分组的
PostgreSQL的FTI与中文全文索引的实践
PostgreSQL 8.3文档-V 服务器编程-扩展SQL-C 语言
在Windows系统上安装和运行PostgreSQL的常见问题
PostgreSQL常见问题
PostgreSQL 简介
Ubuntu系统下安装和配置PostgreSQL 8.1
影响postgresql性能的几个重要参数
PostgreSQL相关
如何从网络上登录其它计算机的PostgreSQL
在Ubuntu和Debian系统下安装PostgreSQL
导入文本文件中存放的数据
从其他机器登陆PostgreSQL
PostgreSQL入门
PostgreSQL 7.2 教程
PostgreSQL 8.0.0入门之创建数据库
postgresql-数据库物理存储
PL/pgSQL的结构
Postgresql-基本语句
PL/pgSQL控制结构
在 Windows 上安装客户端