diff --git a/src/interfaces/ecpg/ChangeLog b/src/interfaces/ecpg/ChangeLog
index 8131d499f67040b3d75f6d8fd650af983102e266..1907471a731cceb061ef6bc473a0383cfdbd26d5 100644
--- a/src/interfaces/ecpg/ChangeLog
+++ b/src/interfaces/ecpg/ChangeLog
@@ -258,3 +258,15 @@ Tue Jul  7 15:14:14 CEST 1998
 
 	- Fixed some bugs in preproc.y
 	- Set version to 2.3.4
+
+Mon Jul 27 17:13:11 CEST 1998
+
+	- Changed text of error message to make emacs happy
+
+Mon Aug  3 17:23:18 CEST 1998
+
+	- Added latest changes from gram.y resp. scan.l to
+	  preproc.y resp. pgc.l
+	- Fixed cursor handling
+	- Set version to 2.3.5
+	- Set library version to 2.4
diff --git a/src/interfaces/ecpg/TODO b/src/interfaces/ecpg/TODO
index b174b56e5e9ea3fbbbd60e2ae4decb867597174d..5811cb767de7b102aa2ae4e9d082cafa23b5013e 100644
--- a/src/interfaces/ecpg/TODO
+++ b/src/interfaces/ecpg/TODO
@@ -1,3 +1,5 @@
+What happens to a cursor declaration with variables?
+
 The complete structure definition has to be listed inside the declare
 section of the structure variable for ecpg to be able to understand it.
 
diff --git a/src/interfaces/ecpg/include/ecpgerrno.h b/src/interfaces/ecpg/include/ecpgerrno.h
index cddc7e6a686afca3966a63079895d007c9da360b..f9373557e9b68e4434cf011a3bd188e79521d13c 100644
--- a/src/interfaces/ecpg/include/ecpgerrno.h
+++ b/src/interfaces/ecpg/include/ecpgerrno.h
@@ -23,6 +23,7 @@
 #define ECPG_CONVERT_BOOL	-207
 #define ECPG_EMPTY		-208
 #define ECPG_NO_CONN		-209
+#define ECPG_UNDECLARED_CURSOR	-210
 
 /* finally the backend error messages, they start at 300 */
 #define ECPG_PGSQL		-300
diff --git a/src/interfaces/ecpg/include/ecpglib.h b/src/interfaces/ecpg/include/ecpglib.h
index c0603b2e7f547b79fb3bbfb7a32ec4d8785f483c..a81ca7e8b9cda3139ae9fc3955d4d3796f4bf4db 100644
--- a/src/interfaces/ecpg/include/ecpglib.h
+++ b/src/interfaces/ecpg/include/ecpglib.h
@@ -13,6 +13,9 @@ bool		ECPGdisconnect(int, const char *);
 
 void		ECPGlog(const char *format,...);
 
+bool		ECPGdeclare(int, const char *, char *);
+bool		ECPGopen(int, const char *);
+
 #ifdef LIBPQ_FE_H
 bool		ECPGsetdb(PGconn *);
 
@@ -32,6 +35,11 @@ struct ECPGgeneric_varchar
 /* print an error message */
 void		sqlprint(void);
 
+struct cursor {	const char *name;
+		char *command;
+		struct cursor *next;
+	      };
+
 /* define this for simplicity as well as compatibility */
 
 #define		  SQLCODE	 sqlca.sqlcode
diff --git a/src/interfaces/ecpg/lib/Makefile.in b/src/interfaces/ecpg/lib/Makefile.in
index 6387a203419739bcabfff359a6b6ed44e39f3b6d..8fd6b7720302382cb873202c9da1017d264f6bda 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=3
+SO_MINOR_VERSION=4
 
 PORTNAME=@PORTNAME@
 
diff --git a/src/interfaces/ecpg/lib/ecpglib.c b/src/interfaces/ecpg/lib/ecpglib.c
index ecbd2354617998d5b104fbe5748bdb3ab0ca5ea5..86021d6ee461b381372910f04748ab32a7efb489 100644
--- a/src/interfaces/ecpg/lib/ecpglib.c
+++ b/src/interfaces/ecpg/lib/ecpglib.c
@@ -940,3 +940,56 @@ sqlprint(void)
 	sqlca.sqlerrm.sqlerrmc[sqlca.sqlerrm.sqlerrml] = '\0';
 	printf("sql error %s\n", sqlca.sqlerrm.sqlerrmc);
 }
