2010/12/11 Florian Pflug <f...@phlo.org>: > On Dec11, 2010, at 16:03 , Pavel Stehule wrote: >> 2010/12/11 Florian Pflug <f...@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. 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 > > -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers