If I enable server side prepare (UseServerSidePrepare=1 in my DSN) and connect to the database, execute a query, then
disconnect,the following code path is taken:
SQL_Disconnect calls PGAPI_Disconnect
PGAPI_Disconnect calls CC_Cleanup
CC_Cleanup iterates through its statements:
/* Free all the stmts on this connection */
for (i = 0; i < self->num_stmts; i++)
{
stmt = self->stmts[i];
if (stmt)
{
stmt->hdbc = NULL; /* prevent any more dbase interactions */
SC_Destructor(stmt);
self->stmts[i] = NULL;
}
}
SC_Destructor calls SC_initialize_stmts(self, TRUE)
SC_Initialize_stmts calls SC_set_prepared(self, FALSE), which dereferences the hdbc pointer, which was set to null in
thecode block above:
void
SC_set_prepared(StatementClass *stmt, BOOL prepared)
{
if (prepared == stmt->prepared)
return;
if (!prepared)
{
ConnectionClass *conn = SC_get_conn(stmt);
*** CRASH *** if (CONN_CONNECTED == conn->status)
{
QResultClass *res;
char dealloc_stmt[128];
sprintf(dealloc_stmt, "DEALLOCATE _PLAN%0x", stmt);
res = CC_send_query(conn, dealloc_stmt, NULL, 0);
if (res)
QR_Destructor(res);
}
}
stmt->prepared = prepared;
}
The SC_set_prepared function is trying to deallocate the query plan on the server side - is this necessary if we're
shuttingdown the connection? (anyway, the socket has already been closed before the statements are deallocated.)
I think the proper way to fix this is to simply add a check for a null pointer in the SC_set_prepared function, but I
wantedto ask here first since I don't know if this will have any unforseen consequences.