-- Special node such as orphaned and deleted nodes. ALTER TABLE public.node ADD special bool DEFAULT false NOT NULL; -- Needs to be dropped in order to drop the index on UUID. ALTER TABLE public.node DROP CONSTRAINT node_node_fk; -- Index was missing user ID. DROP INDEX public.node_uuid_idx; CREATE UNIQUE INDEX node_user_uuid_idx ON public.node (user_id,"uuid"); -- Restore the "foreign" key of parent UUID back to UUID. ALTER TABLE public.node ADD CONSTRAINT node_node_fk FOREIGN KEY (user_id,parent_uuid) REFERENCES public.node(user_id,"uuid") ON DELETE RESTRICT ON UPDATE RESTRICT; -- Auto-create the special nodes for each user. CREATE OR REPLACE FUNCTION create_user_nodes() RETURNS TRIGGER AS $$ BEGIN -- NEW holds the row being created. -- No semi-colons omitted here, PL/pgSQL requires them. INSERT INTO public.node (user_id, uuid, parent_uuid, special, name) VALUES (NEW.id, '00000000-0000-0000-0000-000000000000'::uuid, null, true, 'Start'), (NEW.id, '00000000-0000-0000-0000-000000000001'::uuid, null, true, 'Orphaned nodes'), (NEW.id, '00000000-0000-0000-0000-000000000002'::uuid, null, true, 'Deleted nodes'); RETURN NEW; END; $$ LANGUAGE plpgsql; CREATE TRIGGER trg_after_user_insert AFTER INSERT ON public.user FOR EACH ROW EXECUTE FUNCTION create_user_nodes();