+
+/* keep a list of cursors */
+struct cursor *cur = NULL;
+
+bool ECPGdeclare(int lineno, const char *name, char *command)
+{
+	struct cursor *ptr;
+	
+	for (ptr = cur; ptr != NULL; ptr = ptr->next)
+	{
+		if (strcmp(name, ptr->name) == 0)
+		{
+		        /* re-definition */
+           		free(ptr->command);
+                        ptr->command = command;
+                        break;
+                }
+        }
+                        
+        if (ptr == NULL)
+        {
+        	struct cursor *this = (struct cursor *) malloc(sizeof(struct cursor));
+
+		if (!this)
+		{
+		        ECPGlog("out of memory\n");
+		        register_error(ECPG_OUT_OF_MEMORY, "out of memory in line %d", lineno);
+                	return false;
+                }
+        	/* initial definition */
+	        this->next = cur;
+	        this->name = name;
+	        this->command = command;
+        	cur = this;
+	}
+	
+	return(true);
+}
+
+bool ECPGopen(int lineno, const char *name)
+{
+	struct cursor *ptr;
+
+        for (ptr = cur; ptr != NULL; ptr=ptr->next)
+        {
+               if (strcmp(ptr->name, name) == 0)
+                    return(ECPGdo(lineno, ptr->command, ECPGt_EOIT, ECPGt_EORT));
+        }
+
+	ECPGlog("trying to open undeclared cursor %s\n", name);
+	register_error(ECPG_UNDECLARED_CURSOR, "trying to open undeclared cursor %s in line %d", name, lineno);        
+        return(false);
+}
diff --git a/src/interfaces/ecpg/preproc/Makefile b/src/interfaces/ecpg/preproc/Makefile
index da392d205462feb4e20c73d82aa5e3b0150053ad..2b73c8ed88e09f278eefb1908ede0a172b7d9e02 100644
--- a/src/interfaces/ecpg/preproc/Makefile
+++ b/src/interfaces/ecpg/preproc/Makefile
@@ -3,11 +3,11 @@ include $(SRCDIR)/Makefile.global
 
 MAJOR_VERSION=2
 MINOR_VERSION=3
-PATCHLEVEL=4
+PATCHLEVEL=5
 
 CFLAGS+=-I../include -DMAJOR_VERSION=$(MAJOR_VERSION) \
 	-DMINOR_VERSION=$(MINOR_VERSION) -DPATCHLEVEL=$(PATCHLEVEL) \
-	-DINCLUDE_PATH=\"$(DESTDIR)$(HEADERDIR)\"
+	-DINCLUDE_PATH=\"$(DESTDIR)$(HEADERDIR)\" 
 
 OBJ=y.tab.o pgc.o type.o ecpg.o ecpg_keywords.o ../../../backend/parser/scansup.o \
     keywords.o c_keywords.o ../lib/typename.o
diff --git a/src/interfaces/ecpg/preproc/ecpg.c b/src/interfaces/ecpg/preproc/ecpg.c
index 825b292a5436cfd8ebab1487a95c812490f56c1c..f12b799850c035c9464d25631f65144beb2b4fd9 100644
--- a/src/interfaces/ecpg/preproc/ecpg.c
+++ b/src/interfaces/ecpg/preproc/ecpg.c
@@ -141,20 +141,6 @@ main(int argc, char *const argv[])
 				/* initialize lex */
 				lex_init();
 				
