Thread: Convert Datum* to char*

Convert Datum* to char*

From
Masterprojekt Naumann1
Date:
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?

Best regards
Maria
Attachment

Re: Convert Datum* to char*

From
Heikki Linnakangas
Date:
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



Re: Convert Datum* to char*

From
Masterprojekt Naumann1
Date:
<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> 

Re: Convert Datum* to char*

From
Craig Ringer
Date:
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



Re: Convert Datum* to char*

From
Masterprojekt Naumann1
Date:
<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> 

Re: Convert Datum* to char*

From
Thomas Fanghaenel
Date:
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?



Re: Convert Datum* to char*

From
Masterprojekt Naumann1
Date:
<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> 

Re: Convert Datum* to char*

From
Tom Lane
Date:
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



Re: Convert Datum* to char*

From
Robert Haas
Date:
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