-- Charakter-Verknüpfungen auch bei DELETEs außerhalb der Worker bereinigen. -- Löscht bestehende verwaiste Beziehungen; vorher auf der Ziel-DB sichern. BEGIN; LOCK TABLE falukant_data.character, falukant_data.relationship, falukant_data.relationship_state, falukant_data.child_relation IN SHARE ROW EXCLUSIVE MODE; DELETE FROM falukant_data.relationship_state rs WHERE NOT EXISTS ( SELECT 1 FROM falukant_data.relationship r WHERE r.id = rs.relationship_id ) OR EXISTS ( SELECT 1 FROM falukant_data.relationship r WHERE r.id = rs.relationship_id AND ((r.character1_id IS NOT NULL AND NOT EXISTS ( SELECT 1 FROM falukant_data.character c WHERE c.id = r.character1_id)) OR (r.character2_id IS NOT NULL AND NOT EXISTS ( SELECT 1 FROM falukant_data.character c WHERE c.id = r.character2_id))) ); DELETE FROM falukant_data.relationship r WHERE (r.character1_id IS NOT NULL AND NOT EXISTS ( SELECT 1 FROM falukant_data.character c WHERE c.id = r.character1_id )) OR (r.character2_id IS NOT NULL AND NOT EXISTS ( SELECT 1 FROM falukant_data.character c WHERE c.id = r.character2_id )); DELETE FROM falukant_data.child_relation cr WHERE (cr.child_character_id IS NOT NULL AND NOT EXISTS ( SELECT 1 FROM falukant_data.character c WHERE c.id = cr.child_character_id )) OR (cr.father_character_id IS NOT NULL AND NOT EXISTS ( SELECT 1 FROM falukant_data.character c WHERE c.id = cr.father_character_id )) OR (cr.mother_character_id IS NOT NULL AND NOT EXISTS ( SELECT 1 FROM falukant_data.character c WHERE c.id = cr.mother_character_id )); -- Vorhandene einspaltige FKs ersetzen (deren Namen sind je nach Backend verschieden). -- Auch relationship_state absichern, damit es die Kaskade nicht blockieren kann. DO $$ DECLARE target record; existing_fk record; BEGIN FOR target IN SELECT * FROM (VALUES ('relationship', 'character1_id', 'character'), ('relationship', 'character2_id', 'character'), ('child_relation', 'child_character_id', 'character'), ('child_relation', 'father_character_id', 'character'), ('child_relation', 'mother_character_id', 'character'), ('relationship_state', 'relationship_id', 'relationship') ) AS targets(table_name, column_name, referenced_table) LOOP FOR existing_fk IN SELECT con.conname FROM pg_constraint con JOIN pg_attribute att ON att.attrelid = con.conrelid AND con.conkey = ARRAY[att.attnum] WHERE con.contype = 'f' AND con.conrelid = format('falukant_data.%I', target.table_name)::regclass AND con.confrelid = format('falukant_data.%I', target.referenced_table)::regclass AND att.attname = target.column_name LOOP EXECUTE format('ALTER TABLE falukant_data.%I DROP CONSTRAINT %I', target.table_name, existing_fk.conname); END LOOP; EXECUTE format( 'ALTER TABLE falukant_data.%I ADD CONSTRAINT %I FOREIGN KEY (%I) REFERENCES falukant_data.%I (id) ON DELETE CASCADE', target.table_name, target.table_name || '_' || target.column_name || '_fkey', target.column_name, target.referenced_table); END LOOP; END; $$; COMMIT;