From 339a5bbfb17ecd171ebe076c5bf016c4e66e2c0a Mon Sep 17 00:00:00 2001
From: Michael Meskes <meskes@postgresql.org>
Date: Wed, 20 Sep 2000 13:25:52 +0000
Subject: [PATCH] *** empty log message ***

---
 src/interfaces/ecpg/ChangeLog             |   7 ++
 src/interfaces/ecpg/include/ecpgerrno.h   |  15 +++
 src/interfaces/ecpg/include/sqlca.h       |  25 ++---
 src/interfaces/ecpg/lib/connect.c         | 123 ++++++++++++++++++++-
 src/interfaces/ecpg/lib/descriptor.c      |   4 +-
 src/interfaces/ecpg/lib/execute.c         | 128 +++++++++++++++++-----
 src/interfaces/ecpg/lib/extern.h          |  16 ++-
 src/interfaces/ecpg/lib/pg_type.h         |  72 ++++++++++++
 src/interfaces/ecpg/lib/typename.c        |  40 +++----
 src/interfaces/ecpg/test/Makefile         |  12 +-
 src/interfaces/ecpg/test/test_code100.pgc |  51 +++++++++
 src/interfaces/ecpg/test/test_init.pgc    |  61 +++++++++++
 src/interfaces/ecpg/test/test_notice      | Bin 0 -> 22483 bytes
 src/interfaces/ecpg/test/test_notice.pgc  |  94 ++++++++++++++++
 14 files changed, 575 insertions(+), 73 deletions(-)
 create mode 100644 src/interfaces/ecpg/lib/pg_type.h
 create mode 100644 src/interfaces/ecpg/test/test_code100.pgc
 create mode 100644 src/interfaces/ecpg/test/test_init.pgc
 create mode 100755 src/interfaces/ecpg/test/test_notice
 create mode 100644 src/interfaces/ecpg/test/test_notice.pgc

