是否可以使用 plpgsql 或 SQL 创建用户定义的类型?

Eva*_*oll 5 postgresql datatypes plpgsql

不同于DOMAIN我想知道是否可以在没有 C 的情况下创建用户定义的类型。

具体来说,我想创建一个这样的类型

CREATE TYPE name (
    INPUT = input_function,
    OUTPUT = output_function
    [ , RECEIVE = receive_function ]
    [ , SEND = send_function ]
    [ , TYPMOD_IN = type_modifier_input_function ]
    [ , TYPMOD_OUT = type_modifier_output_function ]
    [ , ANALYZE = analyze_function ]
    [ , INTERNALLENGTH = { internallength | VARIABLE } ]
    [ , PASSEDBYVALUE ]
    [ , ALIGNMENT = alignment ]
    [ , STORAGE = storage ]
    [ , LIKE = like_type ]
    [ , CATEGORY = category ]
    [ , PREFERRED = preferred ]
    [ , DEFAULT = default ]
    [ , ELEMENT = element ]
    [ , DELIMITER = delimiter ]
    [ , COLLATABLE = collatable ]
)
Run Code Online (Sandbox Code Playgroud)

input_function 和 output_function 都说,

input_function 将类型的外部文本表示转换为为该类型定义的运算符和函数使用的内部表示。output_function 执行反向转换。输入函数可以声明为采用一个 cstring 类型的参数,或者采用cstring、 oid 和 integer类型的三个参数。第一个参数是输入文本作为C 字符串,第二个参数是类型自己的 OID(数组类型除外,它们接收其元素类型的 OID),第三个参数是目标列的 typmod,如果已知(如果不知道,将传递 -1)。输入函数必须返回数据类型本身的值。通常,输入函数应声明为 STRICT;如果不是,则在读取 NULL 输入值时将使用 NULL 第一个参数调用它。在这种情况下,该函数仍必须返回 NULL,除非它引发错误。(这种情况主要是为了支持域输入函数,这可能需要拒绝 NULL 输入。)输出函数必须声明为采用新数据类型的一个参数。输出函数必须返回类型 cstring。不为 NULL 值调用输出函数。

在这两种情况下,都需要 a cstring,但在这两种情况下,当我尝试创建它时,我得到

错误:PL/pgSQL 函数不能接受类型 cstring

或者,

错误:SQL 函数不能有 cstring 类型的参数

这可以在没有 C 的情况下完成吗?

war*_*yen 0

在 PostgreSQL 中,不使用 C 就不可能创建用户定义类型。 CREATE TYPE 语句旨在创建需要低级实现和操作的复杂数据类型,这通常涉及编写 C 函数。

您收到的错误消息表明 PL/pgSQL 函数(用 PostgreSQL 过程语言编写的函数)无法接受或具有 cstring 类型的参数。此外,SQL 函数(用 SQL 编写的函数)也不能具有 cstring 类型的参数。

如果要创建具有自定义输入和输出函数的用户定义类型,则需要使用 PostgreSQL 扩展 API 在 C 中实现这些函数。输入函数将处理类型的外部文本表示形式到内部表示形式的转换,输出函数将执行相反的转换。

下面是如何使用 C 创建具有自定义输入和输出函数的用户定义类型的示例:

#include "postgres.h"
#include "fmgr.h"
#include "utils/builtins.h"

PG_MODULE_MAGIC;

typedef struct
{
    /* Define your type's internal representation here */
    /* ... */
} MyType;

PG_FUNCTION_INFO_V1(mytype_in);

Datum mytype_in(PG_FUNCTION_ARGS)
{
    char* str = PG_GETARG_CSTRING(0);
    /* Implement the conversion logic from external textual representation to internal representation */
    /* ... */
    PG_RETURN_POINTER(result);
}

PG_FUNCTION_INFO_V1(mytype_out);

Datum mytype_out(PG_FUNCTION_ARGS)
{
    MyType* mytype = (MyType*)PG_GETARG_POINTER(0);
    /* Implement the conversion logic from internal representation to external textual representation */
    /* ... */
    PG_RETURN_CSTRING(result);
}

/* Register the input and output functions */

void _PG_init(void)
{
    /* Define the user-defined type here using the appropriate API functions */
    /* ... */
}
Run Code Online (Sandbox Code Playgroud)

请注意,使用 C 创建具有自定义输入和输出函数的用户定义类型需要熟悉 C 编程和 PostgreSQL 扩展开发过程。您需要将 C 代码编译成共享库(扩展)并将其安装到您的 PostgreSQL 服务器中。