Обсуждение: Convert table to view 9.1

Поиск
Список
Период
Сортировка

Convert table to view 9.1

От
salah jubeh
Дата:
Hello Guys,

ERROR:  could not convert table "b" to a view because it has triggers
HINT:  In particular, the table cannot be involved in any foreign key relationships.

********** Error **********

ERROR: could not convert table "b" to a view because it has triggers
SQL state: 55000
Hint: In particular, the table cannot be involved in any foreign key relationships.

Scenario:

create table a (id int primary key);
create table b (id int primary key, a_id int references a (id));

insert into  a values (1);
insert into  b values (1,1);

create table c AS SELECT * FROM b;

TRUNCATE b;
ALTER TABLE b DROP CONSTRAINT b_a_id_fkey;
ALTER TABLE b DROP CONSTRAINT b_pkey;
ALTER TABLE b ALTER COLUMN id DROP NOT NULL;
 
CREATE RULE "_RETURN" AS ON SELECT TO b DO INSTEAD SELECT * FROM C;



Re: Convert table to view 9.1

От
Albe Laurenz
Дата:
salah jubeh wrote:

> ERROR:  could not convert table "b" to a view because it has triggers
> HINT:  In particular, the table cannot be involved in any foreign key relationships.
> 
> ********** Error **********
> 
> ERROR: could not convert table "b" to a view because it has triggers
> SQL state: 55000
> Hint: In particular, the table cannot be involved in any foreign key relationships.
> 
> 
> Scenario:
> 
> create table a (id int primary key);
> create table b (id int primary key, a_id int references a (id));
> 
> insert into  a values (1);
> insert into  b values (1,1);
> 
> create table c AS SELECT * FROM b;
> 
> TRUNCATE b;
> ALTER TABLE b DROP CONSTRAINT b_a_id_fkey;
> ALTER TABLE b DROP CONSTRAINT b_pkey;
> ALTER TABLE b ALTER COLUMN id DROP NOT NULL;
> 
> CREATE RULE "_RETURN" AS ON SELECT TO b DO INSTEAD SELECT * FROM C;

SELECT relhastriggers FROM pg_class WHERE oid = 'b'::regclass;

 relhastriggers
----------------
 t
(1 row)

http://www.postgresql.org/docs/current/static/catalog-pg-class.html

relhastriggers bool     True if table has (or once had) triggers

This is what is queried when you try to convert the table into a view.
So there is no way to convert your table to a view unless you are
wiling to tamper with the pg_class.

Yours,
Laurenz Albe

Re: Convert table to view 9.1

От
salah jubeh
Дата:

>> ERROR:  could not convert table "b" to a view because it has triggers
>> HINT:  In particular, the table cannot be involved in any foreign key relationships.
>>
>> ********** Error **********
>>
>> ERROR: could not convert table "b" to a view because it has triggers
>> SQL state: 55000
>> Hint: In particular, the table cannot be involved in any foreign key relationships.
>>
>>
>> Scenario:
>>
>> create table a (id int primary key);
>>create table b (id int primary key, a_id int references a (id));
>>
>>insert into  a values (1);
>> insert into  b values (1,1);
>>
>> create table c AS SELECT * FROM b;
>>
>> TRUNCATE b;
>> ALTER TABLE b DROP CONSTRAINT b_a_id_fkey;
>> ALTER TABLE b DROP CONSTRAINT b_pkey;
>> ALTER TABLE b ALTER COLUMN id DROP NOT NULL;
>>
> >CREATE RULE "_RETURN" AS ON SELECT TO b DO INSTEAD SELECT * FROM C;

>SELECT relhastriggers FROM pg_class WHERE oid = 'b'::regclass;

>relhastriggers
>(1 row)

>http://www.postgresql.org/docs/current/static/catalog-pg-class.html

>relhastriggers bool    True if table has (or once had) triggers

>This is what is queried when you try to convert the table into a view.
>So there is no way to convert your table to a view unless you are
>wiling to tamper with the pg_class.

