I'm using PostgreSQL version 13.2 and I need to do an insert into a foreign table (Postgres also), that has a sequence generated id, returning the generated id from the foreign table.
I've added the "postgres_fdw" extension, created the server and the user mapping.
When I do:
INSERT INTO public.remote_users (name) VALUES ('username') RETURNING id;
Using the following foreign table definition:
CREATE FOREIGN TABLE public.remote_users
(
id bigint,
name character varying(20)
)
SERVER remote
OPTIONS (schema_name 'public', table_name 'users');
I get an error saying that id can't be null (because the fdw builds the remote insert statement using the 'id' column and it has a non-null constraint).
ERROR: null value in column "id" of relation "users" violates not-null constraint DETAIL: Failing row contains (null, username). CONTEXT: remote SQL command: INSERT INTO public.users(id, name) VALUES ($1, $2) RETURNING id SQL state: 23502
Using this foreign table definition:
CREATE FOREIGN TABLE public.remote_users
(
name character varying(20)
)
SERVER remote
OPTIONS (schema_name 'public', table_name 'users');
I get an error saying that "column "id" does not exist".
Is there any way to make the INSERT INTO public.remote_users (name) VALUES ('username') RETURNING id;
statement work?
I found a workaround (although it isn't the solution I desired).
Creating a before insert trigger on the remote table to check for null id and replacing by the sequence value, I can use the insert (using the foreign table definition specifying the id column).
More explicitly...
On remote:
CREATE FUNCTION public.users_insert()
RETURNS trigger
LANGUAGE 'plpgsql'
AS $BODY$
BEGIN
IF (new.id IS NULL) THEN
new.id = nextval('public.users_id_seq'::regclass);
END IF;
RETURN new;
END;
$BODY$;
CREATE TRIGGER insert_tr
BEFORE INSERT
ON public.users
FOR EACH ROW
EXECUTE PROCEDURE public.users_insert();