diff --git a/src/interfaces/ecpg/lib/Makefile.in b/src/interfaces/ecpg/lib/Makefile.in
index e236487d6aaec05d351744292689d85f7e14712b..53f3d5ac44abf91be8b3dfc81b971583a469384a 100644
--- a/src/interfaces/ecpg/lib/Makefile.in
+++ b/src/interfaces/ecpg/lib/Makefile.in
@@ -4,7 +4,7 @@ include $(SRCDIR)/Makefile.global
 PQ_INCLUDE=-I$(SRCDIR)/interfaces/libpq
 
 SO_MAJOR_VERSION=2
-SO_MINOR_VERSION=5
+SO_MINOR_VERSION=6
 
 PORTNAME=@PORTNAME@
 
diff --git a/src/interfaces/ecpg/lib/ecpglib.c b/src/interfaces/ecpg/lib/ecpglib.c
index 0d3d4fa0e6a471ca82607d4c8fb6cebf2657c467..e2b8e2ce5993ac5130ae7a05c93313e949256bd1 100644
--- a/src/interfaces/ecpg/lib/ecpglib.c
+++ b/src/interfaces/ecpg/lib/ecpglib.c
@@ -24,7 +24,32 @@
 #include <ecpglib.h>
 #include <sqlca.h>
 
-extern int no_auto_trans;
+/* variables visible to the programs */
+int no_auto_trans;
+
+static struct sqlca sqlca_init  =
+{
+         {'S', 'Q', 'L', 'C', 'A', ' ', ' ', ' '},
+         sizeof(struct sqlca),
+         0,
+         { 0, {0}},
+         {'N', 'O', 'T', ' ', 'S', 'E', 'T', ' '},
+         {0, 0, 0, 0, 0, 0},
+         {0, 0, 0, 0, 0, 0, 0, 0},
+         {0, 0, 0, 0, 0, 0, 0, 0}
+};
+
+struct sqlca sqlca =
+{
+         {'S', 'Q', 'L', 'C', 'A', ' ', ' ', ' '},
+         sizeof(struct sqlca),
+         0,
+         { 0, {0}},
+         {'N', 'O', 'T', ' ', 'S', 'E', 'T', ' '},
+         {0, 0, 0, 0, 0, 0},
+         {0, 0, 0, 0, 0, 0, 0, 0},
+         {0, 0, 0, 0, 0, 0, 0, 0}
+};
 
 static struct connection
 {
@@ -72,39 +97,6 @@ register_error(long code, char *fmt,...)
 	sqlca.sqlerrm.sqlerrml = strlen(sqlca.sqlerrm.sqlerrmc);
 }
 
-/* This function returns a newly malloced string that has the ' and \
-   in the argument quoted with \.
- */
-static
-char *
-quote_postgres(char *arg)
-{
-	char	   *res = (char *) malloc(2 * strlen(arg) + 1);
-	int			i,
-				ri;
-
-	if (!res)
-		return(res);
-		
-	for (i = 0, ri = 0; arg[i]; i++, ri++)
-	{
-		switch (arg[i])
-		{
-			case '\'':
-			case '\\':
-				res[ri++] = '\\';
-			default:
-				;
-		}
-
-		res[ri] = arg[i];
-	}
-	res[ri] = '\0';
-
-	return res;
-}
-
-
 static void
 ECPGfinish(struct connection *act)
 {
@@ -139,6 +131,54 @@ ECPGfinish(struct connection *act)
 		ECPGlog("ECPGfinish: called an extra time.\n");
 }
 
+static char *ecpg_alloc(long size, int lineno)
+{
+	char *new = (char *) malloc(size);
+
+	if (!new)
+	{
+		ECPGfinish(actual_connection);
+		ECPGlog("out of memory\n");
+	        register_error(ECPG_OUT_OF_MEMORY, "out of memory in line %d", lineno);
+		return NULL;
+	}
+	
+	memset(new, '\0', size);
+	return(new);
+}
+
+/* This function returns a newly malloced string that has the ' and \
+   in the argument quoted with \.
+ */
+static
+char *
+quote_postgres(char *arg, int lineno)
+{
+	char	   *res = (char *) ecpg_alloc(2 * strlen(arg) + 1, lineno);
+	int			i,
+				ri;
+
+	if (!res)
+		return(res);
+		
+	for (i = 0, ri = 0; arg[i]; i++, ri++)
+	{
+		switch (arg[i])
+		{
+			case '\'':
+			case '\\':
+				res[ri++] = '\\';
+			default:
+				;
+		}
+
+		res[ri] = arg[i];
+	}
+	res[ri] = '\0';
+
+	return res;
+}
+
 /* create a list of variables */
 static bool
 create_statement(int lineno, struct statement **stmt, char *query, va_list ap)
@@ -146,15 +186,8 @@ create_statement(int lineno, struct statement **stmt, char *query, va_list ap)
 	struct variable **list = &((*stmt)->inlist);
 	enum ECPGttype	type;
 	
