| -- |
| -- Verify system catalog foreign key relationships |
| -- |
| DO $doblock$ |
| declare |
| fk record; |
| nkeys integer; |
| cmd text; |
| err record; |
| begin |
| for fk in select * from pg_get_catalog_foreign_keys() |
| loop |
| raise notice 'checking % % => % %', |
| fk.fktable, fk.fkcols, fk.pktable, fk.pkcols; |
| nkeys := array_length(fk.fkcols, 1); |
| cmd := 'SELECT ctid'; |
| for i in 1 .. nkeys loop |
| cmd := cmd || ', ' || quote_ident(fk.fkcols[i]); |
| end loop; |
| if fk.is_array then |
| cmd := cmd || ' FROM (SELECT ctid'; |
| for i in 1 .. nkeys-1 loop |
| cmd := cmd || ', ' || quote_ident(fk.fkcols[i]); |
| end loop; |
| cmd := cmd || ', unnest(' || quote_ident(fk.fkcols[nkeys]); |
| cmd := cmd || ') as ' || quote_ident(fk.fkcols[nkeys]); |
| cmd := cmd || ' FROM ' || fk.fktable::text || ') fk WHERE '; |
| else |
| cmd := cmd || ' FROM ' || fk.fktable::text || ' fk WHERE '; |
| end if; |
| if fk.is_opt then |
| for i in 1 .. nkeys loop |
| cmd := cmd || quote_ident(fk.fkcols[i]) || ' != 0 AND '; |
| end loop; |
| end if; |
| cmd := cmd || 'NOT EXISTS(SELECT 1 FROM ' || fk.pktable::text || ' pk WHERE '; |
| for i in 1 .. nkeys loop |
| if i > 1 then cmd := cmd || ' AND '; end if; |
| cmd := cmd || 'pk.' || quote_ident(fk.pkcols[i]); |
| cmd := cmd || ' = fk.' || quote_ident(fk.fkcols[i]); |
| end loop; |
| cmd := cmd || ')'; |
| -- raise notice 'cmd = %', cmd; |
| for err in execute cmd loop |
| raise warning 'FK VIOLATION IN %(%): %', fk.fktable, fk.fkcols, err; |
| end loop; |
| end loop; |
| end |
| $doblock$; |