-				/* initialize cursor list */
-				for (ptr = cur; ptr != NULL;)
-				{
-					struct cursor *c;
-					
-					free(ptr->name);
-					free(ptr->command);
-					c = ptr;
-					ptr = ptr->next;
-					free(c);
-				}
-				
-				cur = NULL;
-				
 				/* 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);
 
diff --git a/src/interfaces/ecpg/preproc/extern.h b/src/interfaces/ecpg/preproc/extern.h
index e18bb33219c78e81099188e0e17646a01226f288..d2eec0c097807d426c0c12e81005f8b20ca32b33 100644
--- a/src/interfaces/ecpg/preproc/extern.h
+++ b/src/interfaces/ecpg/preproc/extern.h
@@ -16,13 +16,6 @@ struct _include_path {  char * path;
 
 extern struct _include_path *include_paths;
 
-struct cursor {	char *name;
-		char *command;
-		struct cursor *next;
-	      };
-
-extern struct cursor *cur;
-
 /* 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 eabc4fd6c6d69308179a87e626e4384eccf0d5dd..f578ec8c766fe1c572ceebdc4ce034eabb82d518 100644
--- a/src/interfaces/ecpg/preproc/pgc.l
+++ b/src/interfaces/ecpg/preproc/pgc.l
@@ -335,7 +335,7 @@ cppline		{space}*#.*(\\{space}*\n)*\n*
 
 					BEGIN(xm);
 					for(i = 0; yytext[i]; i++)
-						if (isupper(yytext[i]))
+						if (isascii((unsigned char)yytext[i]) && isupper(yytext[i]))
 							yytext[i] = tolower(yytext[i]);
 
 					keyword = ScanKeywordLookup((char*)yytext);
@@ -417,7 +417,7 @@ cppline		{space}*#.*(\\{space}*\n)*\n*
 					ScanKeyword		*keyword;
 
 					for(i = 0; yytext[i]; i++)
-						if (isupper(yytext[i]))
+						if (isascii((unsigned char)yytext[i]) && isupper(yytext[i]))
 							yytext[i] = tolower(yytext[i]);
 
 					keyword = ScanKeywordLookup((char*)yytext);
diff --git a/src/interfaces/ecpg/preproc/preproc.y b/src/interfaces/ecpg/preproc/preproc.y
index 6f320b06d500f6157573003d458fc86682192f72..290440a39f5c2517f8688df38118c91e1ea7b43c 100644
--- a/src/interfaces/ecpg/preproc/preproc.y
+++ b/src/interfaces/ecpg/preproc/preproc.y
@@ -8,6 +8,10 @@
 #include "type.h"
 #include "extern.h"
 
+#ifdef MULTIBYTE
+#include "mb/pg_wchar.h"
+#endif
+
 #define STRUCT_DEPTH 128
 
 /*
@@ -22,9 +26,6 @@ static char     *actual_storage[STRUCT_DEPTH];
 /* temporarily store struct members while creating the data structure */
 struct ECPGstruct_member *struct_member_list[STRUCT_DEPTH] = { NULL };
 
-/* keep a list of cursors */
-struct cursor *cur = NULL;
-
 struct ECPGtype ecpg_no_indicator = {ECPGt_NO_INDICATOR, 0L, {NULL}};
 struct variable no_indicator = {"no_indicator", &ecpg_no_indicator, 0, NULL};
 
@@ -542,7 +543,7 @@ output_statement(char * stmt, int mode)
                 GRANT, GROUP, HAVING, HOUR_P,
                 IN, INNER_P, INSERT, INTERVAL, INTO, IS,
                 JOIN, KEY, LANGUAGE, LEADING, LEFT, LIKE, LOCAL,
-                MATCH, MINUTE_P, MONTH_P,
+                MATCH, MINUTE_P, MONTH_P, NAMES,
                 NATIONAL, NATURAL, NCHAR, NO, NOT, NOTIFY, NULL_P, NUMERIC,
                 ON, OPTION, OR, ORDER, OUTER_P,
                 PARTIAL, POSITION, PRECISION, PRIMARY, PRIVILEGES, PROCEDURE, PUBLIC,
@@ -570,7 +571,7 @@ output_statement(char * stmt, int mode)
                 NEW, NONE, NOTHING, NOTNULL, OIDS, OPERATOR, PROCEDURAL,
                 RECIPE, RENAME, RESET, RETURNS, ROW, RULE,
                 SEQUENCE, SETOF, SHOW, START, STATEMENT, STDIN, STDOUT, TRUSTED,
-                VACUUM, VERBOSE, VERSION
+                VACUUM, VERBOSE, VERSION, ENCODING
 
 /* Keywords (obsolete; retain through next version for parser - thomas 1997-12-0 4) */
 %token  ARCHIVE
@@ -614,21 +615,20 @@ output_statement(char * stmt, int mode)
 %left		'.'
 %left		'[' ']'
 %nonassoc	TYPECAST
