概述
我尝试使用C为postgres创建一个简单的自定义用户定义类型;但是,每当我使用自定义类型查询表时,数据似乎被截断(或者存在对齐问题)。我相信我在处理输入的变量性质时做错了什么。
下面是我的代码:
PG_FUNCTION_INFO_V1(hierarchy_in);
PG_FUNCTION_INFO_V1(hierarchy_out);
typedef struct Hierarchy
{
int32 length;
char path[FLEXIBLE_ARRAY_MEMBER];
} Hierarchy;
Datum
hierarchy_in(PG_FUNCTION_ARGS)
{
char *input_str = PG_GETARG_CSTRING(0);
int32 input_len = strlen(input_str);
Hierarchy *result;
result = (Hierarchy *)palloc(VARHDRSZ + input_len);
SET_VARSIZE(result, VARHDRSZ + input_len);
strncpy(result->path, input_str, input_len);
PG_RETURN_POINTER(result);
}
Datum
hierarchy_out(PG_FUNCTION_ARGS)
{
Hierarchy *input = (Hierarchy *)PG_GETARG_POINTER(0);
char *result;
int32 input_len = VARSIZE(input) - VARHDRSZ;
result = pnstrdup(input->path, input_len);
PG_RETURN_CSTRING(result);
}
下面是我的测试用例:
DROP TABLE TESTING;
DROP EXTENSION hierarchy CASCADE;
CREATE EXTENSION hierarchy;
CREATE TABLE TESTING (
id SERIAL PRIMARY KEY,
position hierarchy
);
INSERT INTO TESTING (position) VALUES ('0123456789');
INSERT INTO TESTING (position) VALUES ('Hello World');
SELECT * FROM TESTING;
1条答案
按热度按时间vuktfyat1#
这就像你的字符串的空终止丢失了。
虽然这样可以工作,但在开始时仍然会有缺失的字符。
由于PostgreSQL data type期望第一个字节存储可变长度数据的长度,因此代码需要为:
从“User-Defined Types”开始,PostgreSQL提供的
VARSIZE
和SET_VARSIZE
宏用于处理头部分。hierarchy_in()
函数已经读取了没有空终止符的输入字符串,将字符串的长度存储在Hierarchy
结构体的length字段中,并使用memcpy
将没有空终止符的输入字符串复制到result->path
。但是,
hierarchy_out()
函数会从提取的数据创建一个新的以null结尾的C字符串,并将其作为C字符串返回。这应该可以让你打印出C-String,包括所有预期的字符。