Thread: Writing values to relation using bytearray ...

Writing values to relation using bytearray ...

From
Kedar Potdar
Date:
Hi,<br /><br /><div style="text-align: left;">I am trying to write values of different types to relation using
followingcode.<br /></div><br /><span style="font-family: courier new,monospace;">            if(typbyval)</span><br
style="font-family:courier new,monospace;" /><span style="font-family: courier new,monospace;">            {</span><br
style="font-family:courier new,monospace;" /><span style="font-family: courier new,monospace;">                min_ba =
(bytea*) palloc(len+1+VARHDRSZ);</span><br style="font-family: courier new,monospace;" /><span style="font-family:
couriernew,monospace;">                memcpy(VARDATA(min_ba), &min_datum, len);</span><br style="font-family:
couriernew,monospace;" /><span style="font-family: courier new,monospace;">                SET_VARSIZE(min_ba,
len+VARHDRSZ);</span><brstyle="font-family: courier new,monospace;" /><span style="font-family: courier
new,monospace;">               VARDATA(min_ba)[len] = '\0';</span><br style="font-family: courier new,monospace;"
/><spanstyle="font-family: courier new,monospace;">                values[Anum_pg_partition_minval        -1]=
(Datum)min_ba;</span><br style="font-family: courier new,monospace;" /><br style="font-family: courier new,monospace;"
/><spanstyle="font-family: courier new,monospace;">                max_ba = (bytea *) palloc(len+1+VARHDRSZ);</span><br
style="font-family:courier new,monospace;" /><span style="font-family: courier new,monospace;">               
memcpy(VARDATA(max_ba),&max_datum, len);</span><br style="font-family: courier new,monospace;" /><span
style="font-family:courier new,monospace;">                SET_VARSIZE(max_ba, len+VARHDRSZ);</span><br
style="font-family:courier new,monospace;" /><span style="font-family: courier new,monospace;">               
VARDATA(max_ba)[len]= '\0';</span><br style="font-family: courier new,monospace;" /><span style="font-family: courier
new,monospace;">               values[Anum_pg_partition_maxval        -1]=(Datum)max_ba;</span><br style="font-family:
couriernew,monospace;" /><span style="font-family: courier new,monospace;">            }</span><br style="font-family:
couriernew,monospace;" /><span style="font-family: courier new,monospace;">            else</span><br
style="font-family:courier new,monospace;" /><span style="font-family: courier new,monospace;">            {</span><br
style="font-family:courier new,monospace;" /><span style="font-family: courier new,monospace;">               
values[Anum_pg_partition_minval       -1]=min_datum;</span><br style="font-family: courier new,monospace;" /><span
style="font-family:courier new,monospace;">                values[Anum_pg_partition_maxval       
-1]=max_datum;</span><brstyle="font-family: courier new,monospace;" /><span style="font-family: courier
new,monospace;">           }</span><br /><br />These values are then written to relation using heap_form_tuple() and
simple_heap_insert()functions. <br /><br />I am using following code to read the values from relation.<br /><br /><span
style="font-family:courier new,monospace;">        part_attr = heap_getattr
(pg_parttup,Anum_pg_partition_maxval,</span><brstyle="font-family: courier new,monospace;" /><span style="font-family:
couriernew,monospace;">                                            pg_partrel->rd_att,&isnull);</span><br
style="font-family:courier new,monospace;" /><span style="font-family: courier new,monospace;">        if ( typbyval
)</span><brstyle="font-family: courier new,monospace;" /><span style="font-family: courier new,monospace;">       
{</span><brstyle="font-family: courier new,monospace;" /><span style="font-family: courier new,monospace;">           
short_datum= 0;</span><br style="font-family: courier new,monospace;" /><span style="font-family: courier
new,monospace;">           memcpy(&short_datum, VARDATA_ANY(part_attr), len);</span><br style="font-family: courier
new,monospace;"/><span style="font-family: courier new,monospace;">            part_attr = short_datum;</span><br
style="font-family:courier new,monospace;" /><span style="font-family: courier new,monospace;">        }</span><br
style="font-family:courier new,monospace;" /><span style="font-family: courier new,monospace;">        else if (len !=
-1)</span><br style="font-family: courier new,monospace;" /><span style="font-family: courier
new,monospace;">           part_attr = (Datum)VARDATA_ANY(part_attr);</span><br /><br /><br />The aforementioned code
worksfine for types like int, data, text and I can read values from the relation correctly. The problem arises for type
"float8"which is not "by value" type and it has fixed length (8) where I can't read the values written to relation
correctly.<br/><br />Am i missing something here? <br /><br />Thanking you in anticipation.<br /><br />With warm
regards,<br/>--<br />Kedar.<br /> 

Re: Writing values to relation using bytearray ...

From
Greg Stark
Date:
On Fri, Mar 6, 2009 at 10:03 AM, Kedar Potdar <kedar.potdar@gmail.com> wrote:
>
> The aforementioned code works fine for types like int, data, text and I can
> read values from the relation correctly. The problem arises for type
> "float8" which is not "by value" type and it has fixed length (8) where I
> can't read the values written to relation correctly.
>
> Am i missing something here?

Well as you've correctly diagnosed, not all byvalue data types are
variable-length.

This code all seems unnecessary. The whole point of heap_form_datum
and heap_deform_datum/heap_getattr is that you don't have to worry
about all this. there are also functions like datumCopy() but you
probably don't even need them here, you can just put the datums you
have handy into the values[] array and pass that to heap_form_tuple --
it'll copy them into the resulting tuple so once you've formed the
tuple you don't have to worry about the lifetime of the original
datums. heap_deform_tuple() and heap_getattr can return pointers into
the original tuple so you do have to be careful to copy them if you
need them to survive the original tuple -- but you might not be
anyways.


-- 
greg


Re: Writing values to relation using bytearray ...

From
Kedar Potdar
Date:
Thanks Greg, for showing interest.<br /><br />The problem here is I need to store values of different types into
bytearraycolumn of relation. <br /><br /><div class="gmail_quote">On Fri, Mar 6, 2009 at 4:33 PM, Greg Stark <span
dir="ltr"><<ahref="mailto:stark@enterprisedb.com">stark@enterprisedb.com</a>></span> wrote:<br /><blockquote
class="gmail_quote"style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left:
1ex;"><divclass="im">On Fri, Mar 6, 2009 at 10:03 AM, Kedar Potdar <<a
href="mailto:kedar.potdar@gmail.com">kedar.potdar@gmail.com</a>>wrote:<br /> ><br /> > The aforementioned code
worksfine for types like int, data, text and I can<br /> > read values from the relation correctly. The problem
arisesfor type<br /> > "float8" which is not "by value" type and it has fixed length (8) where I<br /> > can't
readthe values written to relation correctly.<br /> ><br /> > Am i missing something here?<br /><br /></div>Well
asyou've correctly diagnosed, not all byvalue data types are<br /> variable-length.<br /><br /> This code all seems
unnecessary.The whole point of heap_form_datum<br /> and heap_deform_datum/heap_getattr is that you don't have to
worry<br/> about all this. there are also functions like datumCopy() but you<br /> probably don't even need them here,
youcan just put the datums you<br /> have handy into the values[] array and pass that to heap_form_tuple --<br /> it'll
copythem into the resulting tuple so once you've formed the<br /> tuple you don't have to worry about the lifetime of
theoriginal<br /> datums. heap_deform_tuple() and heap_getattr can return pointers into<br /> the original tuple so you
dohave to be careful to copy them if you<br /> need them to survive the original tuple -- but you might not be<br />
anyways.<br/><br /><br /> --<br /><font color="#888888">greg<br /></font></blockquote></div><br /> 

Re: Writing values to relation using bytearray ...

From
Greg Stark
Date:
On Fri, Mar 6, 2009 at 11:41 AM, Kedar Potdar <kedar.potdar@gmail.com> wrote:
> Thanks Greg, for showing interest.
>
> The problem here is I need to store values of different types into bytearray
> column of relation.

Oh, hm. I think you need to look at typlen instead of typbyval.

But you have an additional problem for typbyval types: the pointer to
Datum isn't necessarily pointing at the right bytes. I think you have
to use the GET_[1248]_BYTES macros depending on typlen. There may be a
helper function for this but I don't know of one.


-- 
greg


Re: Writing values to relation using bytearray ...

From
Greg Stark
Date:
On Fri, Mar 6, 2009 at 12:01 PM, Greg Stark <stark@enterprisedb.com> wrote:
> But you have an additional problem for typbyval types: the pointer to
> Datum isn't necessarily pointing at the right bytes. I think you have
> to use the GET_[1248]_BYTES macros depending on typlen. There may be a
> helper function for this but I don't know of one.

Actually on further thought I think I would suggest just storing the
whole datum for all typbyval types setting your bytea length to
SIZEOF_DATUM.

And use datumGetSize() for non-typbyval datums. Assuming you have
typbyval and typlen handy.

-- 
greg


Re: Writing values to relation using bytearray ...

From
Tom Lane
Date:
Kedar Potdar <kedar.potdar@gmail.com> writes:
> The problem here is I need to store values of different types into bytearray
> column of relation.

Perhaps you should study the ANALYZE code.  AFAICS your requirements are
not different from those of the pg_statistic data store.  You should do
things the same way they are done there, if only to reduce the surprise
factor for readers of the code.
        regards, tom lane


Re: Writing values to relation using bytearray ...

From
Kedar Potdar
Date:
Thanks Tom for your interest.

I could find a workaround for the issue wherein the value of type
which is not stored "by value" and has fixed data length, is being
stored in string format to the relation.

While retrieving from relation, this value is converted by using
"coerce_to_specific_type()"to its native type datum represation as required.

This is a bit of overhead and I'd like to find more efficient solution
and will look pg_statistics data store.

Regards,
-
Kedar

- sent from a mobile device.

On 3/6/09, Tom Lane <tgl@sss.pgh.pa.us> wrote:
> Kedar Potdar <kedar.potdar@gmail.com> writes:
>> The problem here is I need to store values of different types into
>> bytearray
>> column of relation.
>
> Perhaps you should study the ANALYZE code.  AFAICS your requirements are
> not different from those of the pg_statistic data store.  You should do
> things the same way they are done there, if only to reduce the surprise
> factor for readers of the code.
>
>             regards, tom lane
>


Re: Writing values to relation using bytearray ...

From
Tom Lane
Date:
Kedar Potdar <kedar.potdar@gmail.com> writes:
> I could find a workaround for the issue wherein the value of type
> which is not stored "by value" and has fixed data length, is being
> stored in string format to the relation.

The answer is simple: don't do that.  You do not need to, and should
not, convert to string format.  Again, please look at how ANALYZE
does it.
        regards, tom lane