如何使用数组编写 Postgres 用户定义类型

how to write a Postgres user definded type with array

我正在 Postgres 中编写一个名为 personname 的用户定义类型:

#define FLXIBLE_ARRAY_MEMBER 0

PG_MODULE_MAGIC;

typedef struct personname{
    int familyLen;
    int givenLen;
    int givenStart;
    char pname[FLXIBLE_ARRAY_MEMBER];
}personname;

我的 personname_in 和 personname_out 函数大致如下:

PG_FUNCTION_INFO_V1(pname_in);

Datum
pname_in(PG_FUNCTION_ARGS){
    char* str = PG_GETARG_CSTRING(0);
    personname *name;
    ...
    name = (personname*) palloc(sizeof(personname) + strlen(str) + 1);
    name->familyLen = familyNameLen;
    name->givenLen = givenNameLen;
    name->givenStart = givenNameStart;

    strcpy(name->pname, str);

    PG_RETURN_POINTER(name);
}

PG_FUNCTION_INFO_V1(pname_out);

Datum
pname_out(PG_FUNCTION_ARGS){
    personname *name = (personname*) PG_GETARG_POINTER(0);

    char* family = getFamily(name);
    char* given = getGiven(name);
    char* nameStr;   
    nameStr = psprintf("%s,%s", family, given);

    pfree(family);
    pfree(given);

    PG_RETURN_CSTRING(nameStr);
}

而我的sql是这样的:

CREATE FUNCTION pname_in(cstring)
   RETURNS personname
   AS '_OBJWD_/pname'
   LANGUAGE C IMMUTABLE STRICT;

CREATE FUNCTION pname_out(personname)
   RETURNS cstring
   AS '_OBJWD_/pname'
   LANGUAGE C IMMUTABLE STRICT;

CREATE TYPE personname (
   internallength = 12,
   input = pname_in,
   output = pname_out
);

现在我的代码可以正确响应 select "NAME" :: personname;,当我插入和 select 时,它可以正确访问除 pname 数组之外的 personname 中的所有参数。

我创建了一个名为 users 的 table,其中包含 pname 数组,当我键入 select * from users 时;它显示了这个:

然而,当我将我的 personname_in 和 personname_out 代码复制并粘贴到另一个 c 文件中时,将 palloc 替换为 malloc 并使用来自终端的一些输入字符串对其进行测试,它可以打印正确的 pname 值.

谁能告诉我哪里做错了,或者在 PostgreSQL 中使用数组创建新类型的正确方法是什么?

CREATE TYPE 语句不符合代码,缺少 4 字节 varlena header。

Qoth documentation:

While the details of the new type's internal representation are only known to the I/O functions and other functions you create to work with the type, there are several properties of the internal representation that must be declared to PostgreSQL. Foremost of these is internallength. Base data types can be fixed-length, in which case internallength is a positive integer, or variable-length, indicated by setting internallength to VARIABLE. (Internally, this is represented by setting typlen to -1.) The internal representation of all variable-length types must start with a 4-byte integer giving the total length of this value of the type. (Note that the length field is often encoded, as described in Section 68.2; it's unwise to access it directly.)

你必须用

定义类型
INTERNALLENGTH = VARIABLE

并且该结构必须以 4 字节整数开头。

我没有检查其他错误。