1

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

Peter Krauss
  • 13,174
  • 24
  • 167
  • 304

1 Answers1

1

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"  
klin
  • 112,967
  • 15
  • 204
  • 232
  • Thanks again Klin! Well, bad news for me about PostgreSQL (all versions!?)... So, is it?... **PostgreSQL Domain is ugly**, no reuse or recurrency in custom datatypes. Your solution, of course, is valid and seems the only way... I just did not believe that PostgreSQL Domain was so poor: non-elegant and difficult to extend/generalize datatypes. PS: I'll wait another few days to see if no one gives a clue, before accept your answer. – Peter Krauss Jan 31 '18 at 21:16
  • The concept of domains is simple by design. On the other hand, you can get the desired effect in a relatively easy way. – klin Jan 31 '18 at 22:03