'Is it possible to copy an enum type from one schema to another

I'm using postgREST to generate a http accessible api (great stuff). There is a little bug that I'm trying to work around.

For whatever reason, when calling a function, and only in the function parameters, I cannot use the types the api can normally reference using qualified notation e.g., core.my_type. It can however access api.my_type where of course I don't need to qualify the type.

So, to be clear, it all works in postgres. It's just a quirk with the postgREST.

One work-around that is prone to error over time, is to copy/paste the definition of each type in each of the schemas.

The other is the topic of this post: is there a way to automatically create a copy of the type in the core schema to one in the api? Or, is there a way to reference the core.my_type using an alias? (not sure if the latter would solve the problem, but perhaps worth a try).

I realize it would require casting where required. However, it does solve the problem of tracking the entries in each of the enums (in this case).



Solution 1:[1]

For whatever reason, when calling a function, and only in the function parameters, I cannot use the types the api can normally reference using qualified notation

That is because PostgREST uses a CTE when building the query to call the function and casts the data to the types of the parameters as seen in these lines of code.

There is a closed issue in the GitHub repository mentioning this problem that is labeled as won't fix.

The other is the topic of this post: is there a way to automatically create a copy of the type in the core schema to one in the api? Or, is there a way to reference the core.my_type using an alias?

You could create a DOMAIN as a workaround. That way, any modification you do using ALTER on the underlying private data type will be reflected on the domain. For instance:

create schema api;
create schema private;
create role web_anon nologin;
-- web_anon doesn't have usage on the private schema
grant usage on schema api to web_anon;

-- create type and domain
create type private.grade as enum('a','b','c','d','e');
create domain api.grade as private.grade;

-- The function uses the domain api.grade instead of private.grade
create or replace function
  api.get_grade(g api.grade) returns text as $$
begin
  return (select g);
end;
$$ language plpgsql;

-- This change will reflect on the domain
alter type private.grade add value 'f';

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Laurence Isla