Custom domain array by recurrency of custom domain

145 Views Asked by At

Documentation say nothing about create a domain from other custom domains.

I need only to create array of (previously created) custom domains, so it is not the problem/solution discussed here.

Example:

CREATE DOMAIN jbag AS JSONb
  CHECK(  VALUE IS NULL OR  jsonb_typeof(VALUE) IN ('object','null')  );  

But PostgreSQL not accepting declations like CREATE FUNCTION intersection(jbag[]) RETURNS jbag.

How to do a kind of CREATE DOMAIN jbag[] AS jbag[]?... Or say to postgresql-parser "hello let's accept arrays of atomic custom types!"?


For details see bag.sql

1

There are 1 best solutions below

2
On

You can create a domain based on a predefined array type, in this case on jsonb[]. Define a check constraint using a function which ensures that all array elements are compatible with jbag:

create or replace function jbags_check(jsonb[])
returns boolean language sql immutable as $$
    select bool_and(elem is null or jsonb_typeof(elem) in ('object','null'))
    from unnest($1) u(elem);
$$;

create domain jbags as jsonb[] 
    check(jbags_check(value));

Now your function may look like this:

CREATE FUNCTION intersection(jbags) RETURNS jbag AS $f$
    SELECT jsonb_object_agg(e,m::int)::jbag
    FROM (
      SELECT e, MIN(m) AS m
        FROM unnest($1), jsonb_each_text(unnest) as a(e, m)
        GROUP BY e
        HAVING COUNT(*)=array_length($1,1)
    ) t
$f$ language SQL IMMUTABLE;

The function in action:

select intersection(array['{"a": 2}', '{"a": 3, "b": 3}']::jbags);

 intersection 
--------------
 {"a": 2}
(1 row)

but:

select intersection(array['1', '{"a": 3, "b": 3}']::jbags);

ERROR:  value for domain jbags violates check constraint "jbags_check"