Commit fa0dc92f authored by Michael Meskes's avatar Michael Meskes

- Fixed segfault in ecpg when using an array element.

- Free all memory in auto-prepare mode.
parent 8d363727
...@@ -2301,3 +2301,10 @@ Tue, 15 Jan 2008 11:26:14 +0100 ...@@ -2301,3 +2301,10 @@ Tue, 15 Jan 2008 11:26:14 +0100
- Set compat library version to 3.0. - Set compat library version to 3.0.
- Set ecpg library version to 6.0. - Set ecpg library version to 6.0.
- Set ecpg version to 4.4. - 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.
/* $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. * 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 ...@@ -1489,7 +1489,7 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
*/ */
if (statement_type == ECPGst_prepnormal) 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); return (false);
/* /*
......
/* $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 #ifndef _ECPG_LIB_EXTERN_H
#define _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); ...@@ -146,7 +146,7 @@ void ecpg_raise_backend(int line, PGresult *result, PGconn *conn, int compat);
char *ecpg_prepared(const char *, struct connection *, int); char *ecpg_prepared(const char *, struct connection *, int);
bool ecpg_deallocate_all_conn(int lineno, enum COMPAT_MODE c, struct connection * conn); bool ecpg_deallocate_all_conn(int lineno, enum COMPAT_MODE c, struct connection * conn);
void ecpg_log(const char *format,...); 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); void ecpg_init_sqlca(struct sqlca_t * sqlca);
/* SQLSTATE values generated or processed by ecpglib (intentionally /* SQLSTATE values generated or processed by ecpglib (intentionally
......
/* $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 #define POSTGRES_ECPG_INTERNAL
#include "postgres_fe.h" #include "postgres_fe.h"
...@@ -373,30 +373,26 @@ SearchStmtCache(const char *ecpgQuery) ...@@ -373,30 +373,26 @@ SearchStmtCache(const char *ecpgQuery)
* OR negative error code * OR negative error code
*/ */
static int static int
ecpg_freeStmtCacheEntry(int entNo) /* entry # to free */ ecpg_freeStmtCacheEntry(int lineno, int compat, int entNo) /* entry # to free */
{ {
stmtCacheEntry *entry; stmtCacheEntry *entry;
PGresult *results;
char deallocText[100];
struct connection *con; struct connection *con;
struct prepared_statement *this, *prev;
entry = &stmtCacheEntries[entNo]; entry = &stmtCacheEntries[entNo];
if (!entry->stmtID[0]) /* return if the entry isn't in use */ if (!entry->stmtID[0]) /* return if the entry isn't in use */
return (0); return (0);
con = ecpg_get_connection(entry->connection); 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); return (-1);
PQclear(results);
entry->stmtID[0] = '\0'; entry->stmtID[0] = '\0';
/* free the memory used by the cache entry */ /* free the memory used by the cache entry */
if (entry->ecpgQuery) if (entry->ecpgQuery)
{ {
ecpg_free(entry->ecpgQuery); ecpg_free(entry->ecpgQuery);
...@@ -414,6 +410,7 @@ static int ...@@ -414,6 +410,7 @@ static int
AddStmtToCache(int lineno, /* line # of statement */ AddStmtToCache(int lineno, /* line # of statement */
char *stmtID, /* statement ID */ char *stmtID, /* statement ID */
const char *connection, /* connection */ const char *connection, /* connection */
int compat, /* compatibility level */
const char *ecpgQuery) /* query */ const char *ecpgQuery) /* query */
{ {
int ix, int ix,
...@@ -444,7 +441,7 @@ AddStmtToCache(int lineno, /* line # of statement */ ...@@ -444,7 +441,7 @@ AddStmtToCache(int lineno, /* line # of statement */
entNo = luEntNo; /* re-use the 'least used' entry */ entNo = luEntNo; /* re-use the 'least used' entry */
/* 'entNo' is the entry to use - make sure its free */ /* 'entNo' is the entry to use - make sure its free */
if (ecpg_freeStmtCacheEntry(entNo) < 0) if (ecpg_freeStmtCacheEntry(lineno, compat, entNo) < 0)
return (-1); return (-1);
/* add the query to the entry */ /* add the query to the entry */
...@@ -460,7 +457,7 @@ AddStmtToCache(int lineno, /* line # of statement */ ...@@ -460,7 +457,7 @@ AddStmtToCache(int lineno, /* line # of statement */
/* handle cache and preparation of statments in auto-prepare mode */ /* handle cache and preparation of statments in auto-prepare mode */
bool 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; int entNo;
...@@ -483,7 +480,7 @@ ecpg_auto_prepare(int lineno, const char *connection_name, const int questionmar ...@@ -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)) if (!ECPGprepare(lineno, connection_name, questionmarks, ecpg_strdup(*name, lineno), query))
return (false); return (false);
if (AddStmtToCache(lineno, *name, connection_name, query) < 0) if (AddStmtToCache(lineno, *name, connection_name, compat, query) < 0)
return (false); return (false);
} }
......
/* $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" #include "postgres_fe.h"
...@@ -237,7 +237,7 @@ find_variable(char *name) ...@@ -237,7 +237,7 @@ find_variable(char *name)
case ECPGt_union: 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)); 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: 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));
} }
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment