invalid memory alloc after insert with c trigger function

Started by Dudás Józsefalmost 19 years ago15 messagesgeneral
Jump to latest
#1Dudás József
dj1999@freemail.hu

Hello Everybody!

I know that something doing wrong, but I can't find out what is it. This
is a part from trigger function:
/
attnum[3] = SPI_fnumber( tupdesc, "arfolyam" );
datums[3] = _selectFunctionB( "SELECT ertek FROM foo WHERE
parameter='rate'" ); // this come back with Datum type from select -
PG_RETURN_FLOAT8( b ); is end of this function where b is double type
arfolyam = DatumGetFloat8( datums[3] );
elog( INFO, "2.5.0 arfolyam = %f", arfolyam );
if ( attnum[3] == PointerGetDatum( NULL ) ) {
elog( ERROR, "Hianyzo arfolyam" );
SPI_finish();
return PointerGetDatum(NULL);
}
elog( INFO, "2.5.1 Datums[3] = %f", DatumGetFloat8( datums[3] ) );
rettuple = SPI_modifytuple( trigdata->tg_relation, tmptuple, 4,
&attnum[0], &datums[0], &isNull[0] );
SPI_freetuple(tmptuple);
SPI_finish();
return PointerGetDatum( rettuple );/

After insert:
INFO: string vissza : 1.000000
INFO: 2.5.0 arfolyam = 1.000000
INFO: 2.5.1 Datums[3] = 1.000000
INSERT 0 1
ELES=# SELECT * FROM pgsor;
ERROR: invalid memory alloc request size 4294967293

The datums[0 - 2] are char* / VARCHAR type. If I set /SPI_modifytuple(
trigdata->tg_relation, tmptuple, 3, &attnum[0], &datums[0], &isNull[0]
); /than everything is OK after insert.

The question: what is wrong with converting double to Datum?

Thanks in advance!
dj

#2Tom Lane
tgl@sss.pgh.pa.us
In reply to: Dudás József (#1)
Re: invalid memory alloc after insert with c trigger function

=?ISO-8859-2?Q?Dud=E1s_J=F3zsef?= <dj1999@freemail.hu> writes:

I know that something doing wrong, but I can't find out what is it.

Getting a stack trace from the point of the errfinish call would
probably help narrow it down. One thing that's not clear is whether
SPI_modifytuple itself is failing (have you checked all the *other*
arguments you're passing it?) or whether it happens later.

regards, tom lane

#3Dudás József
dj1999@freemail.hu
In reply to: Tom Lane (#2)
Re: invalid memory alloc after insert with c trigger function

Thanks for your reply!
I was run gdb and errfinish but didn't get much help because I write to
list.
Yes the first datas ( datums[0-2] ) are char* / VARCHAR types and if I
call SPI_modifytuple( ( trigdata->tg_relation, tmptuple, 3, &attnum[0],
&datums[0], &isNull[0] ) than everything is OK.
Just have problem with this conversion from TEXT - double - Datum (
NUMERIC ) where in TEXT is a number value forexample now the value is 1.00

Show quoted text

=?ISO-8859-2?Q?Dud=E1s_J=F3zsef?= <dj1999@freemail.hu> writes:

I know that something doing wrong, but I can't find out what is it.

Getting a stack trace from the point of the errfinish call would
probably help narrow it down. One thing that's not clear is whether
SPI_modifytuple itself is failing (have you checked all the *other*
arguments you're passing it?) or whether it happens later.

regards, tom lane

---------------------------(end of broadcast)---------------------------
TIP 2: Don't 'kill -9' the postmaster

#4Dudás József
dj1999@freemail.hu
In reply to: Tom Lane (#2)
Re: invalid memory alloc after insert with c trigger function

Here is the output from gdb:

#0 errfinish (dummy=0) at elog.c:312
#1 0x0827f378 in elog_finish (elevel=20,
fmt=0x83586d8 "invalid memory alloc request size %lu") at elog.c:937
#2 0x082983d7 in MemoryContextAlloc (context=0x843a1ac, size=4294967293)
at mcxt.c:504
#3 0x0825751d in varcharout (fcinfo=0xbf8a1e7c) at varchar.c:447
#4 0x08281ceb in FunctionCall1 (flinfo=0x8460298, arg1=3052138532)
at fmgr.c:1128
#5 0x0807e88f in printtup (slot=0x843d038, self=0x8405df4) at
printtup.c:326
#6 0x0816b14f in ExecutorRun (queryDesc=0x8474698,
direction=ForwardScanDirection, count=0) at execMain.c:1310
#7 0x0820059b in PortalRunSelect (portal=0x842f1f4,
forward=<value optimized out>, count=0, dest=0x8405df4) at pquery.c:831
#8 0x08201799 in PortalRun (portal=0x842f1f4, count=2147483647,
dest=0x8405df4, altdest=0x8405df4, completionTag=0xbf8a22e8 "")
at pquery.c:684
#9 0x081fd150 in exec_simple_query (
query_string=0x840593c "SELECT * FROM pgsor;") at postgres.c:939
#10 0x081fe761 in PostgresMain (argc=4, argv=<value optimized out>,
username=0x83accdc "dj") at postgres.c:3424
#11 0x081d1cb8 in ServerLoop () at postmaster.c:2931
#12 0x081d2aa7 in PostmasterMain (argc=3, argv=0x83a78a8) at
postmaster.c:963
#13 0x0818d2f0 in main (argc=3, argv=Cannot access memory at address 0x4
) at main.c:188

