gpt4 book ai didi

c - 这是逻辑错误还是发生了什么? foreach 的问题

转载 作者:行者123 更新时间:2023-11-30 19:01:07 26 4
gpt4 key购买 nike

我有一个在 Postgresql 服务器上运行的名为 get_ndistinct 的 c 函数,它返回 Postgresql 数据库中某些表的列的 get_ndistinct 统计值。事实是,当 foreach 输入两次(第二次)时,在 idxcd-> varattnames [i] 中加载的值对我来说显示为数字,而实际上我应该返回列名称值。在我看来,数字与循环上一步中为 get_ndistinct 返回的值相匹配?我真的想了很多,不明白为什么会出现这种情况。我不知道这是我的逻辑错误还是发生了什么。这很奇怪,特别是因为该数字与循环上一步返回的值一致......我不知道它在 idxcd-> varattnombre [i]¿ 中的位置或方式加载?要使用调试器,我不知道是否可以......因为我使用 Makefile。我不知道是否可以通过 Makefile 使用调试器,我是 Linux 的新手。请给我答复,我将不胜感激。我的源码如下:

/**
* 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 循环遍历传递给函数的列表,因此列表中的值取决于函数的调用者。也许你应该开始寻找那里。

关于附加与 Makefile 无关的调试器:

  • 确保使用 -g 选项进行编译。如果您配置了 PostgreSQL --enable-debug,这种情况会自动发生。

  • sleep(10) 放在函数的开头。

  • 启动 PostgreSQL session 并使用 SELECT pg_backend_pid(); 获取后端进程 ID。

  • 调用您的函数并快速附加调试器

    gdb /path/to/postgres 12345

    其中 12345 是后端进程 ID。

关于c - 这是逻辑错误还是发生了什么? foreach 的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58404890/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com