2013-05-30 193 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的文檔會告訴你:

視圖constraint_column_usage標識當前dat中的所有列被某些約束所使用的基礎。 只顯示包含在由當前啓用的角色擁有的表中的列。

由於information_schema.constraint_column_usage是一個視圖,你可以在PSQL外殼採用

\d+ information_schema.constraint_column_usage 

看到它的定義。乍一看,結果看起來很可怕,但實際上並沒有那麼糟糕。最有趣的事情 - 爲第一個測試 - 在最後一行的一部分:

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

如果粘貼定義到psql的外殼是由非所有者rights_test_role開放,並刪除最後一行你會得到期望的結果。這很好,因爲這意味着基本元數據不受系統保護。因此,您可以剝離視圖定義以僅包含您真正需要的部分。

+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 
相關問題