From fa0dc92fd8611ea299fec32458da844da8807ef3 Mon Sep 17 00:00:00 2001
From: Michael Meskes <meskes@postgresql.org>
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 871630923c1..846c67cc0c9 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 2ccdcbb68fb..20231c62a7d 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 975904eb774..41098903ec8 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 616310e6501..6c0268bdb1d 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 bf0a85e4709..7ff0e0db632 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));
 				}
 			}
 		}
-- 
GitLab