创建自定义域postgres数组

Noa*_*oah 8 sql postgresql enums

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

CREATE DOMAIN foo AS text CHECK (VALUE IN ('foo', 'bar'));
CREATE TABLE foo_table(foo_column foo[]);
Run Code Online (Sandbox Code Playgroud)

我收到了错误

type "foo[]" does not exist
Run Code Online (Sandbox Code Playgroud)

做了一些谷歌搜索,我从2004年发现了这一点,看起来对它的支持似乎即将到来.有没有办法做到这一点?

谢谢!

UPDATE

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

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

CREATE TABLE foo_table(foo_column foo_group);
Run Code Online (Sandbox Code Playgroud)

以下工作:

INSERT INTO foo_table VALUES(ARRAY['foo']);
INSERT INTO foo_table VALUES(ARRAY['foo', 'bar']);
INSERT INTO foo_table VALUES(ARRAY['bar']);
Run Code Online (Sandbox Code Playgroud)

以下不:

INSERT INTO foo_table VALUES(ARRAY['foo', 'baz']);
INSERT INTO foo_table VALUES(ARRAY['baz']);
Run Code Online (Sandbox Code Playgroud)

Chr*_*ers 1

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

CREATE TYPE foo_tup AS (item foo);
Run Code Online (Sandbox Code Playgroud)

域类型可以包装在像这样的元组中,这为您提供了一个数组构造函数。缺点是现在您可能想要创建强制转换:

select array[row('foo')::foo_tup, row('bar')];
Run Code Online (Sandbox Code Playgroud)

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

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);
Run Code Online (Sandbox Code Playgroud)

那么聚合就变得容易了:

select array_agg(myfoo::foo_tup) from my_table; 
Run Code Online (Sandbox Code Playgroud)

尽管你得到了额外的括号。