Re: proposal: auxiliary functions for record type

Поиск
Список
Период
Сортировка
От Florian Pflug
Тема Re: proposal: auxiliary functions for record type
Дата
Msg-id DF02606E-71D2-49B0-8C29-B9312F118C9D@phlo.org
обсуждение исходный текст
Ответ на Re: proposal: auxiliary functions for record type  (Pavel Stehule <pavel.stehule@gmail.com>)
Ответы Re: proposal: auxiliary functions for record type  (Pavel Stehule <pavel.stehule@gmail.com>)
Re: proposal: auxiliary functions for record type  (Jim Nasby <jim@nasby.net>)
Список pgsql-hackers
On Dec11, 2010, at 16:03 , Pavel Stehule wrote:
> 2010/12/11 Florian Pflug <fgp@phlo.org>:
>> On Dec11, 2010, at 06:20 , Pavel Stehule wrote:
>>> I wrote a few functions for record type - record_expand,
>>> record_get_fields, record_get_field, record_set_fields.
>>
>> Just FYI, I've created something similar a while ago. The code can be found at
>> https://github.com/fgp/pg_record_inspect
>>
>> The main difference seems to be that my code allows you to retrieve fields from a record without casting it to text.
Asa consequence, however, it lacks the set-returning functions that your's provides. It also doesn't provide a way to
modifyfields. 
>
> Casting to text is necessary for PL/pgSQL. I am not happy from this,
> but there are not other way than using a common type - text - because
> you don't know a target type.


I use the anyarray/anyelement machinery to cheat there, at least a bit. My function fieldvalue() returns anyelement and
takesa parameter <defval> of type anyelement, which serves two purposes. 

First, by virtue of the anyelement machinery, the return type of fieldvalue() is that of <defval>. If the actual type
ofthe requested field matches that type, the value is returned. If they don't match, the parameter <coerce> decided
whetherfieldvalue() tries to cast the value to the requested type, or simply raises an error. 

Second, to also give the *value*, not only the *type* of <defval> a meaning, it serves as the default return value. If
requestedfield contains NULL, <defvalue> is returned instead. You are, of course, free to pass NULL for <defvalue>
itselfto turn that mapping into a NOP. 

Note that the returned value's type is always the same as <defval>'s type, so the whole thing is perfectly type-safe
fromthe point of view of the rest of the system. 

As long as you know all possible types than can appear in your record's fields, you can do in Pl/PgSQL something along
theline of  
declarev_value_type1 type1;v_value_type2 type2;...v_value_typeN typeN;
beginfor v_field in select * from fieldinfos(myrec) loop    case        when v_field.fieldtype = 'type1'::regtype then
         v_value_type1 := fieldvalue(myrec, NULL::type1, false);            <Do something with v_value_type1>
...       when v_field.fieldtype = 'typeN'::regtype then            v_value_typeN := fieldvalue(myrec, NULL::typeN,
false);           <Do something with v_value_typeN>        else raise exception 'Unexpected type % in record %',
v_field.fieldtype,myrec;    end case;end loop; 
end;

It works pretty well for me...

best regards,
Florian Pflug



В списке pgsql-hackers по дате отправления:

Предыдущее
От: Pavel Stehule
Дата:
Сообщение: Re: proposal: auxiliary functions for record type
Следующее
От: Tom Lane
Дата:
Сообщение: Re: [COMMITTERS] pgsql: Use symbolic names not octal constants for file permission flags