diff --git a/src/interfaces/ecpg/ChangeLog b/src/interfaces/ecpg/ChangeLog
index 18708efae166d32cbba96febb61af4ede1bec74f..668bc986a8030ce4ae40d25218ff8615ad1e26f3 100644
--- a/src/interfaces/ecpg/ChangeLog
+++ b/src/interfaces/ecpg/ChangeLog
@@ -1101,5 +1101,11 @@ Tue Sep 25 20:10:03 CEST 2001
 
 	- Synced preproc.y with gram.y.
 	- Changed locale handling.
+
+Mon Okt  1 13:49:40 CEST 2001
+
+	- Fixed truncate bug.
+	- Added patch by Christof Petig <christof.petig@wtal.de> to clean up
+	  ecpglib.
 	- Set ecpg version to 2.9.0.
         - Set library version to 3.3.0.
diff --git a/src/interfaces/ecpg/lib/data.c b/src/interfaces/ecpg/lib/data.c
index 8bed8f711ed8a09aab8a620d60ca19c0f9e01e9c..5d5338131455df1d5f1539dced88438fb39b8118 100644
--- a/src/interfaces/ecpg/lib/data.c
+++ b/src/interfaces/ecpg/lib/data.c
@@ -1,4 +1,4 @@
-/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/data.c,v 1.15 2001/09/19 14:09:32 meskes Exp $ */
+/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/data.c,v 1.16 2001/10/01 12:02:28 meskes Exp $ */
 
 #include "postgres_fe.h"
 
@@ -12,7 +12,7 @@
 #include "sqlca.h"
 
 bool
-get_data(PGresult *results, int act_tuple, int act_field, int lineno,
+get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 		 enum ECPGttype type, enum ECPGttype ind_type,
 		 void *var, void *ind, long varcharsize, long offset,
 		 bool isarray)