-	*stmt = calloc(sizeof(struct statement), 1);
-	
-	if (!*stmt)
-	{
-	       ECPGfinish(actual_connection);
-	       ECPGlog("out of memory\n");
-	       register_error(ECPG_OUT_OF_MEMORY, "out of memory in line %d", lineno);
-	       return false;
-	}
+	if (!(*stmt = (struct statement *) ecpg_alloc(sizeof(struct statement), lineno)))
+		return false;
 	
 	(*stmt)->command = query;
 	(*stmt)->lineno = lineno;
@@ -173,14 +206,8 @@ create_statement(int lineno, struct statement **stmt, char *query, va_list ap)
    	   {
 		struct variable *var, *ptr;
 						
-		var = malloc(sizeof(struct variable));
-		if (!var)
-		{
-			ECPGfinish(actual_connection);
-			ECPGlog("out of memory\n");
-		        register_error(ECPG_OUT_OF_MEMORY, "out of memory in line %d", lineno);
+		if (!(var = (struct variable *) ecpg_alloc(sizeof(struct variable), lineno)))
 			return false;
-		}
 	   	
 	   	var->type = type;
 	   	var->value = va_arg(ap, void *);
@@ -217,8 +244,8 @@ ECPGexecute(struct statement *stmt)
 	PGnotify   *notify;
 	struct variable *var;
 
-	memset((char *) &sqlca, 0, sizeof (sqlca));
-
+ 	memcpy((char *)&sqlca, (char *)&sqlca_init, sizeof(sqlca));
+	
 	copiedquery = strdup(stmt->command);
 
 	/*
@@ -314,36 +341,19 @@ ECPGexecute(struct statement *stmt)
 					int			slen = (var->varcharsize == 0) ? strlen((char *) var->value) : var->varcharsize;
 					char * tmp;
 
-					newcopy = (char *) malloc(slen + 1);
-					if (!newcopy)
-					{
-						ECPGfinish(actual_connection);
-						ECPGlog("out of memory\n");
-				                register_error(ECPG_OUT_OF_MEMORY, "out of memory in line %d", stmt->lineno);
+					if (!(newcopy = ecpg_alloc(slen + 1, stmt->lineno)))
 						return false;
-					}
 						
 					strncpy(newcopy, (char *) var->value, slen);
 					newcopy[slen] = '\0';
 
-					mallocedval = (char *) malloc(2 * strlen(newcopy) + 3);
-					if (!mallocedval)
-					{
-						ECPGfinish(actual_connection);
-						ECPGlog("out of memory\n");
-				                register_error(ECPG_OUT_OF_MEMORY, "out of memory in line %d", stmt->lineno);
+					if (!(mallocedval = (char *) ecpg_alloc(2 * strlen(newcopy) + 3, stmt->lineno)))
 						return false;
-					}
 						
 					strcpy(mallocedval, "'");
-					tmp = quote_postgres(newcopy);
+					tmp = quote_postgres(newcopy, stmt->lineno);
 					if (!tmp)
-					{
-						ECPGfinish(actual_connection);
-						ECPGlog("out of memory\n");
-				                register_error(ECPG_OUT_OF_MEMORY, "out of memory in line %d", stmt->lineno);
 						return false;
-					}
 						
 					strcat(mallocedval, tmp);
 					strcat(mallocedval, "'");
@@ -360,36 +370,19 @@ ECPGexecute(struct statement *stmt)
 					(struct ECPGgeneric_varchar *) (var->value);
 					char *tmp;
 
-					newcopy = (char *) malloc(variable->len + 1);
-					if (!newcopy)
-					{
-						ECPGfinish(actual_connection);
-						ECPGlog("out of memory\n");
-				                register_error(ECPG_OUT_OF_MEMORY, "out of memory in line %d", stmt->lineno);
+					if (!(newcopy = (char *) ecpg_alloc(variable->len + 1, stmt->lineno)))
 						return false;
-					}
 						
 					strncpy(newcopy, variable->arr, variable->len);
 					newcopy[variable->len] = '\0';
 
-					mallocedval = (char *) malloc(2 * strlen(newcopy) + 3);
-					if (!mallocedval)
-					{
-						ECPGfinish(actual_connection);
-						ECPGlog("out of memory\n");
-				                register_error(ECPG_OUT_OF_MEMORY, "out of memory in line %d", stmt->lineno);
+					if (!(mallocedval = (char *) ecpg_alloc(2 * strlen(newcopy) + 3, stmt->lineno)))
 						return false;
-					}
 					
 					strcpy(mallocedval, "'");
-					tmp = quote_postgres(newcopy);
+					tmp = quote_postgres(newcopy, stmt->lineno);
 					if (!tmp)
-					{
-						ECPGfinish(actual_connection);
-						ECPGlog("out of memory\n");
-				                register_error(ECPG_OUT_OF_MEMORY, "out of memory in line %d", stmt->lineno);
 						return false;
-					}
 					                                                
 					strcat(mallocedval, tmp);
 					strcat(mallocedval, "'");
@@ -415,16 +408,8 @@ ECPGexecute(struct statement *stmt)
 		 * Now tobeinserted points to an area that is to be inserted at
 		 * the first %s
 		 */
-		newcopy = (char *) malloc(strlen(copiedquery)
-								  + strlen(tobeinserted)
-								  + 1);
-		if (!newcopy)
-		{
-			ECPGfinish(actual_connection);
-			ECPGlog("out of memory\n");
-	                register_error(ECPG_OUT_OF_MEMORY, "out of memory in line %d", stmt->lineno);
+		if (!(newcopy = (char *) ecpg_alloc(strlen(copiedquery) + strlen(tobeinserted) + 1, stmt->lineno)))
 			return false;
-		}
 		 	
 		strcpy(newcopy, copiedquery);
 		if ((p = strstr(newcopy, ";;")) == NULL)
@@ -857,7 +842,15 @@ ECPGdo(int lineno, char *query, ...)
 	if (create_statement(lineno, &stmt, query, args) == false)
 		return(false);
 	va_end(args);
-	
+
+	/* are we connected? */
+	if (actual_connection == NULL || actual_connection->connection == NULL)
+	{		
+		ECPGlog("ECPGdo: not connected\n");
+		register_error(ECPG_NOT_CONN, "Not connected in line %d", lineno);
+		return false;
+	}		
+
 	return(ECPGexecute(stmt));
 }
 
