You design doesn't work. It makes no sense to have id
as IDENTITY
column, combined with a PK on (id, user_id)
.
Proper design
CREATE TABLE chatroom (
chatroom_id integer PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY
);
CREATE TABLE chatroom_user (
chatroom_id int REFERENCES chatroom ON DELETE CASCADE
, user_id int -- REFERENCES users ON DELETE CASCADE
, CONSTRAINT chatroom_user_pkey PRIMARY KEY (chatroom_id, user_id)
);
Then to insert an input array of existing users into the same, new chat room, use a data-modifying CTE:
WITH ins_chatroom AS (
INSERT INTO chatroom DEFAULT VALUES
RETURNING chatroom_id
)
INSERT INTO chatroom_user (chatroom_id, user_id)
SELECT chatroom_id, u
FROM ins_chatroom, unnest('{1,2,3}'::int[]) u -- input users as array
RETURNING *; -- just to show result in fiddle
fiddle
See:
Minimalist design
If you want to avoid the additional table for chatrooms, you can make do with a SEQUENCE
, and good old sequence manipulation functions:
CREATE SEQUENCE IF NOT EXISTS public.chat_user_chat_id_seq;
CREATE TABLE chat_user (
chat_id int DEFAULT nextval('public.chat_user_chat_id_seq') -- optional default
, user_id int -- REFERENCES users ON DELETE CASCADE
, CONSTRAINT chat_rooms_pkey PRIMARY KEY (chat_id, user_id)
);
ALTER SEQUENCE public.chat_user_chat_id_seq OWNED BY chat_user.chat_id;
Then to insert an input array of existing users into the same, new chat room, use these two commands in the same session (better in the same transaction):
SELECT nextval('public.chat_user_chat_id_seq');
INSERT INTO chat_user (chat_id, user_id)
SELECT currval('public.chat_user_chat_id_seq'), unnest('{1,2,3}'::int[]) u
RETURNING *; -- just to show result in fiddle
fiddle
See: