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
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
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
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
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.