Pessoal, estou com um problema até certo ponto bastante complexo e que
pensei em utilizar o sistema de regras no PostgreSQL para resolver, mas não
estou sendo bem-sucedido. Acho que estou precisando de uma luz da
comunidade.

Tenho basicamente três tabelas que se relacionam: rels, organizations e
parties, que possuem as seguintes características:

               Tabela "public.acs_rels"
    Coluna     |          Tipo          | Modificadores
---------------+------------------------+---------------
 rel_id        | integer                | not null
 rel_type      | character varying(100) | not null
 object_id_one | integer                | not null
 object_id_two | integer                | not null
Índices:
    "acs_rels_pk" PRIMARY KEY, btree (rel_id)
    "acs_object_rels_un" UNIQUE, btree (rel_type, object_id_one,
object_id_two)
    "acs_rels_object_id_one_idx" btree (object_id_one)
    "acs_rels_object_id_two_idx" btree (object_id_two)
Restrições de chave estrangeira:
    "acs_object_rels_one_fk" FOREIGN KEY (object_id_one) REFERENCES
acs_objects(object_id) ON DELETE CASCADE
    "acs_object_rels_two_fk" FOREIGN KEY (object_id_two) REFERENCES
acs_objects(object_id) ON DELETE CASCADE
    "acs_rels_rel_id_fk" FOREIGN KEY (rel_id) REFERENCES
acs_objects(object_id) ON DELETE CASCADE
    "acs_rels_rel_type_fk" FOREIGN KEY (rel_type) REFERENCES
acs_rel_types(rel_type)
Gatilhos:
    acs_rels_in_tr BEFORE INSERT OR UPDATE ON acs_rels FOR EACH ROW EXECUTE
PROCEDURE acs_rels_in_tr()


              Tabela "public.parties"
  Coluna  |          Tipo          | Modificadores
----------+------------------------+---------------
 party_id | integer                | not null
 email    | character varying(100) |
 url      | character varying(200) |
Índices:
    "parties_pk" PRIMARY KEY, btree (party_id)
    "parties_email_un" UNIQUE, btree (email)
    "parties_email_lower_idx" btree (lower(email::text))
Restrições de chave estrangeira:
    "parties_party_id_fk" FOREIGN KEY (party_id) REFERENCES
acs_objects(object_id)
Gatilhos:
    parties_del_tr BEFORE DELETE ON parties FOR EACH ROW EXECUTE PROCEDURE
parties_del_tr()
    parties_in_tr AFTER INSERT ON parties FOR EACH ROW EXECUTE PROCEDURE
parties_in_tr()


              Tabela "public.organizations"
     Coluna      |          Tipo          | Modificadores
-----------------+------------------------+---------------
 organization_id | integer                | not null
 name            | character varying(200) | not null
 legal_name      | character varying(200) |
 reg_number      | character varying(100) |
 notes           | text                   |
 country_iso     | character varying      |
 state_abbrev    | character varying      |
 org_legal_id    | integer                |
Índices:
    "organization_id_pk" PRIMARY KEY, btree (organization_id)
    "organization_name_uq" UNIQUE, btree (name)
    "organization_name_ix" btree (name)
Restrições de chave estrangeira:
    "org_legal_id_fk" FOREIGN KEY (org_legal_id) REFERENCES
organization_legal_types(org_legal_id)
    "organization_id_fk" FOREIGN KEY (organization_id) REFERENCES
parties(party_id)
    "organizations_country_fk" FOREIGN KEY (country_iso) REFERENCES
countries(iso)


O problema basicamente é o seguinte: eu preciso cadastrar organizações na
tabela organizations, que possui uma chave estrangeira para a tabela parties
e para a tabela groups, como podem ver acima. A questão central está no
e-mail da organização; quando alguém cadastra uma organização, o e-mail vai
para a tabela parties, que além disso grava a URL.

Pois bem, acontece que essa tabela parties também grava as informações do
usuário, e o email nessa tabela possui restrição de unicidade, ou seja, tem
que ser único. No nosso modelo de negócios, uma organização pode sim ter o
mesmo email do usuário, e isso se tornou um problema. Pensei em apagar a
restrição de unicidade, mas nesse caso eu poderia ter duplicação de emails,
o que não pode acontecer já que ele é utilizado para o login.

A solução que eu pensei foi a seguinte: vou criar uma regra para todas as
vezes em que for cadastrar uma organização, o email da dela vá como nulo
para a tabela parties. O sistema de regras faria que, todas as vezes que eu
desse um select na tabela parties e o email fosse nulo, eu buscaria o
endereço do responsável numa outra tabela, que é a de relações. Tentei criar
a regra com a seguinte seqüência de comandos:

    CREATE OR REPLACE VIEW organization_party_email AS
    SELECT a.object_id_one as party_id, p.email, p.url
    FROM parties p, acs_rels a
    WHERE p.party_id = a.object_id_two
    AND a.rel_type = 'organization_admin';

    CREATE OR REPLACE RULE "_RETURN" AS ON SELECT TO parties
    WHERE email IS NULL
    DO INSTEAD SELECT * FROM organization_party_email;


Contudo, quando tento criar a regra, o seguinte erro aparece:

ERRO:  regra ON SELECT não pode utilizar OLD

Aparentemente o sistema está entendendo de alguma forma que estou tentando
utilizar a tabela OLD para a regra, o que não é o caso. Já li os seguintes
documentos:

http://www.postgresql.org/docs/8.1/static/sql-createrule.html

http://www.postgresql.org/docs/8.1/static/rules-views.html

http://s2k-ftp.cs.berkeley.edu:8000/postgres/papers/ERL-M90-36.pdf

Alguém tem alguma idéia?

Obs.: Desculpem pelo longo post, mas a dúvida é cabeluda.
_______________________________________________
pgbr-geral mailing list
[email protected]
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral

Responder a