diff --git a/src/interfaces/ecpg/ChangeLog b/src/interfaces/ecpg/ChangeLog
index 647f649438a..82d28b80bc5 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 2a826988be5..58e70a0752b 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 da1fdee4f35..9bc958a1af7 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 416fcf17dd4..59a3f794851 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 37423255336..3363381d90c 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 0741db622aa..762aab49c7e 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 db2f3a7d419..780fc933bb8 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 00000000000..e265de3b0c4
--- /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 c66ed7709dd..a638c7d7666 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 0b9135a5afb..9a6614a4087 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 00000000000..913d5175c06
--- /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 00000000000..86e6b6da848
--- /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
GIT binary patch
literal 22483
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%0DsuKaF}@t<12>_+
zt-O%BeQgfUI-zTy?-RURc>YwdYI=)c?N{#>to`c4g0)|LPO$cqZwUTdk@L@jzbyDg
z!N&xjjYHO!oYEV!R`553zD@9xf~N#OE%;W!|0wtag0+nv6Z`|Ae?#zp68v8T|7XE3
z3;v<tv)~F_=D!NQSnzX#lY)OD_^pCp5bOzlS@6Sxe=qp&1*`x6uHXyBhrcX%p|t7J
zi-P`;5`31>Dc~WIV$5#PZ?`y1KWORSix~59$%~GR>z@Uq)7i_(Isf0yFDD6l%fy8H
zt%7wd+$1<5^oHOb!S5BkQSgI;Hw!*0Sl3<82p$vq9|Q|Dsf$@wK_X*<)i>q@-z@YG
z3N8sgE?D!v2}8YQo{&h7;A4U(1Zy9t3)b<-L}&XwptBCYP+DNVC_IwYj7BI^Z7B&>
z`mY3Uk;v;X{j>xb^A*9@NbFg`*9!if;I|9DWOcy5SMWZezeBM4|IZ7)Md-&v{6{gR
zwajfoe@3uCbH^IeKO~V)3jUNP;QvED3h?D?gSLK42=5Nz=@5QT2vgjAGG7b*LC9&5
z5!X|gde@k<WN-K!@ExFWpUAX9(A_nNT_;?WT!Z+<RJ}5J&b7Ugc&XX$^PFdH^6~jb
zdkxDnW*XtwQtnE_-yco_KY(2?3tfcipLnUC7Yhd;uL|k#rVzf!K!jX_=3?7ZsLv%v
zdjavA{qZ>nEk5G&UuI_s@?38IyH8(lbcIOz2D4^?liy+X`1lG_^l_K@xR1Nd7kwNv
zKk;$g{BIxk819344Vt8Ri;q*L=Hp)TXFk5te8R_@&ENU>Dl_BbEqb6JGPjz<LQ1Fn
z0kgx$L*`Z=Z!;hC@pkjHk4MapeSEcf{URr4hZ*qks5#){F>{xXuQ6Zq@ow{sk0;FH
z#ZJy1bD@u~GjH|r_2z9p{!??ek8d>Z_wn1zLq2}H`Q$9T68)!zQxqIDpSsv$oEM(z
z5c~#n0+?DHLpYNF*N+gKoHf9owlcH8OK_%Rc*y19jIEf-b!JRgp)#H8s#fZasamey
zRh_~qU{}4C>B3=Lu9i<{K$PE{r>DD^v&&3nGBFRwa@Arfm+ds*>us#-?uf46T$5X0
zcXzDYzYvRV^shd{ACHAUru?z>ecgT0*v38_IF_e)1SqNT*Cwr5t{11uxvZZr5z6Q5
z(A^C!;=U5DtT~x`{x34OX`2i(Mnk0ru&+BPJ%p^$B5RH|8v~(%Aes`Y&o){0LZ#O5
zYa*rDQ|tS#h{rZ2Q+@mo)0JyZX`7UN6PqL1(-ZFjr&g`sV$p7^Q8#2pV<~MmUsAy5
zx<Zt~Vm%O*#{sYHCbr#?mO!e>R+>07)*cizdWuO>E#dT_aicLZuoISWs_HsT6b)EU
z;Vin;D?PEJyCWX!!(sE3jmKjo1Q|nWxh70ny`1cD`L0DauJ02C9nTy^ZQVyv`Ksyu
zN-?W8qMoVSruC+?6Jsn>YG!jXz#50Dxz2*=YSwE$oexb^W)t%`Yj0w#&ZgH7)w?p;
zTz*c%RJqwzZ!{<U1U`9$QH)2ACcBF9R8pTo>WX!4>gkMy3x_n6QZK$E=dtyY9OTeG
zv0l}D&2rMUDagUYEahg#+n>hsA9c#xDDpOTpi6A9mC|PZWU*22V!cpv&ue<Ni>0g{
z(dc?1OP7Yc6eU3rDwo{aEm9rmR;o0KY%5_!X9BfHS#N2kvtnWj6w)`69-^XqfSM!~
zVpEnE9RgI03ziq6qy0%2^+1j$Ex$H?%CY-&jx1yly}=)kS$;?mK`uj(poXF$M4x2B
zWl&p1Pbw57sJUuZI-9Mz3^W(@3HvtSE*Z1A{VtUTvP#50S3~I5q{c~|D*99!XQ{<<
z#Y%|LvJ`ua=S^3#+K<pqG|V!W@dVt>j-7T{dL^HCRJBS9EQQFl$?9D7^@wQ$O5NA}
zu8ShI358xO6{nqSHBl5K*{`vfS}C>%!b3*p>pnTIR>omfJ>{W?!vVnx7?XB$Vqdh6
zU1B|aQZfM-ga@ZW%@9`$MY&9vt|rD|6Gupl)z~QFAuA3al%O_A#ncZ>mRvQ)wPOk$
zzjS4Mx^_&V=d<2)x_-0D(T*v$f{tInbcoo-qgn9xo|n(oJq}7*muRyt4)dVTCfXP6
zj;V$CfzK+M2-#PxX1t)e6527P>%)Ldx#6;CJBqHF;5SWzX4{6(*V}W2n$sl(`9e*a
zujh-UP-)t*(hXdapRY&jLAye^64135OD1&7fUdnbCJ7C%o=M}^No!V5s4qA0JX~9v
z)`cynQEm8{{64*HWXBNNCMF&*Mt^s(&d2M7-adK2JI|dwykRWe%K0Mw@d3J1Q7fwQ
zFkP-U2jDgwk#>l?N4CI^MWfdL(veAm^-D<59PG!#;t{QjLyFqXcGi?2k6O*jf+2oy
zjdHYz_hTNU;5Xx&bG6=ybx1)m=#d_Nq;2#v4&fV=u5-RupKRtO1;RI=x?<}w969-W
zSnAr<Kr*4L0l)qxgb|VxDKB42PdP?eMvx0ji>!xck<s1bi*zY?IMJo3Y(LLrx}I}M
zo06gjG99QD8#ynWhEdj@7%D89^!3n;q2i*O)Hn!*;cX&gF)@>>Fe#KN*5hkZPw#J6
zB$o0O;g9UiYMab>%vVKnhJ?m@R1<A2)S$FZM?9rkpvx7@wqZIFQB?pVF;}kGR!JnZ
zWDIM1Z%0jOiIq~;!%(A#f(MAj*LU=w^Riv>!#}!qsW}btoJu=-5(&&}ecpa~D#6c1
z|Aa(TW~$GVm4oXl7-WIF?xwp&ujxsq$jELfYRg0^eY2xyqpBb1(}N7jZg{3dpVut&
zVb_>sf>R14M|<o{klYxf_M8mRICf-1G`$piEPQ>jqJ1u3#-K+My%Y<FL(0>BU6534
zPjXzcY#<wkNgG=|m%G{Xxi})pg&~rMu`>CfKzTGG;G*jx7Yw&tc?==(5U6-0N;9;(
z9$C1_;uTB1X}B6UX~(b<a5?xSa)YZo4rz|{oKSR;7wyo9+g&I%W~sX1i_hj!a>A0~
zuzGuDvyhmyL|F=MoXsKBl%-BqDy7~{Hln)))P<^McLs268sDF;$@&!iv5gSxjXF)!
zwOaa6Z`5g6Z`7KZMsGCG5)ZcYVo+#)anF!i<Wn`hQK#w9*vLe0)M+?0whJ+*;^>$+
zGCDXi&_6M@s~3Y*1<@p3_{N;Fe!Yg$VjX?@+_&E-=s(gZS&XbEYEE-!v2<yqd(})t
zib&1odeumYS8KUUu})*u)GTI?Y%!B=RBE<KvK|)))4AzMxO6o*>%j|5H443IXx1y^
zY4TpR6A?TRB=w-C!V6>?a00e9;FbL%ZG&VnavDygZ4;&0oK9a(!KhxRsTgmYB<l^0
z4WfFJsF_*YHO#K)*KOMscZh-m6bD}ei-$Q3Y-6%PL?i2@huQFSvNL}~s6V%#E^~!j
zsk%SOqKnu`7Nfr{4@R$=m@VpV09}WyxN-7L-O{YU1v9(OxV7B0jk-;CDU_3b0y#1G
zgPic);?r$TL|x8yMX;@Pdq95&7>kQC+z6VcdU39b;?#`}iBt}Cp{bL?(#GHYfl>Vs
zs@dP<fk<B`>&j-Z_XAm%n^>0lOMVb_p^240&ME9p1yo&Oa^>gtKp^Vc5?diWsAek@
z`s<=HiY=MjM1fUYH_XDC$KNiIZ0&-%!FGvs>wsyn-Hni{#$lgk+(MgFwGR6u6Jk}{
zVkj@zERk8w;{+4zQ%F|>v0pL4K819(F%HAssvlIh`vZ4dn{o?-e(3LHutZ_s!o-jA
zn&N@AHMMg><EGo=Qz|P%cFWx2+ID9}$Wj#~-JX+^6@fmAng`jgMM-B>aH1vIE<{OY
zWw1+=Y*+Invo2)wFP$oo&bk1*^uc!dtPRzW-7qLYHj1LAhziQ!))6_-8T>b4T<=wD
zQAk@AV#!rZmuI^InRw?<;_;9^r#Nq>KbBOS!g>q2JP${L9=!N;F(V6rI4eu)fQuC*
zg3l#TZKR`JbnhseVi3?I!CHvhMjpZhyGHhjdNr59q986Fr=Du;$Br~Z@8VnrDCL0U
z+(xjY#VXqNC-iH7Lkp@7qXhaxTV+b!9I8*JGc|FLp)DoaUpD91@QMSNm1Nxr+Rg16
zb!CKHI@}V_0B=-fE7Lk_VviA}pQ*=Ed0E^eif)HJiu6D05`z@$6!8XF18ZSn#`2OY
zUP|?3wnELo4eP!_sM(x5@w6KXq1JO%>!R&e0v$znGb+|@B5)>4cI<&<niqvJ0_w5E
zK~Vs`K4`!g+fR1=iBw<OrgvZokEk>m(x4dD;as^p0T?q_38wmr<)WKJtV(_D4U;Zm
zs!B`O<6$edtNF54a8$f16sI3W?E#?4?FzNMaT|D5jr(0xYPM)yb=*y~7+1l8WL*0V
z(~K<ru;^BjoV{$tYH%F8KcTWKArbu>J5Ms1@e0N|mNSy99Rr<!z9gkI^*X*cQlk1C
z=Zci34hJITP*G_iXCuBwsez*rKchsMTExr9k~JQahE!YZc*TSvX~{$=&3YPmYn#uC
zqi>~&uu0BogUptJhLJ%!GCCt9u==doGM6A3Hj)}m+FY~<WDF3J<1tI7Nfd@bN_S?3
z$W&s5fa-+EL827`vJ)axgcWk2Qp-9a))Ht!sxO3%r9w#dg*daI$!=~%wcXiZJP9`=
ze5BhFwZ$;|jg%YxvdULxYa`}Y4j`<8F$7Q&=Ye1lxeXy|ZWFhIW4gf=33g&Yaf3Ma
zpVs1dvM7F2iGH6HPet+4QUqwKp@W&7xq3Z4Weu>7iCq&(xhkKg=N1gyFs+_|{}pDT
zh-;SLOafljixz91_95$*zE}k}8^scSJ;a*?v!|RnOw$=z1@FvFS89g_Di}vN*=ejx
z=mdisEZ)E<TJT`KjScmZ?lr@u%4E8v37V0OiVSE($q3sH*27$yugz7=QL8Er2-;(G
zN&nQJKwvi(Dxf9U9!Z&2K;taHAG$1+oelcC(IR~?DGN^>BI!&C=ReY<Nm+V|BrX7|
zwMs@Mv$M&j!0gIRjf0%a;<q17lNJzPm2Z}DrmCJPDQi%OLYISQg2MK&fDMk_BsN)T
zHa8OB3+k!;C2o?WS8lW`a**H^<m5sRxl-tqlZP6)v=%I@Q5Aq+lck{;lfflorMmXx
z<qPchq=IBcN*=UE(C>K?LgIRZpU2wR#cZU&#98cOFL#F0d};><S<^Z>kq66zT)M=-
z!3_FPPqHsv!mpasc&}ryIX!(Syo2d8qfV?gDi`Qf58i?)YKb}=G`Vz0By(9mfeEv&
z@1>0JcRrG>tDzekz&k9MQT-(AZkTks?uWfs^_DC0TqQ@)S_wIz%?*r=jt&h>jEs$X
zV^{ZfcZA|w`v<W-4-s}x^zWJ&8pJj|MBLdwIE0OQh|+&u|H#D1=&-kIX!rQo=<XqG
z*~7_uCbqMzo-h$_m=BF!i*0)!Oe>dnV{Ou`Pw*rMBUTQjRbi((sv<W&i~_vzu^l^D
z*tUM0V-LcDcJi*F{y`+ekaqfYyF^FW(oTnB@mZvPRL`|Eq7U=2KGZOdH-)eQn60Mx
z2OeQLHPJV%nnOFsCvNbr*)z2324Ba4v7I~nM+aFMPQ8ge<2zs!C{D3~vGE(cu{{&M
zT0$5Zg+8h|nklI19!ne@8{O7Ffw%XEcJ0EsP12IXw2eHQIhf1LHi82MRgR%OK8(#j
zj|mZ_XTS~P;$Xcx#S{N>FBtHnakC_DH72Vku+TXOk4-bxsZl%{l0RfS9bH5`S<98=
zFvgB9JCr7K{2j**A$ypNS|8@KB@iH*h^t^Z806#E=u;=+#_D)W%d&8!kVPgf0yKmy
z<ghZR-omwkWu&pP5c9^bsq*^+W7US$6Bc8BE#Q0}3owzE<cP<bl;ho}@GKWg>2fw*
zgW@a;Y#6PnzCvTV6!%Hkkf!=_2dm)B1&r8er249uNP{9U!KC`~#at=7o2zTgq41cx
zK9^%>YG|ptKF_3e!nH)ZJ{Jk%WJD=69Dj|aEPq`bGFfYu>m*u$SqJsOHs+TXP@vA|
zNaC6a`wVQzxvX(|$e~NFydQIcBk2x`D{MZ~<EUze`!N%`s0BEN%jxf%R8N1f$QJ8W
zIs9zbn&i+SzQ4hkqptc5u1!^K^p*bF)K)ol*EFtpn1;@R{iMuTTpQ?q31^Ks2;gMv
z4w0JDl-&O}6Py?&uPg;Zxv<KRwhTypw(aH|_vLD}@|-6z<|XPDd_H#h(o5I8nbP%X
zKS5r`M7KsyXZuAH-9pik#_1=R+cw%CDdab0aHS{RHd)(_8F@4dS=c&j^MM8x<gku&
zSbbyCQraGxu{06KIuFWBZnA}<)8JQ>zCP&#_|>CN^T-|(YIbalCsCW0icST4&>Vpv
zS@lA#R5$7$>t1A+*H6jF?JR!Mvf23~pAw_p_{~awKbP@Oet7oYZAj*kS@_Ym>Qu(?
z<06{4-ryOOOmCHpg7*V+^vK4G>v&DEZ*baJc2a)><arT)MMPFJJTTB3S%<IltdHme
zGZA^(Ef(vJtQ*Wt;!q}n#I7Cutk3^f?DCW?9x~)Jq21BW?kFEPMBw%Rl4d&Vho<3d
zac|W0UT_F*Ay=!KPE0(x&i<_<S2WU7rn8W)7ffgNP#GEZ-l&;QJe<_IKUd?=7Hts^
zX_x>zrz#Bv_#BObY6%pcVVF*VTnn4dJSa%7U<sXuborkv=*MwPC)dQtp4FSkgd%C2
zs6l^`EdMY`i9zW}n1WnbL1N9ShG><(mj8I{U#gyu)XI0TaDQDWqkViAPZJw?I+}d)
zy(%O`LVWhISHmXd<D}%{d%^3#_W-a<=beF1x1WnZKE5yfP4JB)FfVSxgV)E*RS0}E
zmwbG`_yR;WkilLK4kONYgUQGDg14fO4ZyBk(itWY_%1Oq-zP4CfzNh_%SF^=5Y9#*
zAKyp*82IFQZNyh0P%h(qBf#-J0=`E=e0<x%@ijwye9!qYBou5qpZ#`xe-2EW_^dA9
zvt9+oSf}nHAFn$Q9N%{EZ3o|vm|!pRF&sf~eEe2gHv}&|%QE4{I_7mRg5%?R-B&I%
z_<~w+xpF^f`B*P|!M7KDpJhgSMeP0KxRcDbTZ;F+<vVFMjW;LnVPMC{FX>!>_oG}|
znD28TK7Q@sBJera5$5BYJWk#k@U1xw-&aF?d>_37e1jBZFY3T>41sMyJNRBbzvuQi
zF#8KH@=%Yb5m+t*zXKI<6^l48(s_Lkf&7%`_#Odvm$T^^5L_OnQQnRf#^6;XxmYgy
z4c`u;EO(VI#hAI=#R3^W1t~1=v)he%V~F73ufZ4U9_AlL@V&J_oG$~aw3WO0t;YP%
zdH5)oeZ^f%#xc%Od3c4!Y(k(NtSXM7upQU$G3K42j7~qW&AI5eNYpO^qJH5|G_C^Z
zhcvDw(BEjBrK?}jxVEbMuE0Y3#610krfbd6A81@|hT~r2v_ijQpz(7g&T*`9dOUpp
z%a5}K^&5t~FO)C!>30=0ejaZ!&NPnBhl}G$<J!qMZZytT!MOF~`Ys8_fu^fxXMfi?
zJ(>1vjlW*v?3WtXcejE#Jz8)rG<bn8bS?CIrxF($yucQ^7KYyEC3#_+hhZEqWrePV
z=p}6T3HyEyzhp>@!|||2i}1Zb^6w4tuST37@WKtUmdkrHu09rErb~b>-~6)aTX1*z
z&p>&6lgica0=%bFMEr3ppXm+6`9Uw%!~(nnO8<Q{l>T1Cp9{t5KLdHo&BKVh_F8~1
z{>^94a=w!x*D~`(++CdIKZSV2w{N9kc?rwU^x5UnuefiA(EcAI9_X_|>YM%_WL(S4
z|4<<RS--4*c}GMj%gi5ezaIUW^E7)K-#B;QAK~{K`A!i(es(L;*cMSX5H2_FQ-~i#
z`V*ir|J8`Q@v;&tgliCg57Hk+8uK?0{}AHt`;INdIj<oJt-H+JiTJ0H{vzU(_m_yf
z{!4xM&Jy3j;yW)Z!T%8AN5RiGBFX;*?rwZVAn_j&|0dGAti0zCe-`mqZTzQ*yZTy*
zFK#}M_zcqTx9KMlKZ&^eKIA!YNnw3fAnwK^^}8JL@b@7*EdTo;kKc!kAs+rd<N)H~
z??diFobR(uOZm%;hq$w6IqWGR?yd;Itao*G<YbAOsWtFEKt7Mxf2y5v{Bk>p$A!Ed
zBfBT?jY*yYl)#tmOdus&@uuWt-IEoomu?;eb!fY{ZCC%!A#dx@@W?1Kan0*xd7^46
zllyS++Zl}-{T!rHxk|PS_%u%j4=`8c=S2t`2o)YKP*%#eK;ap}>6_=YbrID=W8v*z
zMjvI8FI@&-$(-*ylUud~pON(PRj+WsedMw&Mb`PJ`P^lgk&j&QFovJiv|p{1r?7ZL
z4CRAwS=ujO;-okHEzGbe?j5WM+3x1Ui4>Zx7*Dnv5(z%nsbAj=xbdM-`z_6RKNBin
f)x`EYlhzM*wq?YliJ@<IhPU0YCZyr4PnG^3lWhHW

literal 0
HcmV?d00001

diff --git a/src/interfaces/ecpg/test/test_notice.pgc b/src/interfaces/ecpg/test/test_notice.pgc
new file mode 100644
index 00000000000..db700294e21
--- /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;
+}
-- 
GitLab