diff --git a/src/interfaces/ecpg/ChangeLog b/src/interfaces/ecpg/ChangeLog
index 647f649438a6a54d10b7884f0dd2ae5fa4c2beb3..82d28b80bc5948cb4bea5e35e6d6e9e5795cd284 100644
--- a/src/interfaces/ecpg/ChangeLog
+++ b/src/interfaces/ecpg/ChangeLog
@@ -933,5 +933,12 @@ Mon Sep  4 14:10:38 PDT 2000
 Mon Sep 18 13:55:11 PDT 2000
 
 	- Added int8 support based on a patch by Martijn Schoemaker <martijn@osp.nl>
+
+Mit Sep 20 12:40:27 PDT 2000
+
+	- Added patch by Christof Petig <christof.petig@wtal.de> to process
+	  backend NOTICEs.
+	- Added patch by Christof Petig <christof.petig@wtal.de> to cache
+	  type information.
 	- Set ecpg version to 2.8.0. 
 	- Set library version to 3.2.0.
diff --git a/src/interfaces/ecpg/include/ecpgerrno.h b/src/interfaces/ecpg/include/ecpgerrno.h
index 2a826988be5ea1b8a03481818c57db99a5a024fd..58e70a0752bcc56433066db6f258bd9e2af38333 100644
--- a/src/interfaces/ecpg/include/ecpgerrno.h
+++ b/src/interfaces/ecpg/include/ecpgerrno.h
@@ -43,4 +43,19 @@
 #define ECPG_TRANS			-401
 #define ECPG_CONNECT			-402
 
+/* backend notices, starting at 600 */
+#define ECPG_NOTICE_UNRECOGNIZED       -600
+               /* NOTICE:  (transaction aborted): queries ignored until END */
+               /* NOTICE:  current transaction is aborted, queries ignored until end of transaction block */
+#define ECPG_NOTICE_QUERY_IGNORED      -601
+               /* NOTICE:  PerformPortalClose: portal "*" not found */
+#define ECPG_NOTICE_UNKNOWN_PORTAL     -602
+               /* NOTICE:  BEGIN: already a transaction in progress */
+#define ECPG_NOTICE_IN_TRANSACTION     -603
+               /* NOTICE:  AbortTransaction and not in in-progress state */
+               /* NOTICE:  COMMIT: no transaction in progress */
+#define ECPG_NOTICE_NO_TRANSACTION     -604
+               /* NOTICE:  BlankPortalAssignName: portal * already exists */
+#define ECPG_NOTICE_PORTAL_EXISTS      -605
+                                        
 #endif	 /* !_ECPG_ERROR_H */
diff --git a/src/interfaces/ecpg/include/sqlca.h b/src/interfaces/ecpg/include/sqlca.h
index da1fdee4f35043f51de3c087837fbe100c4201f0..9bc958a1af77256b87e2325ac1d63c99d22a6ffa 100644
--- a/src/interfaces/ecpg/include/sqlca.h
+++ b/src/interfaces/ecpg/include/sqlca.h
@@ -22,23 +22,22 @@ extern		"C"
 		long		sqlerrd[6];
 		/* Element 0: empty						*/
 		/* 1: OID of processed tuple if applicable			*/
-		/* 2: number of rows processed	*/
-		/* after an INSERT, UPDATE or */
-		/* DELETE statement			 */
+		/* 2: number of rows processed				*/
+		/* after an INSERT, UPDATE or 				*/
+		/* DELETE statement					*/
 		/* 3: empty						*/
 		/* 4: empty						*/
 		/* 5: empty						*/
 		char		sqlwarn[8];
-		/* Element 0: set to 'W' if at least one other is 'W' */
-		/* 1: if 'W' at least one character string	  */
-		/* value was truncated when it was		   */
-		/* stored into a host variable.			   */
-		/* 2: empty									  */
-		/* 3: empty									  */
-		/* 4: empty									  */
-		/* 5: empty									  */
-		/* 6: empty									  */
-		/* 7: empty									  */
+		/* Element 0: set to 'W' if at least one other is 'W' 	*/
+		/* 1: if 'W' at least one character string	  	*/
+		/* value was truncated when it was		   	*/
+		/* stored into a host variable.			   	*/
+		/* 2: if 'W' a (hopefully) non-fatal notice occured 	*/		/* 3: empty									  */
+		/* 4: empty						*/
+		/* 5: empty						*/
+		/* 6: empty						*/
+		/* 7: empty						*/
 
 		char		sqlext[8];
 	};
diff --git a/src/interfaces/ecpg/lib/connect.c b/src/interfaces/ecpg/lib/connect.c
index 416fcf17dd400e361bc0135d953344c56a2c5c9d..59a3f794851dc995127d9d78079ea1dd980701f2 100644
--- a/src/interfaces/ecpg/lib/connect.c
+++ b/src/interfaces/ecpg/lib/connect.c
@@ -27,6 +27,8 @@ ecpg_finish(struct connection * act)
 {
 	if (act != NULL)
 	{
+		struct ECPGtype_information_cache *cache, *ptr;
+		
 		ECPGlog("ecpg_finish: finishing %s.\n", act->name);
 		PQfinish(act->connection);
 
@@ -45,6 +47,7 @@ ecpg_finish(struct connection * act)
 		if (actual_connection == act)
 			actual_connection = all_connections;
 
+		for (cache = act->cache_head; cache; ptr = cache, cache = cache->next, free(ptr));
 		free(act->name);
 		free(act);
 	}
@@ -107,6 +110,120 @@ ECPGsetconn(int lineno, const char *connection_name)
 	return true;
 }
 
