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; }