>Yours,
>Laurenz Albe

I have tried the follwoing and itworks, I need to update also relhasindex

UPDATE  pg_class SET relhastriggers = FALSE WHERE oid = 'b'::regclass;
UPDATE  pg_class SET relhasindex = FALSE WHERE oid = 'b'::regclass;

To be honest I do not like to play with catalog tables, so my question would be, what are the reason for "(or recently had)" in the case of index, or (or once had) in the case of triggers. I find the ability to convert a table to a view an extremly handy in applications were buisnes logic is modelled as views. For example, I need to refactor b, but keep it for backward compatability as updatabale view.

Regards

--
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general


On Wednesday, December 11, 2013 2:18 PM, Albe Laurenz <laurenz.albe@wien.gv.at> wrote:
salah jubeh wrote:

> ERROR:  could not convert table "b" to a view because it has triggers
> HINT:  In particular, the table cannot be involved in any foreign key relationships.
>
> ********** Error **********
>
> ERROR: could not convert table "b" to a view because it has triggers
> SQL state: 55000
> Hint: In particular, the table cannot be involved in any foreign key relationships.
>
>
> Scenario:
>
> create table a (id int primary key);
> create table b (id int primary key, a_id int references a (id));
>
> insert into  a values (1);
> insert into  b values (1,1);
>
> create table c AS SELECT * FROM b;
>
> TRUNCATE b;
> ALTER TABLE b DROP CONSTRAINT b_a_id_fkey;
> ALTER TABLE b DROP CONSTRAINT b_pkey;
> ALTER TABLE b ALTER COLUMN id DROP NOT NULL;
>
> CREATE RULE "_RETURN" AS ON SELECT TO b DO INSTEAD SELECT * FROM C;

SELECT relhastriggers FROM pg_class WHERE oid = 'b'::regclass;

relhastriggers

----------------
t

(1 row)

http://www.postgresql.org/docs/current/static/catalog-pg-class.html

relhastriggers bool    True if table has (or once had) triggers

This is what is queried when you try to convert the table into a view.
So there is no way to convert your table to a view unless you are
wiling to tamper with the pg_class.

Yours,
Laurenz Albe

--
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general



Re: Convert table to view 9.1

От
Albe Laurenz
Дата:
salah jubeh wrote:
>> http://www.postgresql.org/docs/current/static/catalog-pg-class.html
>> relhastriggers bool    True if table has (or once had) triggers
> 
>> This is what is queried when you try to convert the table into a view.
>> So there is no way to convert your table to a view unless you are
>> wiling to tamper with the pg_class.

> I have tried the follwoing and itworks, I need to update also relhasindex
> 
> UPDATE  pg_class SET relhastriggers = FALSE WHERE oid = 'b'::regclass;
> UPDATE  pg_class SET relhasindex = FALSE WHERE oid = 'b'::regclass;
> 
> To be honest I do not like to play with catalog tables, so my question would be, what are the reason
> for "(or recently had)" in the case of index, or (or once had) in the case of triggers. I find the
> ability to convert a table to a view an extremly handy in applications were buisnes logic is modelled
> as views. For example, I need to refactor b, but keep it for backward compatability as updatabale
> view.

You are right to be reluctant to tamper with pg_class.

This comment in backend/commands/trigger.c explains why
relhastriggers is left "true":

    /*
     * We do not bother to try to determine whether any other triggers remain,
     * which would be needed in order to decide whether it's safe to clear the
     * relation's relhastriggers.  (In any case, there might be a concurrent
     * process adding new triggers.)  Instead, just force a relcache inval to
     * make other backends (and this one too!) rebuild their relcache entries.
     * There's no great harm in leaving relhastriggers true even if there are
     * no triggers left.
     */

So I guess it is just left because nobody cared enough.

What keeps you from creating a copy of b:

CREATE TABLE b_copy(LIKE b EXCLUDING CONSTRAINTS);
DROP TABLE b;
ALTER TABLE b_copy RENAME TO b;

