50 lines
1.5 KiB
SQL
50 lines
1.5 KiB
SQL
--
|
|
-- 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$;
|