Thread: Convert Datum* to char*
Hi,
I want to read an attribute value from a TupleTableSlot. When I try to convert an attribute of SQL type varchar from Datum* to char* with the help of the method TextDatumGetCString(...), sometimes there is a segmentation fault. The segmentation fault comes from the method TextDatumGetCString(...), which is defined in utils/builtins.h. Unfortunately, the fault is not always reproducible. I debugged the code and figured out that the value of result->tts_values[i] sometimes is random. It may be uninitialized memory. In other cases, the variable value is NULL. Then, I can just skip the conversion from Datum* to char*, so that there is no segmentation fault. I attached a patch with the code. The relevant line is:char *value = TextDatumGetCString(result->tts_values[i]);
The SQL-Query is a simple "SELECT * from ..." on the TPC-H table customer. About every third execution leads to a segmentation fault.
Why is the memory of the variable uninitialized?I am not very familiar with Postgres. Is there another method to get a varchar attribute out of a TupleTableSlot as string?
Attachment
On 01/06/2014 03:09 PM, Masterprojekt Naumann1 wrote: > I want to read an attribute value from a TupleTableSlot. When I try to > convert an attribute of SQL type varchar from Datum* to char* with the help > of the method TextDatumGetCString(...), sometimes there is a segmentation > fault. The segmentation fault comes from the method > TextDatumGetCString(...), which is defined in utils/builtins.h. > Unfortunately, the fault is not always reproducible. I debugged the code > and figured out that the value of result->tts_values[i] sometimes is > random. It may be uninitialized memory. In other cases, the variable value > is NULL. Then, I can just skip the conversion from Datum* to char*, so that > there is no segmentation fault. I attached a patch with the code. The > relevant line is: > char *value = TextDatumGetCString(result->tts_values[i]); > The SQL-Query is a simple "SELECT * from ..." on the TPC-H table customer. > About every third execution leads to a segmentation fault. Maybe the field is NULL? By convention, we normally set the Datum to 0 on an SQL NULL, but you're supposed to check tts_isnull first, and ignore tts_values[x] when tts_isnull[x] is true. - Heikki
<div dir="ltr">Yes, in some cases, Datum is 0, which I test before conversion. Additionally, I looked at tts_isnull but itdoes not prevent the segmentation fault in some cases. The problem is. that sometimes the value is random, but I don'tknow why and how I can detect that case.<br /></div><div class="gmail_extra"><br /><br /><div class="gmail_quote">2014/1/6Heikki Linnakangas <span dir="ltr"><<a href="mailto:hlinnakangas@vmware.com" target="_blank">hlinnakangas@vmware.com</a>></span><br/><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px#ccc solid;padding-left:1ex"><div class="im">On 01/06/2014 03:09 PM, Masterprojekt Naumann1 wrote:<br/><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"> I wantto read an attribute value from a TupleTableSlot. When I try to<br /> convert an attribute of SQL type varchar from Datum*to char* with the help<br /> of the method TextDatumGetCString(...), sometimes there is a segmentation<br /> fault.The segmentation fault comes from the method<br /> TextDatumGetCString(...), which is defined in utils/builtins.h.<br/> Unfortunately, the fault is not always reproducible. I debugged the code<br /> and figured out thatthe value of result->tts_values[i] sometimes is<br /> random. It may be uninitialized memory. In other cases, thevariable value<br /> is NULL. Then, I can just skip the conversion from Datum* to char*, so that<br /> there is no segmentationfault. I attached a patch with the code. The<br /> relevant line is:<br /> char *value = TextDatumGetCString(result-><u></u>tts_values[i]);<br/> The SQL-Query is a simple "SELECT * from ..." on the TPC-H tablecustomer.<br /> About every third execution leads to a segmentation fault.<br /></blockquote><br /></div> Maybe thefield is NULL? By convention, we normally set the Datum to 0 on an SQL NULL, but you're supposed to check tts_isnull first,and ignore tts_values[x] when tts_isnull[x] is true.<span class="HOEnZb"><font color="#888888"><br /><br /> - Heikki<br/></font></span></blockquote></div><br /></div>
On 01/06/2014 09:09 PM, Masterprojekt Naumann1 wrote: > Why is the memory of the variable uninitialized? Are there any other patches you've made to the running PostgreSQL instance? I'd want to run under Valgrind and see what turned up. This might be a bit tricky with an intermittent fault during something like a TPC-H run, though. -- Craig Ringer http://www.2ndQuadrant.com/PostgreSQL Development, 24x7 Support, Training & Services
<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">2014/1/6 Craig Ringer <span dir="ltr"><<a href="mailto:craig@2ndquadrant.com"target="_blank">craig@2ndquadrant.com</a>></span><br /><blockquote class="gmail_quote"style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div class="im">On01/06/2014 09:09 PM, Masterprojekt Naumann1 wrote:<br /><br /> > Why is the memory of the variable uninitialized?<br/><br /></div>Are there any other patches you've made to the running PostgreSQL instance?<br /><br /> I'dwant to run under Valgrind and see what turned up. This might be a<br /> bit tricky with an intermittent fault duringsomething like a TPC-H run,<br /> though.<br /><span class=""><font color="#888888"><br /> --<br /> Craig Ringer <a href="http://www.2ndQuadrant.com/" target="_blank">http://www.2ndQuadrant.com/</a><br /> PostgreSQLDevelopment, 24x7 Support, Training & Services<br /></font></span></blockquote></div><br /></div><div class="gmail_extra">Iam on the latest commit of the master branch of the GitHub repository (commit 10a82cda67731941c18256e009edad4a784a2994)and I only applied the attached patch. I hope that you can reproduce the fault.<br/></div><div class="gmail_extra">Thanks, Maria<br /></div></div>
On Mon, Jan 6, 2014 at 8:09 AM, Masterprojekt Naumann1 <mpws2013n1@gmail.com> wrote: > Why is the memory of the variable uninitialized? Are you checking that "i <= slot->tts_nvalid" before accessing the tts_values and tts_isnull arrays?
<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">2014/1/6 Thomas Fanghaenel <span dir="ltr"><<a href="mailto:tfanghaenel@salesforce.com"target="_blank">tfanghaenel@salesforce.com</a>></span><br /><blockquote class="gmail_quote"style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div class="im">OnMon, Jan 6, 2014 at 8:09 AM, Masterprojekt Naumann1<br /> <<a href="mailto:mpws2013n1@gmail.com">mpws2013n1@gmail.com</a>>wrote:<br /> > Why is the memory of the variable uninitialized?<br/><br /></div>Are you checking that "i <= slot->tts_nvalid" before accessing the<br /> tts_valuesand tts_isnull arrays?<br /></blockquote></div><br /><br /></div><div class="gmail_extra">Thanks for your ideas!I could fix the segmentation fault. I have to check both, slot->tts_isnull and 0 == slot->tts_values[i]. If bothare false, I can convert the value with the method TextDatumGetCString(...).<br /> Nevertheless, slot->tts_nvalidis always 0. I hope that there is no other problem.<br /></div></div>
Masterprojekt Naumann1 <mpws2013n1@gmail.com> writes: > Nevertheless, slot->tts_nvalid is always 0. I hope that there is no other > problem. You should not be touching the tts_values/tts_isnull arrays without having first called slot_getsomeattrs or slot_getallattrs. See comments in src/include/executor/tuptable.h for some documentation. regards, tom lane
On Mon, Jan 6, 2014 at 11:34 AM, Tom Lane <tgl@sss.pgh.pa.us> wrote: > Masterprojekt Naumann1 <mpws2013n1@gmail.com> writes: >> Nevertheless, slot->tts_nvalid is always 0. I hope that there is no other >> problem. > > You should not be touching the tts_values/tts_isnull arrays without having > first called slot_getsomeattrs or slot_getallattrs. > > See comments in src/include/executor/tuptable.h for some documentation. Another problem is that TextDatumGetCString() is only the right thing to do if the value is, in fact, of type text. If you've got an integer column, for example, TextDatumGetCString() is not your friend. -- Robert Haas EnterpriseDB: http://www.enterprisedb.com The Enterprise PostgreSQL Company