Yours,
Laurenz Albe

Re: Convert table to view 9.1

От
salah jubeh
Дата:

salah jubeh wrote:
>>> http://www.postgresql.org/docs/current/static/catalog-pg-class.html
>>> relhastriggers bool    True if table has (or once had) triggers
>>
>>> This is what is queried when you try to convert the table into a view.
>>> So there is no way to convert your table to a view unless you are
>>> wiling to tamper with the pg_class.

>> I have tried the follwoing and itworks, I need to update also relhasindex
>>
>> UPDATE  pg_class SET relhastriggers = FALSE WHERE oid = 'b'::regclass;
>> UPDATE  pg_class SET relhasindex = FALSE WHERE oid = 'b'::regclass;
>>
>> To be honest I do not like to play with catalog tables, so my question would be, what are the reason
>> for "(or recently had)" in the case of index, or (or once had) in the case of triggers. I find the
>> ability to convert a table to a view an extremly handy in applications were buisnes logic is modelled
>> as views. For example, I need to refactor b, but keep it for backward compatability as updatabale
>> view.

>You are right to be reluctant to tamper with pg_class.
>
>This comment in backend/commands/trigger.c explains why
>relhastriggers is left "true":
>
>    /*
>    * We do not bother to try to determine whether any other triggers remain,
>    * which would be needed in order to decide whether it's safe to clear the
 >   * relation's relhastriggers.  (In any case, there might be a concurrent
>    * process adding new triggers.)  Instead, just force a relcache inval to
>    * make other backends (and this one too!) rebuild their relcache entries.
>    * There's no great harm in leaving relhastriggers true even if there are
>    * no triggers left.
>    */
>
>So I guess it is just left because nobody cared enough.

>What keeps you from creating a copy of b:

>CREATE TABLE b_copy(LIKE b EXCLUDING CONSTRAINTS);
>DROP TABLE b;
>ALTER TABLE b_copy RENAME TO b;

Thanks for the reply, In the scenario above this will work, but if I add a view as:
create view a_b as SELECT a.id as a_id, b.id as b_id FROM b join a on a.id = b.a_id;

then the -DROP table b;- will fail, unless I drop also a_b view,  or use cascade option. In certain applications, it is easy. In some cases, it will take a lot of time and effort.

Is there a plan to fix this in the comming releases.  Finally, what is the risk of changing the cataloge tables in this case?

Regards 






On Wednesday, December 11, 2013 3:15 PM, Albe Laurenz <laurenz.albe@wien.gv.at> wrote:
salah jubeh wrote:
>> http://www.postgresql.org/docs/current/static/catalog-pg-class.html
>> relhastriggers bool    True if table has (or once had) triggers
>
>> This is what is queried when you try to convert the table into a view.
>> So there is no way to convert your table to a view unless you are
>> wiling to tamper with the pg_class.

> I have tried the follwoing and itworks, I need to update also relhasindex
>
> UPDATE  pg_class SET relhastriggers = FALSE WHERE oid = 'b'::regclass;
> UPDATE  pg_class SET relhasindex = FALSE WHERE oid = 'b'::regclass;
>
> To be honest I do not like to play with catalog tables, so my question would be, what are the reason
> for "(or recently had)" in the case of index, or (or once had) in the case of triggers. I find the
> ability to convert a table to a view an extremly handy in applications were buisnes logic is modelled
> as views. For example, I need to refactor b, but keep it for backward compatability as updatabale
> view.

You are right to be reluctant to tamper with pg_class.

This comment in backend/commands/trigger.c explains why
relhastriggers is left "true":

    /*
    * We do not bother to try to determine whether any other triggers remain,
    * which would be needed in order to decide whether it's safe to clear the
    * relation's relhastriggers.  (In any case, there might be a concurrent
    * process adding new triggers.)  Instead, just force a relcache inval to
    * make other backends (and this one too!) rebuild their relcache entries.
    * There's no great harm in leaving relhastriggers true even if there are
    * no triggers left.
    */