diff --git a/src/interfaces/ecpg/lib/execute.c b/src/interfaces/ecpg/lib/execute.c
index 87e690eaa8c2d57af64be82ab5dfca6a963b4dc0..c696afe54b6dcca38f4624528d2504fe958cd0c8 100644
--- a/src/interfaces/ecpg/lib/execute.c
+++ b/src/interfaces/ecpg/lib/execute.c
@@ -1,4 +1,4 @@
-/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/execute.c,v 1.25 2001/09/29 20:12:07 tgl Exp $ */
+/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/execute.c,v 1.26 2001/10/01 12:02:28 meskes Exp $ */
 
 /*
  * The aim is to get a simpler inteface to the database routines.
@@ -370,40 +370,107 @@ ECPGis_type_an_array(int type, const struct statement * stmt, const struct varia
 	return isarray;
 }
 
-static bool
-ECPGexecute(struct statement * stmt)
-{
-	bool		status = false;
-	char	   *copiedquery;
-	PGresult   *results;
-	PGnotify   *notify;
-	struct variable *var;
 
-	copiedquery = ecpg_strdup(stmt->command, stmt->lineno);
+bool
+ECPGstore_result(const PGresult *results, int act_field, 
+			const struct statement * stmt, struct variable *var)
+{	int		isarray,
+			act_tuple,
+			ntuples = PQntuples(results);
+	bool	status = true;
+				
+					isarray = ECPGis_type_an_array(PQftype(results, act_field), stmt, var);
 
-	/*
-	 * Now, if the type is one of the fill in types then we take the
-	 * argument and enter that in the string at the first %s position.
-	 * Then if there are any more fill in types we fill in at the next and
-	 * so on.
-	 */
-	var = stmt->inlist;
-	while (var)
-	{
-		char	   *newcopy;
+					if (!isarray)
+					{
+
+						/*
+						 * if we don't have enough space, we cannot read
+						 * all tuples
+						 */
+						if ((var->arrsize > 0 && ntuples > var->arrsize) || (var->ind_arrsize > 0 && ntuples > var->ind_arrsize))
+						{
+							ECPGlog("ECPGexecute line %d: Incorrect number of matches: %d don't fit into array of %d\n",
+									stmt->lineno, ntuples, var->arrsize);
+							ECPGraise(stmt->lineno, ECPG_TOO_MANY_MATCHES, NULL);
+							return false;
+						}
+					}
+					else
+					{
+
+						/*
+						 * since we read an array, the variable has to be
+						 * an array too
+						 */
+						if (var->arrsize == 0)
+						{
+							ECPGlog("ECPGexecute line %d: variable is not an array\n");
+							ECPGraise(stmt->lineno, ECPG_NO_ARRAY, NULL);
+							return false;
+						}
+					}
+
+					/*
+					 * allocate memory for NULL pointers
+					 */
+					if ((var->arrsize == 0 || var->varcharsize == 0) && var->value == NULL)
+					{
+						int			len = 0;
+
+						switch (var->type)
+						{
+							case ECPGt_char:
+							case ECPGt_unsigned_char:
+								var->varcharsize = 0;
+								/* check strlen for each tuple */
+								for (act_tuple = 0; act_tuple < ntuples; act_tuple++)
+								{
+									int			len = strlen(PQgetvalue(results, act_tuple, act_field)) + 1;
+
+									if (len > var->varcharsize)
+										var->varcharsize = len;
+								}
+								var->offset *= var->varcharsize;
+								len = var->offset * ntuples;
+								break;
+							case ECPGt_varchar:
+								len = ntuples * (var->varcharsize + sizeof(int));
+								break;
+							default:
+								len = var->offset * ntuples;
+								break;
+						}
+						var->value = (void *) ecpg_alloc(len, stmt->lineno);
+						*((void **) var->pointer) = var->value;
+						add_mem(var->value, stmt->lineno);
+					}
+
+					for (act_tuple = 0; act_tuple < ntuples && status; act_tuple++)
+					{
+						if (!get_data(results, act_tuple, act_field, stmt->lineno,
+									var->type, var->ind_type, var->value,
+									  var->ind_value, var->varcharsize, var->offset, isarray))
+							status = false;
+					}
+	return status;
+}
+
+static bool
+ECPGstore_input(const struct statement * stmt, const struct variable *var,
+			const char **tobeinserted_p, bool *malloced_p)
+{
 		char	   *mallocedval = NULL;
-		char	   *tobeinserted = NULL;
-		char	   *p;
-		char		buff[20];
-		int			hostvarl = 0;
+		char	   *newcopy = NULL;
 
 		/*
 		 * Some special treatment is needed for records since we want
 		 * their contents to arrive in a comma-separated list on insert (I
 		 * think).
 		 */
-
-		buff[0] = '\0';
+		
+		*malloced_p=false;
+		*tobeinserted_p="";
 
 		/* check for null value and set input buffer accordingly */
 		switch (var->ind_type)
@@ -411,30 +478,30 @@ ECPGexecute(struct statement * stmt)
 			case ECPGt_short:
 			case ECPGt_unsigned_short:
 				if (*(short *) var->ind_value < 0)
-					strcpy(buff, "null");
+					*tobeinserted_p="null";
 				break;
 			case ECPGt_int:
 			case ECPGt_unsigned_int:
 				if (*(int *) var->ind_value < 0)
-					strcpy(buff, "null");
+					*tobeinserted_p="null";
 				break;
 			case ECPGt_long:
 			case ECPGt_unsigned_long:
 				if (*(long *) var->ind_value < 0L)
-					strcpy(buff, "null");
+					*tobeinserted_p="null";
 				break;
 #ifdef HAVE_LONG_LONG_INT_64
 			case ECPGt_long_long:
 			case ECPGt_unsigned_long_long:
 				if (*(long long int *) var->ind_value < (long long) 0)
-					strcpy(buff, "null");
+					*tobeinserted_p="null";
 				break;
 #endif	 /* HAVE_LONG_LONG_INT_64 */
 			default:
 				break;
 		}
 
