2011/1/23 Jan Urbański <wulc...@wulczer.org>: > On 22/01/11 11:15, Hitoshi Harada wrote: >> This is a review for >> https://commitfest.postgresql.org/action/patch_view?id=460 > > Thanks, > >> One issue is typmod of record type. >> >> regression=# create or replace function func1(t text) returns record >> as $$ return {'name': t, 'value': 0} $$ language plpythonu; >> regression=# select * from func1('jan') as (name text, value bigint); >> name | value >> ------+------- >> jan | 0 >> (1 row) >> >> regression=# select * from func1('jan') as (name text, value int); >> ERROR: function return row and query-specified return row do not match >> DETAIL: Returned type bigint at ordinal position 2, but query expects >> integer. > > That's a bug, thanks for spotting it. > >> It seems that typmod of PLyTypeInfo is not updated over statements >> within the session. I saw the error doesn't occur when I re-connect to >> the backend after the error. > > I tracked it down to caching the I/O functions for the return type. Your > example shows that you can't just discover the output record type once, > but you have to recheck whether the returned record's structure has not > changed between calls. > > I implemented it by looping over the attributes of the output record and > checking if type for which we have already cached the I/O function is > binary coercible to the type that's actually in the record. This allows > the code to skip recaching the functions in the common case when the > record stays the same, and fixes the bug you found. > > Attached is a new patch for table function support and an incremental > patch with the change I did. The new patch for table functions does not > apply to HEAD, it's a refinement of the previous table-functions patch. > After the refactor patches are all applied or rejected, I'll post a > frech patch that applies cleanly to HEAD.
I tested the new incremental patch and the previous example works fine. I don't know if this can be handled properly but another example is: regression=# create function func1(t text) returns record as $$ return {'name':t, 'value':0}; $$ language plpythonu ; CREATE FUNCTION regression=# select * from func1('jan') as (name text, value bigint); name | value ------+------- jan | 0 (1 row) regression=# select * from func1('jan') as (value text, name bigint); value | name -------+------ jan | 0 (1 row) where value and name don't point to the correct data. Your data-type-check logic might not be enough. Regards, -- Hitoshi Harada -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers