Hi Postgres Team,

Kindly assist with the issue faced while calling procedures on postgresql
using libpq in C. I have attached all the details in the note. Please let
me know if you need any more information


Regards,
Sasmit Utkarsh
+91-7674022625
In general code flow:
main() -> SQL_init_db_connection() -> SQL_get_RIAT_size()

globals:
char SelectSizeName[11];
char SelectSizeCommand[150];
int  SelectSizeNParams;
Oid  SelectSizeParamTypes[2];



//SQL_init_db_connection() which initiates connection and creates procedures 
e.t.c

SQL_init_db_connection():
{

//some code

res = PQexec(conn, "CREATE OR REPLACE PROCEDURE sql_select_size_procedure(hexid 
text, rtp_in integer, INOUT size_data text) LANGUAGE plpgsql AS $$ BEGIN SELECT 
size FROM riat WHERE id = hexid AND rtp = rtp_in INTO size_data; END; $$;");
if(PQresultStatus(res) != PGRES_COMMAND_OK)
{
        LOG_ERROR("CREATE sql_select_size_procedure failed! %s", 
PQerrorMessage(conn));
        SQL_exit_nicely(conn,res);
}
PQclear(res);


// some other code

sprintf(SelectSizeName,"%s","SelectSize");
if(SQL_vsn10) {
        sprintf(SelectSizeCommand,"%s","SELECT size FROM riat WHERE id = $1 AND 
rtp = $2");
} else {
        sprintf(SelectSizeCommand,"%s","CALL SQL_select_size_procedure($1, $2, 
NULL)");
}

SelectSizeNParams       = 2;
SelectSizeParamTypes[0] = 25;  // {text}
SelectSizeParamTypes[1] = 23;  // {int}

//some other code

res = PQprepare(conn,
                SelectSizeName,
                SelectSizeCommand,
                SelectSizeNParams,
                SelectSizeParamTypes);
LOG_DEBUG("%s() PREPARE SelectSize PQresultStatus = 
%s",__func__,PQresStatus(PQresultStatus(res)));
if(PQresultStatus(res) != PGRES_COMMAND_OK)
{
        LOG_ERROR("PREPARE failed for RIAT! %s", PQerrorMessage(conn));
        SQL_exit_nicely(conn,res);
}
PQclear(res);
}

//But in SQL_get_RIAT_size():

/*-------------------------------------------------------------
 return block size from RIAT table for record ID and RTP
 --------------------------------------------------------------*/
void SQL_get_RIAT_size(unsigned int ID, int rtp, int *BlkSize)
{
int blkSz = BLOCK_L4;  // default to 4k if RIAT table does not contain the 
blocksize for the Record ID and rtp
char *size = NULL;

char *rtpVal = (char *)&rtp;
char hexId[9] = {0};
char *hexIdVal = (char *)&hexId;

const char *paramValues[2] = {hexIdVal, rtpVal};
int paramLengths[2] = {4, sizeof(rtp)};
int paramFormats[2] = {1, 1};
int resultFormat = 1;

int nFields = 0;
int nTuples = 0;
PGresult *res = NULL;

                sprintf (hexId, "%04X", ID);
                LOG_TRACE("%s() - ID %s rtp %i 
---------------------------------------",__func__,hexId,rtp);

                if(sql_db) 
                {
                        LOG_DEBUG("%s() SelectSizeCommand = %s '%s' 
%d",__func__,SelectSizeCommand,hexId,rtp);
                        LOG_DEBUG("%s() SeelctSizeNParams = 
%i",__func__,SelectSizeNParams);
                        res = PQexecPrepared (conn, 
                                              SelectSizeName, 
                                              SelectSizeNParams,
                                              paramValues, 
                                              paramLengths, 
                                              paramFormats,
                                              resultFormat);
                }
                else
                {
                        char queryStmt[100] = {0};
                        sprintf (queryStmt, "SELECT size FROM riat WHERE id = 
'%s' AND rtp = %d", hexId, rtp);
                        LOG_DEBUG("%s() FILE path - %s",__func__,queryStmt);
                        PQclear(res);
                        res = PQexec (conn, queryStmt);
                }
                LOG_DEBUG("%s() res = 
%s",__func__,PQresStatus(PQresultStatus(res)));

                if ( PQresultStatus(res) != PGRES_TUPLES_OK ) {
                        LOG_ERROR("SELECT failed: %s", PQerrorMessage(conn));
                        PQclear(res);
                } else {
                        nFields = PQnfields(res);
                        nTuples = PQntuples(res);
                        LOG_DEBUG("%s() nFields=%i 
nTuples=%i",__func__,nFields,nTuples);
                        if (nFields == 0 || nTuples == 0) {
                                LOG_ERROR("SELECT failed: NO ROWS/COLUMNS 
RETURNED");
                                PQclear(res);
                        } else if ( nTuples > 1 ) {
                                LOG_ERROR("More than 1 row is returned");
                                PQclear(res);
                        } else {
                                size = PQgetvalue (res, 0, 0);
                                LOG_DEBUG("%s() - size = %s",__func__,size);    
              //See the below logs size is showing empty, even if there are 
records in db

                                if ( memcmp (size, "Small", 5) == 0 ) {
                                        blkSz = BLOCK_L1;
                                } else if ( memcmp (size,  "Large", 5) == 0 ) {
                                        blkSz = BLOCK_L2;
                                } else if ( memcmp (size, "4K", 2) == 0)  {
                                        blkSz = BLOCK_L4;
                                }
                        }
                }
        *BlkSize = blkSz;
}

Logs:
----

<7>0490218-SQL_init_db_connection() Connection to shc_data database SUCCESSFUL
<6>0490218-[INFO] PostgreSQL Server Version = 1200.16 protocol 3
<7>0490218-SQL_init_db_connection() PREPARE AdvisoryLockData PQresultStatus = 
PGRES_COMMAND_OK
<7>0490218-SQL_init_db_connection() PREPARE AdvisoryUnLockData PQresultStatus = 
PGRES_COMMAND_OK

<7>0490218-SQL_init_db_connection() CREATE sql_select_size_procedure 
PQresultStatus = PGRES_COMMAND_OK
<7>0490218-SQL_init_db_connection() PREPARE SelectSize PQresultStatus = 
PGRES_COMMAND_OK

<7>0490218-SQL_init_db_connection() CREATE sql_select_data_procedure 
PQresultStatus = PGRES_COMMAND_OK
<7>0490218-SQL_init_db_connection() PREPARE SelectData PQresultStatus = 
PGRES_COMMAND_OK
<7>0490218-SQL_init_db_connection() CREATE sql_insert_data_procedure 
PQresultStatus = PGRES_COMMAND_OK
<7>0490218-SQL_init_db_connection() PREPARE InsertData PQresultStatus = 
PGRES_COMMAND_OK
<7>0490218-SQL_init_db_connection() CREATE sql_update_data_procedure 
PQresultStatus = PGRES_COMMAND_OK
<7>0490218-SQL_init_db_connection() PREPARE UpdateData PQresultStatus = 
PGRES_COMMAND_OK

<7>0490218-SQL_get_RIAT_size() SelectSizeCommand = CALL 
SQL_select_size_procedure($1, $2, NULL) 'C1C1' 4
<7>0490218-SQL_get_RIAT_size() SeelctSizeNParams = 2
<7>0490218-SQL_get_RIAT_size() res = PGRES_TUPLES_OK
<7>0490218-SQL_get_RIAT_size() nFields=1 nTuples=1
<7>0490218-SQL_get_RIAT_size() - size =                                    
//See this line and in DB i could see the record but size is null or empty

DB:
--
[shc_user@cucmtpccu1 ~]$ shc_data
psql (16.1, server 15.4)
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, compression: 
off)
Type "help" for help.

shc_data=> select size from riat where ID='C1C1' and rtp=4;
 size
-------
 Large
(1 row)

//whereas when rtp is 0, it fetches the correct values in the logs and DB

<7>0002301-SQL_get_RIAT_size() SelectSizeCommand = CALL 
SQL_select_size_procedure($1, $2, NULL) 'D6D4' 0
<7>0002301-SQL_get_RIAT_size() SeelctSizeNParams = 2
<7>0002301-SQL_get_RIAT_size() res = PGRES_TUPLES_OK
<7>0002301-SQL_get_RIAT_size() nFields=1 nTuples=1
<7>0002301-SQL_get_RIAT_size() - size = Large                          //look 
this line it fetches the correct value of size

shc_data=> select size from riat where ID='D6D4' and rtp=0;
 size
-------
 Large
(1 row)

I dnt understand why the procedure only works for rtp=0.. Is something missing 
while calling the procedure or some logical errors in the code. Please
assist

Reply via email to