-		if (*buff == '\0')
+		if (**tobeinserted_p == '\0')
 		{
 			switch (var->type)
 			{
@@ -456,7 +523,8 @@ ECPGexecute(struct statement * stmt)
 					else
 						sprintf(mallocedval, "%hd", *((short *) var->value));
 
-					tobeinserted = mallocedval;
+					*tobeinserted_p = mallocedval;
+					*malloced_p = true;
 					break;
 
 				case ECPGt_int:
@@ -475,7 +543,8 @@ ECPGexecute(struct statement * stmt)
 					else
 						sprintf(mallocedval, "%d", *((int *) var->value));
 
-					tobeinserted = mallocedval;
+					*tobeinserted_p = mallocedval;
+					*malloced_p = true;
 					break;
 
 				case ECPGt_unsigned_short:
@@ -494,7 +563,8 @@ ECPGexecute(struct statement * stmt)
 					else
 						sprintf(mallocedval, "%hu", *((unsigned short *) var->value));
 
-					tobeinserted = mallocedval;
+					*tobeinserted_p = mallocedval;
+					*malloced_p = true;
 					break;
 
 				case ECPGt_unsigned_int:
@@ -513,7 +583,8 @@ ECPGexecute(struct statement * stmt)
 					else
 						sprintf(mallocedval, "%u", *((unsigned int *) var->value));
 
-					tobeinserted = mallocedval;
+					*tobeinserted_p = mallocedval;
+					*malloced_p = true;
 					break;
 
 				case ECPGt_long:
@@ -532,7 +603,8 @@ ECPGexecute(struct statement * stmt)
 					else
 						sprintf(mallocedval, "%ld", *((long *) var->value));
 
-					tobeinserted = mallocedval;
+					*tobeinserted_p = mallocedval;
+					*malloced_p = true;
 					break;
 
 				case ECPGt_unsigned_long:
@@ -551,7 +623,8 @@ ECPGexecute(struct statement * stmt)
 					else
 						sprintf(mallocedval, "%lu", *((unsigned long *) var->value));
 
-					tobeinserted = mallocedval;
+					*tobeinserted_p = mallocedval;
+					*malloced_p = true;
 					break;
 #ifdef HAVE_LONG_LONG_INT_64
 				case ECPGt_long_long:
@@ -570,7 +643,8 @@ ECPGexecute(struct statement * stmt)
 					else
 						sprintf(mallocedval, "%lld", *((long long *) var->value));
 
-					tobeinserted = mallocedval;
+					*tobeinserted_p = mallocedval;
+					*malloced_p = true;
 					break;
 
 				case ECPGt_unsigned_long_long:
@@ -589,7 +663,8 @@ ECPGexecute(struct statement * stmt)
 					else
 						sprintf(mallocedval, "%llu", *((unsigned long long *) var->value));
 
-					tobeinserted = mallocedval;
+					*tobeinserted_p = mallocedval;
+					*malloced_p = true;
 					break;
 #endif	 /* HAVE_LONG_LONG_INT_64 */
 				case ECPGt_float:
@@ -608,7 +683,8 @@ ECPGexecute(struct statement * stmt)
 					else
 						sprintf(mallocedval, "%.14g", *((float *) var->value));
 
-					tobeinserted = mallocedval;
+					*tobeinserted_p = mallocedval;
+					*malloced_p = true;
 					break;
 
 				case ECPGt_double:
@@ -627,7 +703,8 @@ ECPGexecute(struct statement * stmt)
 					else
 						sprintf(mallocedval, "%.14g", *((double *) var->value));
 
-					tobeinserted = mallocedval;
+					*tobeinserted_p = mallocedval;
+					*malloced_p = true;
 					break;
 
 				case ECPGt_bool:
@@ -664,7 +741,8 @@ ECPGexecute(struct statement * stmt)
 							ECPGraise(stmt->lineno, ECPG_CONVERT_BOOL, "different size");
 					}
 
-					tobeinserted = mallocedval;
+					*tobeinserted_p = mallocedval;
+					*malloced_p = true;
 					break;
 
 				case ECPGt_char:
@@ -685,7 +763,8 @@ ECPGexecute(struct statement * stmt)
 
 						free(newcopy);
 
-						tobeinserted = mallocedval;
+						*tobeinserted_p = mallocedval;
+						*malloced_p = true;
 					}
 					break;
 				case ECPGt_char_variable:
@@ -698,7 +777,8 @@ ECPGexecute(struct statement * stmt)
 						strncpy(mallocedval, (char *) var->value, slen);
 						mallocedval[slen] = '\0';
 
-						tobeinserted = mallocedval;
+						*tobeinserted_p = mallocedval;
+						*malloced_p = true;
 					}
 					break;
 				case ECPGt_varchar:
@@ -718,7 +798,8 @@ ECPGexecute(struct statement * stmt)
 
 						free(newcopy);
 
-						tobeinserted = mallocedval;
+						*tobeinserted_p = mallocedval;
+						*malloced_p = true;
 					}
 					break;
 
@@ -729,9 +810,38 @@ ECPGexecute(struct statement * stmt)
 					break;
 			}
 		}
-		else
-			tobeinserted = buff;
+	return true;
+}
 