+static void
+ECPGnoticeProcessor_raise(int code, const char *message)
+{
+	sqlca.sqlcode = code;
+	strncpy(sqlca.sqlerrm.sqlerrmc, message, sizeof(sqlca.sqlerrm.sqlerrmc));
+	sqlca.sqlerrm.sqlerrmc[sizeof(sqlca.sqlerrm.sqlerrmc)-1]=0;
+	sqlca.sqlerrm.sqlerrml = strlen(sqlca.sqlerrm.sqlerrmc);
+	
+	// remove trailing newline
+	if (sqlca.sqlerrm.sqlerrml 
+		&& sqlca.sqlerrm.sqlerrmc[sqlca.sqlerrm.sqlerrml-1]=='\n')
+	{
+		sqlca.sqlerrm.sqlerrmc[sqlca.sqlerrm.sqlerrml-1]=0;
+		sqlca.sqlerrm.sqlerrml--;
+	}
+	
+	ECPGlog("raising sqlcode %d\n",code);
+}
+
+/* 
+ * I know this is a mess, but we can't redesign the backend 
+ */
+
+static void
+ECPGnoticeProcessor(void *arg, const char *message)
+{
+	/* these notices raise an error */	
+	if (strncmp(message,"NOTICE: ",8))
+	{
+		ECPGlog("ECPGnoticeProcessor: strange notice '%s'\n", message);
+		ECPGnoticeProcessor_raise(ECPG_NOTICE_UNRECOGNIZED, message);
+		return;
+	}
+	
+	message+=8;
+	while (*message==' ') message++;
+	ECPGlog("NOTICE: %s", message);
+		
+	/* NOTICE:  (transaction aborted): queries ignored until END */
+	/* NOTICE:  current transaction is aborted, queries ignored until end of transaction block */
+	if (strstr(message,"queries ignored") && strstr(message,"transaction")
+		&& strstr(message,"aborted"))
+	{
+		ECPGnoticeProcessor_raise(ECPG_NOTICE_QUERY_IGNORED, message);
+		return;
+	}
+	
+	/* NOTICE:  PerformPortalClose: portal "*" not found */
+	if (!strncmp(message,"PerformPortalClose: portal",26) 
+		&& strstr(message+26,"not found"))
+	{
+		ECPGnoticeProcessor_raise(ECPG_NOTICE_UNKNOWN_PORTAL, message);
+		return;
+	}
+	
+	/* NOTICE:  BEGIN: already a transaction in progress */
+	if (!strncmp(message,"BEGIN: already a transaction in progress",40))
+	{
+		ECPGnoticeProcessor_raise(ECPG_NOTICE_IN_TRANSACTION, message);
+		return;
+	}
+	
+	/* NOTICE:  AbortTransaction and not in in-progress state */
+	/* NOTICE:  COMMIT: no transaction in progress */
+	/* NOTICE:  ROLLBACK: no transaction in progress */
+	if (!strncmp(message,"AbortTransaction and not in in-progress state",45)
+		|| !strncmp(message,"COMMIT: no transaction in progress",34)
+		|| !strncmp(message,"ROLLBACK: no transaction in progress",36))
+	{
+		ECPGnoticeProcessor_raise(ECPG_NOTICE_NO_TRANSACTION, message);
+		return;
+	}
+	
+	/* NOTICE:  BlankPortalAssignName: portal * already exists */
+	if (!strncmp(message,"BlankPortalAssignName: portal",29)
+			&& strstr(message+29,"already exists"))
+	{
+		ECPGnoticeProcessor_raise(ECPG_NOTICE_PORTAL_EXISTS, message);
+		return;
+	}
+
+	/* these are harmless - do nothing */
+	/* NOTICE:  CREATE TABLE/PRIMARY KEY will create implicit index '*' for table '*' */
+	/* NOTICE:  ALTER TABLE ... ADD CONSTRAINT will create implicit trigger(s) for FOREIGN KEY check(s) */
+	/* NOTICE:  CREATE TABLE will create implicit sequence '*' for SERIAL column '*.*' */
+	/* NOTICE:  CREATE TABLE will create implicit trigger(s) for FOREIGN KEY check(s) */
+	if ((!strncmp(message,"CREATE TABLE",12) || !strncmp(message,"ALTER TABLE",11))
+			&& strstr(message+11,"will create implicit"))
+		return;
+	
+	/* NOTICE:  QUERY PLAN: */
+	if (!strncmp(message,"QUERY PLAN:",11)) // do we really see these?
+		return;
+	
+	/* NOTICE:  DROP TABLE implicitly drops referential integrity trigger from table "*" */
+	if (!strncmp(message,"DROP TABLE implicitly drops",27))
+		return;
+	
+	/* NOTICE:  Caution: DROP INDEX cannot be rolled back, so don't abort now */
+	if (strstr(message,"cannot be rolled back"))
+		return;
+
+	/* these and other unmentioned should set sqlca.sqlwarn[2] */
+	/* NOTICE:  The ':' operator is deprecated.  Use exp(x) instead. */
+	/* NOTICE:  Rel *: Uninitialized page 0 - fixing */
+	/* NOTICE:  PortalHeapMemoryFree: * not in alloc set! */
+	/* NOTICE:  Too old parent tuple found - can't continue vc_repair_frag */
+	/* NOTICE:  identifier "*" will be truncated to "*" */
+	/* NOTICE:  InvalidateSharedInvalid: cache state reset */
+	/* NOTICE:  RegisterSharedInvalid: SI buffer overflow */
+	sqlca.sqlwarn[2]='W';
+	sqlca.sqlwarn[0]='W';
+}
+
 bool
 ECPGconnect(int lineno, const char *dbname, const char *user, const char *passwd, const char *connection_name, int autocommit)
 {
@@ -119,12 +236,14 @@ ECPGconnect(int lineno, const char *dbname, const char *user, const char *passwd
 
 	if (dbname == NULL && connection_name == NULL)
 		connection_name = "DEFAULT";
-
+		
 	/* add connection to our list */
 	if (connection_name != NULL)
 		this->name = ecpg_strdup(connection_name, lineno);
 	else
 		this->name = ecpg_strdup(dbname, lineno);
+		
+	this->cache_head = NULL;
 
 	if (all_connections == NULL)
 		this->next = NULL;
@@ -147,6 +266,8 @@ ECPGconnect(int lineno, const char *dbname, const char *user, const char *passwd
 
 	this->committed = true;
 	this->autocommit = autocommit;
+	
+	PQsetNoticeProcessor(this->connection,&ECPGnoticeProcessor,(void*)this);
 
 	return true;
 }
diff --git a/src/interfaces/ecpg/lib/descriptor.c b/src/interfaces/ecpg/lib/descriptor.c
index 374232553364d3498bba1923e12ad83c7b8d31a0..3363381d90cb4d0a8d1634a891781102118d0a6b 100644
--- a/src/interfaces/ecpg/lib/descriptor.c
+++ b/src/interfaces/ecpg/lib/descriptor.c
@@ -302,10 +302,10 @@ ECPGdeallocate_desc(int line, const char *name)
 bool
 ECPGallocate_desc(int line, const char *name)
 {
-	struct descriptor *new = (struct descriptor *) malloc(sizeof(struct descriptor));
+	struct descriptor *new = (struct descriptor *) ecpg_alloc(sizeof(struct descriptor), line);
 
 	new->next = all_descriptors;
-	new->name = malloc(strlen(name) + 1);
+	new->name = ecpg_alloc(strlen(name) + 1, line);
 	new->result = PQmakeEmptyPGresult(NULL, 0);
 	strcpy(new->name, name);
 	all_descriptors = new;
diff --git a/src/interfaces/ecpg/lib/execute.c b/src/interfaces/ecpg/lib/execute.c
index 0741db622aac7f165943cd55873b216f47ce0661..762aab49c7e2081f8b50516d0e2f1c29fd62aeec 100644
--- a/src/interfaces/ecpg/lib/execute.c
+++ b/src/interfaces/ecpg/lib/execute.c
@@ -15,6 +15,8 @@
 #include <stdio.h>
 #include <locale.h>
 
+#include "pg_type.h"
+
 #include "ecpgtype.h"
 #include "ecpglib.h"
 #include "ecpgerrno.h"
@@ -252,13 +254,110 @@ next_insert(char *text)
 	return (*ptr == '\0') ? NULL : ptr;
 }
 
+/*
+ * push a value on the cache
+ */
+
+static void
+ECPGtypeinfocache_push(struct ECPGtype_information_cache **cache, int oid, bool isarray, int lineno)
+{
+	struct ECPGtype_information_cache	*new_entry 
+						= ecpg_alloc(sizeof(struct ECPGtype_information_cache), lineno);
+	new_entry->oid = oid;
+	new_entry->isarray = isarray;
+	new_entry->next = *cache;
+	*cache = new_entry;
+}
+
+static bool
+ECPGis_type_an_array(int type,const struct statement * stmt,const struct variable *var)
+{
+	char	   *array_query;
+	int		isarray = 0;
+	PGresult	*query;
+	struct ECPGtype_information_cache	*cache_entry;
+	
+	if ((stmt->connection->cache_head)==NULL)
+	{	
+		/* populate cache with well known types to speed things up */
+		ECPGtypeinfocache_push(&(stmt->connection->cache_head),  BOOLOID, false, stmt->lineno);
+		ECPGtypeinfocache_push(&(stmt->connection->cache_head),  BYTEAOID, true, stmt->lineno);
+		ECPGtypeinfocache_push(&(stmt->connection->cache_head),  CHAROID, false, stmt->lineno);
+		ECPGtypeinfocache_push(&(stmt->connection->cache_head),  NAMEOID, true, stmt->lineno);
+		ECPGtypeinfocache_push(&(stmt->connection->cache_head),  INT8OID, false, stmt->lineno);
+		ECPGtypeinfocache_push(&(stmt->connection->cache_head),  INT2OID, false, stmt->lineno);
+		ECPGtypeinfocache_push(&(stmt->connection->cache_head),  INT2VECTOROID, true, stmt->lineno);
+		ECPGtypeinfocache_push(&(stmt->connection->cache_head),  INT4OID, false, stmt->lineno);
+		ECPGtypeinfocache_push(&(stmt->connection->cache_head),  REGPROCOID, false, stmt->lineno);
+		ECPGtypeinfocache_push(&(stmt->connection->cache_head),  TEXTOID, true, stmt->lineno);
+		ECPGtypeinfocache_push(&(stmt->connection->cache_head),  OIDOID, false, stmt->lineno);
+		ECPGtypeinfocache_push(&(stmt->connection->cache_head),  TIDOID, false, stmt->lineno);
+		ECPGtypeinfocache_push(&(stmt->connection->cache_head),  XIDOID, false, stmt->lineno);
+		ECPGtypeinfocache_push(&(stmt->connection->cache_head),  CIDOID, false, stmt->lineno);
+		ECPGtypeinfocache_push(&(stmt->connection->cache_head),  OIDVECTOROID, true, stmt->lineno);
+		ECPGtypeinfocache_push(&(stmt->connection->cache_head),  POINTOID, true, stmt->lineno);
+		ECPGtypeinfocache_push(&(stmt->connection->cache_head),  LSEGOID, true, stmt->lineno);
+		ECPGtypeinfocache_push(&(stmt->connection->cache_head),  PATHOID, true, stmt->lineno);
+		ECPGtypeinfocache_push(&(stmt->connection->cache_head),  BOXOID, true, stmt->lineno);
+		ECPGtypeinfocache_push(&(stmt->connection->cache_head),  POLYGONOID, false, stmt->lineno);
+		ECPGtypeinfocache_push(&(stmt->connection->cache_head),  LINEOID, true, stmt->lineno);
+		ECPGtypeinfocache_push(&(stmt->connection->cache_head),  FLOAT4OID, false, stmt->lineno);
+		ECPGtypeinfocache_push(&(stmt->connection->cache_head),  FLOAT8OID, false, stmt->lineno);
+		ECPGtypeinfocache_push(&(stmt->connection->cache_head),  ABSTIMEOID, false, stmt->lineno);
+		ECPGtypeinfocache_push(&(stmt->connection->cache_head),  RELTIMEOID, false, stmt->lineno);
+		ECPGtypeinfocache_push(&(stmt->connection->cache_head),  TINTERVALOID, false, stmt->lineno);
+		ECPGtypeinfocache_push(&(stmt->connection->cache_head),  UNKNOWNOID, true, stmt->lineno);
+		ECPGtypeinfocache_push(&(stmt->connection->cache_head),  CIRCLEOID, false, stmt->lineno);
+		ECPGtypeinfocache_push(&(stmt->connection->cache_head),  CASHOID, false, stmt->lineno);
+		ECPGtypeinfocache_push(&(stmt->connection->cache_head),  INETOID, false, stmt->lineno);
+		ECPGtypeinfocache_push(&(stmt->connection->cache_head),  CIDROID, false, stmt->lineno);
+		ECPGtypeinfocache_push(&(stmt->connection->cache_head),  BPCHAROID, false, stmt->lineno);
+		ECPGtypeinfocache_push(&(stmt->connection->cache_head),  VARCHAROID, false, stmt->lineno);
+		ECPGtypeinfocache_push(&(stmt->connection->cache_head),  DATEOID, false, stmt->lineno);
+		ECPGtypeinfocache_push(&(stmt->connection->cache_head),  TIMEOID, false, stmt->lineno);
+		ECPGtypeinfocache_push(&(stmt->connection->cache_head),  TIMESTAMPOID, false, stmt->lineno);
+		ECPGtypeinfocache_push(&(stmt->connection->cache_head),  INTERVALOID, false, stmt->lineno);
+		ECPGtypeinfocache_push(&(stmt->connection->cache_head),  TIMETZOID, false, stmt->lineno);
+		ECPGtypeinfocache_push(&(stmt->connection->cache_head),  ZPBITOID, false, stmt->lineno);
+		ECPGtypeinfocache_push(&(stmt->connection->cache_head),  VARBITOID, false, stmt->lineno);
+		ECPGtypeinfocache_push(&(stmt->connection->cache_head),  NUMERICOID, false, stmt->lineno);
+	}
+
+	for (cache_entry = (stmt->connection->cache_head);cache_entry != NULL;cache_entry=cache_entry->next)
+	{
+		if (cache_entry->oid==type) 
+			return cache_entry->isarray;
+	}
+		
+	array_query = (char *) ecpg_alloc(strlen("select typelem from pg_type where oid=") + 11, stmt->lineno);
+	sprintf(array_query, "select typelem from pg_type where oid=%d", type);
+	query = PQexec(stmt->connection->connection, array_query);
+	if (PQresultStatus(query) == PGRES_TUPLES_OK)
+	{
+		isarray = atol((char *) PQgetvalue(query, 0, 0));
+		if (ECPGDynamicType(type) == SQL3_CHARACTER ||
+			ECPGDynamicType(type) == SQL3_CHARACTER_VARYING)
+		{
+
+			/*
+			 * arrays of character strings are not yet
+			 * implemented
+			 */
+			isarray = false;
+		}
+		ECPGlog("ECPGexecute line %d: TYPE database: %d C: %d array: %s\n", stmt->lineno, type, var->type, isarray ? "yes" : "no");
+		ECPGtypeinfocache_push(&(stmt->connection->cache_head), type, isarray, stmt->lineno);
+	}
+	PQclear(query);
+	return isarray;
+}
+
 static bool
 ECPGexecute(struct statement * stmt)
 {
 	bool		status = false;
 	char	   *copiedquery;
-	PGresult   *results,
-			   *query;
+	PGresult   *results;
 	PGnotify   *notify;
 	struct variable *var;
 
@@ -700,8 +799,6 @@ ECPGexecute(struct statement * stmt)
 
 				for (act_field = 0; act_field < nfields && status; act_field++)
 				{
-					char	   *array_query;
-
 					if (var == NULL)
 					{
 						ECPGlog("ECPGexecute line %d: Too few arguments.\n", stmt->lineno);
@@ -709,26 +806,7 @@ ECPGexecute(struct statement * stmt)
 						return (false);
 					}
 
-					array_query = (char *) ecpg_alloc(strlen("select typelem from pg_type where oid=") + 11, stmt->lineno);
-					sprintf(array_query, "select typelem from pg_type where oid=%d", PQftype(results, act_field));
-					query = PQexec(stmt->connection->connection, array_query);
-					isarray = 0;
-					if (PQresultStatus(query) == PGRES_TUPLES_OK)
-					{
-						isarray = atol((char *) PQgetvalue(query, 0, 0));
-						if (ECPGDynamicType(PQftype(results, act_field)) == SQL3_CHARACTER ||
-							ECPGDynamicType(PQftype(results, act_field)) == SQL3_CHARACTER_VARYING)
-						{
-
-							/*
-							 * arrays of character strings are not yet
-							 * implemented
-							 */
-							isarray = false;
-						}
-						ECPGlog("ECPGexecute line %d: TYPE database: %d C: %d array: %s\n", stmt->lineno, PQftype(results, act_field), var->type, isarray ? "yes" : "no");
-					}
-					PQclear(query);
+					isarray = ECPGis_type_an_array(PQftype(results, act_field), stmt, var);
 
 					if (!isarray)
 					{
@@ -911,7 +989,7 @@ ECPGdo(int lineno, const char *connection_name, char *query,...)
  *
  * Copyright (c) 2000, Christof Petig <christof.petig@wtal.de>
  *
- * $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/execute.c,v 1.8 2000/09/19 11:47:13 meskes Exp $
+ * $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/execute.c,v 1.9 2000/09/20 13:25:51 meskes Exp $
  */
 
 PGconn	   *ECPG_internal_get_connection(char *name);
diff --git a/src/interfaces/ecpg/lib/extern.h b/src/interfaces/ecpg/lib/extern.h
index db2f3a7d419f26e5980098e64a7fecb98fe0de3e..780fc933bb8253750a497d33f59bf149552fa1d8 100644
--- a/src/interfaces/ecpg/lib/extern.h
+++ b/src/interfaces/ecpg/lib/extern.h
@@ -21,6 +21,17 @@ struct ECPGgeneric_varchar
 	char		arr[1];
 };
 
+/*
+ * type information cache
+ */
+ 
+struct ECPGtype_information_cache
+{
+	struct ECPGtype_information_cache	*next;
+	int		oid;
+	bool	isarray;
+};
+
 /* structure to store one statement */
 struct statement
 {
@@ -36,7 +47,8 @@ struct connection
 {
 	char	   *name;
 	PGconn	   *connection;
-	bool		committed;
-	int			autocommit;
+	bool	    committed;
+	int	    autocommit;
+	struct ECPGtype_information_cache        *cache_head;
 	struct connection *next;
 };
diff --git a/src/interfaces/ecpg/lib/pg_type.h b/src/interfaces/ecpg/lib/pg_type.h
new file mode 100644
index 0000000000000000000000000000000000000000..e265de3b0c4c2dbd54d1df870ad34c2861568777
--- /dev/null
+++ b/src/interfaces/ecpg/lib/pg_type.h
@@ -0,0 +1,72 @@
+/*-------------------------------------------------------------------------
+ *
+ * pg_type.h
+ *	  definition of the system "type" relation (pg_type)
+ *	  along with the relation's initial contents.
+ *
+ *
+ * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * $Id: pg_type.h,v 1.1 2000/09/20 13:25:51 meskes Exp $
+ *
+ * NOTES
+ *	  the genbki.sh script reads this file and generates .bki
+ *	  information from the DATA() statements.
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef PG_TYPE_H
+#define PG_TYPE_H
+
+/* ----------------
+ *		initial contents of pg_type
+ * ----------------
+ */
+
+/* keep the following ordered by OID so that later changes can be made easier*/
+
+/* OIDS 1 - 99 */
+#define BOOLOID			16
+#define BYTEAOID		17
+#define CHAROID			18
+#define NAMEOID			19
+#define INT8OID			20
+#define INT2OID			21
+#define INT2VECTOROID	22
+#define INT4OID			23
+#define REGPROCOID		24
+#define TEXTOID			25
+#define OIDOID			26
+#define TIDOID		27
+#define XIDOID 28
+#define CIDOID 29
+#define OIDVECTOROID	30
+#define POINTOID		600
+#define LSEGOID			601
+#define PATHOID			602
+#define BOXOID			603
+#define POLYGONOID		604
+#define LINEOID			628
+#define FLOAT4OID 700
+#define FLOAT8OID 701
+#define ABSTIMEOID		702
+#define RELTIMEOID		703
+#define TINTERVALOID	704
+#define UNKNOWNOID		705
+#define CIRCLEOID		718
+#define CASHOID 790
+#define INETOID 869
+#define CIDROID 650
+#define BPCHAROID		1042
+#define VARCHAROID		1043
+#define DATEOID			1082
+#define TIMEOID			1083
+#define TIMESTAMPOID	1184
+#define INTERVALOID		1186
+#define TIMETZOID		1266
+#define ZPBITOID	 1560
+#define VARBITOID	  1562
+#define NUMERICOID		1700
+
+#endif	 /* PG_TYPE_H */
diff --git a/src/interfaces/ecpg/lib/typename.c b/src/interfaces/ecpg/lib/typename.c
index c66ed7709dd950d53bc3115c6cd1048dd9513c8e..a638c7d76669e5a018719fe0f1e12de3ae0f91f3 100644
--- a/src/interfaces/ecpg/lib/typename.c
+++ b/src/interfaces/ecpg/lib/typename.c
@@ -3,6 +3,7 @@
 #include "ecpglib.h"
 #include "extern.h"
 #include "sql3types.h"
+#include "pg_type.h"
 
 /*
  * This function is used to generate the correct type names.
@@ -12,7 +13,7 @@ ECPGtype_name(enum ECPGttype typ)
 {
 	switch (typ)
 	{
-			case ECPGt_char:
+		case ECPGt_char:
 			return "char";
 		case ECPGt_unsigned_char:
 			return "unsigned char";
@@ -53,31 +54,18 @@ ECPGDynamicType(Oid type)
 {
 	switch (type)
 	{
-			case 16:return SQL3_BOOLEAN;		/* bool */
-		case 21:
-			return SQL3_SMALLINT;		/* int2 */
-		case 23:
-			return SQL3_INTEGER;/* int4 */
-		case 25:
-			return SQL3_CHARACTER;		/* text */
-		case 700:
-			return SQL3_REAL;	/* float4 */
-		case 701:
-			return SQL3_DOUBLE_PRECISION;		/* float8 */
-		case 1042:
-			return SQL3_CHARACTER;		/* bpchar */
-		case 1043:
-			return SQL3_CHARACTER_VARYING;		/* varchar */
-		case 1082:
-			return SQL3_DATE_TIME_TIMESTAMP;	/* date */
-		case 1083:
-			return SQL3_DATE_TIME_TIMESTAMP;	/* time */
-		case 1184:
-			return SQL3_DATE_TIME_TIMESTAMP;	/* datetime */
-		case 1296:
-			return SQL3_DATE_TIME_TIMESTAMP;	/* timestamp */
-		case 1700:
-			return SQL3_NUMERIC;/* numeric */
+		case BOOLOID:		return SQL3_BOOLEAN;		/* bool */
+		case INT2OID:		return SQL3_SMALLINT;		/* int2 */
+		case INT4OID:		return SQL3_INTEGER;/* int4 */
+		case TEXTOID:		return SQL3_CHARACTER;		/* text */
+		case FLOAT4OID:		return SQL3_REAL;	/* float4 */
+		case FLOAT8OID:		return SQL3_DOUBLE_PRECISION;		/* float8 */
+		case BPCHAROID:		return SQL3_CHARACTER;		/* bpchar */
+		case VARCHAROID:	return SQL3_CHARACTER_VARYING;		/* varchar */
+		case DATEOID:		return SQL3_DATE_TIME_TIMESTAMP;	/* date */
+		case TIMEOID:		return SQL3_DATE_TIME_TIMESTAMP;	/* time */
+		case TIMESTAMPOID:	return SQL3_DATE_TIME_TIMESTAMP;	/* datetime */
+		case NUMERICOID:	return SQL3_NUMERIC;/* numeric */
 		default:
 			return -type;
 	}
diff --git a/src/interfaces/ecpg/test/Makefile b/src/interfaces/ecpg/test/Makefile
index 0b9135a5afbc5a773a6e4a6ec0f192062c237aee..9a6614a408707482be1f7f1f6aea55c0ca7ecb00 100644
--- a/src/interfaces/ecpg/test/Makefile
+++ b/src/interfaces/ecpg/test/Makefile
@@ -1,9 +1,10 @@
-all: test1 test2 test3 test4 perftest dyntest dyntest2
+all: test1 test2 test3 test4 perftest dyntest dyntest2 test_notice
 
-LDFLAGS=-g -I /usr/local/pgsql/include -L/usr/local/pgsql/lib -lecpg -lpq
+#LDFLAGS=-g -I /usr/local/pgsql/include -L/usr/local/pgsql/lib -lecpg -lpq
+LDFLAGS=-g -I ../include -I /usr/include/postgresql -L /usr/lib -lecpg -lpq
 
-ECPG=/usr/local/pgsql/bin/ecpg -I../include
-#ECPG=../preproc/ecpg -I../include
+#ECPG=/usr/local/pgsql/bin/ecpg -I../include
+ECPG=../preproc/ecpg -I../include
 
 .SUFFIXES: .pgc .c
 
@@ -14,6 +15,9 @@ test4: test4.c
 perftest: perftest.c
 dyntest: dyntest.c
 dyntest2: dyntest2.c
+test_code100: test_code100.c
+test_notice: test_notice.c
+test_init: test_init.c
 
 .pgc.c:
 	$(ECPG) $? 
diff --git a/src/interfaces/ecpg/test/test_code100.pgc b/src/interfaces/ecpg/test/test_code100.pgc
new file mode 100644
index 0000000000000000000000000000000000000000..913d5175c064963e945350c7f75aeb20ae695acf
--- /dev/null
+++ b/src/interfaces/ecpg/test/test_code100.pgc
@@ -0,0 +1,51 @@
+// $Id: test_code100.pgc,v 1.1 2000/09/20 13:25:52 meskes Exp $
+
+exec sql include sqlca;
+#include <stdio.h>
+
+int main(int argc, char **argv)
+{  exec sql begin declare section;
+   int index;
+   exec sql end declare section;
+
+
+   // ECPGdebug(1,stdout);
+   
+   exec sql connect to test;
+   if (sqlca.sqlcode) printf("%ld:%s\n",sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
+
+   exec sql create table test (
+        "index" numeric(3) primary key,
+        "payload" int4 NOT NULL);
+   if (sqlca.sqlcode) printf("%ld:%s\n",sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
+   exec sql commit work;
+   if (sqlca.sqlcode) printf("%ld:%s\n",sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
+   
+   for (index=0;index<10;++index)
+   {  exec sql insert into test
+                (payload, index)
+                values (0, :index);
+      if (sqlca.sqlcode) printf("%ld:%s\n",sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
+   }
+   exec sql commit work;
+   if (sqlca.sqlcode) printf("%ld:%s\n",sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
+   
+   exec sql update test
+   	set payload=payload+1 where index=-1;
+   if (sqlca.sqlcode!=100) printf("%ld:%s\n",sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
+   
+   exec sql delete from test where index=-1;
+   if (sqlca.sqlcode!=100) printf("%ld:%s\n",sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
+
+   exec sql insert into test (select * from test where index=-1);
+   if (sqlca.sqlcode!=100) printf("%ld:%s\n",sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
+
+   exec sql drop table test;
+   if (sqlca.sqlcode) printf("%ld:%s\n",sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
+   exec sql commit work;
+   if (sqlca.sqlcode) printf("%ld:%s\n",sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
+   
+   exec sql disconnect;
+   if (sqlca.sqlcode) printf("%ld:%s\n",sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
+   return 0;
+}
diff --git a/src/interfaces/ecpg/test/test_init.pgc b/src/interfaces/ecpg/test/test_init.pgc
new file mode 100644
index 0000000000000000000000000000000000000000..86e6b6da848fac09c60908fbd67cdb1206018287
--- /dev/null
+++ b/src/interfaces/ecpg/test/test_init.pgc
@@ -0,0 +1,61 @@
+exec sql include sqlca;
+
+int fa() { return 2; }
+int fb(int x) { return x; }
+int fc(const char *x) { return *x; }
+int fd(const char *x,int i) { return (*x)*i; }
+enum e { ENUM0, ENUM1 };
+int fe(enum e x) { return (int)x; }
+struct sa { int member; };
+
+void sqlmeldung(char *meldung, short trans)
+{
+}
+
+#define NO 0
+#define YES 1
+
+#ifdef _cplusplus
+namespace N
+{ static const int i=2;
+};
+#endif
+
+int main()
+{ struct sa x,*y;
+exec sql begin declare section;
+int a=2;
+int b=2+2;
+int d=x.member;
+int g=fb(2);
+int i=3^1;
+int j=1?1:2;
+
+/*int e=y->member; /* compile error */
+/*int c=10>>2; /* compile error */
+/*bool h=2||1; /* compile error */
+exec sql end declare section;
+
+/* not working */
+int f=fa();
+
+#ifdef _cplusplus
+exec sql begin declare section;
+int k=N::i; /* compile error */
+exec sql end declare section;
+#endif
+
+exec sql whenever sqlerror do fa();
+exec sql select now();
+exec sql whenever sqlerror do fb(20);
+exec sql select now();
+exec sql whenever sqlerror do fc("50");
+exec sql select now();
+exec sql whenever sqlerror do fd("50",1);
+exec sql select now();
+exec sql whenever sqlerror do fe(ENUM0);
+exec sql select now();
+/* ex ec sql whenever sqlerror do sqlmeldung(NULL,NO); */
+exec sql select now();
+return 0;
+}
diff --git a/src/interfaces/ecpg/test/test_notice b/src/interfaces/ecpg/test/test_notice
new file mode 100755
index 0000000000000000000000000000000000000000..9d9506a83bc229b4d8bb2350a6c1306ff52d34ae
Binary files /dev/null and b/src/interfaces/ecpg/test/test_notice differ
diff --git a/src/interfaces/ecpg/test/test_notice.pgc b/src/interfaces/ecpg/test/test_notice.pgc
new file mode 100644
index 0000000000000000000000000000000000000000..db700294e216cedb3236e1373eb72cf72a7e4466
--- /dev/null
+++ b/src/interfaces/ecpg/test/test_notice.pgc
@@ -0,0 +1,94 @@
+// $Id: test_notice.pgc,v 1.1 2000/09/20 13:25:52 meskes Exp $
+
+exec sql include sqlca;
+
+#include <stdio.h>
+
+void printwarning(void)
+{
+   if (sqlca.sqlwarn[0]) printf("sqlca.sqlwarn: %c",sqlca.sqlwarn[0]);
+   else return;
+
+   if (sqlca.sqlwarn[1]) putchar('1');
+   if (sqlca.sqlwarn[2]) putchar('2');
+
+   putchar('\n');
+}
+
+int main(int argc, char **argv)
+{
+   exec sql begin declare section;
+ 	  int index,payload;
+   exec sql end declare section;
+   FILE *dbgs; 
+
+   /* actually this will print 'sql error' if a warning occurs */
+   exec sql whenever sqlwarning do printwarning();
+
+   if ((dbgs = fopen("log", "w")) != NULL)
+   	ECPGdebug(1, dbgs);
+   
+   exec sql connect to mm;
+   if (sqlca.sqlcode) printf("%d %ld:%s\n",__LINE__,sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
+
+   exec sql create table test (
+        "index" numeric(3) primary key,
+        "payload" int4 NOT NULL);
+   if (sqlca.sqlcode) printf("%d %ld:%s\n",__LINE__,sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
+
+   exec sql commit work;
+   if (sqlca.sqlcode) printf("%d %ld:%s\n",__LINE__,sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
+   
+   exec sql begin work;
+   if (sqlca.sqlcode) printf("%d %ld:%s\n",__LINE__,sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
+   
+   exec sql begin work;
+   if (sqlca.sqlcode!=ECPG_NOTICE_IN_TRANSACTION) printf("%d %ld:%s\n",__LINE__,sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
+   
+   exec sql commit;
+   if (sqlca.sqlcode) printf("%d %ld:%s\n",__LINE__,sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
+   
+   exec sql commit;
+   if (sqlca.sqlcode!=ECPG_NOTICE_NO_TRANSACTION) printf("%d %ld:%s\n",__LINE__,sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
+   
+   exec sql rollback;
+   if (sqlca.sqlcode!=ECPG_NOTICE_NO_TRANSACTION) printf("%d %ld:%s\n",__LINE__,sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
+   
+   sqlca.sqlcode=0;
+   exec sql declare x cursor for select * from test;
+   if (sqlca.sqlcode) printf("%d %ld:%s\n",__LINE__,sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
+   
+   exec sql open x;
+   if (sqlca.sqlcode) printf("%d %ld:%s\n",__LINE__,sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
+   
+   exec sql open x;
+   if (sqlca.sqlcode!=ECPG_NOTICE_PORTAL_EXISTS) printf("%d %ld:%s\n",__LINE__,sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
+   
+   exec sql close x;
+   if (sqlca.sqlcode) printf("%d %ld:%s\n",__LINE__,sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
+   
+   exec sql close x;
+   if (sqlca.sqlcode!=ECPG_NOTICE_UNKNOWN_PORTAL) printf("%d %ld:%s\n",__LINE__,sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
+   
+   exec sql update test set nonexistent=2;
+   if (sqlca.sqlcode!=ECPG_PGSQL) printf("%d %ld:%s\n",__LINE__,sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
+   
+   exec sql select payload into :payload from test where index=1;
+   if (sqlca.sqlcode!=ECPG_NOTICE_QUERY_IGNORED) printf("%d %ld:%s\n",__LINE__,sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
+   
+   exec sql rollback;
+   if (sqlca.sqlcode) printf("%d %ld:%s\n",__LINE__,sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
+   
+   // this will raise a warning
+   exec sql drop table test;
+   if (sqlca.sqlcode) printf("%d %ld:%s\n",__LINE__,sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
+   exec sql commit work;
+   if (sqlca.sqlcode) printf("%d %ld:%s\n",__LINE__,sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
+   
+   exec sql disconnect;
+   if (sqlca.sqlcode) printf("%d %ld:%s\n",__LINE__,sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
+
+   if (dbgs != NULL)
+                fclose(dbgs);   
+   return 0;
+}