如何使用数组编写 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 字节整数开头。
我没有检查其他错误。
我正在 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 caseinternallength
is a positive integer, or variable-length, indicated by settinginternallength
toVARIABLE
. (Internally, this is represented by settingtyplen
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 字节整数开头。
我没有检查其他错误。