1
0
mirror of https://github.com/postgres/postgres.git synced 2025-10-21 02:52:47 +03:00

Applied patch by Boszormenyi Zoltan <zb@cybertec.at> to fix problem in auto-prepare mode if the connection is closed and re-opened and the previously prepared query is issued again.

This commit is contained in:
Michael Meskes
2010-01-22 14:13:03 +00:00
parent b13da41eba
commit 5bc75618e4
6 changed files with 232 additions and 26 deletions

View File

@@ -1,4 +1,4 @@
/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/prepare.c,v 1.34 2010/01/15 10:44:34 meskes Exp $ */
/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/prepare.c,v 1.35 2010/01/22 14:13:03 meskes Exp $ */
#define POSTGRES_ECPG_INTERNAL
#include "postgres_fe.h"
@@ -99,27 +99,13 @@ replace_variables(char **text, int lineno)
return true;
}
/* handle the EXEC SQL PREPARE statement */
/* questionmarks is not needed but remians in there for the time being to not change the API */
bool
ECPGprepare(int lineno, const char *connection_name, const bool questionmarks, const char *name, const char *variable)
static bool
prepare_common(int lineno, struct connection *con, const bool questionmarks, const char *name, const char *variable)
{
struct connection *con;
struct statement *stmt;
struct prepared_statement *this,
*prev;
struct prepared_statement *this;
PGresult *query;
con = ecpg_get_connection(connection_name);
if (!ecpg_init(con, connection_name, lineno))
return false;
/* check if we already have prepared this statement */
this = ecpg_find_prepared_statement(name, con, &prev);
if (this && !deallocate_one(lineno, ECPG_COMPAT_PGSQL, con, prev, this))
return false;
/* allocate new statement */
this = (struct prepared_statement *) ecpg_alloc(sizeof(struct prepared_statement), lineno);
if (!this)
@@ -169,6 +155,28 @@ ECPGprepare(int lineno, const char *connection_name, const bool questionmarks, c
return true;
}
/* handle the EXEC SQL PREPARE statement */
/* questionmarks is not needed but remians in there for the time being to not change the API */
bool
ECPGprepare(int lineno, const char *connection_name, const bool questionmarks, const char *name, const char *variable)
{
struct connection *con;
struct prepared_statement *this,
*prev;
con = ecpg_get_connection(connection_name);
if (!ecpg_init(con, connection_name, lineno))
return false;
/* check if we already have prepared this statement */
this = ecpg_find_prepared_statement(name, con, &prev);
if (this && !deallocate_one(lineno, ECPG_COMPAT_PGSQL, con, prev, this))
return false;
return prepare_common(lineno, con, questionmarks, name, variable);
}
struct prepared_statement *
ecpg_find_prepared_statement(const char *name,
struct connection * con, struct prepared_statement ** prev_)
@@ -465,21 +473,37 @@ ecpg_auto_prepare(int lineno, const char *connection_name, const int compat, cha
/* if not found - add the statement to the cache */
if (entNo)
{
char *stmtID;
struct connection *con;
struct prepared_statement *prep;
ecpg_log("ecpg_auto_prepare on line %d: statement found in cache; entry %d\n", lineno, entNo);
*name = ecpg_strdup(stmtCacheEntries[entNo].stmtID, lineno);
stmtID = stmtCacheEntries[entNo].stmtID;
con = ecpg_get_connection(connection_name);
prep = ecpg_find_prepared_statement(stmtID, con, NULL);
/* This prepared name doesn't exist on this connection. */
if (!prep && !prepare_common(lineno, con, 0, stmtID, query))
return (false);
*name = ecpg_strdup(stmtID, lineno);
}
else
{
char stmtID[STMTID_SIZE];
ecpg_log("ecpg_auto_prepare on line %d: statement not in cache; inserting\n", lineno);
/* generate a statement ID */
*name = (char *) ecpg_alloc(STMTID_SIZE, lineno);
sprintf(*name, "ecpg%d", nextStmtID++);
sprintf(stmtID, "ecpg%d", nextStmtID++);
if (!ECPGprepare(lineno, connection_name, 0, ecpg_strdup(*name, lineno), query))
if (!ECPGprepare(lineno, connection_name, 0, stmtID, query))
return (false);
if (AddStmtToCache(lineno, *name, connection_name, compat, query) < 0)
if (AddStmtToCache(lineno, stmtID, connection_name, compat, query) < 0)
return (false);
*name = ecpg_strdup(stmtID, lineno);
}
/* increase usage counter */