Creating an array of custom domain postgres

Due to enum inheritance restrictions (you cannot add values ​​to an enumeration from inside the function), I go to user domains with a check constraint checking the values. I need to create arrays of my custom enums, but when I try something like this:

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

I get an error

 type "foo[]" does not exist 

Performing some searches, I found this since 2004 , which made it look like support for this. Is there any way to do this?

Thanks!

UPDATE

I came up with a hacker solution, which I will answer if in a few days no one finds a better solution. This solution means you cannot reuse the type to be an array, you need to create a separate type that acts like an array:

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

Next job:

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

It does not follow:

 INSERT INTO foo_table VALUES(ARRAY['foo', 'baz']); INSERT INTO foo_table VALUES(ARRAY['baz']); 
+5
source share
1 answer

Another possible workaround:

 CREATE TYPE foo_tup AS (item foo); 

Domain types can be wrapped in tuples like this, and this gives you an array constructor. The downside is that you probably want to create castings:

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

For example, you can create a function and a cast:

 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); 

Then aggregation becomes easy:

 select array_agg(myfoo::foo_tup) from my_table; 

although you will get extra parentheses.

0
source

Source: https://habr.com/ru/post/1266423/


All Articles