创建自定义域postgres数组

时间:2017-04-06 15:11:26

标签: sql postgresql enums

由于枚举的继承限制(您无法在函数中向枚举添加值),我将切换到自定义域,并使用检查约束来验证值。我需要能够创建自定义枚举的数组,但是当我尝试这样的事情时:

CREATE DOMAIN foo AS text CHECK (VALUE IN ('foo', 'bar'));
CREATE TABLE foo_table(foo_column foo[]);

我收到错误

type "foo[]" does not exist

进行一些谷歌搜索,我发现this from 2004使得它看起来像是对此的支持。有没有办法做到这一点?

谢谢!

更新

我想出了一个hacky解决方案,如果没有人在几天内找到更好的解决方案,我会把它作为答案。此解决方案意味着您不能将类型重用为数组,您必须创建一个充当数组的单独类型:

CREATE DOMAIN foo_group AS text[] CHECK (VALUE <@ ARRAY['foo', 'bar']);

CREATE TABLE foo_table(foo_column foo_group);

以下工作:

INSERT INTO foo_table VALUES(ARRAY['foo']);
INSERT INTO foo_table VALUES(ARRAY['foo', 'bar']);
INSERT INTO foo_table VALUES(ARRAY['bar']);

以下内容不是:

INSERT INTO foo_table VALUES(ARRAY['foo', 'baz']);
INSERT INTO foo_table VALUES(ARRAY['baz']);

1 个答案:

答案 0 :(得分:0)

另一种可能的解决方法是:

CREATE TYPE foo_tup AS (item foo);

域类型可以包含在这样的元组中,并为您提供数组构造函数。缺点是你现在可能想要创建演员:

select array[row('foo')::foo_tup, row('bar')];

例如,您可以创建一个函数和一个强制转换:

create function foo_tup(foo) returns foo_tup language sql as $$
    select row($1)::foo_tup;
$$ immutable;
create function foo(foo_tup) returns foo language sql as $$
     select $1.item;
$$;
create cast (foo as foo_tup) with function foo_tup(foo);
create cast (foo_tup as foo) with function foo(foo_tup);

然后聚合变得容易:

select array_agg(myfoo::foo_tup) from my_table; 

虽然你得到额外的括号。