create table p_words (
   recid int8 not null,
   f_words text,
   e_words_1 text,
   e_words_2 text,
   e_words_3 text,
   e_words_4 text,
   e_words_5 text,
   primary key (recid)
);

create table p_words__f_words (
   parent__id int8 not null,
   word text not null
);

create table p_words__e_words (
   parent__id int8 not null,
   list__index int4 not null,
   word text not null
);

create or replace function p_words__e_words_1__upd_trg()
returns trigger
language plpgsql
as
$$
begin
   delete from p_words__e_words where p_words__e_words.parent__id = new.recid and p_words__e_words.list__index = 1;
   if new.e_words_1 is null or new.e_words_1 = '' then
      return new;
   end if;
   insert into p_words__e_words select * from words(new.recid, 1, new.e_words_1, true);
   return new;
end;
$$;

drop trigger if exists p_words__e_words_1__upd ON p_words;

create trigger p_words__e_words_1__upd after
update of e_words_1
   on
   p_words for each row
   when (old.e_words_1 is distinct from new.e_words_1)
   execute procedure p_words__e_words_1__upd_trg();

create or replace function p_words__e_words_2__upd_trg()
returns trigger
language plpgsql
as
$$
begin
   delete from p_words__e_words where p_words__e_words.parent__id = new.recid and p_words__e_words.list__index = 2;
   if new.e_words_2 is null or new.e_words_2 = '' then
      return new;
   end if;
   insert into p_words__e_words select * from words(new.recid, 2, new.e_words_2, true);
   return new;
end;
$$;

drop trigger if exists p_words__e_words_2__upd ON p_words;

create trigger p_words__e_words_2__upd after
update of e_words_2
   on
   p_words for each row
   when (old.e_words_2 is distinct from new.e_words_2)
   execute procedure p_words__e_words_2__upd_trg();

create or replace function p_words__e_words_3__upd_trg()
returns trigger
language plpgsql
as
$$
begin
   delete from p_words__e_words where p_words__e_words.parent__id = new.recid and p_words__e_words.list__index = 3;
   if new.e_words_3 is null or new.e_words_3 = '' then
      return new;
   end if;
   insert into p_words__e_words select * from words(new.recid, 3, new.e_words_3, true);
   return new;
end;
$$;

drop trigger if exists p_words__e_words_3__upd ON p_words;

create trigger p_words__e_words_3__upd after
update of e_words_3
   on
   p_words for each row
   when (old.e_words_3 is distinct from new.e_words_3)
   execute procedure p_words__e_words_3__upd_trg();

create or replace function p_words__e_words_4__upd_trg()
returns trigger
language plpgsql
as
$$
begin
   delete from p_words__e_words where p_words__e_words.parent__id = new.recid and p_words__e_words.list__index = 4;
   if new.e_words_4 is null or new.e_words_4 = '' then
      return new;
   end if;
   insert into p_words__e_words select * from words(new.recid, 4, new.e_words_4, true);
   return new;
end;
$$;

drop trigger if exists p_words__e_words_4__upd ON p_words;

create trigger p_words__e_words_4__upd after
update of e_words_4
   on
   p_words for each row
   when (old.e_words_4 is distinct from new.e_words_4)
   execute procedure p_words__e_words_4__upd_trg();

create or replace function p_words__e_words_5__upd_trg()
returns trigger
language plpgsql
as
$$
begin
   delete from p_words__e_words where p_words__e_words.parent__id = new.recid and p_words__e_words.list__index = 5;
   if new.e_words_5 is null or new.e_words_5 = '' then
      return new;
   end if;
   insert into p_words__e_words select * from words(new.recid, 5, new.e_words_5, true);
   return new;
end;
$$;

drop trigger if exists p_words__e_words_5__upd ON p_words;

create trigger p_words__e_words_5__upd after
update of e_words_5
   on
   p_words for each row
   when (old.e_words_5 is distinct from new.e_words_5)
   execute procedure p_words__e_words_5__upd_trg();

drop trigger if exists p_words__e_words__ins ON p_words;

create or replace function p_words__e_words__ins_trg()
returns trigger
language plpgsql
as
$$
begin
   if new.e_words_1 is not null and new.e_words_1 <> '' then
      insert into p_words__e_words select * from words(new.recid, 1, new.e_words_1, true);
   end if;
   if new.e_words_2 is not null and new.e_words_2 <> '' then
      insert into p_words__e_words select * from words(new.recid, 2, new.e_words_2, true);
   end if;
   if new.e_words_3 is not null and new.e_words_3 <> '' then
      insert into p_words__e_words select * from words(new.recid, 3, new.e_words_3, true);
   end if;
   if new.e_words_4 is not null and new.e_words_4 <> '' then
      insert into p_words__e_words select * from words(new.recid, 4, new.e_words_4, true);
   end if;
   if new.e_words_5 is not null and new.e_words_5 <> '' then
      insert into p_words__e_words select * from words(new.recid, 5, new.e_words_5, true);
   end if;
   return new;
end;
$$;

create trigger p_words__e_words__ins after
insert
   on
   p_words for each row execute procedure p_words__e_words__ins_trg();

create or replace function p_words__f_words__upd_trg()
returns trigger
language plpgsql
as
$$
begin
   delete from p_words__f_words where p_words__f_words.parent__id = new.recid;
   if new.f_words is null or new.f_words = '' then
      return new;
   end if;
   insert into p_words__f_words select * from words(new.recid, new.f_words, true);
   return new;
end;
$$;

create or replace function p_words__f_words__ins_trg()
returns trigger
language plpgsql
as
$$
begin
   if new.f_words is null or new.f_words = '' then
      return new;
   end if;
   insert into p_words__f_words select * from words(new.recid, new.f_words, true);
   return new;
end;
$$;

drop trigger if exists p_words__f_words__upd ON p_words;

create trigger p_words__f_words__upd after
update of f_words
   on
   p_words for each row
   when (old.f_words is distinct from new.f_words)
   execute procedure p_words__f_words__upd_trg();

drop trigger if exists p_words__f_words__ins ON p_words;

create trigger p_words__f_words__ins after
insert
   on
   p_words for each row execute procedure p_words__f_words__ins_trg();

alter table p_words__e_words   drop constraint if exists pk__p_words__e_words;
alter table p_words__e_words   add constraint pk__p_words__e_words   primary key (parent__id, list__index, word);
drop index if exists idx__p_words__e_words;
create index idx__p_words__e_words on p_words__e_words (word, parent__id);
alter table p_words__e_words   drop constraint if exists fk__p_words__e_words;
drop index if exists fkidx__p_words__e_words;
create index fkidx__p_words__e_words on p_words__e_words (parent__id);
alter table p_words__e_words
   add constraint fk__p_words__e_words
   foreign key (parent__id)
   references p_words(recid)
   on delete cascade;

alter table p_words__f_words   drop constraint if exists pk__p_words__f_words;
alter table p_words__f_words   add constraint pk__p_words__f_words   primary key (parent__id, word);
drop index if exists idx__p_words__f_words;
create index idx__p_words__f_words on p_words__f_words (word, parent__id);
alter table p_words__f_words   drop constraint if exists fk__p_words__f_words;
drop index if exists fkidx__p_words__f_words;
create index fkidx__p_words__f_words on p_words__f_words (parent__id);
alter table p_words__f_words
   add constraint fk__p_words__f_words
   foreign key (parent__id)
   references p_words(recid)
   on delete cascade;