-%nonassoc	REDUCE
 %left		UNION
 
-%type  <str>	Iconst Sconst TransactionStmt CreateStmt UserId
+%type  <str>	Iconst Fconst Sconst TransactionStmt CreateStmt UserId
 %type  <str>	CreateAsElement OptCreateAs CreateAsList CreateAsStmt
 %type  <str>	OptArchiveType OptInherit key_reference key_action
 %type  <str>    key_match constraint_expr ColLabel SpecialRuleRelation
 %type  <str> 	ColId default_expr ColQualifier columnDef ColQualList
-%type  <str>    ColConstraint ColConstraintElem default_list
+%type  <str>    ColConstraint ColConstraintElem default_list NumericOnly FloatOnly
 %type  <str>    OptTableElementList OptTableElement TableConstraint
 %type  <str>    ConstraintElem key_actions constraint_list TypeId
 %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
-%type  <str>    file_name recipe_name AexprConst ParamNo NumConst TypeId
+%type  <str>    file_name recipe_name AexprConst ParamNo TypeId
 %type  <str>	in_expr_nodes not_in_expr_nodes a_expr b_expr
 %type  <str> 	opt_indirection expr_list extract_list extract_arg
 %type  <str>	position_list position_expr substr_list substr_from
@@ -645,7 +645,7 @@ output_statement(char * stmt, int mode)
 %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 
+%type  <str>    NotifyStmt columnElem copy_dirn SubUnion
 %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
@@ -661,15 +661,15 @@ output_statement(char * stmt, int mode)
 %type  <str>    RemoveOperStmt RenameStmt all_Op user_valid_clause
 %type  <str>    VariableSetStmt var_value zone_value VariableShowStmt
 %type  <str>    VariableResetStmt AddAttrStmt alter_clause DropUserStmt
-%type  <str>    user_passwd_clause user_createdb_clause
+%type  <str>    user_passwd_clause user_createdb_clause opt_trans
 %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>    TriggerActionTime CreateTrigStmt DropPLangStmt PLangTrusted
 %type  <str>    CreatePLangStmt IntegerOnly TriggerFuncArgs TriggerFuncArg
-%type  <str>    ViewStmt LoadStmt CreatedbStmt opt_database location
-%type  <str>    DestroydbStmt ClusterStmt grantee RevokeStmt
+%type  <str>    ViewStmt LoadStmt CreatedbStmt opt_database1 opt_database2 location
+%type  <str>    DestroydbStmt ClusterStmt grantee RevokeStmt encoding
 %type  <str>	GrantStmt privileges operation_commalist operation
 
 %type  <str>	ECPGWhenever ECPGConnect connection_target ECPGOpen open_opts
@@ -737,10 +737,10 @@ stmt:  AddAttrStmt			{ output_statement($1, 0); }
 		| RenameStmt		{ output_statement($1, 0); }
 		| RevokeStmt		{ output_statement($1, 0); }
                 | OptimizableStmt	{
-						if (strncmp($1, "/* declare" , sizeof("/* declare")-1) == 0)
+						if (strncmp($1, "ECPGdeclare" , sizeof("ECPGdeclare")-1) == 0)
 						{
 							fputs($1, yyout);
-							output_line_number();
+							whenever_action(0);
 							free($1);
 						}
 						else
@@ -775,7 +775,10 @@ stmt:  AddAttrStmt			{ output_statement($1, 0); }
 						whenever_action(0);
 						free($1);
 					}
-		| ECPGOpen		{ output_statement($1, 0); }
+		| ECPGOpen		{	fprintf(yyout, "ECPGopen(__LINE__, %s);", $1);
+						whenever_action(0);
+						free($1);
+					}
 		| ECPGRelease		{ /* output already done */ }
 		| ECPGSetConnection     {
 						fprintf(yyout, "ECPGsetconn(__LINE__, %s);", $1);
@@ -898,8 +901,15 @@ VariableSetStmt:  SET ColId TO var_value
 				{
 					$$ = cat2_str(make1_str("set time zone"), $4);
 				}
-
-		;
+		| SET NAMES encoding
+                                {
+#ifdef MB
+					$$ = cat2_str(make1_str("set names"), $3);
+#else
+                                        yyerror("SET NAMES is not supported");
+#endif
+                                }
+                ;
 
 var_value:  Sconst			{ $$ = $1; }
 		| DEFAULT			{ $$ = make1_str("default"); }
@@ -1403,6 +1413,20 @@ OptSeqElem:  CACHE IntegerOnly
 				}
 		;
 
