Thread: ERROR: Memory exhausted in AllocSetAlloc(909324558)
I saw someone else also saw this error. I am seeing it in 7.1.2 and I think I may have tracked it down. It's after a different operation but perhaps it is related. I have written a trigger. It dies with that error when I make the following call. SPI_modifytuple (rel,rettuple,1,&targ_att,&newval,NULL) I created targ_att as follows. targ_att = SPI_fnumber (tupdesc, args[0] This returns 23 in my case which is the correct field that I want to modify. The existing value for that field is NULL. I looked at the length of that fields with rel->rd_att->attrs[23]->attlen and it is -1. I assume that that is OK for a NULL value. I eventually followed this call to heaptuple.c. In heap_formtuple() there is a call to ComputeDataSize() with the existing tuple, the value I am changing to and the nulls. In that function the length (-1) is added to the total length. This causes the problem I am seeing. Am I misunderstanding the call? I thought that the nulls parameter was to map out which values you were changing to were NULL. It appears to be the value of the existing value. Why would I care about that value? Is it up to me to find all the NULLS in an existing tuple before calling SPI functions? I called this function that way in an earlier version with no problem. -- D'Arcy J.M. Cain <darcy@{druid|vex}.net> | Democracy is three wolves http://www.druid.net/darcy/ | and a sheep voting on +1 416 425 1212 (DoD#0082) (eNTP) | what's for dinner.
darcy@druid.net (D'Arcy J.M. Cain) writes: > Am I misunderstanding the call? I thought that the nulls parameter was > to map out which values you were changing to were NULL. heap_formtuple is for constructing a tuple from scratch. It sounds like you should be using heap_modifytuple instead. regards, tom lane
Re: ERROR: Memory exhausted in AllocSetAlloc(909324558)
From
darcy@druid.net (D'Arcy J.M. Cain)
Date:
Thus spake Tom Lane > darcy@druid.net (D'Arcy J.M. Cain) writes: > > Am I misunderstanding the call? I thought that the nulls parameter was > > to map out which values you were changing to were NULL. > > heap_formtuple is for constructing a tuple from scratch. It sounds like > you should be using heap_modifytuple instead. But I am using SPI_modifytuple(). The rest came from tracing that function. -- D'Arcy J.M. Cain <darcy@{druid|vex}.net> | Democracy is three wolves http://www.druid.net/darcy/ | and a sheep voting on +1 416 425 1212 (DoD#0082) (eNTP) | what's for dinner.
darcy@druid.net (D'Arcy J.M. Cain) writes: >> heap_formtuple is for constructing a tuple from scratch. It sounds like >> you should be using heap_modifytuple instead. > But I am using SPI_modifytuple(). The rest came from tracing that > function. Hm. Looks like the author of SPI_modifytuple didn't realize he could use heap_modifytuple :-(. But he is correctly extracting the old data. I don't see anything wrong there, assuming that you are passing a relation descriptor that matches the original tuple. regards, tom lane
Re: ERROR: Memory exhausted in AllocSetAlloc(909324558)
From
darcy@druid.net (D'Arcy J.M. Cain)
Date:
Thus spake Tom Lane > darcy@druid.net (D'Arcy J.M. Cain) writes: > >> heap_formtuple is for constructing a tuple from scratch. It sounds like > >> you should be using heap_modifytuple instead. > > > But I am using SPI_modifytuple(). The rest came from tracing that > > function. > > Hm. Looks like the author of SPI_modifytuple didn't realize he could > use heap_modifytuple :-(. But he is correctly extracting the old data. > I don't see anything wrong there, assuming that you are passing a > relation descriptor that matches the original tuple. Well, let's see. SPI_modifytuple (rel,rettuple,1,&targ_att,&newval,NULL) Here are (I think) the relevant lines that get me the data for that call. Datum mk_cardnum(PG_FUNCTION_ARGS) { TriggerData *trigdata = (TriggerData *) fcinfo->context; int nargs; /* # of arguments */ Datum newval; /* new value of column */ char **args; /* arguments */ char *relname; /* triggered relation name */ Relation rel; /* triggered relation */ HeapTuple rettuple = NULL; int targ_att; bool isnull; char cardnum[48]; ... /* assume full error checking - leaving out for clarity */ rel = trigdata->tg_relation; relname = SPI_getrelname(rel); targ_att = SPI_fnumber (tupdesc, args[0]); newval = CStringGetDatum(cardnum); -- D'Arcy J.M. Cain <darcy@{druid|vex}.net> | Democracy is three wolves http://www.druid.net/darcy/ | and a sheep voting on +1 416 425 1212 (DoD#0082) (eNTP) | what's for dinner.
darcy@druid.net (D'Arcy J.M. Cain) writes: > char cardnum[48]; > ... > newval = CStringGetDatum(cardnum); And you are trying to assign this datum to what kind of column? (Hint: there isn't any kind for which a plain C string is valid data.) regards, tom lane
Re: ERROR: Memory exhausted in AllocSetAlloc(909324558)
From
darcy@druid.net (D'Arcy J.M. Cain)
Date:
Thus spake Tom Lane > darcy@druid.net (D'Arcy J.M. Cain) writes: > > char cardnum[48]; > > ... > > newval = CStringGetDatum(cardnum); > > And you are trying to assign this datum to what kind of column? > (Hint: there isn't any kind for which a plain C string is valid data.) Right. That was just my latest try. I did notice that CStringGetDatum was just defined as PointerGetDatum. I tried to find something specific for text but nothing seemed to fit the bill. I saw DatumGetTextP but that detoasts a toasted object. There were the various PG_RETURNxxx macros but this is a user created strting, not an argument. Do I have to manually create a varlena? I'll try that next. -- D'Arcy J.M. Cain <darcy@{druid|vex}.net> | Democracy is three wolves http://www.druid.net/darcy/ | and a sheep voting on +1 416 425 1212 (DoD#0082) (eNTP) | what's for dinner.
darcy@druid.net (D'Arcy J.M. Cain) writes: > Do I have to manually create a varlena? I'll try that next. The best way to get from a C string to a valid datum is to invoke the datatype's input conversion routine. If you know you want text, you could do #define _textin(str) DirectFunctionCall1(textin, CStringGetDatum(str)) to produce a datum from a C string. regards, tom lane
Re: ERROR: Memory exhausted in AllocSetAlloc(909324558)
From
darcy@druid.net (D'Arcy J.M. Cain)
Date:
Thus spake Tom Lane > darcy@druid.net (D'Arcy J.M. Cain) writes: > > Do I have to manually create a varlena? I'll try that next. > > The best way to get from a C string to a valid datum is to invoke the > datatype's input conversion routine. If you know you want text, > you could do > > #define _textin(str) DirectFunctionCall1(textin, CStringGetDatum(str)) > > to produce a datum from a C string. Ah, that was it. I had done a similar thing in another trigger with a date type. I should have thought of that. Hmm. Does this suggest more macros in fmgr.h or postgres.h? -- D'Arcy J.M. Cain <darcy@{druid|vex}.net> | Democracy is three wolves http://www.druid.net/darcy/ | and a sheep voting on +1 416 425 1212 (DoD#0082) (eNTP) | what's for dinner.