in src/odbc/rsodbc/rslibpq.c [2689:2815]
SQLRETURN libpqPrepareOnThreadWithoutStoringResults(RS_STMT_INFO *pStmt, char *pszCmd)
{
SQLRETURN rc = SQL_SUCCESS;
RS_CONN_INFO *pConn = pStmt->phdbc;
if(pszCmd)
{
PGresult *pgResult = NULL;
ExecStatusType pqRc = PGRES_COMMAND_OK;
int asyncEnable = isAsyncEnable(pStmt);
int sendStatus = 1;
if(asyncEnable)
{
sendStatus = pqSendPrepareAndDescribe(pConn->pgConn, pStmt->szCursorName, pszCmd, 0, NULL);
if(sendStatus)
{
pgResult = PQgetResult(pConn->pgConn);
pqRc = PQresultStatus(pgResult);
}
else
pqRc = PGRES_FATAL_ERROR;
}
else
{
pgResult = pqPrepare(pConn->pgConn, pStmt->szCursorName, pszCmd, 0, NULL);
pqRc = PQresultStatus(pgResult);
}
// Multi prepare loop
do
{
if(!(pqRc == PGRES_COMMAND_OK
|| pqRc == PGRES_TUPLES_OK
|| pqRc == PGRES_COPY_IN
|| pqRc == PGRES_COPY_OUT))
{
char *pError = libpqErrorMsg(pConn);
// Even one result in error, we are retuning error.
rc = SQL_ERROR;
if(pError && *pError != '\0')
addError(&pStmt->pErrorList,"HY000", pError, 0, pConn);
// Clear this result because we are not storing it
PQclear(pgResult);
pgResult = NULL;
}
else
{
PGresult *pgResultDescParam = PQgetResult(pConn->pgConn);
if(pgResultDescParam == NULL)
{
// 'Z' must be followed to 't' during above PQgetResult
// So read from resultForDescParam
pgResultDescParam = pqgetResultForDescribeParam(pConn->pgConn);
}
PQclear(pgResultDescParam);
pgResultDescParam = NULL;
if(pqRc == PGRES_TUPLES_OK)
{
// SELECT kind of operation returning rows description
pgResult = PQgetResult(pConn->pgConn);
PQclear(pgResult);
pgResult = NULL;
} // SELECT
} // Success
if (pqRc == PGRES_COPY_IN ||
pqRc == PGRES_COPY_OUT ||
pqRc == PGRES_COPY_BOTH ||
(pConn && pConn->pgConn && PQstatus(pConn->pgConn) == CONNECTION_BAD)
)
{
// No need to loop any more.
break;
}
// Loop for next result
if(asyncEnable)
{
// If command not send, no need to check for next result.
if(!sendStatus)
break;
}
PQclear(pgResult);
pgResult = NULL;
// Get next result description
pgResult = PQgetResult(pConn->pgConn);
if(!pgResult)
{
// 'Z' must be followed to 'T' during above PQgetResult
// So read from resultForDescRowPrep and release it.
PGresult *pgResultDescRowPrep = pqgetResultForDescribeRowPrep(pConn->pgConn);
PQclear(pgResultDescRowPrep);
pgResultDescRowPrep = NULL;
break;
}
// Get result status
pqRc = PQresultStatus(pgResult);
}while(TRUE); // Results loop
}
else
{
rc = SQL_ERROR;
addError(&pStmt->pErrorList,"HY000", "Invalid command buffer", 0, NULL);
goto error;
}
error:
return rc;
}