首页 > 解决方案 > appendStringInfo 的问题

问题描述

我有一个调用函数get_columnames,它通过传递属性号返回表的列的名称。

我真的想了很多关于为什么会这样,但我仍然不明白为什么我的表达方式是错误的

appendStringInfo (& cols, "% s a.attnum =% d", (i> 0? "OR": ""), idxcd-> varattno [i]);

进入循环时,该错误仅对我出现

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

不止一次,即存在多个候选索引时。如果只输入一次循环,则该功能正常工作。

我得到的错误是与 PostgreSQL 服务器的连接直接丢失。我通过打印一些值证明了这个语句中发生了错误。

错误是:

The connection to the server was lost. Attempting reset: Failed.

这是代码:

static List*
get_columnnames( List* candidates )

{
    int proc;
    int ret;
    StringInfoData  query;  /* string for Query */
    StringInfoData  cols;   /* string for Columns */
    Oid             advise_oid;
    ListCell        *cell;
    int b=0;

    IndexCandidate* idxcd;

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


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

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

        idxcd = (IndexCandidate*)lfirst( cell );

        if( !idxcd->idxused )
            continue;

        if (idxcd!=NULL)
        {

            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 )
            {
                pfree( cols.data );
                cols.data = NULL;
            } /*IF col.len>0*/
            appendStringInfo( &query, "select a.attname from pg_class c,pg_attribute a where c.oid=%d AND a.attrelid = c.oid AND (", idxcd->reloid);

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

            }/* foreach col in varattno*/

            appendStringInfo( &cols, "%s", ")");

            /* 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 )
                {
                        ret=SPI_exec(query.data, 0);
                        proc=SPI_processed;
                    elog(INFO,"proc:%d", query.len);
                    if( ret>0 )
                    {
                        b=1;

                        if( SPI_tuptable != NULL)
                         {
                            SPITupleTable *tuptable = SPI_tuptable;
                            TupleDesc tupdesc = tuptable->tupdesc;
                            char buf[8192];
                            int i,j;

                            for(j=0;j<proc;j++)
                            {

                                HeapTuple tuple=tuptable->vals[j];  
                                if (tuple!=NULL)
                                {

                                    for (i=1,buf[0]=0;i<=tupdesc->natts;i++)
                                    {
                                        /* cada columna de cada fila*/
                                        char *data;
                                        data=SPI_getvalue(tuple,tupdesc,i);
                                        idxcd->varattnombres[j]=data;
                                        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 )*/
        } /*if (idxcd!=null)*/
        else
            elog( INFO, "idxcd IS NULL" );
    }   /* 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;
}

标签: cpostgresql

解决方案


推荐阅读