+static bool
+ECPGexecute(struct statement * stmt)
+{
+	bool		status = false;
+	char	   *copiedquery;
+	PGresult   *results;
+	PGnotify   *notify;
+	struct variable *var;
+
+	copiedquery = ecpg_strdup(stmt->command, stmt->lineno);
+
+	/*
+	 * Now, if the type is one of the fill in types then we take the
+	 * argument and enter that in the string at the first %s position.
+	 * Then if there are any more fill in types we fill in at the next and
+	 * so on.
+	 */
+	var = stmt->inlist;
+	while (var)
+	{
+		char 	   *newcopy = NULL;
+		const char *tobeinserted = NULL;
+		char	   *p;
+		bool	   malloced=FALSE;
+		int		   hostvarl = 0;
+
+		if (!ECPGstore_input(stmt, var, &tobeinserted, &malloced))
+			return false;
+			
 		/*
 		 * Now tobeinserted points to an area that is to be inserted at
 		 * the first %s
@@ -770,10 +880,10 @@ ECPGexecute(struct statement * stmt)
 		 * oldcopy and let the copiedquery get the var->value from the
 		 * newcopy.
 		 */
-		if (mallocedval != NULL)
+		if (malloced)
 		{
-			free(mallocedval);
-			mallocedval = NULL;
+			free((char*)tobeinserted);
+			tobeinserted = NULL;
 		}
 
 		free(copiedquery);
@@ -823,9 +933,7 @@ ECPGexecute(struct statement * stmt)
 		{
 				int			nfields,
 							ntuples,
-							act_tuple,
-							act_field,
-							isarray;
+							act_field;
 
 			case PGRES_TUPLES_OK:
 				nfields = PQnfields(results);
@@ -861,83 +969,9 @@ ECPGexecute(struct statement * stmt)
 						ECPGraise(stmt->lineno, ECPG_TOO_FEW_ARGUMENTS, NULL);
 						return (false);
 					}
+					
+					status = ECPGstore_result(results, act_field, stmt, var);
 
-					isarray = ECPGis_type_an_array(PQftype(results, act_field), stmt, var);
-
-					if (!isarray)
-					{
-
-						/*
-						 * if we don't have enough space, we cannot read
-						 * all tuples
-						 */
-						if ((var->arrsize > 0 && ntuples > var->arrsize) || (var->ind_arrsize > 0 && ntuples > var->ind_arrsize))
-						{
-							ECPGlog("ECPGexecute line %d: Incorrect number of matches: %d don't fit into array of %d\n",
-									stmt->lineno, ntuples, var->arrsize);
-							ECPGraise(stmt->lineno, ECPG_TOO_MANY_MATCHES, NULL);
-							status = false;
-							break;
-						}
-					}
-					else
-					{
-
-						/*
-						 * since we read an array, the variable has to be
-						 * an array too
-						 */
-						if (var->arrsize == 0)
-						{
-							ECPGlog("ECPGexecute line %d: variable is not an array\n");
-							ECPGraise(stmt->lineno, ECPG_NO_ARRAY, NULL);
-							status = false;
-							break;
-						}
-					}
-
-					/*
-					 * allocate memory for NULL pointers
-					 */
-					if ((var->arrsize == 0 || var->varcharsize == 0) && var->value == NULL)
-					{
-						int			len = 0;
-
-						switch (var->type)
-						{
-							case ECPGt_char:
-							case ECPGt_unsigned_char:
-								var->varcharsize = 0;
-								/* check strlen for each tuple */
-								for (act_tuple = 0; act_tuple < ntuples; act_tuple++)
-								{
-									int			len = strlen(PQgetvalue(results, act_tuple, act_field)) + 1;
-
-									if (len > var->varcharsize)
-										var->varcharsize = len;
-								}
-								var->offset *= var->varcharsize;
-								len = var->offset * ntuples;
-								break;
-							case ECPGt_varchar:
-								len = ntuples * (var->varcharsize + sizeof(int));
-								break;
-							default:
-								len = var->offset * ntuples;
-								break;
-						}
-						var->value = (void *) ecpg_alloc(len, stmt->lineno);
-						*((void **) var->pointer) = var->value;
-						add_mem(var->value, stmt->lineno);
-					}
-
-					for (act_tuple = 0; act_tuple < ntuples && status; act_tuple++)
-					{
-						if (!get_data(results, act_tuple, act_field, stmt->lineno,
-									var->type, var->ind_type, var->value,
-									  var->ind_value, var->varcharsize, var->offset, isarray))
-							status = false;
-					}
 					var = var->next;
 				}
 
@@ -1006,26 +1040,23 @@ ECPGdo(int lineno, const char *connection_name, char *query,...)
 	va_list		args;
 	struct statement *stmt;
 	struct connection *con = get_connection(connection_name);
-	bool		status;
-	char	   	*oldlocale;
+	bool		status = true;
+	char	   	*locale;
 
 	/* Make sure we do NOT honor the locale for numeric input/output */
 	/* since the database wants the standard decimal point */
-	oldlocale = strdup(setlocale(LC_NUMERIC, NULL));
-	setlocale(LC_NUMERIC, "C");
+	locale = setlocale(LC_NUMERIC, "C");
 
 	if (!ecpg_init(con, connection_name, lineno))
 	{
-		setlocale(LC_NUMERIC, oldlocale);
-		free(oldlocale);
+		setlocale(LC_NUMERIC, locale);
 		return (false);
 	}
 
 	va_start(args, query);
 	if (create_statement(lineno, con, &stmt, query, args) == false)
 	{
-		setlocale(LC_NUMERIC, oldlocale);
-		free(oldlocale);
+		setlocale(LC_NUMERIC, locale);
 		return (false);
 	}
 	va_end(args);
@@ -1036,8 +1067,7 @@ ECPGdo(int lineno, const char *connection_name, char *query,...)
 		free_statement(stmt);
 		ECPGlog("ECPGdo: not connected to %s\n", con->name);
 		ECPGraise(lineno, ECPG_NOT_CONN, NULL);
-		setlocale(LC_NUMERIC, oldlocale);
-		free(oldlocale);
+		setlocale(LC_NUMERIC, locale);
 		return false;
 	}
 
