【发布时间】:2017-07-05 00:21:34
【问题描述】:
我使用的是 PostgreSQL 9.6。我想在 PostgreSQL 上创建一个新的货币类型扩展,其中包含一个字符串和一个数值。
根据文档https://www.postgresql.org/docs/9.6/static/sql-createtype.html,我可以直接在 PostgreSQL 中使用 compose 类型,但这不是我想要的,因为我希望能够使用字符串来表示类型并进行强制转换。所以解决方案是创建一个自定义类型,例如示例“box”类型。文档显示:
CREATE TYPE box;
CREATE FUNCTION my_box_in_function(cstring) RETURNS box AS ... ;
CREATE FUNCTION my_box_out_function(box) RETURNS cstring AS ... ;
CREATE TYPE box (
INTERNALLENGTH = 16,
INPUT = my_box_in_function,
OUTPUT = my_box_out_function
);
但是对于如何编写这样的函数并没有真正的帮助。进一步搜索显示该函数只能用 C 编写,并且显示的是简单类型的示例,而不是结构类型。
所以我基本上想要类似的东西
typedef struct {
char code[4];
Numeric numeric;
} Currency
我想使用固定类型的 Numeric,这样可以避免实现 varlena 标头的额外工作。此外货币通常有固定的小数点。我还希望能够在内部使用 Numeric 类型,因为它允许我重用 Numeric 的功能。
如何使用 Numeric,以便可以使用与 PostgreSQL 类似的语法(例如 Numeric(10,2))来定义我的结构?我可以在 currency_in 函数中使用 numeric_in 函数吗?
【问题讨论】:
-
我怀疑你实际上是想创建一个 Composite 类型,而不是 Base 类型。
-
以这种方式做你想做的事是很多工作。您需要定义运算符、用于索引访问的运算符类等等。你需要对 postgres 的很多内容有深入的了解; C 语言中的用户定义数据类型的全面实现并非易事。考虑一个域或复合类型。
-
事实上,按照你描述的方式去做是行不通的,因为 VARLENA 标题必须放在第一位。
-
@Kevin 是的,但是对于复合类型,我不能有自定义输出,也不能输入。我必须输入内容为 ('USD', 1) 而不是 'USD1'
-
@CraigRinger 但如果它是固定大小的数字类型,您是否需要 varlena 标头。那么整个货币类型也是固定大小的。
标签: c postgresql postgresql-extensions