Discussion:
Problems with MemoryContextSwitchTo ()
(too old to reply)
Yessica Brinkmann
2020-09-16 03:14:21 UTC
Permalink
Hello.
I think several of you will already remember me. I'm the one with the IndexAdviser topic. Only that I changed my email address.
As you may recall, I am doing my thesis on the subject of IndexAdviser modifications.
I really appreciate the help they have given me in various Postgresql groups.
Well, I was really nearing the end of the programming part of the thesis, when I had a problem to be able to compile my program in a moment, and by accident some lines of source code were moved.
And for this reason, I think I have problems again with the context switch issue, since at some point my context switch stopped working for me, I think because of the issue that some lines of source code were moved.
Well, the fact is that I have a function called get_columnnames, which in the second foreach, is printing the values ​​of idxcd-> varattnnames [i] the null value.
This second foreach, I only do it to test if the data is really saved well and if I can recover it properly.
And since the data is not retrieved properly, or is not saved properly, in the following functions of my program, the value of idxcd-> varattnnames [i] continues to appear as null.
I will appreciate a lot please help, if you can tell me please why the function prints null in the values ​​of idxcd-> varattnnames [i], in the second foreach, if it is due to an error in the context switch, or why it could be .
Best regards,
Yessica Brinkmann.
Below I write my function:
static List*
get_columnnames( List* candidates )
{
int proc;
int ret;
StringInfoData query; /* string for Query */
StringInfoData cols; /* string for Columns */
MemoryContext outerContext;
ListCell *cell;




IndexCandidate* idxcd;


elog( DEBUG3, "IND ADV: get_column_names: ENTER" );




initStringInfo( &query );
initStringInfo( &cols );

foreach( cell, candidates ) /* foreach cell in candidates */
{

int i;



/*elog (INFO, "Ingresando a foreach");*/
idxcd = (IndexCandidate*)lfirst( cell );

if (idxcd == NULL) {
elog( INFO, "idxcd IS NULL" );
continue; /* Or is that fatal enough to break instead? */
}

if (!idxcd->idxused)
continue;




/* pfree() the memory allocated for the previous candidate. FIXME: Avoid
* meddling with the internals of a StringInfo, and try to use an API.
*/
if( cols.len > 0 )
{
initStringInfo(&cols);
} /*IF col.len>0*/

if( query.len > 0 )
{
initStringInfo(&query);
} /*IF col.len>0*/

elog(INFO,"reloid:%d", idxcd->reloid);
appendStringInfo( &query, "select a.attname from pg_class c,pg_attribute a where c.oid=%d AND a.attrelid = c.oid AND (", idxcd->reloid);

/*elog(INFO,"QUERY:%s", query.data);*/

/*elog(INFO,"ncols:%d", idxcd->ncols);*/

for (i = 0; i < idxcd->ncols; ++i)
{
/*elog(INFO,"i:%d", i);*/
/*elog(INFO,"var attno i:%d", idxcd->varattno[i]);*/
/*elog(INFO,"cols:%s", cols.data);*/
appendStringInfo( &cols, "%s a.attnum=%d", (i>0 ? " OR" : ""), idxcd->varattno[i]);
/*elog(INFO,"cols:%s", cols.data);*/
/*elog(INFO,"i:%d", i);*/
elog(INFO,"varattno i:%d", idxcd->varattno[i]);


}/* foreach col in varattno*/

/*elog(INFO,"PASA EL FOR");*/
appendStringInfo( &cols, "%s", ")");

/* FIXME: Mention the column names explicitly after the table name. */
appendStringInfo( &query, "%s;", cols.data);

elog(INFO,"QUERY:%s", query.data);
/*elog(INFO,"LONGITUD:%d", query.len);*/

if( query.len > 0 ) /* if we generated any SQL */
{


outerContext = CurrentMemoryContext;
if( SPI_connect() == SPI_OK_CONNECT )
{
/*elog(INFO,"CONECTADO:%d", query.len);*/

ret=SPI_exec(query.data, 0);
proc=SPI_processed;
TupleDesc tupdesc=SPI_tuptable->tupdesc;
SPITupleTable *tuptable=SPI_tuptable;
char buf[8192];
if( ret>0 )
{
/*elog(INFO,"EJECUTA:%d", query.len);*/


if( SPI_tuptable != NULL)
{

//TupleDesc tupdesc;

//SPITupleTable *tuptable = SPI_tuptable;

//tupdesc = tuptable->tupdesc;


elog(INFO,"procantesciclo:%d", proc);
int i,j;
for(j=0;j<proc;j++)
{
HeapTuple tuple;
elog(INFO,"procdespuesciclo:%d", proc);
/*cada fila*/
int cont=0;
tuple=tuptable->vals[j];
if (tuple!=NULL)
{

for (i=1,buf[0]=0;i<=tupdesc->natts;i++)
{
char *data;

/* cada columna de cada fila*/

data=SPI_getvalue(tuple,tupdesc,i);
elog(INFO,"data:%s", data);


idxcd->varattnombres[i]=MemoryContextStrdup(outerContext, data);

elog(INFO,"valorgc:%s", idxcd->varattnombres[i]);
elog(INFO,"indice:%d", cont);
cont++;
snprintf(buf + strlen (buf), sizeof(buf) - strlen(buf), " %s%s", SPI_getvalue(tuple, tupdesc, i),(i == tupdesc->natts) ? " " : " |");

} /* (i=0,buf[0]=0;i<tupdesc->natts;i++)*/
elog (INFO, "EXECQ: %s", buf);
} /* if (tuple!=null)*/
else
elog( WARNING, "IND ADV: tuple is null." );
} /* (j=0;j<proc;j++)*/
} /*if( SPI_tuptable != NULL)*/
else
elog( WARNING, "IND ADV: SPI_tuptable is null." );
}
else
elog( WARNING, "IND ADV: SPI_execute failed while select." );
if( SPI_finish() != SPI_OK_FINISH )
elog( WARNING, "IND ADV: SPI_finish failed while select." );

} /*if( SPI_connect() == SPI_OK_CONNECT )*/

else
elog( WARNING, "IND ADV: SPI_connect failed while select." );



} /*if( query.len > 0 )*/
elog (INFO, "if( query.len > 0");

/*if( query.len > 0 )*/

} /* foreach cell in candidates */
elog (INFO, "/* foreach cell in candidates */");

foreach( cell, candidates ) /* foreach cell in candidates */
{


MemoryContext oldContext = MemoryContextSwitchTo( outerContext );
MemoryContextSwitchTo( oldContext );


/*elog (INFO, "Ingresando a foreach");*/
idxcd = (IndexCandidate*)lfirst( cell );

if (idxcd == NULL) {
elog( INFO, "idxcd IS NULL" );
continue; /* Or is that fatal enough to break instead? */
}

if (!idxcd->idxused)
continue;


int i;
for (i = 0; i < idxcd->ncols; ++i)
{

/*elog(INFO,"cols:%s", cols.data);*/
elog(INFO,"i:%d", i);
elog(INFO,"varattnombres i:%s", idxcd->varattnombres[i]);
elog(INFO,"varattno i:%d", idxcd->varattno[i]);


}/* foreach col in varattno*/

}


/* TODO: Propose to -hackers to introduce API to free a StringInfoData . */
if ( query.len > 0 )
pfree( query.data );


elog( DEBUG3, "IND ADV: select: EXIT" );
elog (INFO, "retornando get_columnnames");
return candidates;
}
Yessica Brinkmann
2020-09-16 04:28:56 UTC
Permalink
Post by Yessica Brinkmann
Hello.
I think several of you will already remember me. I'm the one with the IndexAdviser topic. Only that I changed my email address.
As you may recall, I am doing my thesis on the subject of IndexAdviser modifications.
I really appreciate the help they have given me in various Postgresql groups.
Well, I was really nearing the end of the programming part of the thesis, when I had a problem to be able to compile my program in a moment, and by accident some lines of source code were moved.
And for this reason, I think I have problems again with the context switch issue, since at some point my context switch stopped working for me, I think because of the issue that some lines of source code were moved.
Well, the fact is that I have a function called get_columnnames, which in the second foreach, is printing the values ​​of idxcd-> varattnnames [i] the null value.
This second foreach, I only do it to test if the data is really saved well and if I can recover it properly.
And since the data is not retrieved properly, or is not saved properly, in the following functions of my program, the value of idxcd-> varattnnames [i] continues to appear as null.
I will appreciate a lot please help, if you can tell me please why the function prints null in the values ​​of idxcd-> varattnnames [i], in the second foreach, if it is due to an error in the context switch, or why it could be .
Best regards,
Yessica Brinkmann.
static List*
get_columnnames( List* candidates )
{
int proc;
int ret;
StringInfoData query; /* string for Query */
StringInfoData cols; /* string for Columns */
MemoryContext outerContext;
ListCell *cell;
IndexCandidate* idxcd;
elog( DEBUG3, "IND ADV: get_column_names: ENTER" );
initStringInfo( &query );
initStringInfo( &cols );
foreach( cell, candidates ) /* foreach cell in candidates */
{
int i;
/*elog (INFO, "Ingresando a foreach");*/
idxcd = (IndexCandidate*)lfirst( cell );
if (idxcd == NULL) {
elog( INFO, "idxcd IS NULL" );
continue; /* Or is that fatal enough to break instead? */
}
if (!idxcd->idxused)
continue;
/* pfree() the memory allocated for the previous candidate. FIXME: Avoid
* meddling with the internals of a StringInfo, and try to use an API.
*/
if( cols.len > 0 )
{
initStringInfo(&cols);
} /*IF col.len>0*/
if( query.len > 0 )
{
initStringInfo(&query);
} /*IF col.len>0*/
elog(INFO,"reloid:%d", idxcd->reloid);
appendStringInfo( &query, "select a.attname from pg_class c,pg_attribute a where c.oid=%d AND a.attrelid = c.oid AND (", idxcd->reloid);
/*elog(INFO,"QUERY:%s", query.data);*/
/*elog(INFO,"ncols:%d", idxcd->ncols);*/
for (i = 0; i < idxcd->ncols; ++i)
{
/*elog(INFO,"i:%d", i);*/
/*elog(INFO,"var attno i:%d", idxcd->varattno[i]);*/
/*elog(INFO,"cols:%s", cols.data);*/
appendStringInfo( &cols, "%s a.attnum=%d", (i>0 ? " OR" : ""), idxcd->varattno[i]);
/*elog(INFO,"cols:%s", cols.data);*/
/*elog(INFO,"i:%d", i);*/
elog(INFO,"varattno i:%d", idxcd->varattno[i]);
}/* foreach col in varattno*/
/*elog(INFO,"PASA EL FOR");*/
appendStringInfo( &cols, "%s", ")");
/* FIXME: Mention the column names explicitly after the table name. */
appendStringInfo( &query, "%s;", cols.data);
elog(INFO,"QUERY:%s", query.data);
/*elog(INFO,"LONGITUD:%d", query.len);*/
if( query.len > 0 ) /* if we generated any SQL */
{
outerContext = CurrentMemoryContext;
if( SPI_connect() == SPI_OK_CONNECT )
{
/*elog(INFO,"CONECTADO:%d", query.len);*/
ret=SPI_exec(query.data, 0);
proc=SPI_processed;
TupleDesc tupdesc=SPI_tuptable->tupdesc;
SPITupleTable *tuptable=SPI_tuptable;
char buf[8192];
if( ret>0 )
{
/*elog(INFO,"EJECUTA:%d", query.len);*/
if( SPI_tuptable != NULL)
{
//TupleDesc tupdesc;
//SPITupleTable *tuptable = SPI_tuptable;
//tupdesc = tuptable->tupdesc;
elog(INFO,"procantesciclo:%d", proc);
int i,j;
for(j=0;j<proc;j++)
{
HeapTuple tuple;
elog(INFO,"procdespuesciclo:%d", proc);
/*cada fila*/
int cont=0;
tuple=tuptable->vals[j];
if (tuple!=NULL)
{
for (i=1,buf[0]=0;i<=tupdesc->natts;i++)
{
char *data;
/* cada columna de cada fila*/
data=SPI_getvalue(tuple,tupdesc,i);
elog(INFO,"data:%s", data);
idxcd->varattnombres[i]=MemoryContextStrdup(outerContext, data);
elog(INFO,"valorgc:%s", idxcd->varattnombres[i]);
elog(INFO,"indice:%d", cont);
cont++;
snprintf(buf + strlen (buf), sizeof(buf) - strlen(buf), " %s%s", SPI_getvalue(tuple, tupdesc, i),(i == tupdesc->natts) ? " " : " |");
} /* (i=0,buf[0]=0;i<tupdesc->natts;i++)*/
elog (INFO, "EXECQ: %s", buf);
} /* if (tuple!=null)*/
else
elog( WARNING, "IND ADV: tuple is null." );
} /* (j=0;j<proc;j++)*/
} /*if( SPI_tuptable != NULL)*/
else
elog( WARNING, "IND ADV: SPI_tuptable is null." );
}
else
elog( WARNING, "IND ADV: SPI_execute failed while select." );
if( SPI_finish() != SPI_OK_FINISH )
elog( WARNING, "IND ADV: SPI_finish failed while select." );
} /*if( SPI_connect() == SPI_OK_CONNECT )*/
else
elog( WARNING, "IND ADV: SPI_connect failed while select." );
} /*if( query.len > 0 )*/
elog (INFO, "if( query.len > 0");
/*if( query.len > 0 )*/
} /* foreach cell in candidates */
elog (INFO, "/* foreach cell in candidates */");
foreach( cell, candidates ) /* foreach cell in candidates */
{
MemoryContext oldContext = MemoryContextSwitchTo( outerContext );
MemoryContextSwitchTo( oldContext );
/*elog (INFO, "Ingresando a foreach");*/
idxcd = (IndexCandidate*)lfirst( cell );
if (idxcd == NULL) {
elog( INFO, "idxcd IS NULL" );
continue; /* Or is that fatal enough to break instead? */
}
if (!idxcd->idxused)
continue;
int i;
for (i = 0; i < idxcd->ncols; ++i)
{
/*elog(INFO,"cols:%s", cols.data);*/
elog(INFO,"i:%d", i);
elog(INFO,"varattnombres i:%s", idxcd->varattnombres[i]);
elog(INFO,"varattno i:%d", idxcd->varattno[i]);
}/* foreach col in varattno*/
}
/* TODO: Propose to -hackers to introduce API to free a StringInfoData . */
if ( query.len > 0 )
pfree( query.data );
elog( DEBUG3, "IND ADV: select: EXIT" );
elog (INFO, "retornando get_columnnames");
return candidates;
}
I wanted to send my function as a separate source code file, but I am not allowed to send emails from the mail, I get a warning that messages can only be sent from Google Groups, and it does not allow sending messages with attachments.
Loading...