Thread: alter table tablename add column - breaks pl/pgsql function returns tablename
alter table tablename add column - breaks pl/pgsql function returns tablename
From
Palle Girgensohn
Date:
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Hi! This is an old problem, referred to in bug #4907: CREATE TABLE test(id INTEGER); INSERT INTO test VALUES (1); CREATE OR REPLACE FUNCTION test_func() returns SETOF test as $$ DECLARE res_ test; BEGIN FOR res_ IN SELECT * FROM test LOOP RETURN NEXT res_; END LOOP; END $$ LANGUAGE 'plpgsql'; SELECT * FROM test_func(); ALTER TABLE test ADD COLUMN foo INTEGER; SELECT * FROM test_func(); - -- ERROR: wrong record type supplied in RETURN NEXT You have to run create or replace again to fix it when changing the schema. How come it fails? Is the return type "hardcoded" when the function is created? Is this very hard to fix? IS there a suggested work-around? It seems to work to change to a generic "record", but that is also more sloppy as it is not as well typed. Thoughts? Palle -----BEGIN PGP SIGNATURE----- Version: GnuPG/MacGPG2 v2.0.17 (Darwin) Comment: GPGTools - http://gpgtools.org Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iQEcBAEBAgAGBQJQkWwGAAoJEIhV+7FrxBJDc6wIAK0w3h7hvPT0zsu7YyviKL+f vi/cL5f+B9NYRkXxQ4AJ5+Qr0xwODNvSFlCEoqrREcdcCAZHoEktunZtp0FTvNLQ HJEemac23/YyUaYE5rFI7KIySxTEnpY6qQx+YkHW1OiDF4/X/XzEFYFjCa9x3jNi BfrnmYP0MXCB0y+vXRpUn4vm8QW7o5m+hQE0nQ0Ni4xk+GHbGOh2q21WzYevOe6s Gj4r8nDPMX1q0Sk4zmnNrUbudVx6YsEtj7ogAbGCg5KbB3ebjfj5eJdSAD9z/uCs 0ikfZt2kvDAkdbrz/uEaRhq91gkkjZR2+Tm1iEKJhedRsRBk2y554zw7esxkj/c= =sVM9 -----END PGP SIGNATURE-----
Re: alter table tablename add column - breaks pl/pgsql function returns tablename
From
Amit kapila
Date:
On Wednesday, October 31, 2012 11:50 PM Palle Girgensohn wrote: Hash: SHA1 Hi! > This is an old problem, referred to in bug #4907: >ALTER TABLE test ADD COLUMN foo INTEGER; > SELECT * FROM test_func(); > - -- ERROR: wrong record type supplied in RETURN NEXT > You have to run create or replace again to fix it when changing the > schema. How come it fails? Is the return type "hardcoded" when the > function is created? I think it is because compiled body of function is created with that type of table. You will notsee this problem if you reconnect or select from another new session. > Is this very hard to fix? Currently the compiled body is not discarded on DDL's, so I believe it is not a bug as per current implementation. Howeverit can be thought of as a new feature. > IS there a suggested work-around? Considering DDL's are used less often, you can see how feasible it is for you thatafter a DDL, you reconnect sessions which use functions. I know this is not good workaround, but I am sorry nothingelse comes to my mind for now. Anybody else can think of any other better workarounds for this problem? With Regards, Amit Kapila.
Re: alter table tablename add column - breaks pl/pgsql function returns tablename
From
Robert Haas
Date:
On Thu, Nov 1, 2012 at 12:14 AM, Amit kapila <amit.kapila@huawei.com> wrote: >> Is this very hard to fix? > > Currently the compiled body is not discarded on DDL's, so I believe it is not a bug as per current implementation. > However it can be thought of as a new feature. Seems like a bug to me. -- Robert Haas EnterpriseDB: http://www.enterprisedb.com The Enterprise PostgreSQL Company
Re: alter table tablename add column - breaks pl/pgsql function returns tablename
From
Palle Girgensohn
Date:
5 nov 2012 kl. 19:36 skrev Robert Haas <robertmhaas@gmail.com>: > On Thu, Nov 1, 2012 at 12:14 AM, Amit kapila <amit.kapila@huawei.com> wrote: >>> Is this very hard to fix? >> >> Currently the compiled body is not discarded on DDL's, so I believe it is not a bug as per current implementation. >> However it can be thought of as a new feature. > > Seems like a bug to me. > Please note that this problem does not go away by disconnecting and reconnecting, and other sessions get the error immediately,so the claim that it is bound to a session is false. The work-around I use now is to "create or replace function ..." with a verbatim copy of what is already the defined function.Seems stupid to me, I agree it seems like a bug. > Robert Haas > EnterpriseDB: http://www.enterprisedb.com > The Enterprise PostgreSQL Company
Re: alter table tablename add column - breaks pl/pgsql function returns tablename
From
Tom Lane
Date:
Palle Girgensohn <girgen@pingpong.net> writes: > Please note that this problem does not go away by disconnecting and reconnecting, and other sessions get the error immediately,so the claim that it is bound to a session is false. Huh? The test case you provided certainly doesn't exhibit any such behavior. I get regression=# SELECT * FROM test_func(); ERROR: wrong record type supplied in RETURN NEXT CONTEXT: PL/pgSQL function test_func() line 6 at RETURN NEXT regression=# \c - You are now connected to database "regression" as user "postgres". regression=# SELECT * FROM test_func();id | foo ----+----- 1 | (1 row) regards, tom lane
Re: alter table tablename add column - breaks pl/pgsql function returns tablename
From
Palle Girgensohn
Date:
5 nov 2012 kl. 22:23 skrev Tom Lane <tgl@sss.pgh.pa.us>: > Palle Girgensohn <girgen@pingpong.net> writes: >> Please note that this problem does not go away by disconnecting and reconnecting, and other sessions get the error immediately,so the claim that it is bound to a session is false. > > Huh? The test case you provided certainly doesn't exhibit any such > behavior. I get > > regression=# SELECT * FROM test_func(); > ERROR: wrong record type supplied in RETURN NEXT > CONTEXT: PL/pgSQL function test_func() line 6 at RETURN NEXT > regression=# \c - > You are now connected to database "regression" as user "postgres". > regression=# SELECT * FROM test_func(); > id | foo > ----+----- > 1 | > (1 row) > > regards, tom lane Ah, sorry. Other sessions get the error immediately as well though. Would input parameters matter, or is it just the returntype? I'll see if I can find a test case that breaks permanently, but I'm probably mistaken about that bit then.
Re: alter table tablename add column - breaks pl/pgsql function returns tablename
From
Tom Lane
Date:
Palle Girgensohn <girgen@pingpong.net> writes: > Ah, sorry. Other sessions get the error immediately as well though. Would input parameters matter, or is it just the returntype? I'll see if I can find a test case that breaks permanently, but I'm probably mistaken about that bit then. It's not the return value as such that's choking, it's the local variable. I believe the issue would appear with any local variable or parameter of a named composite type. The general case of this is quite difficult: should we expect that an ALTER TYPE done (perhaps in some other session) while a function is running would affect the *current value* of such a local variable? There's really no practical way to implement that in the current system structure, and certainly no way to enforce the behavior you get for row values in regular tables, namely that the ALTER TYPE rolls back if any row value conversion fails. However I think we could realistically hope that subsequent function calls would work with the up-to-date rowtype definition. My opinion about how to do that is to stop using the "row" code path in plpgsql for values of named composite types, and instead treat them as "records"; that is, store a HeapTuple value plus a tuple descriptor (or something morally equivalent such as a TupleTableSlot) and not break the value up into a separate plpgsql variable (a/k/a PLpgSQL_datum) per column. The fundamental problem here is that doing that bakes the rowtype's column set into the compiled form of the function. There was some objection to that in the previous discussion on the grounds of possible performance loss, but I think that objection is at best premature; it ignores some salient facts such as (1) some operations would get faster not slower, (2) there is scope for performance-improvement efforts, (3) per the old saying, code can be arbitrarily fast if it doesn't have to give the right answer. Objecting to this fixwithout proposing a more-workable alternative is useless. regards, tom lane