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