这是一个逻辑错误还是发生了什么?foreach的问题
我在c语言中有一个函数,它在Postgresql服务器上运行,名为get\u ndistint,它为Postgresql数据库中某些表的列返回get\u ndistint的统计值。 事实上,当foreach输入两次(第二次)时,在idxcd->varattnames[i]中加载的值在我看来是一个数字,而实际上我应该返回一个列名值。在我看来,出现的数字与在循环的前一步中为get\u ndistinct返回的值相匹配?我真的想了很多,我不明白为什么会这样。我不知道这是我的逻辑错误还是发生了什么。这很奇怪,尤其是因为数字与循环前一步返回的值一致。。。我不知道在idxcd->varattnombre[I]中它在哪里或如何加载? 要使用调试器,我不知道是否可以。。。因为我使用一个Makefile。我不知道我是否可以将调试器与Makefile一起使用,我是Linux新手。 请给我答复,我将不胜感激。 我的源代码如下:这是一个逻辑错误还是发生了什么?foreach的问题,c,postgresql,C,Postgresql,我在c语言中有一个函数,它在Postgresql服务器上运行,名为get\u ndistint,它为Postgresql数据库中某些表的列返回get\u ndistint的统计值。 事实上,当foreach输入两次(第二次)时,在idxcd->varattnames[i]中加载的值在我看来是一个数字,而实际上我应该返回一个列名值。在我看来,出现的数字与在循环的前一步中为get\u ndistinct返回的值相匹配?我真的想了很多,我不明白为什么会这样。我不知道这是我的逻辑错误还是发生了什么。这很
/**
* get_distinct
* for every candidate get an entry into IndexCandidate
*/
static List*
get_ndistinct( List* candidates )
{
int proc;
StringInfoData query; /* string for Query */
StringInfoData cols; /* string for Columns */
Oid advise_oid;
ListCell *cell;
IndexCandidate* idxcd;
elog( DEBUG3, "IND ADV: get_distinct: ENTER" );
initStringInfo( &query );
initStringInfo( &cols );
foreach( cell, candidates ) /* foreach cell in candidates */
{
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;
/* 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*/
appendStringInfo( &query, "select n_distinct from pg_stats where ");
for (i = 0; i < idxcd->ncols; ++i)
{
appendStringInfo( &cols, "%s attname='%s'", (i>0?" OR":""), idxcd->varattnombres[i]);
}/* foreach col in varattno*/
/* FIXME: Mention the column names explicitly after the table name. */
appendStringInfo( &query, "%s;", cols.data);
if( query.len > 0 ) /* if we generated any SQL */
{
if( SPI_connect() == SPI_OK_CONNECT )
{
if( SPI_execute( query.data, true, 0 ) != SPI_OK_SELECT )
elog( WARNING, "IND ADV: SPI_execute failed while select." );
else /* SPI_OK_SELECT*/
{
proc=SPI_processed;
TupleDesc tupdesc=SPI_tuptable->tupdesc;
SPITupleTable *tuptable=SPI_tuptable;
char buf[8192];
int i,j;
for(j=0;j<proc;j++)
{
/*cada fila*/
HeapTuple tuple=tuptable->vals[j];
for (i=1,buf[0]=0;i<=tupdesc->natts;i++)
{
/* cada columna de cada fila*/
char *data;
data=SPI_getvalue(tuple,tupdesc,i);
idxcd->ndistinct[j]=data;
snprintf(buf+strlen(buf),sizeof(buf)-strlen(buf),"%s %s",data,(i==tupdesc->natts)?"": "|");
}
elog(INFO,"EXECQ:%s",buf);
}
}
if( SPI_finish() != SPI_OK_FINISH )
elog( WARNING, "IND ADV: SPI_finish failed while select." );
}
else /* SPI_connect() != SPI_OK_CONNECT*/
elog( WARNING, "IND ADV: SPI_connect failed while select." );
} /*if( query.len > 0 ) if we generated any SQL */
} /* foreach cell in candidates */
/* TODO: Propose to -hackers to introduce API to free a StringInfoData . */
if ( query.len > 0 )
pfree( query.data );
elog( DEBUG3, "IND ADV: select: EXIT" );
return candidates;
}
根据所提供的信息,不可能精确定位错误。由于foreach循环遍历传递给函数的列表,因此它取决于函数的调用方列表中的值。也许你应该开始看看那里 关于附加与生成文件无关的调试器: 确保使用-g选项编译。如果配置了PostgreSQL-enable调试,则会自动发生这种情况 在函数的开头放一个sleep10 启动PostgreSQL会话并使用SELECT pg_backend_pid;获取后端进程ID 调用函数并使用
gdb /path/to/postgres 12345
其中12345是后端进程ID
生成文件与调试器无关。生成文件控制可执行文件的生成方式。调试器在运行时逐步执行代码。一个与另一个无关。问题是我将idxcd->varattnombres[I]的值打印为整数值,使用%d,而实际上我必须将其打印为字符串值,使用%s,这就是我打印数值的原因。很高兴听到您在开发和调试PostgreSQL代码方面取得了进展。我从自己的经验中知道,令人尴尬的琐碎错误会让你困惑好几天。