gpt4 book ai didi

sql - C 中带有嵌套结构的 Postgres UDT

转载 作者:行者123 更新时间:2023-11-29 11:44:44 25 4
gpt4 key购买 nike

您好,我正在尝试创建一个用 C 编写的 postgres UDT。它是一种分数类型。我正在尝试使用内部包含 int64 和结构分数的结构混合数进行试验。

#include "postgres.h"
#include "fmgr.h"
#include <stdbool.h>

PG_MODULE_MAGIC;

typedef struct Fraction
{
int64 numerator;
int64 denominator;
} Fraction;

PG_FUNCTION_INFO_V1(fraction_in);

Datum
fraction_in(PG_FUNCTION_ARGS)
{
char *input = PG_GETARG_CSTRING(0);
int64 n, d;
bool valid;

Fraction *result;

valid = sscanf(input, "(%ld/%ld)", &n, &d) == 2;

if (!valid)
ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
errmsg("invalid input syntax for fraction: \"%s\"", input)));

if (d == 0)
ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
errmsg("denominator cannot be \"%ld\" in \"%s\"", d, input)));

result = (Fraction *) palloc(sizeof(Fraction));

result->numerator = n;
result->denominator = d;

PG_RETURN_POINTER(result);
}

PG_FUNCTION_INFO_V1(fraction_out);

Datum
fraction_out(PG_FUNCTION_ARGS)
{
Fraction *fraction = (Fraction *) PG_GETARG_POINTER(0);
char *result;

result = psprintf("(%ld/%ld)", fraction->numerator, fraction->denominator);

PG_RETURN_CSTRING(result);
}

//////////////////////////////////////
// Mixed Fractions or Mixed Numbers //
//////////////////////////////////////

typedef struct MixedNumber
{
int64 wholeNumber;
Fraction *fraction;
} MixedNumber;

PG_FUNCTION_INFO_V1(mixednumber_in);

Datum
mixednumber_in(PG_FUNCTION_ARGS)
{
char *input = PG_GETARG_CSTRING(0);
int64 w, n, d;
bool valid;

MixedNumber *mixed;

valid = sscanf(input, "(%ld+(%ld/%ld))", &w, &n, &d)
== 3;

if (!valid)
ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
errmsg("invalid input syntax for fraction: \"%s\"", input)));

if (d == 0)
ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
errmsg("denominator cannot be \"%ld\" in \"%s\"", d, input)));

mixed = (MixedNumber *) palloc(sizeof(MixedNumber));

mixed->wholeNumber = w;
mixed->fraction = (Fraction *) palloc(sizeof(Fraction));
mixed->fraction->numerator = n;
mixed->fraction->denominator = d;

PG_RETURN_POINTER(mixed);
}

PG_FUNCTION_INFO_V1(mixednumber_out);

Datum
mixednumber_out(PG_FUNCTION_ARGS)
{
MixedNumber *mixed = (MixedNumber *) PG_GETARG_POINTER(0);

char *result;

result = psprintf("(%ld+(%ld/%ld))",
mixed->wholeNumber, mixed->fraction->numerator, mixed->fraction->denominator);

PG_RETURN_CSTRING(result);
}

问题是当我检索混合数字列时,小数部分的值是错误的。例如

CREATE TABLE mixednumber_test (val mixednumber);

INSERT INTO mixednumber_test VALUES ('(1+(7/8))'), ('(-1+(-7/8))'), ('(+1+(7/- 8))'), ('(0+(-7/-8))'), ('(-0+(+7/8))'), ('(2+(7/+8)) '), ('(9+(+7/+8))');

SELECT * FROM mixednumber_test;

结果是:..

"(1+(0/0))"
"(-1+(32/4294967952))"
"(1+(94284056329736/16))"
"(0+(94284055669488/128))"
"(0+(0/94284056646312))"
"(2+(524/94284056644432))"
"(9+(94284055669488/16))"

任何专家都可以帮助我了解发生了什么吗?

最佳答案

用户数据类型不能包含指针引用的嵌套结构,因为数据(尤其是 MixedNumber 结构中的 Fraction * 指针)“按原样”存储“(而不是递归地指向它指向的数据)。因此,如果指针在导入保存的值后被取消引用,它可能不再包含原始值。

您必须在连续的内存块中提供所有数据,也许可以通过将定义更改为

typedef struct MixedNumber {
int64 wholeNumber;
Fraction fraction;
} MixedNumber;

并相应地更改成员访问权限。另外不要忘记将内部长度扩大到现在的 24 字节 (sizeof(MixedNumber))。

关于sql - C 中带有嵌套结构的 Postgres UDT,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42437834/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com