So I guess it is just left because nobody cared enough.

What keeps you from creating a copy of b:

CREATE TABLE b_copy(LIKE b EXCLUDING CONSTRAINTS);
DROP TABLE b;
ALTER TABLE b_copy RENAME TO b;


Yours,
Laurenz Albe

--
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general


Re: Convert table to view 9.1

От
Tom Lane
Дата:
salah jubeh <s_jubeh@yahoo.com> writes:
> create table a (id int primary key);
> create table b (id int primary key, a_id int references a (id));

> insert into� a values (1);
> insert into� b values (1,1);

> create table c AS SELECT * FROM b;

> TRUNCATE b;
> ALTER TABLE b DROP CONSTRAINT b_a_id_fkey;
> ALTER TABLE b DROP CONSTRAINT b_pkey;
> ALTER TABLE b ALTER COLUMN id DROP NOT NULL;
> �
> CREATE RULE "_RETURN" AS ON SELECT TO b DO INSTEAD SELECT * FROM C;

Patient: Doctor, it hurts when I do this.
Doctor: So, don't do that.

Why would you think this is a good thing to do?  Why not just rename
table b to c, and then create the view as b?

(For context, it's not even considered a supported operation to
manually create _RETURN rules like that.  Any arbitrary restrictions
we might put on transforming tables to views are perfectly legitimate
IMHO, because the only case we care about supporting is pg_dump's
usage of this hack to break circular dependencies between views.
And in that case, the "table" never had any table-only features.)

            regards, tom lane


Re: Convert table to view 9.1

От
salah jubeh
Дата:
Hello Tom,

>Patient: Doctor, it hurts when I do this.
>Doctor: So, don't do that.

>Why would you think this is a good thing to do?  Why not just rename
>table b to c, and then create the view as b?
>(For context, it's not even considered a supported operation to
>manually create _RETURN rules like that. 

I have stumbled upon this in the documentation, http://www.postgresql.org/docs/9.1/static/rules-views.html, and it seems an option to solve a problem in a legacy system. This might not the best approch, but it gives me the chance to refactor a node in  complex tree, without dropping and creating the subtree which depends on this certain node. In my case the table b  has a  bad design and refactoring is requiered . Still, since this is a legacy application, and the table b is used in hundreds of views, and the code in not maintained in git repository ....etc. It would be easier for me just to replace it with updatable view without dropping the views.

Normally, I do not convert a table to view using this approch. But, since this approach is mentioned in the docs. I think it would be nice to either have more clarification. Still, I think there is data inconsistency, I have queried in the past for example pg_class to determine if a table has no index to determine misusage or bad designs.

Regards





On Wednesday, December 11, 2013 4:50 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
salah jubeh <s_jubeh@yahoo.com> writes:

> create table a (id int primary key);
> create table b (id int primary key, a_id int references a (id));

> insert into  a values (1);
> insert into  b values (1,1);

> create table c AS SELECT * FROM b;

> TRUNCATE b;
> ALTER TABLE b DROP CONSTRAINT b_a_id_fkey;
> ALTER TABLE b DROP CONSTRAINT b_pkey;
> ALTER TABLE b ALTER COLUMN id DROP NOT NULL;
>  
> CREATE RULE "_RETURN" AS ON SELECT TO b DO INSTEAD SELECT * FROM C;


Patient: Doctor, it hurts when I do this.
Doctor: So, don't do that.

Why would you think this is a good thing to do?  Why not just rename
table b to c, and then create the view as b?

(For context, it's not even considered a supported operation to
manually create _RETURN rules like that.  Any arbitrary restrictions
we might put on transforming tables to views are perfectly legitimate
IMHO, because the only case we care about supporting is pg_dump's
usage of this hack to break circular dependencies between views.
And in that case, the "table" never had any table-only features.)

            regards, tom lane