@@ -902,14 +895,10 @@ ECPGsetconn(int lineno, const char *connection_name)
 bool
 ECPGconnect(int lineno, const char *dbname, const char *user, const char *passwd, const char * connection_name)
 {
-	struct connection *this = malloc(sizeof(struct connection));
+	struct connection *this = (struct connection *) ecpg_alloc(sizeof(struct connection), lineno);
 
 	if (!this)
-	{
-		ECPGlog("out of memory\n");
-                register_error(ECPG_OUT_OF_MEMORY, "out of memory in line %d", lineno);
 		return false;
-	}
 				
 	if (dbname == NULL && connection_name == NULL)
 		connection_name = "DEFAULT";
@@ -937,7 +926,6 @@ ECPGconnect(int lineno, const char *dbname, const char *user, const char *passwd
 	{
 		ECPGfinish(this);
                 ECPGlog("connect: could not open database %s %s%s in line %d\n", dbname ? dbname : "NULL", user ? "for user ": "", user ? user : "", lineno);
-                
 		register_error(ECPG_CONNECT, "connect: could not open database %s.", dbname ? dbname : "NULL");
 		return false;
 	}
diff --git a/src/interfaces/ecpg/preproc/Makefile b/src/interfaces/ecpg/preproc/Makefile
index 2b73c8ed88e09f278eefb1908ede0a172b7d9e02..207259559586243f6b0c45084e9686fedb95a82e 100644
--- a/src/interfaces/ecpg/preproc/Makefile
+++ b/src/interfaces/ecpg/preproc/Makefile
@@ -2,8 +2,8 @@ SRCDIR= ../../..
 include $(SRCDIR)/Makefile.global
 
 MAJOR_VERSION=2
-MINOR_VERSION=3
-PATCHLEVEL=5
+MINOR_VERSION=4
+PATCHLEVEL=1
 
 CFLAGS+=-I../include -DMAJOR_VERSION=$(MAJOR_VERSION) \
 	-DMINOR_VERSION=$(MINOR_VERSION) -DPATCHLEVEL=$(PATCHLEVEL) \
diff --git a/src/interfaces/ecpg/preproc/ecpg.c b/src/interfaces/ecpg/preproc/ecpg.c
index 1fe777845b7ad3979130c06bbd75347a669da60a..3d8624b334aabbb75208146a6192d2901879af06 100644
--- a/src/interfaces/ecpg/preproc/ecpg.c
+++ b/src/interfaces/ecpg/preproc/ecpg.c
@@ -22,7 +22,7 @@ extern char *optarg;
 #include "extern.h"
 
 struct _include_path *include_paths;
-static int no_auto_trans = 0;
+int no_auto_trans = 0;
 struct cursor *cur = NULL;
 
 static void
@@ -138,10 +138,12 @@ main(int argc, char *const argv[])
 			else
 			{
 				struct cursor *ptr;
+				struct _defines *defptr;
 				
 				/* remove old cursor definitions if any are still there */
-				for (ptr = cur; ptr != NULL; ptr=ptr->next)
+				for (ptr = cur; ptr != NULL;)
 				{
+					struct cursor *this = ptr;
 					struct arguments *l1, *l2;
 					
 					free(ptr->command);
@@ -156,12 +158,25 @@ main(int argc, char *const argv[])
 						l2 = l1->next;
 						free(l1);
 					}
+					ptr = ptr->next;
+					free(this);
 				}
+				
+				/* remove old defines as well */
+				for (defptr = defines; defptr != NULL;)
+				{
+					struct _defines *this = defptr;
+					free(defptr->new);
+					free(defptr->old);
+					defptr = defptr->next;
+					free(this);
+				}
+				
 				/* initialize lex */
 				lex_init();
 				
 				/* we need two includes and a constant */
-				fprintf(yyout, "/* Processed by ecpg (%d.%d.%d) */\n/*These two include files are added by the preprocessor */\n#include <ecpgtype.h>\n#include <ecpglib.h>\n\nconst int no_auto_trans = %d;\n\n", MAJOR_VERSION, MINOR_VERSION, PATCHLEVEL, no_auto_trans);
+				fprintf(yyout, "/* Processed by ecpg (%d.%d.%d) */\n/* These two include files are added by the preprocessor */\n#include <ecpgtype.h>\n#include <ecpglib.h>\n\n", MAJOR_VERSION, MINOR_VERSION, PATCHLEVEL);
 
 				/* and parse the source */
 				yyparse();
diff --git a/src/interfaces/ecpg/preproc/extern.h b/src/interfaces/ecpg/preproc/extern.h
index 43a15394af3d86c92f548255e471c6778c7c1b67..1f25d0824dd0c736d1a63f89199b76e3f3a92046 100644
--- a/src/interfaces/ecpg/preproc/extern.h
+++ b/src/interfaces/ecpg/preproc/extern.h
@@ -3,7 +3,7 @@
 
 /* variables */
 
-extern int  braces_open;
+extern int  braces_open, no_auto_trans;
 extern char *yytext;
 extern int	yylineno,
 			yyleng;
@@ -25,6 +25,13 @@ struct cursor { char *name;
                                            
 extern struct cursor *cur;
 
+struct _defines { char *old;
+                  char *new;
+                  struct _defines *next;
+                };
+
+extern struct _defines *defines;
+                                                                                        
 /* This is a linked list of the variable names and types. */
 struct variable
 {
diff --git a/src/interfaces/ecpg/preproc/pgc.l b/src/interfaces/ecpg/preproc/pgc.l
index f578ec8c766fe1c572ceebdc4ce034eabb82d518..5336d132bf9121ef99690a8b5d31fd34265fc056 100644
--- a/src/interfaces/ecpg/preproc/pgc.l
+++ b/src/interfaces/ecpg/preproc/pgc.l
@@ -46,9 +46,12 @@ struct _yy_buffer { YY_BUFFER_STATE 	buffer;
 		    struct _yy_buffer * next;
 		  } *yy_buffer = NULL;
 
+struct _defines *defines = NULL;
+static char *old;
+
 %}
 %option yylineno
-%s C SQL incl
+%s C SQL incl def def_ident
 /* OK, here is a short description of lex/flex rules behavior.
  * The longest pattern which matches an input string is always chosen.
  * For equal-length patterns, the first occurring in the rules list is chosen.
@@ -156,6 +159,7 @@ other			.
 /* some stuff needed for ecpg */
 ccomment	"//".*\n
 exec    [eE][xX][eE][cC]
+define	[dD][eE][fF][iI][nN][eE]
 include [iI][nN][cC][lL][uU][dD][eE]
 sql     [sS][qQ][lL]
 
@@ -307,7 +311,6 @@ cppline		{space}*#.*(\\{space}*\n)*\n*
 
 
 <SQL>{typecast}			{ 	return TYPECAST; }
-
 <SQL>{self}/{space}*-[\.0-9]	{
 					BEGIN(xm);
 					return (yytext[0]);
@@ -328,7 +331,6 @@ cppline		{space}*#.*(\\{space}*\n)*\n*
 					yylval.ival = atoi((char*)&yytext[1]);
 					return (PARAM);
 				}
-
 <SQL>{identifier}/{space}*-{number}	{
 					int i;
 					ScanKeyword		*keyword;
@@ -350,12 +352,36 @@ cppline		{space}*#.*(\\{space}*\n)*\n*
 						}
 						else
 						{
-							yylval.str = strdup((char*)yytext);
-							return (IDENT);
+							struct _defines *ptr;
+
+							for (ptr = defines; ptr; ptr = ptr->next)
+							{
+								if (strcmp(yytext, ptr->old) == 0)
+								{
+									struct _yy_buffer *yb;
+
+									yb = mm_alloc(sizeof(struct _yy_buffer));
+
+						                        yb->buffer =  YY_CURRENT_BUFFER;
+						                        yb->lineno = yylineno;
+						                        yb->filename = strdup(input_filename);
+						                        yb->next = yy_buffer;
+
+						                        yy_buffer = yb;
+
+ 									yy_scan_string(ptr->new);
+									break;
+								}
+							}
+							if (ptr == NULL) 
+							{
+								yylval.str = strdup((char*)yytext);
+								return (IDENT);
+							}
 						}
 					}
 				}
-{integer}/{space}*-{number}	{
+<SQL>{integer}/{space}*-{number}	{
 					char* endptr;
 
 					BEGIN(xm);
@@ -372,7 +398,7 @@ cppline		{space}*#.*(\\{space}*\n)*\n*
 					}
 					return (ICONST);
 				}
-{real}/{space}*-{number} {
+<SQL>{real}/{space}*-{number} {
 					char* endptr;
 
 					BEGIN(xm);
@@ -382,7 +408,7 @@ cppline		{space}*#.*(\\{space}*\n)*\n*
 						yyerror("ERROR: Bad float8 input");
 					return (FCONST);
 				}
-{integer}		{
+<SQL>{integer}		{
 					char* endptr;
 
 					errno = 0;
@@ -398,7 +424,7 @@ cppline		{space}*#.*(\\{space}*\n)*\n*
 					}
 					return (ICONST);
 				}
-{real}			{
+<SQL>{real}			{
 					char* endptr;
 
 					errno = 0;
@@ -407,7 +433,39 @@ cppline		{space}*#.*(\\{space}*\n)*\n*
 						yyerror("ERROR: Bad float input");
 					return (FCONST);
 				}
+<C>{integer}/{space}*-{number}	{
+					char* endptr;
 
+					BEGIN(xm);
+					errno = 0;
+					yylval.ival = strtol((char *)yytext,&endptr,10);
+					if (*endptr != '\0' || errno == ERANGE)
+					{
+						errno = 0;
+						yylval.dval = strtod(((char *)yytext),&endptr);
+						if (*endptr != '\0' || errno == ERANGE)
+							yyerror("ERROR: Bad integer input");
+						yyerror("WARNING: Integer input is out of range; promoted to float");
+						return (FCONST);
+					}
+					return (ICONST);
+				}
+<C>{integer}		{
+					char* endptr;
+
+					errno = 0;
+					yylval.ival = strtol((char *)yytext,&endptr,10);
+					if (*endptr != '\0' || errno == ERANGE)
+					{
+						errno = 0;
+						yylval.dval = strtod(((char *)yytext),&endptr);
+						if (*endptr != '\0' || errno == ERANGE)
+							yyerror("ERROR: Bad integer input");
+						yyerror("WARNING: Integer input is out of range; promoted to float");
+						return (FCONST);
+					}
+					return (ICONST);
+				}
 <SQL>:{identifier}(("->"|\.){identifier})*	{
 					yylval.str = strdup((char*)yytext+1);
 					return(CVARIABLE);
@@ -432,15 +490,38 @@ cppline		{space}*#.*(\\{space}*\n)*\n*
 						}
 						else
 						{
-							yylval.str = strdup((char*)yytext);
-							return (IDENT);
+							struct _defines *ptr;
+
+							for (ptr = defines; ptr; ptr = ptr->next)
+							{
+								if (strcmp(yytext, ptr->old) == 0)
+								{
+									struct _yy_buffer *yb;
+
+									yb = mm_alloc(sizeof(struct _yy_buffer));
+
+						                        yb->buffer =  YY_CURRENT_BUFFER;
+						                        yb->lineno = yylineno;
+						                        yb->filename = strdup(input_filename);
+						                        yb->next = yy_buffer;
+
+						                        yy_buffer = yb;
+
+ 									yy_scan_string(ptr->new);
+									break;
+								}
+							}
+							if (ptr == NULL) 
+							{
+								yylval.str = strdup((char*)yytext);
+								return (IDENT);
+							}
 						}
 					}
 				}
 <SQL>{space}			{ /* ignore */ }
 <SQL>";"	                { BEGIN C; return SQL_SEMI; }
 <SQL>{other}			{ return (yytext[0]); }
-
 <C>{exec}{space}{sql}		{ BEGIN SQL; return SQL_START; }
 <C>{ccomment}			{ /* ignore */ } 
 <C>{cppline}			{
@@ -456,8 +537,32 @@ cppline		{space}*#.*(\\{space}*\n)*\n*
 					}
 					else
 					{
-						yylval.str = strdup((char*)yytext);
-						return (IDENT);
+						struct _defines *ptr;
+
+						for (ptr = defines; ptr; ptr = ptr->next)
+						{
+							if (strcmp(yytext, ptr->old) == 0)
+							{
+								struct _yy_buffer *yb;
+
+								yb = mm_alloc(sizeof(struct _yy_buffer));
+
+					                        yb->buffer =  YY_CURRENT_BUFFER;
+					                        yb->lineno = yylineno;
+					                        yb->filename = strdup(input_filename);
+					                        yb->next = yy_buffer;
+
+					                        yy_buffer = yb;
+
+								yy_scan_string(ptr->new);
+								break;
+							}
+						}
+						if (ptr == NULL) 
+						{
+							yylval.str = strdup((char*)yytext);
+							return (IDENT);
+						}
 					}
 				}
 <C>";"	      	        { return(';'); }
