嗨我試圖創建一個用C寫的postgres UDT。它是一種分數類型。 我試着用一個int64和struct fraction裏面的struct mixednumber做實驗。C嵌套結構的Postgres UDT
#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);
}
存在的問題是,當我檢索mixednumber柱的小數部分的值是錯誤.. 例
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))"
任何專家可以幫助我瞭解這是怎麼回事?
噢,謝謝:) – Marc