C 如何使用数组编写Postgres用户定义的类型
我正在Postgres中编写一个名为personname的用户定义类型:C 如何使用数组编写Postgres用户定义的类型,c,postgresql,user-defined-types,C,Postgresql,User Defined Types,我正在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_输入和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_输入和personname_输出函数大致如下所示:
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);
}
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
);
我的sql是这样的:
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);
}
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
);
现在我的代码可以正确响应选择“NAME”::personname代码>,当我插入并选择时,它可以正确访问personname中除pname数组之外的所有参数
当我键入select*from users时,我创建了一个名为users的表,其中包含pname数组;它表明:
然而,当我在另一个c文件中复制并粘贴我的personname_in和personname_out代码时,用malloc替换palloc并用终端的一些输入字符串测试它,它可以打印正确的pname值
有人能告诉我哪里做错了,或者用数组在PostgreSQL中创建新类型的正确方法是什么吗?create type
语句与代码不匹配,并且缺少4字节varlena
头
Qoth the:
虽然新类型的内部表示的详细信息仅为I/O函数和为使用该类型而创建的其他函数所知,但内部表示有几个属性必须声明给PostgreSQL。其中最重要的是内部长度。基本数据类型可以是固定长度,在这种情况下,internallength
是正整数,或者是可变长度,通过将internallength
设置为variable
表示。(在内部,这是通过将typlen
设置为-1来表示的。)所有可变长度类型的内部表示必须以一个4字节的整数开始,给出该类型值的总长度。(请注意,长度字段通常是编码的,如第68.2节所述;直接访问它是不明智的。)
您必须使用
INTERNALLENGTH = VARIABLE
结构必须以4字节整数开始
我没有检查其他错误。为什么要使用C?您可以使用纯SQL创建这样的类型,无需编写C扩展名,我在C文件中编写输入和输出函数,并且我还需要一些其他运算符函数,因此我必须使用C。