Обсуждение: Questions about Views, Rules and DBLink
Hi!
I'm using dblink with some DBs and i'm having a few problems, more
precisely with the dblink_current_query() function.
First I create the following views on a DB:
- create or replace view users as
select *
from dblink('hostaddr=127.0.0.1 dbname=teste user=postgres
password=postgres','select * from users')
as t1(user_id int4, username varchar(20), passwd varchar(20), address
varchar(100), phone varchar(20), group_id int4);
- create or replace view utilizadores as
select *
from dblink('hostaddr=127.0.0.1 dbname=teste1 user=postgres
password=postgres','select * from utilizadores')
as t1(user_id int4, nome varchar(100), sexo char(1), idade int2,
altura int4, peso int2);
With these views I can access and manipulate the records of tables
'users' and 'utilizadores' remotely using dblink_exec() with
dblink_current_query() as parameter directly and transparently, since
the remote tables have the same name of the views. The following rule
does the trick on insert (for example):
- CREATE OR REPLACE RULE users_ins AS ON INSERT TO users
DO INSTEAD
select dblink_exec(
'hostaddr=127.0.0.1 dbname=teste user=postgres password=postgres',
dblink_current_query()
);
So far so good, now I do the following:
- create or replace view users_util as
select
us.user_id, us.username, us.passwd, ut.nome, ut.sexo, ut.idade,
ut.altura, ut.peso, us.address, us.phone, us.group_id
from
users us, utilizadores ut
where
us.user_id = ut.user_id
This creates a view that is a join of the previous views users and
utilizadores. Imagine I want to create a rule that on insert does
instead the insert on the view users:
- CREATE OR REPLACE RULE users_util_ins AS ON INSERT TO users_util
DO INSTEAD
INSERT INTO users VALUES (
NEW.user_id,
NEW.username,
NEW.passwd,
NEW.address,
NEW.phone,
NEW.group_id
)
So now if I do:
- insert into users_util (username, passwd, nome, sexo, idade, altura,
peso, address, phone, group_id) values ('prof_04', 'prof_04',
'prof_04', 'm', 45, 165, 80, 'r. da frente, nº100', '12323572', 13);
The rule should issue the query:
- insert into users values ('prof_04', 'prof_04', 'r. da frente,
nº100', '12323572', 13);
The problem is that the query being sent to table users is the same
that I perform on the users_util view...
So (finally), my question is why does this happen? Using instead on
the users_util insert rule shouldn't discard the original query and
rewrite it according to the specified on the rule?? Is this a problem
of dblink?
Sorry about the extent of my message and thanks in advance,
Joao Afonso
Joao Afonso <joaoaafonso@gmail.com> writes:
> So (finally), my question is why does this happen? Using instead on
> the users_util insert rule shouldn't discard the original query and
> rewrite it according to the specified on the rule?? Is this a problem
> of dblink?
I hadn't noticed the dblink_current_query() function before, but now
that I see it, I consider it a pretty bad idea. It certainly will not
help you the way you are hoping, because what it returns is the text of
the interactive command the backend is currently working on --- which
could be indefinitely far removed from the operation your rule is firing
for.
regards, tom lane
Tom Lane wrote: > Joao Afonso <joaoaafonso@gmail.com> writes: > >> So (finally), my question is why does this happen? Using instead on >>the users_util insert rule shouldn't discard the original query and >>rewrite it according to the specified on the rule?? Is this a problem >>of dblink? > > I hadn't noticed the dblink_current_query() function before, but now > that I see it, I consider it a pretty bad idea. It certainly will not > help you the way you are hoping, because what it returns is the text of > the interactive command the backend is currently working on --- which > could be indefinitely far removed from the operation your rule is firing > for. > When it was added (and discussed on the lists) it was also acknowledged that it would not be useful in all situations. However, there was at least one use case where it worked as intended and needed. Joe
Thanks for your help. But still, do you think there could be a way to alter the dblink_current_query() function so that it could return the right query? Or should I try to build the query in a function and send it through dblink instead of dblink_current_query()? I've also been told that oracle has an auditing service that records every action the users make, including the queries issued. If pg has something like that I could use it instead. On 8/1/05, Tom Lane <tgl@sss.pgh.pa.us> wrote: > Joao Afonso <joaoaafonso@gmail.com> writes: > > So (finally), my question is why does this happen? Using instead on > > the users_util insert rule shouldn't discard the original query and > > rewrite it according to the specified on the rule?? Is this a problem > > of dblink? > > I hadn't noticed the dblink_current_query() function before, but now > that I see it, I consider it a pretty bad idea. It certainly will not > help you the way you are hoping, because what it returns is the text of > the interactive command the backend is currently working on --- which > could be indefinitely far removed from the operation your rule is firing > for. > > regards, tom lane >