@@ -470,6 +575,45 @@ cppline		{space}*#.*(\\{space}*\n)*\n*
 <C>\]			{ return(']'); }
 <C>\=			{ return('='); }
 <C>{other}			{ return (S_ANYTHING); }
+<C>{exec}{space}{sql}{space}{define}	{BEGIN(def_ident);}
+<def_ident>{space}	{}
+<def_ident>{identifier}	{
+				old = strdup(yytext);
+				BEGIN(def);
+				llen = 0;
+				*literal = '\0';
+			}
+<def>{space}		/* eat the whitespace */
+<def>";"		{
+				struct _defines *ptr, *this;
+        
+                                for (ptr = defines; ptr != NULL; ptr = ptr->next)
+                                {
+                                     if (strcmp(old, ptr->old) == 0)
+                                     {
+					free(ptr->new);
+					ptr->new = strdup(scanstr(literal));
+                                     }
+                                }
+				if (ptr == NULL)
+				{                        
+                                        this = (struct _defines *) mm_alloc(sizeof(struct _defines));
+
+                                        /* initial definition */
+                                        this->old = old;
+                                        this->new = strdup(scanstr(literal));
+					this->next = defines;
+					defines = this;
+				}
+
+				BEGIN(C);
+			}
+<def>[^";"]		{
+				if ((llen+yyleng) > (MAX_PARSE_BUFFER - 1))
+					yyerror("ERROR: define statement parse buffer exceeded");
+				memcpy(literal+llen, yytext, yyleng+1);
+				llen += yyleng;
+			}
 <C>{exec}{space}{sql}{space}{include}	{ BEGIN(incl); }
 <incl>{space}		/* eat the whitespace */
 <incl>[^ \t\n]+ 	{ /* got the include file name */
diff --git a/src/interfaces/ecpg/preproc/preproc.y b/src/interfaces/ecpg/preproc/preproc.y
index 4d6960e406bd3d526c6f0cc3959b9499b5ce10e4..5f67ff48d4236e8fe19f8ea978a38d4eeebea111 100644
--- a/src/interfaces/ecpg/preproc/preproc.y
+++ b/src/interfaces/ecpg/preproc/preproc.y
@@ -620,7 +620,7 @@ output_statement(char * stmt, int mode)
 %type  <str> 	ColId default_expr ColQualifier columnDef ColQualList
 %type  <str>    ColConstraint ColConstraintElem default_list NumericOnly FloatOnly
 %type  <str>    OptTableElementList OptTableElement TableConstraint
-%type  <str>    ConstraintElem key_actions constraint_list TypeId
+%type  <str>    ConstraintElem key_actions constraint_list
 %type  <str>    res_target_list res_target_el res_target_list2
 %type  <str>    res_target_el2 opt_id relation_name database_name
 %type  <str>    access_method attr_name class index_name name func_name
@@ -636,12 +636,12 @@ output_statement(char * stmt, int mode)
 %type  <str>	SelectStmt union_clause select_list SubSelect result
 %type  <str>	opt_table opt_union opt_unique sort_clause sortby_list
 %type  <str>	sortby OptUseOp opt_inh_star relation_name_list name_list
-%type  <str>	group_clause groupby_list groupby having_clause from_clause
+%type  <str>	group_clause having_clause from_clause c_list 
 %type  <str>	from_list from_val join_expr join_outer join_spec join_list
 %type  <str> 	join_using where_clause relation_expr row_op sub_type
 %type  <str>	opt_column_list insert_rest InsertStmt OptimizableStmt
 %type  <str>    columnList DeleteStmt LockStmt UpdateStmt CursorStmt
-%type  <str>    NotifyStmt columnElem copy_dirn SubUnion
+%type  <str>    NotifyStmt columnElem copy_dirn SubUnion c_expr
 %type  <str>    copy_delimiter ListenStmt CopyStmt copy_file_name opt_binary
 %type  <str>    opt_with_copy FetchStmt opt_direction fetch_how_many opt_portal_name
 %type  <str>    ClosePortalStmt DestroyStmt VacuumStmt opt_verbose
@@ -652,7 +652,7 @@ output_statement(char * stmt, int mode)
 %type  <str>    def_elem def_list definition def_name def_type DefineStmt
 %type  <str>    opt_instead event event_object OptStmtMulti OptStmtBlock
 %type  <str>    OptStmtList RuleStmt opt_column opt_name oper_argtypes
-%type  <str>    MathOp RemoveOperStmt RemoveFuncStmt aggr_argtype
+%type  <str>    MathOp RemoveFuncStmt aggr_argtype
 %type  <str>    RemoveAggrStmt remove_type RemoveStmt ExtendStmt RecipeStmt
 %type  <str>    RemoveOperStmt RenameStmt all_Op user_valid_clause
 %type  <str>    VariableSetStmt var_value zone_value VariableShowStmt
@@ -661,7 +661,7 @@ output_statement(char * stmt, int mode)
 %type  <str>    user_createuser_clause user_group_list user_group_clause
 %type  <str>    CreateUserStmt AlterUserStmt CreateSeqStmt OptSeqList
 %type  <str>    OptSeqElem TriggerForSpec TriggerForOpt TriggerForType
-%type  <str>	TriggerFuncArgs DropTrigStmt TriggerOneEvent TriggerEvents
+%type  <str>	DropTrigStmt TriggerOneEvent TriggerEvents
 %type  <str>    TriggerActionTime CreateTrigStmt DropPLangStmt PLangTrusted
 %type  <str>    CreatePLangStmt IntegerOnly TriggerFuncArgs TriggerFuncArg
 %type  <str>    ViewStmt LoadStmt CreatedbStmt opt_database1 opt_database2 location
@@ -669,7 +669,7 @@ output_statement(char * stmt, int mode)
 %type  <str>	GrantStmt privileges operation_commalist operation
 
 %type  <str>	ECPGWhenever ECPGConnect connection_target ECPGOpen open_opts
-%type  <str>	indicator ECPGExecute c_expr variable_list dotext
+%type  <str>	indicator ECPGExecute ecpg_expr dotext
 %type  <str>    storage_clause opt_initializer vartext c_anything blockstart
 %type  <str>    blockend variable_list variable var_anything do_anything
 %type  <str>	opt_pointer cvariable ECPGDisconnect dis_name
@@ -756,6 +756,7 @@ stmt:  AddAttrStmt			{ output_statement($1, 0); }
 		| VariableShowStmt	{ output_statement($1, 0); }
 		| VariableResetStmt	{ output_statement($1, 0); }
 		| ECPGConnect		{
+						fprintf(yyout, "no_auto_trans = %d;\n", no_auto_trans);
 						fprintf(yyout, "ECPGconnect(__LINE__, %s);", $1);
 						whenever_action(0);
 						free($1);
@@ -1307,6 +1308,8 @@ constraint_expr:  AexprConst
 				{	$$ = cat3_str($1, $2, $3); }
 			| constraint_expr LIKE constraint_expr
 				{	$$ = cat3_str($1, make1_str("like"), $3); }
+			| constraint_expr NOT LIKE constraint_expr
+				{	$$ = cat3_str($1, make1_str("not like"), $4); }
 			| constraint_expr AND constraint_expr
 				{	$$ = cat3_str($1, make1_str("and"), $3); }
 			| constraint_expr OR constraint_expr
@@ -1333,7 +1336,28 @@ constraint_expr:  AexprConst
 				{	$$ = cat2_str($1, make1_str("is not true")); }
 			| constraint_expr IS NOT FALSE_P
 				{	$$ = cat2_str($1, make1_str("is not false")); }
-		;
+			| constraint_expr IN '(' c_list ')'
+				{	$$ = cat4_str($1, make1_str("in ("), $4, make1_str(")")); }
+			| constraint_expr NOT IN '(' c_list ')'
+				{	$$ = cat4_str($1, make1_str("not in ("), $5, make1_str(")")); }
+			| constraint_expr BETWEEN c_expr AND c_expr
+				{	$$ = cat5_str($1, make1_str("between"), $3, make1_str("and"), $5); }
+			| constraint_expr NOT BETWEEN c_expr AND c_expr
+				{	$$ = cat5_str($1, make1_str("not between"), $4, make1_str("and"), $6); }
+		;
+c_list:  c_list ',' c_expr
+	{
+		$$ = make3_str($1, make1_str(", "), $3);
+	}
+	| c_expr
+	{
+		$$ = $1;
+	}
+
+c_expr:  AexprConst
+	{
+		$$ = $1;
+	}
 
 key_match:  MATCH FULL					{ $$ = make1_str("match full"); }
 		| MATCH PARTIAL					{ $$ = make1_str("match partial"); }
@@ -2025,6 +2049,7 @@ RuleStmt:  CREATE RULE name AS
 OptStmtList:  NOTHING					{ $$ = make1_str("nothing"); }
 		| OptimizableStmt			{ $$ = $1; }
 		| '[' OptStmtBlock ']'			{ $$ = cat3_str(make1_str("["), $2, make1_str("]")); }
+		| '(' OptStmtBlock ')'			{ $$ = cat3_str(make1_str("("), $2, make1_str(")")); }
 		;
 
 OptStmtBlock:  OptStmtMulti
@@ -2480,18 +2505,10 @@ sortby_list:  sortby					{ $$ = $1; }
 		| sortby_list ',' sortby		{ $$ = cat3_str($1, make1_str(","), $3); }
 		;
 
-sortby:  ColId OptUseOp
-				{
-					$$ = cat2_str($1, $2);
-				}
-		| ColId '.' ColId OptUseOp
+sortby: a_expr OptUseOp
 				{
-					$$ = cat2_str(make3_str($1, make1_str("."), $3), $4);
-				}
-		| Iconst OptUseOp
-				{
-					$$ = cat2_str($1, $2);
-				}
+					 $$ = cat2_str($1, $2);
+                                }
 		;
 
 OptUseOp:  USING Op				{ $$ = cat2_str(make1_str("using"), $2); }
@@ -2521,28 +2538,10 @@ name_list:  name
 				{	$$ = cat3_str($1, make1_str(","), $3); }
 		;
 
-group_clause:  GROUP BY groupby_list			{ $$ = cat2_str(make1_str("groub by"), $3); }
+group_clause:  GROUP BY expr_list			{ $$ = cat2_str(make1_str("groub by"), $3); }
 		| /*EMPTY*/				{ $$ = make1_str(""); }
 		;
 
-groupby_list:  groupby					{ $$ = $1; }
-		| groupby_list ',' groupby		{ $$ = cat3_str($1, make1_str(","), $3); }
-		;
-
-groupby:  ColId
-				{
-					$$ = $1;
-				}
-		| ColId '.' ColId
-				{
-					$$ = make3_str($1, make1_str(","), $3);
-				}
-		| Iconst
-				{
-					$$ = $1;
-				}
-		;
-
 having_clause:  HAVING a_expr
 				{
 					$$ = cat2_str(make1_str("having"), $2);
@@ -3410,11 +3409,11 @@ b_expr:  attr opt_indirection
 			        { $$ = make1_str(";;"); }
 		;
 
-opt_indirection:  '[' c_expr ']' opt_indirection
+opt_indirection:  '[' ecpg_expr ']' opt_indirection
 				{
 					$$ = cat4_str(make1_str("["), $2, make1_str("]"), $4);
 				}
-		| '[' c_expr ':' c_expr ']' opt_indirection
+		| '[' ecpg_expr ':' ecpg_expr ']' opt_indirection
 				{
 					$$ = cat2_str(cat5_str(make1_str("["), $2, make1_str(":"), $4, make1_str("]")), $6);
 				}
@@ -4353,7 +4352,7 @@ action : SQL_CONTINUE {
 
 /* some other stuff for ecpg */
 
-c_expr:  attr opt_indirection
+ecpg_expr:  attr opt_indirection
 				{
 					$$ = cat2_str($1, $2);
 				}
@@ -4365,27 +4364,27 @@ c_expr:  attr opt_indirection
 				{
 					$$ = $1;
 				}
-		| '-' c_expr %prec UMINUS
+		| '-' ecpg_expr %prec UMINUS
 				{	$$ = cat2_str(make1_str("-"), $2); }
-		| a_expr '+' c_expr
+		| a_expr '+' ecpg_expr
 				{	$$ = cat3_str($1, make1_str("+"), $3); }
-		| a_expr '-' c_expr
+		| a_expr '-' ecpg_expr
 				{	$$ = cat3_str($1, make1_str("-"), $3); }
-		| a_expr '/' c_expr
+		| a_expr '/' ecpg_expr
 				{	$$ = cat3_str($1, make1_str("/"), $3); }
-		| a_expr '*' c_expr
+		| a_expr '*' ecpg_expr
 				{	$$ = cat3_str($1, make1_str("*"), $3); }
-		| a_expr '<' c_expr
+		| a_expr '<' ecpg_expr
 				{	$$ = cat3_str($1, make1_str("<"), $3); }
-		| a_expr '>' c_expr
+		| a_expr '>' ecpg_expr
 				{	$$ = cat3_str($1, make1_str(">"), $3); }
-		| a_expr '=' c_expr
+		| a_expr '=' ecpg_expr
 				{	$$ = cat3_str($1, make1_str("="), $3); }
-	/*	| ':' c_expr
+	/*	| ':' ecpg_expr
 				{	$$ = cat2_str(make1_str(":"), $2); }*/
-		| ';' c_expr
+		| ';' ecpg_expr
 				{	$$ = cat2_str(make1_str(";"), $2); }
-		| '|' c_expr
+		| '|' ecpg_expr
 				{	$$ = cat2_str(make1_str("|"), $2); }
 		| a_expr TYPECAST Typename
 				{
@@ -4397,13 +4396,13 @@ c_expr:  attr opt_indirection
 				}
 		| '(' a_expr_or_null ')'
 				{	$$ = make3_str(make1_str("("), $2, make1_str(")")); }
-		| a_expr Op c_expr
+		| a_expr Op ecpg_expr
 				{	$$ = cat3_str($1, $2, $3);	}
-		| a_expr LIKE c_expr
+		| a_expr LIKE ecpg_expr
 				{	$$ = cat3_str($1, make1_str("like"), $3); }
-		| a_expr NOT LIKE c_expr
+		| a_expr NOT LIKE ecpg_expr
 				{	$$ = cat3_str($1, make1_str("not like"), $4); }
-		| Op c_expr
+		| Op ecpg_expr
 				{	$$ = cat2_str($1, $2); }
 		| a_expr Op
 				{	$$ = cat2_str($1, $2); }
@@ -4621,11 +4620,11 @@ c_expr:  attr opt_indirection
 				{
 					$$ = make4_str($1, make1_str("=all("), $5, make1_str(")")); 
 				}
-		| a_expr AND c_expr
+		| a_expr AND ecpg_expr
 				{	$$ = cat3_str($1, make1_str("and"), $3); }
-		| a_expr OR c_expr
+		| a_expr OR ecpg_expr
 				{	$$ = cat3_str($1, make1_str("or"), $3); }
-		| NOT c_expr
+		| NOT ecpg_expr
 				{	$$ = cat2_str(make1_str("not"), $2); }
 		| civariableonly
 			        { $$ = make1_str(";;"); }