How to find inherited tables programatically in PostgreSQL?

前端 未结 4 813
借酒劲吻你
借酒劲吻你 2021-01-05 13:41

I have a PostgreSQL 8.3 database where table inheritance is being used. I would like to get a list of all tables along with its schema name which is inherited from a base ta

4条回答
  •  礼貌的吻别
    2021-01-05 14:17

    It's important to note that one table can inherit multiple tables, and none of the solutions listed really expose that; they just walk down the tree of a single parent. Consider:

    CREATE TABLE a();
    CREATE TABLE b();
    CREATE TABLE ab_() INHERITS (a,b);
    CREATE TABLE ba_() INHERITS (b,a);
    CREATE TABLE ab__() INHERITS (ab_);
    CREATE TABLE ba__() INHERITS (ba_);
    CREATE TABLE ab_ba_() INHERITS (ab_, ba_);
    CREATE TABLE ba_ab_() INHERITS (ba_, ab_);
    
    WITH RECURSIVE inh AS (
            SELECT i.inhparent::regclass, i.inhrelid::regclass, i.inhseqno FROM pg_catalog.pg_inherits i WHERE inhparent = 'a'::regclass
            UNION
            SELECT i.inhparent::regclass, i.inhrelid::regclass, i.inhseqno FROM inh INNER JOIN pg_catalog.pg_inherits i ON (inh.inhrelid = i.inhparent)
    ) SELECT * FROM inh;
     inhparent | inhrelid | inhseqno 
    -----------+----------+----------
     a         | ab_      |        1
     a         | ba_      |        2
     ab_       | ab__     |        1
     ba_       | ba__     |        1
     ab_       | ab_ba_   |        1
     ba_       | ab_ba_   |        2
     ba_       | ba_ab_   |        1
     ab_       | ba_ab_   |        2
    (8 rows)
    

    Notice that b doesn't show up at all which is incorrect, as both ab_ and ba_ inherit b.

    I suspect the "best" way to handle this would be a column that's text[] and contains (array[inhparent::regclass])::text for each table. That would give you something like

    inhrelid   path
    ab_        {"{a,b}"}
    ba_        {"{b,a}"}
    ab_ba_     {"{a,b}","{b,a}"}
    

    While obviously not ideal, that would at least expose the complete inheritance path and allow you to access it with enough gymnastics. Unfortunately, constructing that is not at all easy.

    A somewhat simpler alternative is not to include the full inheritance path at each level, only each tables direct parents. That would give you this:

    inhrelid    parents
    ab_         {a,b}
    ba_         {b,a}
    ab_ba_      {ab_,ba_}
    

提交回复
热议问题