O instrutor é inserido na tabela, assim como os logs na tabela de logs, mesmo quando há erro na função, como na função abaixo (não há campo 'teste' na tabela 'log_instrutores'). É como se o erro fosse ignorado. Isso ocorre mesmo quando a trigger é definida before insert. Essa questão já foi levantada no forum, mas não houve solução.
create or replace function valida_instrutores() returns trigger as $$
    declare
        id_instrutor_inserido integer;
        media_salarial decimal;
        instrutores_recebem_menos integer default 0;
        total_instrutores integer default 0;
        salario decimal;
        percentual decimal;
        
    begin
    
        select avg(instrutor.salario) into media_salarial from instrutor where id <> new.id;
        if new.salario > max(instrutor.salario) from instrutor then
            insert into log_instrutores (informacao) values (new.nome ||' não incluído por ganhar acima de todos os colaboradores');
            return null;
        end if;
        
        for salario in select instrutor.salario from instrutor where id <> new.id loop
            total_instrutores := total_instrutores + 1;
            if new.salario > salario then
                instrutores_recebem_menos := instrutores_recebem_menos + 1;
            end if;
        end loop;
        
        percentual = instrutores_recebem_menos::decimal / total_instrutores::decimal * 100;
        
        insert into log_instrutores (informacao, teste) values (new.nome||' recebe mais do que '|| percentual || '% da grade de instrutores', '');
        return new;
        
    exception
        when undefined_column then
            return new;
            
    end
$$ language plpgsql;
create trigger valida_instrutor after insert on instrutor
for each row execute function valida_instrutores();
insert into instrutor (nome, salario) values ('S', 500);
select * from instrutor;
select * from log_instrutores;
 
            