From fa0dc92fd8611ea299fec32458da844da8807ef3 Mon Sep 17 00:00:00 2001 From: Michael Meskes Date: Thu, 7 Feb 2008 11:09:13 +0000 Subject: [PATCH] - Fixed segfault in ecpg when using an array element. - Free all memory in auto-prepare mode. --- src/interfaces/ecpg/ChangeLog | 7 +++++++ src/interfaces/ecpg/ecpglib/execute.c | 4 ++-- src/interfaces/ecpg/ecpglib/extern.h | 4 ++-- src/interfaces/ecpg/ecpglib/prepare.c | 25 +++++++++++-------------- src/interfaces/ecpg/preproc/variable.c | 4 ++-- 5 files changed, 24 insertions(+), 20 deletions(-) diff --git a/src/interfaces/ecpg/ChangeLog b/src/interfaces/ecpg/ChangeLog index 871630923c..846c67cc0c 100644 --- a/src/interfaces/ecpg/ChangeLog +++ b/src/interfaces/ecpg/ChangeLog @@ -2301,3 +2301,10 @@ Tue, 15 Jan 2008 11:26:14 +0100 - Set compat library version to 3.0. - Set ecpg library version to 6.0. - Set ecpg version to 4.4. + +Wed, 06 Feb 2008 09:04:48 +0100 + + - Fixed segfault in ecpg when using an array element. + - Free all memory in auto-prepare mode. + + diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c index 2ccdcbb68f..20231c62a7 100644 --- a/src/interfaces/ecpg/ecpglib/execute.c +++ b/src/interfaces/ecpg/ecpglib/execute.c @@ -1,4 +1,4 @@ -/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/execute.c,v 1.75 2008/01/15 10:31:47 meskes Exp $ */ +/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/execute.c,v 1.76 2008/02/07 11:09:12 meskes Exp $ */ /* * The aim is to get a simpler inteface to the database routines. @@ -1489,7 +1489,7 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char */ if (statement_type == ECPGst_prepnormal) { - if (!ecpg_auto_prepare(lineno, connection_name, questionmarks, &prepname, query)) + if (!ecpg_auto_prepare(lineno, connection_name, compat, questionmarks, &prepname, query)) return (false); /* diff --git a/src/interfaces/ecpg/ecpglib/extern.h b/src/interfaces/ecpg/ecpglib/extern.h index 975904eb77..41098903ec 100644 --- a/src/interfaces/ecpg/ecpglib/extern.h +++ b/src/interfaces/ecpg/ecpglib/extern.h @@ -1,4 +1,4 @@ -/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/extern.h,v 1.33 2008/01/15 10:31:47 meskes Exp $ */ +/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/extern.h,v 1.34 2008/02/07 11:09:12 meskes Exp $ */ #ifndef _ECPG_LIB_EXTERN_H #define _ECPG_LIB_EXTERN_H @@ -146,7 +146,7 @@ void ecpg_raise_backend(int line, PGresult *result, PGconn *conn, int compat); char *ecpg_prepared(const char *, struct connection *, int); bool ecpg_deallocate_all_conn(int lineno, enum COMPAT_MODE c, struct connection * conn); void ecpg_log(const char *format,...); -bool ecpg_auto_prepare(int, const char *, const int, char **, const char *); +bool ecpg_auto_prepare(int, const char *, int, const int, char **, const char *); void ecpg_init_sqlca(struct sqlca_t * sqlca); /* SQLSTATE values generated or processed by ecpglib (intentionally diff --git a/src/interfaces/ecpg/ecpglib/prepare.c b/src/interfaces/ecpg/ecpglib/prepare.c index 616310e650..6c0268bdb1 100644 --- a/src/interfaces/ecpg/ecpglib/prepare.c +++ b/src/interfaces/ecpg/ecpglib/prepare.c @@ -1,4 +1,4 @@ -/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/prepare.c,v 1.25 2007/11/15 22:25:17 momjian Exp $ */ +/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/prepare.c,v 1.26 2008/02/07 11:09:13 meskes Exp $ */ #define POSTGRES_ECPG_INTERNAL #include "postgres_fe.h" @@ -373,30 +373,26 @@ SearchStmtCache(const char *ecpgQuery) * OR negative error code */ static int -ecpg_freeStmtCacheEntry(int entNo) /* entry # to free */ +ecpg_freeStmtCacheEntry(int lineno, int compat, int entNo) /* entry # to free */ { stmtCacheEntry *entry; - PGresult *results; - char deallocText[100]; struct connection *con; + struct prepared_statement *this, *prev; entry = &stmtCacheEntries[entNo]; if (!entry->stmtID[0]) /* return if the entry isn't in use */ return (0); con = ecpg_get_connection(entry->connection); -/* free the server resources for the statement */ - ecpg_log("ecpg_freeStmtCacheEntry line %d: deallocate %s, cache entry #%d\n", entry->lineno, entry->stmtID, entNo); - sprintf(deallocText, "DEALLOCATE PREPARE %s", entry->stmtID); - results = PQexec(con->connection, deallocText); - if (!ecpg_check_PQresult(results, entry->lineno, con->connection, ECPG_COMPAT_PGSQL)) + /* free the 'prepared_statement' list entry */ + this = find_prepared_statement(entry->stmtID, con, &prev); + if (this && !deallocate_one(lineno, compat, con, prev, this)) return (-1); - PQclear(results); entry->stmtID[0] = '\0'; -/* free the memory used by the cache entry */ + /* free the memory used by the cache entry */ if (entry->ecpgQuery) { ecpg_free(entry->ecpgQuery); @@ -414,6 +410,7 @@ static int AddStmtToCache(int lineno, /* line # of statement */ char *stmtID, /* statement ID */ const char *connection, /* connection */ + int compat, /* compatibility level */ const char *ecpgQuery) /* query */ { int ix, @@ -444,7 +441,7 @@ AddStmtToCache(int lineno, /* line # of statement */ entNo = luEntNo; /* re-use the 'least used' entry */ /* 'entNo' is the entry to use - make sure its free */ - if (ecpg_freeStmtCacheEntry(entNo) < 0) + if (ecpg_freeStmtCacheEntry(lineno, compat, entNo) < 0) return (-1); /* add the query to the entry */ @@ -460,7 +457,7 @@ AddStmtToCache(int lineno, /* line # of statement */ /* handle cache and preparation of statments in auto-prepare mode */ bool -ecpg_auto_prepare(int lineno, const char *connection_name, const int questionmarks, char **name, const char *query) +ecpg_auto_prepare(int lineno, const char *connection_name, int compat, const int questionmarks, char **name, const char *query) { int entNo; @@ -483,7 +480,7 @@ ecpg_auto_prepare(int lineno, const char *connection_name, const int questionmar if (!ECPGprepare(lineno, connection_name, questionmarks, ecpg_strdup(*name, lineno), query)) return (false); - if (AddStmtToCache(lineno, *name, connection_name, query) < 0) + if (AddStmtToCache(lineno, *name, connection_name, compat, query) < 0) return (false); } diff --git a/src/interfaces/ecpg/preproc/variable.c b/src/interfaces/ecpg/preproc/variable.c index bf0a85e470..7ff0e0db63 100644 --- a/src/interfaces/ecpg/preproc/variable.c +++ b/src/interfaces/ecpg/preproc/variable.c @@ -1,4 +1,4 @@ -/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/variable.c,v 1.43 2007/12/21 14:33:20 meskes Exp $ */ +/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/variable.c,v 1.44 2008/02/07 11:09:13 meskes Exp $ */ #include "postgres_fe.h" @@ -237,7 +237,7 @@ find_variable(char *name) case ECPGt_union: return (new_variable(name, ECPGmake_struct_type(p->type->u.element->u.members, p->type->u.element->type, p->type->u.element->struct_sizeof), p->brace_level)); default: - return (new_variable(name, ECPGmake_simple_type(p->type->u.element->type, p->type->u.element->size, p->type->u.element->u.element->lineno), p->brace_level)); + return (new_variable(name, ECPGmake_simple_type(p->type->u.element->type, p->type->u.element->size, p->type->u.element->lineno), p->brace_level)); } } } -- 2.40.0