Thread: invalid memory alloc after insert with c trigger function
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
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
=?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
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 > =?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 > > >
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 :)
#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 :)
Dudás József <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
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
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 > =?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 > > >
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'" ); > 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? > >
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
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/ > From each according to his ability. To each according to his ability to litigate.
Attachment
=?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
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. > 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, >
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 :) > =?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/ > > >
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
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 > =?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 > > >
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 > 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. > >