+NumericOnly:  FloatOnly         { $$ = $1; }
+		| IntegerOnly   { $$ = $1; }
+
+FloatOnly:  Fconst
+                               {
+                                       $$ = $1;
+                               }
+                       | '-' Fconst
+                               {
+                                       $$ = cat2_str(make1_str("-"), $2);
+                               }
+               ;
+
+
 IntegerOnly:  Iconst
 				{
 					$$ = $1;
@@ -1502,9 +1526,9 @@ TriggerFuncArg:  Iconst
 				{
 					$$ = $1;
 				}
-			| FCONST
+			| Fconst
 				{
-					$$ = make_name();
+					$$ = $1;
 				}
 			| Sconst	{  $$ = $1; }
 			| ident		{  $$ = $1; }
@@ -1569,7 +1593,7 @@ def_elem:  def_name '=' def_arg	{
 
 def_arg:  ColId			{  $$ = $1; }
 		| all_Op	{  $$ = $1; }
-		| NumConst	{  $$ = $1; /* already a Value */ }
+		| NumericOnly	{  $$ = $1; }
 		| Sconst	{  $$ = $1; }
 		| SETOF ColId
 				{
@@ -2056,15 +2080,16 @@ ListenStmt:  LISTEN relation_name
  *                              (END)
  *
  *****************************************************************************/
-TransactionStmt:  ABORT_TRANS TRANSACTION	{ $$ = make1_str("rollback"); }
-	| BEGIN_TRANS TRANSACTION		{ $$ = make1_str("begin transaction"); }
-	| BEGIN_TRANS WORK			{ $$ = make1_str("begin transaction"); }
-	| COMMIT WORK				{ $$ = make1_str("commit"); }
-	| END_TRANS TRANSACTION			{ $$ = make1_str("commit"); }
-	| ROLLBACK WORK				{ $$ = make1_str("rollback"); }
-	| ABORT_TRANS				{ $$ = make1_str("rollback"); }
-	| COMMIT				{ $$ = make1_str("commit"); }
-	| ROLLBACK				{ $$ = make1_str("rollback"); }
+TransactionStmt:  ABORT_TRANS opt_trans	{ $$ = make1_str("rollback"); }
+	| BEGIN_TRANS opt_trans		{ $$ = make1_str("begin transaction"); }
+	| COMMIT opt_trans		{ $$ = make1_str("commit"); }
+	| END_TRANS opt_trans			{ $$ = make1_str("commit"); }
+	| ROLLBACK opt_trans			{ $$ = make1_str("rollback"); }
+
+opt_trans: WORK 	{ $$ = ""; }
+	| TRANSACTION	{ $$ = ""; }
+	| /*EMPTY*/	{ $$ = ""; }
+                ;
 
 /*****************************************************************************
  *
@@ -2101,21 +2126,40 @@ LoadStmt:  LOAD file_name
  *
  *****************************************************************************/
 
-CreatedbStmt:  CREATE DATABASE database_name opt_database
+CreatedbStmt:  CREATE DATABASE database_name WITH opt_database1 opt_database2
 				{
-					$$ = cat3_str(make1_str("create database"), $3, $4);
+					if (strlen($5) == 0 || strlen($6) == 0) 
+						yyerror("CREATE DATABASE WITH requires at least an option");
+#ifndef MULTIBYTE
+					if (strlen($6) != 0)
+						yyerror("WITH ENCODING is not supported");
+#endif
+					$$ = cat5_str(make1_str("create database"), $3, make1_str("with"), $5, $6);
+				}
+		| CREATE DATABASE database_name
+        			{
+					$$ = cat2_str(make1_str("create database"), $3);
 				}
 		;
 
-opt_database:  WITH LOCATION '=' location	{ $$ = cat2_str(make1_str("with location ="), $4); }
+opt_database1:  LOCATION '=' location	{ $$ = cat2_str(make1_str("location ="), $3); }
 		| /*EMPTY*/			{ $$ = make1_str(""); }
 		;
 
+opt_database2:  ENCODING '=' encoding   { $$ = cat2_str(make1_str("encoding ="), $3); }
+                | /*EMPTY*/	        { $$ = NULL; }
+                ;
+
 location:  Sconst				{ $$ = $1; }
 		| DEFAULT			{ $$ = make1_str("default"); }
 		| /*EMPTY*/			{ $$ = make1_str(""); }
 		;
 
+encoding:  Sconst		{ $$ = $1; }
+		| DEFAULT	{ $$ = make1_str("default"); }
+		| /*EMPTY*/	{ $$ = make1_str(""); }
+               ;
+
 /*****************************************************************************
  *
  *		QUERY:
@@ -2315,31 +2359,7 @@ CursorStmt:  DECLARE name opt_binary CURSOR FOR
 			 group_clause having_clause
 			 union_clause sort_clause
 				{
-					struct cursor *ptr, *this = (struct cursor *) mm_alloc(sizeof(struct cursor));
-
-					this->name = strdup($2);
-					this->command = cat4_str(cat5_str(cat5_str(make1_str("declare"), strdup($2), $3, make1_str("cursor for select"), $7), $8, $9, $10, $11), $12, $13, $14);
-					this->next = NULL;
-
-					for (ptr = cur; ptr != NULL; ptr = ptr->next)
-					{
-						if (strcmp(this->name, ptr->name) == 0)
-						{
-							/* re-definition */
-							free(ptr->command);
-							ptr->command = this->command;
-							break;
-						}
-					}
-
-					if (ptr == NULL)
-					{
-						/* initial definition */
-						this->next = cur;
-						cur = this;
-					}
-
-					$$ = make5_str(make1_str("/* declare cursor \""), $2, make1_str("\" statement has been moved to location of open cursor \""), strdup($2), make1_str("\" statement. */"));
+					$$ = make5_str(make1_str("ECPGdeclare(__LINE__, \""), $2, make1_str("\", \""), cat4_str(cat5_str(cat5_str(make1_str("declare"), strdup($2), $3, make1_str("cursor for select"), $7), $8, $9, $10, $11), $12, $13, $14), make1_str("\");"));
 				}
 		;
 
