From: | Pavel Stehule <pavel(dot)stehule(at)gmail(dot)com> |
---|---|
To: | Florian Pflug <fgp(at)phlo(dot)org> |
Cc: | PostgreSQL Hackers <pgsql-hackers(at)postgresql(dot)org> |
Subject: | Re: proposal: auxiliary functions for record type |
Date: | 2010-12-11 16:55:04 |
Message-ID: | AANLkTikBU81hE54gavuTjR20TSnvL0pYk69k8WcPDs-N@mail.gmail.com |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-hackers |
2010/12/11 Florian Pflug <fgp(at)phlo(dot)org>:
> On Dec11, 2010, at 16:03 , Pavel Stehule wrote:
>> 2010/12/11 Florian Pflug <fgp(at)phlo(dot)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. As a consequence, however, it lacks the set-returning functions that your's provides. It also doesn't provide a way to modify fields.
>>
>> 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 takes a 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 of the requested field matches that type, the value is returned. If they don't match, the parameter <coerce> decided whether fieldvalue() tries to cast the value to the requested type, or simply raises an error.
It same trick, that I use in record_set_fields. But I don't want to
use it for reading of value. I don't like it. You don't need to know a
value, you have to know a type - NULL::type. it is just not nice :). I
though about it too, and maybe is a time for new polymorphic type
"anytype" - and then you don't need to write a litte bit strange
NULL::type
it can be "fieldvalue(myrec, type1, false)"
Regards
Pavel Stehule
>
> Second, to also give the *value*, not only the *type* of <defval> a meaning, it serves as the default return value. If requested field contains NULL, <defvalue> is returned instead. You are, of course, free to pass NULL for <defvalue> itself to 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 from the 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 the line of
> declare
> v_value_type1 type1;
> v_value_type2 type2;
> ...
> v_value_typeN typeN;
> begin
> for 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
>
>
From | Date | Subject | |
---|---|---|---|
Next Message | Tom Lane | 2010-12-11 16:55:19 | Re: [COMMITTERS] pgsql: Use symbolic names not octal constants for file permission flags |
Previous Message | Magnus Hagander | 2010-12-11 16:44:53 | Re: [COMMITTERS] pgsql: Use symbolic names not octal constants for file permission flags |