Convert Datum* to char*

Started by Masterprojekt Naumann1over 12 years ago9 messageshackers
Jump to latest
#1Masterprojekt Naumann1
mpws2013n1@gmail.com

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

Attachments:

datumgetstring.patchtext/x-patch; charset=US-ASCII; name=datumgetstring.patchDownload+13-0
#2Heikki Linnakangas
heikki.linnakangas@enterprisedb.com
In reply to: Masterprojekt Naumann1 (#1)
Re: Convert Datum* to char*

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

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#3Masterprojekt Naumann1
mpws2013n1@gmail.com
In reply to: Heikki Linnakangas (#2)
Re: Convert Datum* to char*

Yes, in some cases, Datum is 0, which I test before conversion.
Additionally, I looked at tts_isnull but it does not prevent the
segmentation fault in some cases. The problem is. that sometimes the value
is random, but I don't know why and how I can detect that case.

2014/1/6 Heikki Linnakangas <hlinnakangas@vmware.com>

Show quoted text

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

#4Craig Ringer
craig@2ndquadrant.com
In reply to: Masterprojekt Naumann1 (#1)
Re: Convert Datum* to char*

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

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#5Masterprojekt Naumann1
mpws2013n1@gmail.com
In reply to: Craig Ringer (#4)
Re: Convert Datum* to char*

2014/1/6 Craig Ringer <craig@2ndquadrant.com>

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

I am 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.
Thanks, Maria

#6Thomas Fanghaenel
tfanghaenel@salesforce.com
In reply to: Masterprojekt Naumann1 (#1)
Re: Convert Datum* to char*

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?

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#7Masterprojekt Naumann1
mpws2013n1@gmail.com
In reply to: Thomas Fanghaenel (#6)
Re: Convert Datum* to char*

2014/1/6 Thomas Fanghaenel <tfanghaenel@salesforce.com>

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?

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 both are false, I
can convert the value with the method TextDatumGetCString(...).
Nevertheless, slot->tts_nvalid is always 0. I hope that there is no other
problem.

#8Tom Lane
tgl@sss.pgh.pa.us
In reply to: Masterprojekt Naumann1 (#7)
Re: Convert Datum* to char*

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

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#9Robert Haas
robertmhaas@gmail.com
In reply to: Tom Lane (#8)
Re: Convert Datum* to char*

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

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers