Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

List constraints for all tables with different owners in PostgreSQL

Do I have to be owner of relation to access constraint related data in information schema? I've tested the following and it seems that I have to be the owner.

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
*/

Is there other way how to get the same information if I am not owner of the relation?

like image 887
Tomas Greif Avatar asked May 30 '13 07:05

Tomas Greif


People also ask

How do I list constraints in PostgreSQL?

To find the name of a constraint in PostgreSQL, use the view pg_constraint in the pg_catalog schema. Join the view pg_catalog. pg_constraint with the view pg_class ( JOIN pg_class t ON t. oid = c.

How do you check constraints on a table in pgAdmin?

A dialog similar to the Check dialog (accessed by right clicking on Constraints in the pgAdmin tree control) opens. Use the fields in the General tab to identify the check constraint: Use the Name field to add a descriptive name for the check constraint. The name will be displayed in the pgAdmin tree control.

Where is Information_schema in PostgreSQL?

You should be able to just run select * from information_schema. tables to get a listing of every table being managed by Postgres for a particular database. You can also add a where table_schema = 'information_schema' to see just the tables in the information schema.


2 Answers

Not all constraint-related data is "protected". You use three relations in your query:

  • table_constraints
  • key_column_usage
  • constraint_column_usage

The first two are not limited, but the documentation for constraint_column_usage tells you:

The view constraint_column_usage identifies all columns in the current database that are used by some constraint. Only those columns are shown that are contained in a table owned by a currently enabled role.

Since information_schema.constraint_column_usage is a view, you can see its definition using

\d+ information_schema.constraint_column_usage

in the psql shell. The result looks frightening at a first glance but it's really not so bad. The most interesting thing - for a first test - is the part in the very last line:

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

If you paste the definition into the psql shell which is open by the non-owner rights_test_role and delete that last line you will get the desired result. This is good, because that means that the basic metadata is not protected by the system. So you can strip down the view definition to include only the parts you really need.

like image 36
A.H. Avatar answered Nov 05 '22 09:11

A.H.


Try using this.. gives all the constraint names and constraint description.

  • Foreign key
  • Check
  • Primary key
  • Unique

Like:

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
like image 112
Anupama Boorlagadda Avatar answered Nov 05 '22 09:11

Anupama Boorlagadda