3

リモート スキーマ:

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

ローカルでINSERTon を実行するとsome_table_view_fdwrelation not found: some_table.

  • some_table_view_fdw から問題なく選択できます (some_table_view は * from を返すだけですsome_table)。
  • insert into some_table_view は、ローカル (リモート) で実行すると問題なく動作します。トリガーは、本来あるべきことを行います。
  • some_table_view_fdw は some_table を直接参照しないことに注意してください。したがって、トリガーが実行されている必要があると思いますが、何らかの理由でそれ自体のテーブルが見つかりませんか?

私はpostgres 9.3を使用しています

4

1 に答える 1

3

search_pathこの問題は、リモート サーバーパラメータのクエリ中に が に設定されていることが原因で発生しますpg_catalog。したがって、スキーマ内のテーブルへの参照publicは自動的に解決されません。

この問題を解決するには、トリガー関数で絶対テーブル名public.my_tableを使用します。たとえば、my_table. これは、トリガーまたはビューで使用されるすべての関数とビューにも適用されます。

トリガー機能を設定することもできますがsearch_path、このソリューションはお勧めしません。トリガーがローカルで起動されると、静かに変更されたパラメーターがセッションの終了まで有効になり、さらに混乱を招く可能性があります。


好奇心として扱ってください:search_pathリモートサーバーでチェックする方法はpostgres_fdw?

リモート サーバー (ローカル) でトリガーを使用してテスト テーブルを作成します。

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) 
于 2015-10-04T22:02:54.773 に答える