Skip to content

Commit

Permalink
Fixed prepared statement leak (added explicit server-side deallocation).
Browse files Browse the repository at this point in the history
  • Loading branch information
Maciej Sobczak authored and Maciej Sobczak committed Oct 7, 2012
1 parent 76f0404 commit 02bb841
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 1 deletion.
11 changes: 10 additions & 1 deletion src/backends/postgresql/session.cpp
Expand Up @@ -55,7 +55,7 @@ postgresql_session_backend::~postgresql_session_backend()
namespace // unnamed
{

// helper function for hardoded queries
// helper function for hardcoded queries
void hard_exec(PGconn * conn, char const * query, char const * errMsg)
{
PGresult* result = PQexec(conn, query);
Expand Down Expand Up @@ -91,6 +91,15 @@ void postgresql_session_backend::rollback()
hard_exec(conn_, "ROLLBACK", "Cannot rollback transaction.");
}

void postgresql_session_backend::deallocate_prepared_statement(
const std::string & statementName)
{
const std::string & query = "DEALLOCATE " + statementName;

hard_exec(conn_, query.c_str(),
"Cannot deallocate prepared statement.");
}

void postgresql_session_backend::clean_up()
{
if (0 != conn_)
Expand Down
2 changes: 2 additions & 0 deletions src/backends/postgresql/soci-postgresql.h
Expand Up @@ -236,6 +236,8 @@ struct postgresql_session_backend : details::session_backend
virtual void commit();
virtual void rollback();

void deallocate_prepared_statement(const std::string & statementName);

virtual std::string get_backend_name() const { return "postgresql"; }

void clean_up();
Expand Down
6 changes: 6 additions & 0 deletions src/backends/postgresql/statement.cpp
Expand Up @@ -48,6 +48,12 @@ void postgresql_statement_backend::clean_up()
{
PQclear(result_);
result_ = NULL;

if (statementName_.empty() == false)

This comment has been minimized.

Copy link
@mloskot

mloskot Oct 29, 2012

Contributor

The statement clean-up here leads to problems with repeated execution of prepared statements I discuss in unnamed prepared statement does not exist

Simple fix would be to change the condition to:

if (stType_ != st_repeatable_query && statementName_.empty() == false)

but then, how to detect final execution after which statement deallocation should occur?

Related ticket #13

{
session_.deallocate_prepared_statement(statementName_);
statementName_.clear();
}
}
}

Expand Down

0 comments on commit 02bb841

Please sign in to comment.