@@ -2361,6 +2381,15 @@ SelectStmt:  SELECT opt_unique res_target_list2
 				}
 		;
 
+SubSelect:  SELECT opt_unique res_target_list2
+                        from_clause where_clause
+                        group_clause having_clause
+                        union_clause
+                               {
+					$$ =cat4_str(cat5_str(make1_str("select"), $2, $3, $4, $5), $6, $7, $8);
+                               }
+               ;
+
 union_clause:  UNION opt_union select_list
 				{
 					$$ = cat3_str(make1_str("union"), $2, $3);
@@ -2369,15 +2398,15 @@ union_clause:  UNION opt_union select_list
 				{ $$ = make1_str(""); }
 		;
 
-select_list:  select_list UNION opt_union SubSelect
+select_list:  select_list UNION opt_union SubUnion
 				{
 					$$ = cat4_str($1, make1_str("union"), $3, $4);
 				}
-		| SubSelect
+		| SubUnion
 				{ $$ = $1; }
 		;
 
-SubSelect:	SELECT opt_unique res_target_list2
+SubUnion:	SELECT opt_unique res_target_list2
 			 from_clause where_clause
 			 group_clause having_clause
 				{
@@ -2477,9 +2506,6 @@ groupby:  ColId
 
 having_clause:  HAVING a_expr
 				{
-#if FALSE
-					yyerror("HAVING clause not yet implemented");
-#endif
 					$$ = cat2_str(make1_str("having"), $2);
 				}
 		| /*EMPTY*/		{ $$ = make1_str(""); }
@@ -3637,9 +3663,9 @@ AexprConst:  Iconst
 				{
 					$$ = $1;
 				}
-		| FCONST
+		| Fconst
 				{
-					$$ = make_name();
+					$$ = $1;
 				}
 		| Sconst
 				{
@@ -3667,11 +3693,8 @@ ParamNo:  PARAM
 				}
 		;
 
-NumConst:  Iconst						{ $$ = $1; }
-		| FCONST						{ $$ = make_name(); }
-		;
-
 Iconst:  ICONST                                 { $$ = make_name();};
+Fconst:  FCONST                                 { $$ = make_name();};
 Sconst:  SCONST                                 {
 							$$ = (char *)mm_alloc(strlen($1) + 3);
 							$$[0]='\'';
@@ -3711,6 +3734,7 @@ ColId:  ident							{ $$ = $1; }
 		| DELIMITERS					{ $$ = make1_str("delimiters"); }
 		| DOUBLE						{ $$ = make1_str("double"); }
 		| EACH							{ $$ = make1_str("each"); }
+		| ENCODING							{ $$ = make1_str("encoding"); }
 		| FUNCTION						{ $$ = make1_str("function"); }
 		| INCREMENT						{ $$ = make1_str("increment"); }
 		| INDEX							{ $$ = make1_str("index"); }
@@ -4197,22 +4221,7 @@ execstring: cvariable |
  * open is an open cursor, at the moment this has to be removed
  */
 ECPGOpen: SQL_OPEN name open_opts {
-		struct cursor *ptr;
-
-		for (ptr = cur; ptr != NULL; ptr=ptr->next)
-		{
-			if (strcmp(ptr->name, $2) == 0)
-			{
-				$$ = ptr->command;
-				break;
-			}
-		}
-
-		if (ptr == NULL)
-		{
-			sprintf(errortext, "unknown cursor %s opened", $2);
-			yyerror(errortext);
-		}
+		$$ = make3_str(make1_str("\""), $2, make1_str("\""));
 };
 
 open_opts: /* empty */		{ $$ = make1_str(""); }
@@ -4633,7 +4642,7 @@ c_thing: c_anything | ';' { $$ = make1_str(";"); }
 c_anything:  IDENT 	{ $$ = $1; }
 	| CSTRING	{ $$ = make3_str(make1_str("\""), $1, make1_str("\"")); }
 	| Iconst	{ $$ = $1; }
-	| FCONST	{ $$ = make_name(); }
+	| Fconst	{ $$ = $1; }
 	| '*'		{ $$ = make1_str("*"); }
 	| S_AUTO	{ $$ = make1_str("auto"); }
 	| S_BOOL	{ $$ = make1_str("bool"); }
@@ -4662,13 +4671,13 @@ c_anything:  IDENT 	{ $$ = $1; }
 do_anything: IDENT	{ $$ = $1; }
         | CSTRING       { $$ = make3_str(make1_str("\""), $1, make1_str("\""));}
         | Iconst        { $$ = $1; }
-	| FCONST	{ $$ = make_name(); }
+	| Fconst	{ $$ = $1; }
 	| ','		{ $$ = make1_str(","); }
 
 var_anything: IDENT 		{ $$ = $1; }
 	| CSTRING       	{ $$ = make3_str(make1_str("\""), $1, make1_str("\"")); }
 	| Iconst		{ $$ = $1; }
-	| FCONST		{ $$ = make_name(); }
+	| Fconst		{ $$ = $1; }
 	| '{' c_line '}'	{ $$ = make3_str(make1_str("{"), $2, make1_str("}")); }
 
 blockstart : '{' {
@@ -4685,6 +4694,6 @@ blockend : '}' {
 
 void yyerror(char * error)
 {
-    fprintf(stderr, "%s in line %d of file %s\n", error, yylineno, input_filename);
+    fprintf(stderr, "%s:%d: %s\n", input_filename, yylineno, error);
     exit(PARSE_ERROR);
 }
diff --git a/src/interfaces/ecpg/test/test2.pgc b/src/interfaces/ecpg/test/test2.pgc
index bfad1a9493b7f33bf8d4be0b2421237280dca94a..1506dd7bfa9b1fda9d323ca0878ab6b0eddde28b 100644
--- a/src/interfaces/ecpg/test/test2.pgc
+++ b/src/interfaces/ecpg/test/test2.pgc
@@ -42,8 +42,8 @@ exec sql end declare section;
 	exec sql commit;
 
 	strcpy(msg, "declare");
-	exec sql declare cur cursor for 
-		select name, born, age, married from meskes;
+	exec sql declare cur cursor for
+                select name, born, age, married from meskes;
 
 	strcpy(msg, "open");
 	exec sql open cur;