Обсуждение: Writing values to relation using bytearray ...
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 />
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
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 />
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
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
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
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 >
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