外部数据包装远程触发器找不到远程表



远程模式:

some_table
some_table_view
some_table_view_trigger (INSTEAD OF INSERT)
    -- tries to access some_table (select/update/insert)

本地模式:

some_table_view_fdw
    -- wraps some_table_view on remote

现在在本地,当我在some_table_view_fdw上运行INSERT时,我得到relation not found: some_table

  • 我可以从some_table_view_fdw中进行选择(some_table_view只是从some_table返回*(
  • 如果在本地(远程(运行,insert到sometable_view就可以正常工作。触发器执行它应该执行的操作
  • 请注意,some_table_view_fdw没有直接引用some_table,所以我想触发器一定在运行,但由于某种原因找不到它自己的表

我使用的是postgres 9.3

问题源于查询远程服务器时search_path参数设置为pg_catalog。因此,对模式public中的表的引用不会被自动解决。

要解决此问题,请在触发器函数中使用绝对表名,例如public.my_table而不是my_table。这也适用于触发器或视图中使用的所有函数和视图。

您也可以在触发器函数中设置search_path,尽管我不建议使用此解决方案。当触发器在本地触发时,悄悄更改的参数将一直有效,直到会话结束,这可能会导致进一步的混乱。


把它当作一个好奇:如何用postgres_fdw在远程服务器上检查search_path

在远程服务器(本地(上创建带有触发器的测试表:

create table test_path (id int, val text);
create or replace function path_trigger()
returns trigger language plpgsql as $$
begin
    select setting into new.val
    from pg_settings where name = 'search_path';
    return new;
end $$;
create trigger path_trigger
before insert on test_path
for each row execute procedure path_trigger();
insert into test_path (id) values (1) returning *;
 id |      val     
----+----------------
  1 | "$user",public
(1 row)

在本地服务器上创建外部表并触发远程触发器:

create foreign table test_path (id int, val text)
server backup_server
options (schema_name 'public', table_name 'test_path'); 
insert into test_path (id) values (2) returning *;
 id |    val     
----+------------
  2 | pg_catalog
(1 row) 

相关内容

  • 没有找到相关文章

最新更新