Hope it is verbose for you, but don't help me :)

Show quoted text

=?ISO-8859-2?Q?Dud=E1s_J=F3zsef?= <dj1999@freemail.hu> writes:

I know that something doing wrong, but I can't find out what is it.

Getting a stack trace from the point of the errfinish call would
probably help narrow it down. One thing that's not clear is whether
SPI_modifytuple itself is failing (have you checked all the *other*
arguments you're passing it?) or whether it happens later.

regards, tom lane

#5Dudás József
dudasj@piperh.hu
In reply to: Tom Lane (#2)
Re: invalid memory alloc after insert with c trigger function

This is the debug of last varcharout routine:

Breakpoint 1, varcharout (fcinfo=0xbf8a1e7c) at varchar.c:441
441 VarChar *s = PG_GETARG_VARCHAR_P(0);
440 {
(gdb) print fcinfo
$25 = (FunctionCallInfo) 0xbf8a1e7c
441 VarChar *s = PG_GETARG_VARCHAR_P(0);
446 len = VARSIZE(s) - VARHDRSZ;
(gdb) print s
$28 = (VarChar *) 0xb5ebf024
447 result = palloc(len + 1);
(gdb) print len
$29 = -4
(gdb) next
Warning:
Cannot insert breakpoint -43.
Error accessing memory address 0xf72a1719: Input/Output error

Show quoted text

=?ISO-8859-2?Q?Dud=E1s_J=F3zsef?= <dj1999@freemail.hu> writes:

I know that something doing wrong, but I can't find out what is it.

Getting a stack trace from the point of the errfinish call would
probably help narrow it down. One thing that's not clear is whether
SPI_modifytuple itself is failing (have you checked all the *other*
arguments you're passing it?) or whether it happens later.

regards, tom lane

#6Bruce Momjian
bruce@momjian.us
In reply to: Dudás József (#4)
Re: invalid memory alloc after insert with c trigger function

Dudás József <dj1999@freemail.hu> writes:

Here is the output from gdb:

#0 errfinish (dummy=0) at elog.c:312
#1 0x0827f378 in elog_finish (elevel=20,
fmt=0x83586d8 "invalid memory alloc request size %lu") at elog.c:937
#2 0x082983d7 in MemoryContextAlloc (context=0x843a1ac, size=4294967293)
at mcxt.c:504
#3 0x0825751d in varcharout (fcinfo=0xbf8a1e7c) at varchar.c:447

I'm sorry I missed the beginning of this thread. This is happening on a
straight simple select of the table right? Did you already post the source of
your C trigger function? How is it constructing the original varchar datum and
doing the insert?

--
Gregory Stark
EnterpriseDB http://www.enterprisedb.com

#7Dudás József
dj1999@freemail.hu
In reply to: Tom Lane (#2)
Re: invalid memory alloc after insert with c trigger function

This is the debug of last varcharout routine:

Breakpoint 1, varcharout (fcinfo=0xbf8a1e7c) at varchar.c:441
441 VarChar *s = PG_GETARG_VARCHAR_P(0);
440 {
(gdb) print fcinfo
$25 = (FunctionCallInfo) 0xbf8a1e7c
441 VarChar *s = PG_GETARG_VARCHAR_P(0);
446 len = VARSIZE(s) - VARHDRSZ;
(gdb) print s
$28 = (VarChar *) 0xb5ebf024
447 result = palloc(len + 1);
(gdb) print len
$29 = -4
(gdb) next
Warning:
Cannot insert breakpoint -43.
Error accessing memory address 0xf72a1719: Input/Output error

Show quoted text

=?ISO-8859-2?Q?Dud=E1s_J=F3zsef?= <dj1999@freemail.hu> writes:

I know that something doing wrong, but I can't find out what is it.

Getting a stack trace from the point of the errfinish call would
probably help narrow it down. One thing that's not clear is whether
SPI_modifytuple itself is failing (have you checked all the *other*
arguments you're passing it?) or whether it happens later.

regards, tom lane

#8Dudás József
dj1999@freemail.hu
In reply to: Dudás József (#7)
Re: invalid memory alloc after insert with c trigger function

Sorry I do not understand. I did not convert float to varchar. The first
3 data are char* these conver to Datum:
attnum[0] = SPI_fnumber( tupdesc, "deviza_kod" );
datums[0] = DirectFunctionCall1(textin, CStringGetDatum(
_selectFunction( "SELECT ertek FROM foo WHERE parameter='currency'" ) ) );
if ( attnum[0] == PointerGetDatum( NULL ) ) {
elog( ERROR, "Hianyzo deviza" );
SPI_finish(); // z�runk
return PointerGetDatum(NULL); // vissza
}
The 1 and 2 are same as this. But these are OK.

I have problem with NUMERIC type. Convert with this function char* to
double to Datum:

PG_FUNCTION_INFO_V1(_selectFunctionB);
Datum
_selectFunctionB( char *sql )
{
double b;
int ret, proc;

ret = SPI_exec( sql, 0 );
proc = SPI_processed;
if (ret == SPI_OK_SELECT && proc > 0) {
SPITupleTable* tuptable = SPI_tuptable;
TupleDesc tupdesc = SPI_tuptable->tupdesc;
HeapTuple tuple = tuptable->vals[ 0 ];
if ( tuple ) {
b = atof( SPI_getvalue( tuple, tupdesc, 1 ) );
}
}
PG_RETURN_FLOAT8( b );
}

I call these to put Datum value to datums[3] array element:
datums[3] = _selectFunctionB( "SELECT ertek FROM foo WHERE
parameter='rate'" );

Show quoted text

Dud�s J�zsef <dj1999@freemail.hu> writes:

elog( INFO, "2.5.1 Datums[3] = %f", DatumGetFloat8( datums[3] ) );
rettuple = SPI_modifytuple( trigdata->tg_relation, tmptuple, 4, &attnum[0],

...

The datums[0 - 2] are char* / VARCHAR type. If I set /SPI_modifytuple(
trigdata->tg_relation, tmptuple, 3, &attnum[0], &datums[0], &isNull[0] ); /than
everything is OK after insert.

At what point does the float get converted to a varchar?

#9Bruce Momjian
bruce@momjian.us
In reply to: Dudás József (#8)
Re: invalid memory alloc after insert with c trigger function

Dudás József <dj1999@freemail.hu> writes:

Sorry I do not understand. I did not convert float to varchar.

Well then there's some kind of miscommunication here. Your crash is happening
trying to read a varchar column later. Someone sometime is putting data into
that varchar column. I don't understand how the snippets of code handling
floats and numerics relate to the varchar that's causing your crash.

I still don't understand what you're doing and what's going on but there are a
few strange things in this code snippet:

attnum[0] = SPI_fnumber( tupdesc, "deviza_kod" );
datums[0] = DirectFunctionCall1(textin, CStringGetDatum( _selectFunction(
"SELECT ertek FROM foo WHERE parameter='currency'" ) ) );
if ( attnum[0] == PointerGetDatum( NULL ) ) {
elog( ERROR, "Hianyzo deviza" );
SPI_finish(); // zárunk
return PointerGetDatum(NULL); // vissza
}

You test attnum[0] == PointerGetDatum(NULL) but attnum contains the result of
SPI_fnumber which isn't a datum at all, it's an attribute number which is an
integer. In case of error it returns SPI_ERROR_NOATTRIBUTE which is -9.

That said if your function is a function which takes PG_FUNCTION_ARGS then the
right way to return NULL is with PG_RETURN_NULL(). Merely returning a
PointerGetDatum(NULL) isn't good enough.

--
Gregory Stark
EnterpriseDB http://www.enterprisedb.com

#10Martijn van Oosterhout
kleptog@svana.org
In reply to: Dudás József (#8)
Re: invalid memory alloc after insert with c trigger function

Are you compiling with warnings? Because this should have blown up on
you:

On Fri, Jun 01, 2007 at 02:03:26PM +0200, Dudás József wrote:

PG_FUNCTION_INFO_V1(_selectFunctionB);
Datum
_selectFunctionB( char *sql )

If you've declared your function V1 then it doesn't get passed
parameters like that. The compiler should have flagged this.

Also, can you show how you defined the function in SQL, does it match?

Have a nice day,
--
Martijn van Oosterhout <kleptog@svana.org> http://svana.org/kleptog/

Show quoted text

From each according to his ability. To each according to his ability to litigate.

#11Tom Lane
tgl@sss.pgh.pa.us
In reply to: Dudás József (#3)
Re: invalid memory alloc after insert with c trigger function

=?ISO-8859-2?Q?Dud=E1s_J=F3zsef?= <dj1999@freemail.hu> writes:

Just have problem with this conversion from TEXT - double - Datum (
NUMERIC ) where in TEXT is a number value forexample now the value is 1.00

NUMERIC? You didn't say anything about NUMERIC before. The code you
posted thinks it is working with a FLOAT8 datum, which is just about
entirely unlike NUMERIC. If you are trying to assign that to a table
column that's declared as NUMERIC, then that type mismatch is exactly
your problem.

regards, tom lane

#12Dudás József
dj1999@freemail.hu
In reply to: Martijn van Oosterhout (#10)
Re: invalid memory alloc after insert with c trigger function

Thanks your replies, these much help me. I am beginer in postgresql c
function, sorry when I wrote stupid thinks too.
This function not call from sql just from c code. So as I understand not
need PG_FUNCTION_INFO_V1 macro. It is need in case I want to call routin
direct from sql or make database function.

Show quoted text

Are you compiling with warnings? Because this should have blown up on
you:

On Fri, Jun 01, 2007 at 02:03:26PM +0200, Dud�s J�zsef wrote:

PG_FUNCTION_INFO_V1(_selectFunctionB);
Datum
_selectFunctionB( char *sql )

If you've declared your function V1 then it doesn't get passed
parameters like that. The compiler should have flagged this.

Also, can you show how you defined the function in SQL, does it match?

Have a nice day,

#13Dudás József
dj1999@freemail.hu
In reply to: Tom Lane (#11)
Re: invalid memory alloc after insert with c trigger function

Yes! You are right! Now must me find out how to convert char* to numeric
datum and double to numeric datum and numeric datum to double :)

Show quoted text

=?ISO-8859-2?Q?Dud=E1s_J=F3zsef?= <dj1999@freemail.hu> writes:

Just have problem with this conversion from TEXT - double - Datum (
NUMERIC ) where in TEXT is a number value forexample now the value is 1.00

NUMERIC? You didn't say anything about NUMERIC before. The code you
posted thinks it is working with a FLOAT8 datum, which is just about
entirely unlike NUMERIC. If you are trying to assign that to a table
column that's declared as NUMERIC, then that type mismatch is exactly
your problem.

regards, tom lane

---------------------------(end of broadcast)---------------------------
TIP 4: Have you searched our list archives?

http://archives.postgresql.org/

#14Bruce Momjian
bruce@momjian.us
In reply to: Dudás József (#13)
Re: invalid memory alloc after insert with c trigger function

Dudás József <dj1999@freemail.hu> writes:

Yes! You are right! Now must me find out how to convert char* to numeric datum
and double to numeric datum and numeric datum to double :)

If you have a char* you can usually call a types input function which is
usally "type_in" or "typein" like:
DirectFunctionCall1(type_in, str).

However in the case of numeric you need to pass a couple extra parameters:
DirectFunctionCall3(numeric_in, str, 0, -1 + VARHDRSZ)

To convert to a float8 datum you would use
DirectFunctionCall1(numeric_float,num).

To convert from a Postgres float8 datum to an actual double you can just call
the macros DatumGetFloat8 and Float8GetDatum. This makes your code depend on
the internal representation of float8 as a C double but it's better than the
alternative.

--
Gregory Stark
EnterpriseDB http://www.enterprisedb.com

#15Dudás József
dj1999@freemail.hu
In reply to: Bruce Momjian (#14)
Re: invalid memory alloc after insert with c trigger function

Thank you and other helpfully peoples the interest about my first steps
in your world. I learned more than I hope.
This function work fine now.
Can you to offer me place where I find these information, because I read
the postgresql source code to find these macros.

Regards,
Josef

Show quoted text

Dud�s J�zsef <dj1999@freemail.hu> writes:

Yes! You are right! Now must me find out how to convert char* to numeric datum
and double to numeric datum and numeric datum to double :)

If you have a char* you can usually call a types input function which is
usally "type_in" or "typein" like:
DirectFunctionCall1(type_in, str).

However in the case of numeric you need to pass a couple extra parameters:
DirectFunctionCall3(numeric_in, str, 0, -1 + VARHDRSZ)

To convert to a float8 datum you would use
DirectFunctionCall1(numeric_float,num).

To convert from a Postgres float8 datum to an actual double you can just call
the macros DatumGetFloat8 and Float8GetDatum. This makes your code depend on
the internal representation of float8 as a C double but it's better than the
alternative.