2013-05-30 15 views
10

情報スキーマの制約関連データにアクセスするには、関係の所有者でなければなりませんか?私は次のことを試してみたが、私は所有者でなければならないようだ。PostgreSQLで異なる所有者を持つすべてのテーブルのリスト制約

create schema rights_test; 

create table rights_test.t1 (id int primary key); 
create table rights_test.t2 (id int references rights_test.t1(id)); 

select 
     tc.constraint_name, 
     tc.constraint_schema || '.' || tc.table_name || '.' || kcu.column_name as physical_full_name, 
     tc.constraint_schema, 
     tc.table_name, 
     kcu.column_name, 
     ccu.table_name as foreign_table_name, 
     ccu.column_name as foreign_column_name, 
     tc.constraint_type 
    from 
     information_schema.table_constraints as tc 
     join information_schema.key_column_usage as kcu on (tc.constraint_name = kcu.constraint_name and tc.table_name = kcu.table_name) 
     join information_schema.constraint_column_usage as ccu on ccu.constraint_name = tc.constraint_name 
    where 
     constraint_type in ('PRIMARY KEY','FOREIGN KEY') 
     and tc.constraint_schema = 'rights_test' 

/* 
This will produce desired output: 
t1_pkey;rights_test.t1.id;rights_test;t1;id;t1;id;PRIMARY KEY 
t2_id_fkey;rights_test.t2.id;rights_test;t2;id;t1;id;FOREIGN KEY 
*/ 

create user rights_test_role with password 'password'; 

grant all on rights_test.t1 to rights_test_role; 
grant all on rights_test.t2 to rights_test_role; 

/* Now login as rights_test_role and try the same constraint select. 
    For rights_test_role it returns nothing although I've added ALL privileges 
*/ 

私が関係の所有者でない場合、同じ情報を得る他の方法はありますか?

答えて

9

すべての制約関連データが「保護されている」わけではありません。

  • table_constraints
  • key_column_usage
  • constraint_column_usage

は、最初の二つは限定されるものではなく、constraint_column_usageのドキュメントがわかります:あなたはあなたのクエリで3つのリレーションを使用

ビューconstraint_column_usageは、現在のdatのすべての列を識別しますいくつかの制約によって使用される。 現在有効になっているロールが所有するテーブルに含まれる列のみが表示されます。 information_schema.constraint_column_usage以来

が表示され、あなたはpsqlのシェルで

\d+ information_schema.constraint_column_usage 

を使用して、その定義を参照することができます。一見すると結果は恐ろしいように見えますが、それほど悪くはありません。あなたは非所有者rights_test_roleによって開かれているpsqlのシェルに定義を貼り付け、その最後の行にあなたを削除した場合

WHERE pg_has_role(x.tblowner, 'USAGE'::text); 

:最も興味深い - - 最初のテストのためには、非常に最後の行では一部であり、希望の結果が得られます。これは基本的なメタデータがシステムによって保護されていないためです。したがって、必要な部分のみを含めるようにビュー定義を削除することができます。

+2

'\ dは+'あなたの友達です。 –

16

これを使用してみてください。すべての制約名と制約の説明を記入してください。

  • 外部キー
  • チェック
  • プライマリキー
  • ユニーク

同様:

select conrelid::regclass AS table_from, conname, pg_get_constraintdef(c.oid) 
from pg_constraint c 
join pg_namespace n ON n.oid = c.connamespace 
where contype in ('f', 'p','c','u') order by contype