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