@@ -1045,9 +1075,7 @@ ECPGdo(int lineno, const char *connection_name, char *query,...)
 	free_statement(stmt);
 
 	/* and reset locale value so our application is not affected */
-	setlocale(LC_NUMERIC, oldlocale);
-	free(oldlocale);
-
+	setlocale(LC_NUMERIC, locale);
 	return (status);
 }
 
diff --git a/src/interfaces/ecpg/lib/extern.h b/src/interfaces/ecpg/lib/extern.h
index 3186b5b11025130b0c7df6cbdacc9a0fe733237c..971924e708a6c8ab71e2108fb2f1a32e76265ef4 100644
--- a/src/interfaces/ecpg/lib/extern.h
+++ b/src/interfaces/ecpg/lib/extern.h
@@ -4,7 +4,7 @@
 /* Here are some methods used by the lib. */
 /* Returns a pointer to a string containing a simple type name. */
 void		free_auto_mem(void);
-bool get_data(PGresult *, int, int, int, enum ECPGttype type,
+bool get_data(const PGresult *, int, int, int, enum ECPGttype type,
 		 enum ECPGttype, void *, void *, long, long, bool);
 struct connection *get_connection(const char *);
 void		init_sqlca(void);
@@ -14,6 +14,7 @@ char	   *ecpg_strdup(const char *, int);
 const char *ECPGtype_name(enum ECPGttype);
 unsigned int ECPGDynamicType(Oid);
 
+
 /* A generic varchar type. */
 struct ECPGgeneric_varchar
 {
@@ -63,3 +64,7 @@ struct descriptor
 
 PGresult **
 ECPGdescriptor_lvalue(int line, const char *descriptor);
+
+bool
+ECPGstore_result(const PGresult *results, int act_field, 
+			const struct statement * stmt, struct variable *var);
diff --git a/src/interfaces/ecpg/preproc/preproc.y b/src/interfaces/ecpg/preproc/preproc.y
index 31a1cb42d4de9625ede555d262bbe6b2cb06c08f..e348f773c745e18630e38ab5d949768be11861bb 100644
--- a/src/interfaces/ecpg/preproc/preproc.y
+++ b/src/interfaces/ecpg/preproc/preproc.y
@@ -1552,7 +1552,7 @@ drop_type:	TABLE		{ $$ = make_str("table"); }
  *****************************************************************************/
 TruncateStmt:  TRUNCATE opt_table relation_name
                                {
-					$$ = cat2_str(make_str("drop table"), $3);
+					$$ = cat2_str(make_str("truncate table"), $3);
                                }
                        ;