OSDN Git Service

- Fixed segfault in ecpg when using an array element.
authorMichael Meskes <meskes@postgresql.org>
Thu, 7 Feb 2008 11:09:13 +0000 (11:09 +0000)
committerMichael Meskes <meskes@postgresql.org>
Thu, 7 Feb 2008 11:09:13 +0000 (11:09 +0000)
- Free all memory in auto-prepare mode.

src/interfaces/ecpg/ChangeLog
src/interfaces/ecpg/ecpglib/execute.c
src/interfaces/ecpg/ecpglib/extern.h
src/interfaces/ecpg/ecpglib/prepare.c
src/interfaces/ecpg/preproc/variable.c

index 8716309..846c67c 100644 (file)
@@ -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.
+
+
index 2ccdcbb..20231c6 100644 (file)
@@ -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);
 
                /*
index 975904e..4109890 100644 (file)
@@ -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
index 616310e..6c0268b 100644 (file)
@@ -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);
        }
 
index bf0a85e..7ff0e0d 100644 (file)
@@ -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));
                                }
                        }
                }