commit 4dd1f10d7f3640b95deda0a548ee302608fd2384
Author: Böszörményi Zoltán <zb@cybertec.at>
Date:   Wed Dec 4 14:19:15 2013 +0100

    ECPG: Start tracking subtransactions and cursors in the runtime
    library to reduce network turnaround.
    
    For this purpose, the arguments to ECPGtrans() have changed and
    4 new public functions were introduced: ECPGopen(), ECPGfetch(),
    ECPGcursor_dml() and ECPGclose(). The previously exposed ecpg_do()
    is used to drive all these functions. The library version was
    changed to 7.0 from 6.6 because of the ECPGtrans change.
    
    New error handling is added to mimic the server behaviour if a
    previous function checking the savepoint or cursor name failed.
    
    A new regression test was added to exercise certain aspects of
    the client-side tracking of cursors and subtransactions.

diff --git a/doc/src/sgml/ecpg.sgml b/doc/src/sgml/ecpg.sgml
index f9536ee..7b825ef 100644
--- a/doc/src/sgml/ecpg.sgml
+++ b/doc/src/sgml/ecpg.sgml
@@ -5274,6 +5274,16 @@ while (1)
     </varlistentry>
 
     <varlistentry>
+     <term>-231 (<symbol>ECPG_INVALID_CURSOR</symbol>)</term>
+     <listitem>
+      <para>
+       The cursor name you are trying to use is invalid.
+       (SQLSTATE 34000)
+      </para>
+     </listitem>
+    </varlistentry>
+
+    <varlistentry>
      <term>-239 (<symbol>ECPG_INFORMIX_DUPLICATE_KEY</symbol>)</term>
      <listitem>
       <para>
@@ -5360,10 +5370,23 @@ while (1)
      <term>-401 (<symbol>ECPG_TRANS</symbol>)</term>
      <listitem>
       <para>
+       This error code may occur in the following conditions.
+      </para>
+      <para>
        The <productname>PostgreSQL</productname> server signaled that
        we cannot start, commit, or rollback the transaction.
        (SQLSTATE 08007)
       </para>
+      <para>
+       While processing a previous command, a client side error happened:
+       invalid savepoint name or invalid cursor name. The actual command
+       was not sent to the server because of this error. To mimic the
+       server behaviour, all subsequent commands return the error for
+       an aborted transaction. (SQLSTATE 25P02)
+      </para>
+      <para>
+       The savepoint name you are trying to use is invalid. (SQLSTATE 3B001)
+      </para>
      </listitem>
     </varlistentry>
 
diff --git a/src/interfaces/ecpg/ecpglib/Makefile b/src/interfaces/ecpg/ecpglib/Makefile
index 946c724..a67ffc4 100644
--- a/src/interfaces/ecpg/ecpglib/Makefile
+++ b/src/interfaces/ecpg/ecpglib/Makefile
@@ -14,8 +14,8 @@ top_builddir = ../../../..
 include $(top_builddir)/src/Makefile.global
 
 NAME= ecpg
-SO_MAJOR_VERSION= 6
-SO_MINOR_VERSION= 6
+SO_MAJOR_VERSION= 7
+SO_MINOR_VERSION= 0
 
 override CPPFLAGS := -I../include -I$(top_srcdir)/src/interfaces/ecpg/include \
 	-I$(libpq_srcdir) -I$(top_builddir)/src/port $(CPPFLAGS)
@@ -25,7 +25,7 @@ override CFLAGS += $(PTHREAD_CFLAGS)
 LIBS := $(filter-out -lpgport, $(LIBS))
 
 OBJS= execute.o typename.o descriptor.o sqlda.o data.o error.o prepare.o memory.o \
-	connect.o misc.o path.o pgstrcasecmp.o \
+	connect.o misc.o path.o cursor.o pgstrcasecmp.o \
 	$(filter snprintf.o strlcpy.o win32setlocale.o isinf.o, $(LIBOBJS))
 
 # thread.c is needed only for non-WIN32 implementation of path.c
diff --git a/src/interfaces/ecpg/ecpglib/connect.c b/src/interfaces/ecpg/ecpglib/connect.c
index 49f2d54..bbe44ae 100644
--- a/src/interfaces/ecpg/ecpglib/connect.c
+++ b/src/interfaces/ecpg/ecpglib/connect.c
@@ -475,6 +475,9 @@ ECPGconnect(int lineno, int c, const char *name, const char *user, const char *p
 
 	this->cache_head = NULL;
 	this->prep_stmts = NULL;
+	this->subxact_desc = NULL;
+	this->cursor_desc = NULL;
+	this->client_side_error = false;
 
 	if (all_connections == NULL)
 		this->next = NULL;
diff --git a/src/interfaces/ecpg/ecpglib/cursor.c b/src/interfaces/ecpg/ecpglib/cursor.c
new file mode 100644
index 0000000..44b6b37
--- /dev/null
+++ b/src/interfaces/ecpg/ecpglib/cursor.c
@@ -0,0 +1,358 @@
+/* src/interfaces/ecpg/ecpglib/cursor.c */
+
+/*
+ * ECPG client-side cursor support routines
+ */
+
+#define POSTGRES_ECPG_INTERNAL
+#include "postgres_fe.h"
+
+#include <stdlib.h>
+#include <limits.h>
+
+#include "ecpgtype.h"
+#include "ecpglib.h"
+#include "ecpgerrno.h"
+#include "extern.h"
+
+static void
+raise_cursor_error(struct connection *con, int lineno, const char *name)
+{
+	con->client_side_error = true;
+	ecpg_raise(lineno, ECPG_INVALID_CURSOR,
+						ECPG_SQLSTATE_INVALID_CURSOR_NAME,
+						(name ? name : ecpg_gettext("<empty>")));
+}
+
+/*
+ * Find the cursor with the given name.
+ * Optionally, return the previous one in the list.
+ */
+static bool
+find_cursor(struct connection *con, int lineno, const char *name, bool ignore,
+				struct cursor_descriptor **out,
+				struct cursor_descriptor **out_prev)
+{
+	struct cursor_descriptor *desc = con->cursor_desc,
+					*prev = NULL;
+	int (* strcmp_fn)(const char *, const char *);
+	bool	found = false;
+
+	if (!name)
+	{
+		raise_cursor_error(con, lineno, name);
+		if (out)
+			*out = NULL;
+		if (out_prev)
+			*out_prev = NULL;
+		return false;
+	}
+
+	/*
+	 * This will ensure that:
+	 * - quoted cursor names will be the first ones in the list ordered case-sensitively
+	 * - unquoted cursor names at the end, ordered case-insensitively.
+	 */
+	strcmp_fn = (name[0] == '"' ? strcmp : pg_strcasecmp);
+
+	while (desc)
+	{
+		int ret = strcmp_fn(desc->name, name);
+
+		if (ret == 0)
+		{
+			found = true;
+			break;
+		}
+		/*
+		 * The cursor list is ordered quasi alphabetically,
+		 * don't search the whole list.
+		 */
+		if (ret > 0)
+			break;
+		prev = desc;
+		desc = desc->next;
+	}
+
+	if (!found)
+	{
+		if (!ignore)
+			raise_cursor_error(con, lineno, name);
+		desc = NULL;
+	}
+
+	if (out)
+		*out = desc;
+	if (out_prev)
+		*out_prev = prev;
+	return found;
+}
+
+/*
+ * Add a new cursor descriptor, maintain "mostly" alphabetic order.
+ * - case sensitive alphabetic order for quoted cursor names
+ * - case insensitive alphabetic order for non-quoted cursor names
+ */
+static struct cursor_descriptor *
+add_cursor(int lineno, struct connection *con,
+					const char *name,
+					int subxact_level,
+					bool with_hold)
+{
+	struct cursor_descriptor *desc, *prev;
+
+	if (!name || name[0] == '\0')
+		return NULL;
+
+	if (find_cursor(con, lineno, name, true, &desc, &prev))
+		return desc;
+
+	desc = (struct cursor_descriptor *)
+			ecpg_alloc(sizeof(struct cursor_descriptor),
+								lineno);
+	if (!desc)
+		return NULL;
+
+	/* Copy the name */
+	desc->name = ecpg_strdup(name, lineno);
+	if (!desc->name)
+	{
+		ecpg_free(desc);
+		return NULL;
+	}
+
+	desc->subxact_level = subxact_level;
+	desc->with_hold = with_hold;
+
+	if (prev)
+	{
+		desc->next = prev->next;
+		prev->next = desc;
+	}
+	else
+	{
+		desc->next = con->cursor_desc;
+		con->cursor_desc = desc;
+	}
+
+	return desc;
+}
+
+/*
+ * Delete the cursor from the list of descriptors.
+ */
+static void
+del_cursor(struct connection *con, int lineno, const char *name)
+{
+	struct cursor_descriptor *desc, *prev;
+
+	if (find_cursor(con, lineno, name, true, &desc, &prev))
+	{
+		if (prev)
+			prev->next = desc->next;
+		else
+			con->cursor_desc = desc->next;
+
+		ecpg_free((void *)desc->name);
+		ecpg_free(desc);
+	}
+}
+
+/*
+ * Commit or roll back cursors:
+ * - all transactional (non-WITH HOLD) cursors are forgotten at
+ *   the end of the transaction, no matter if COMMIT or ROLLBACK
+ * - at RELEASE SAVEPOINT, the cursors are propagated one
+ *   subtransaction level up.
+ * - at ROLLBACK TO SAVEPOINT, all cursors are forgotten that were
+ *   created in this subtransaction or below that level
+ * - WITH HOLD cursors are kept after the transaction in case of
+ *   toplevel COMMIT. The caller checks for the transaction in error
+ *   and sets the rollback flag accordingly.
+ */
+void
+ecpg_commit_cursors(int lineno, struct connection * conn,
+						bool rollback, int level)
+{
+	struct cursor_descriptor *desc, *tmp,
+					*prev = NULL;
+
+	desc = conn->cursor_desc;
+	while (desc)
+	{
+		/* Keep already COMMITted WITH HOLD cursors */
+		if (desc->with_hold && desc->subxact_level == 0)
+			;
+		else if (rollback)
+		{
+			/*
+			 * On ROLLBACK [ TO SAVEPOINT ... ] forget about
+			 * every cursor DECLAREd under this level.
+			 */
+			if (desc->subxact_level >= level)
+			{
+				tmp = desc->next;
+				ecpg_free(desc->name);
+				ecpg_free(desc);
+				desc = tmp;
+				if (prev)
+					prev->next = tmp;
+				else
+					conn->cursor_desc = tmp;
+				continue;
+			}
+		}
+		else
+		{
+			/*
+			 * If this is a WITH HOLD cursor or we're in a
+			 * subtransaction, COMMIT the cursor one level up.
+			 */
+			if (desc->with_hold || level > 1)
+			{
+				if (level > 0)
+					desc->subxact_level = level - 1;
+			}
+			/*
+			 * Otherwise (not WITH HOLD cursor AND it's the
+			 * toplevel transaction) free the cursor.
+			 */
+			else
+			{
+				tmp = desc->next;
+				ecpg_free(desc->name);
+				ecpg_free(desc);
+				desc = tmp;
+				if (prev)
+					prev->next = tmp;
+				else
+					conn->cursor_desc = tmp;
+				continue;
+			}
+		}
+		prev = desc;
+		desc = desc->next;
+	}
+}
+
+/*
+ * Declare the cursor in the backend and create a
+ * minimalistic descriptor to make tracking possible.
+ * This function is called when the ECPG code OPENs the cursor.
+ */
+bool
+ECPGopen(const int lineno, const int compat, const int force_indicator,
+			const char *connection_name, const bool questionmarks,
+			const bool with_hold, const char *curname, const int st, const char *query, ...)
+{
+	struct connection *con = ecpg_get_connection(connection_name);
+	int		subxact_level;
+	bool		ret;
+	va_list		args;
+
+	/*
+	 * Execute the DECLARE query in the backend.
+	 */
+	va_start(args, query);
+	ret = ecpg_do(lineno, compat, force_indicator, connection_name, questionmarks,
+										st,
+										query,
+										args);
+	va_end(args);
+
+	if (!ret)
+		return false;
+
+	/* Finally add the cursor to the connection. */
+	if (con->subxact_desc)
+		subxact_level = con->subxact_desc->level;
+	else
+		subxact_level =
+			(PQtransactionStatus(con->connection) != PQTRANS_IDLE ?
+										1 : 0);
+	add_cursor(lineno, con, curname, subxact_level, with_hold);
+
+	return true;
+}
+
+/*
+ * ECPGfetch
+ * Execute a FETCH or MOVE statement for the application.
+ *
+ * This function maintains the internal cursor descriptor and
+ * reduces the the network roundtrip by returning early for
+ * an unknown cursor name.
+ */
+bool
+ECPGfetch(const int lineno, const int compat, const int force_indicator,
+				const char *connection_name, const bool questionmarks,
+				const char *curname, const int st, const char *query, ...)
+{
+	struct connection  *con = ecpg_get_connection(connection_name);
+	struct cursor_descriptor *cur;
+	bool		ret;
+	va_list		args;
+
+	if (!find_cursor(con, lineno, curname, false, &cur, NULL))
+		return false;
+
+	va_start(args, query);
+	ret = ecpg_do(lineno, compat, force_indicator, connection_name, questionmarks,
+									st,
+									query,
+									args);
+	va_end(args);
+
+	return ret;
+}
+
+/*
+ * ECPGcursor_dml
+ * Called for DELETE / UPDATE ... WHERE CURRENT OF cursorname
+ */
+bool
+ECPGcursor_dml(const int lineno, const int compat, const int force_indicator,
+				const char *connection_name, const bool questionmarks,
+				const char *curname, const int st, const char *query, ...)
+{
+	struct connection  *con = ecpg_get_connection(connection_name);
+	struct cursor_descriptor *cur;
+	bool		ret;
+	va_list		args;
+
+	if (!find_cursor(con, lineno, curname, false, &cur, NULL))
+		return false;
+
+	va_start(args, query);
+	ret = ecpg_do(lineno, compat, force_indicator, connection_name, questionmarks,
+									st, query, args);
+	va_end(args);
+	return ret;
+}
+
+/*
+ * ECPGclose
+ * Close and free a cursor.
+ */
+bool
+ECPGclose(const int lineno, const int compat, const int force_indicator,
+				const char *connection_name, const bool questionmarks,
+				const char *curname, const int st, const char *query, ...)
+{
+	struct connection  *con = ecpg_get_connection(connection_name);
+	struct cursor_descriptor *cur;
+	bool		ret;
+	va_list		args;
+
+	if (!find_cursor(con, lineno, curname, false, &cur, NULL))
+		return false;
+
+	va_start(args, query);
+	ret = ecpg_do(lineno, compat, force_indicator, connection_name, questionmarks,
+									st, query, args);
+	va_end(args);
+
+	del_cursor(con, lineno, curname);
+
+	return ret;
+}
diff --git a/src/interfaces/ecpg/ecpglib/error.c b/src/interfaces/ecpg/ecpglib/error.c
index 715bedb..0e5c2e1 100644
--- a/src/interfaces/ecpg/ecpglib/error.c
+++ b/src/interfaces/ecpg/ecpglib/error.c
@@ -180,10 +180,27 @@ ecpg_raise(int line, int code, const char *sqlstate, const char *str)
 			break;
 
 		case ECPG_TRANS:
-			snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),
+			if (strcmp(sqlstate, ECPG_SQLSTATE_IN_FAILED_SQL_TRANSACTION) == 0)
+			{
+				snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),
+			/*------
+			   translator: this string will be truncated at 149 characters expanded.  */
+					 ecpg_gettext("current transaction is aborted, commands ignored until end of transaction block on line %d"), line);
+			}
+			else if (strcmp(sqlstate, ECPG_SQLSTATE_S_E_INVALID_SPECIFICATION) == 0)
+			{
+				snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),
+			/*------
+			   translator: this string will be truncated at 149 characters expanded.  */
+					 ecpg_gettext("no such savepoint \"%s\" on line %d"), str, line);
+			}
+			else
+			{
+				snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),
 			/*------
 			   translator: this string will be truncated at 149 characters expanded.  */
-			ecpg_gettext("error in transaction processing on line %d"), line);
+					 ecpg_gettext("error in transaction processing on line %d"), line);
+			}
 			break;
 
 		case ECPG_CONNECT:
@@ -193,6 +210,23 @@ ecpg_raise(int line, int code, const char *sqlstate, const char *str)
 					 ecpg_gettext("could not connect to database \"%s\" on line %d"), str, line);
 			break;
 
+		case ECPG_INVALID_CURSOR:
+			if (strcmp(sqlstate, ECPG_SQLSTATE_INVALID_CURSOR_NAME) == 0)
+			{
+				snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),
+			/*------
+			   translator: this string will be truncated at 149 characters expanded.  */
+					 ecpg_gettext("invalid cursorname \"%s\" on line %d"), str, line);
+			}
+			else
+			{
+				snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),
+			/*------
+			   translator: this string will be truncated at 149 characters expanded.  */
+					 ecpg_gettext("invalid cursor error %d on line %d"), code, line);
+			}
+			break;
+
 		default:
 			snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),
 			/*------
diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c
index 1326870..a60e209 100644
--- a/src/interfaces/ecpg/ecpglib/execute.c
+++ b/src/interfaces/ecpg/ecpglib/execute.c
@@ -1866,6 +1866,13 @@ ecpg_do_prologue(int lineno, const int compat, const int force_indicator,
 		return (false);
 	}
 
+	if (con->client_side_error)
+	{
+		ecpg_do_epilogue(stmt);
+		ecpg_raise(lineno, ECPG_TRANS, ECPG_SQLSTATE_IN_FAILED_SQL_TRANSACTION, NULL);
+		return false;
+	}
+
 	/*
 	 * create a list of variables The variables are listed with input
 	 * variables preceding outputvariables The end of each group is marked by
diff --git a/src/interfaces/ecpg/ecpglib/exports.txt b/src/interfaces/ecpg/ecpglib/exports.txt
index 69e9617..dec587e 100644
--- a/src/interfaces/ecpg/ecpglib/exports.txt
+++ b/src/interfaces/ecpg/ecpglib/exports.txt
@@ -29,3 +29,7 @@ ECPGget_PGconn			 26
 ECPGtransactionStatus		 27
 ECPGset_var			 28
 ECPGget_var			 29
+ECPGopen			 30
+ECPGfetch			 31
+ECPGcursor_dml			 32
+ECPGclose			 33
diff --git a/src/interfaces/ecpg/ecpglib/extern.h b/src/interfaces/ecpg/ecpglib/extern.h
index ff12acb..5bb7ecd 100644
--- a/src/interfaces/ecpg/ecpglib/extern.h
+++ b/src/interfaces/ecpg/ecpglib/extern.h
@@ -78,14 +78,39 @@ struct prepared_statement
 	struct prepared_statement *next;
 };
 
+struct subxact_descriptor
+{
+	char	   *name;
+	struct subxact_descriptor *next;
+	int		level;
+};
+
+struct cursor_descriptor {
+	struct cursor_descriptor *next;
+
+	char	   *name;
+
+	/*
+	 * The cursor was created in this level of * (sub-)transaction.
+	 * 0: WITH HOLD, committed successfully in a previous transaction
+	 * 1: cursor declared in the toplevel transaction
+	 * >=2: cursor declared in a named SAVEPOINT at the specified level
+	 */
+	int		subxact_level;
+	bool		with_hold;
+};
+
 /* structure to store connections */
 struct connection
 {
 	char	   *name;
 	PGconn	   *connection;
 	bool		autocommit;
+	bool		client_side_error;
 	struct ECPGtype_information_cache *cache_head;
 	struct prepared_statement *prep_stmts;
+	struct subxact_descriptor *subxact_desc;
+	struct cursor_descriptor *cursor_desc;
 	struct connection *next;
 };
 
@@ -199,6 +224,8 @@ void		ecpg_set_compat_sqlda(int, struct sqlda_compat **, const PGresult *, int,
 struct sqlda_struct *ecpg_build_native_sqlda(int, PGresult *, int, enum COMPAT_MODE);
 void		ecpg_set_native_sqlda(int, struct sqlda_struct **, const PGresult *, int, enum COMPAT_MODE);
 
+void		ecpg_commit_cursors(int lineno, struct connection * conn, bool rollback, int level);
+
 /* SQLSTATE values generated or processed by ecpglib (intentionally
  * not exported -- users should refer to the codes directly) */
 
@@ -214,9 +241,11 @@ void		ecpg_set_native_sqlda(int, struct sqlda_struct **, const PGresult *, int,
 #define ECPG_SQLSTATE_NULL_VALUE_NO_INDICATOR_PARAMETER "22002"
 #define ECPG_SQLSTATE_ACTIVE_SQL_TRANSACTION		"25001"
 #define ECPG_SQLSTATE_NO_ACTIVE_SQL_TRANSACTION		"25P01"
+#define ECPG_SQLSTATE_IN_FAILED_SQL_TRANSACTION		"25P02"
 #define ECPG_SQLSTATE_INVALID_SQL_STATEMENT_NAME	"26000"
 #define ECPG_SQLSTATE_INVALID_SQL_DESCRIPTOR_NAME	"33000"
-#define ECPG_SQLSTATE_INVALID_CURSOR_NAME	"34000"
+#define ECPG_SQLSTATE_INVALID_CURSOR_NAME		"34000"
+#define ECPG_SQLSTATE_S_E_INVALID_SPECIFICATION		"3B001"
 #define ECPG_SQLSTATE_SYNTAX_ERROR			"42601"
 #define ECPG_SQLSTATE_DATATYPE_MISMATCH		"42804"
 #define ECPG_SQLSTATE_DUPLICATE_CURSOR		"42P03"
diff --git a/src/interfaces/ecpg/ecpglib/misc.c b/src/interfaces/ecpg/ecpglib/misc.c
index 9371f71..44ce5a9 100644
--- a/src/interfaces/ecpg/ecpglib/misc.c
+++ b/src/interfaces/ecpg/ecpglib/misc.c
@@ -183,18 +183,155 @@ ECPGtransactionStatus(const char *connection_name)
 	}
 
 	return PQtransactionStatus(con->connection);
+}
+
+static void
+raise_xact_error(struct connection *con, int lineno, const char *name)
+{
+	con->client_side_error = true;
+	ecpg_raise(lineno, ECPG_TRANS, ECPG_SQLSTATE_S_E_INVALID_SPECIFICATION,
+					(name ? name : ecpg_gettext("<empty>")));
+}
+
+static bool
+find_subxact(struct connection *con, int lineno, const char *name, bool ignore,
+					struct subxact_descriptor **out)
+{
+	struct subxact_descriptor *desc = con->subxact_desc;
+	bool    found = false;
+
+	if (!name)
+	{
+		raise_xact_error(con, lineno, name);
+		if (out)
+			*out = NULL;
+		return false;
+	}
+
+	while (desc)
+	{
+		int ret = pg_strcasecmp(desc->name, name);
+
+		if (ret == 0)
+		{
+			found = true;
+			break;
+		}
+
+		desc = desc->next;
+	}
+
+	if (!found && !ignore)
+		raise_xact_error(con, lineno, name);
+	if (out)
+		*out = desc;
+	return found;
+}
+
+static void
+add_savepoint(struct connection *con, int lineno, const char *savepoint_name)
+{
+	struct subxact_descriptor *desc, *oldptr;
+
+	oldptr = con->subxact_desc;
+	desc = (struct subxact_descriptor *)
+		ecpg_alloc(sizeof(struct subxact_descriptor), lineno);
+	desc->level = (oldptr ? oldptr->level + 1 : 2);
+	desc->name = ecpg_strdup(savepoint_name, lineno);
+	desc->next = oldptr;
+	con->subxact_desc = desc;
+}
+
+static void
+release_savepoint(struct connection *con, struct subxact_descriptor *ptr, bool rollback)
+{
+	struct subxact_descriptor *desc, *next = NULL;
+
+	desc = con->subxact_desc;
+	while (desc != ptr)
+	{
+		next = desc->next;
+		ecpg_free(desc->name);
+		ecpg_free(desc);
+		desc = next;
+	}
 
+	if (desc)
+	{
+		/* ROLLBACK TO SAVEPOINT leaves the savepoint in place */
+		if (rollback)
+			con->subxact_desc = desc;
+		else
+		{
+			/* RELEASE SAVEPOINT forgets about the savepoint */
+			con->subxact_desc = desc->next;
+			ecpg_free(desc->name);
+			ecpg_free(desc);
+		}
+	}
+	else
+		con->subxact_desc = NULL;
 }
 
+/*
+ * ECPGtrans
+ * Track (sub-)transactions by flags.
+ * Parameters
+ *	connection_name:connection
+ *	transaction:	the SQL string
+ *	prepared:	prepared transaction or not
+ *	begin:		start or finish transaction
+ *	rollback:	valid if begin is false: commit or rollback
+ *	savepoint_name:	NULL -> top level transaction,
+ *			subtransaction otherwise
+ *
+ * The following table shows the combination of flags (x is ignored):
+ * prepared | begin | rollback | savepoint_name | command
+ * ---------+-------+----------+----------------+-----------------------
+ *   false  | false |   false  |       NULL     | COMMIT
+ *   false  | false |   false  |  valid pointer | RELEASE SAVEPOINT
+ *   false  | false |   true   |       NULL     | ROLLBACK
+ *   false  | false |   true   |  valid pointer | ROLLBACK TO SAVEPOINT
+ *   false  | true  |     x    |       NULL     | BEGIN
+ *   false  | true  |     x    |  valid pointer | SAVEPOINT
+ *   true   | false |   false  |        x       | COMMIT PREPARED
+ *   true   | false |   true   |        x       | ROLLBACK PREPARED
+ *   true   | true  |     x    |        x       | PREPARE TRANSACTION
+ */
 bool
-ECPGtrans(int lineno, const char *connection_name, const char *transaction)
+ECPGtrans(int lineno, const char *connection_name, const char *transaction,
+				bool prepared, bool begin, bool rollback,
+				const char *savepoint_name)
 {
 	PGresult   *res;
 	struct connection *con = ecpg_get_connection(connection_name);
+	bool		rollback_override = false;
 
 	if (!ecpg_init(con, connection_name, lineno))
 		return (false);
 
+	if (con && (con->client_side_error || PQtransactionStatus(con->connection) == PQTRANS_INERROR))
+	{
+		/*
+		 * Follow the backend behaviour for failed transactions:
+		 * - override PREPARE TRANSACTION and COMMIT as ROLLBACK
+		 *   so they don't fail
+		 * - allow ROLLBACK and ROLLBACK TO SAVEPOINT to get through
+		 * - emit "current transaction is aborted..." for everything else
+		 */
+		if ((prepared && begin) ||
+				(!prepared && !begin && !rollback && savepoint_name == NULL))
+		{
+			transaction = "rollback";
+			rollback_override = true;
+		}
+		else if (!(!prepared && !begin && rollback))
+		{
+			ecpg_raise(lineno, ECPG_TRANS, ECPG_SQLSTATE_IN_FAILED_SQL_TRANSACTION, NULL);
+			return false;
+		}
+	}
+
 	ecpg_log("ECPGtrans on line %d: action \"%s\"; connection \"%s\"\n", lineno, transaction, con ? con->name : "null");
 
 	/* if we have no connection we just simulate the command */
@@ -203,23 +340,92 @@ ECPGtrans(int lineno, const char *connection_name, const char *transaction)
 		/*
 		 * If we got a transaction command but have no open transaction, we
 		 * have to start one, unless we are in autocommit, where the
-		 * developers have to take care themselves. However, if the command is
-		 * a begin statement, we just execute it once.
+		 * developers have to take care themselves. However:
+		 * - if the command is a begin statement, we just execute it once
+		 * - the command is COMMIT/ROLLBACK PREPARED, it must be executed
+		 *   outside of a transaction.
 		 */
-		if (PQtransactionStatus(con->connection) == PQTRANS_IDLE && !con->autocommit && strncmp(transaction, "begin", 5) != 0 && strncmp(transaction, "start", 5) != 0)
+		if (PQtransactionStatus(con->connection) == PQTRANS_IDLE && !con->autocommit &&
+			/* exclude BEGIN */
+			!(!prepared && begin && savepoint_name == NULL) &&
+			/* exclude COMMIT/ROLLBACK PREPARED */
+			!(prepared && !begin))
 		{
 			res = PQexec(con->connection, "begin transaction");
 			if (!ecpg_check_PQresult(res, lineno, con->connection, ECPG_COMPAT_PGSQL))
-				return FALSE;
+				return false;
 			PQclear(res);
 		}
 
 		res = PQexec(con->connection, transaction);
 		if (!ecpg_check_PQresult(res, lineno, con->connection, ECPG_COMPAT_PGSQL))
-			return FALSE;
+			return false;
 		PQclear(res);
 	}
 
+	if (con)
+	{
+		struct subxact_descriptor *desc;
+
+		/* Simplify checking rollback conditions for ecpg_commit_cursors() later */
+		if (rollback_override)
+		{
+			prepared = false;
+			begin = false;
+			rollback = true;
+		}
+
+		/*
+		 * We keep track of subtransactions to be able to correctly
+		 * account for transactional cursors as well.
+		 */
+		if (!prepared && savepoint_name)
+		{
+			int	level;
+
+			if (begin)
+			{
+				/* SAVEPOINT nnn */
+				if (find_subxact(con, lineno, savepoint_name, true, &desc))
+				{
+					/*
+					 * SAVEPOINT nnn with an already existing savepoint name
+					 * does an implicit RELEASE SAVEPOINT nnn
+					 */
+					level = desc->level;
+					release_savepoint(con, desc, false);
+					ecpg_commit_cursors(lineno, con, false, level);
+				}
+
+				add_savepoint(con, lineno, savepoint_name);
+			}
+			else
+			{
+				/*
+				 * ROLLBACK TO / RELEASE SAVEPOINT nnn
+				 *
+				 * The above PQexec() already succeeded for savepoint_name
+				 * but check for completeness anyway.
+				 */
+				if (!find_subxact(con, lineno, savepoint_name, false, &desc))
+					return false;
+
+				level = desc->level;
+				release_savepoint(con, desc, rollback);
+				ecpg_commit_cursors(lineno, con, rollback, level);
+			}
+		}
+		/* Toplevel COMMIT / ROLLBACK */
+		else if (!prepared && !begin && savepoint_name == NULL)
+		{
+			release_savepoint(con, NULL, rollback);
+			ecpg_commit_cursors(lineno, con, rollback, 1);
+		}
+
+		/* At this point there's no error anymore. */
+		con->client_side_error = false;
+	}
+
 	return true;
 }
 
diff --git a/src/interfaces/ecpg/include/ecpgerrno.h b/src/interfaces/ecpg/include/ecpgerrno.h
index 36b15b7..f21dad2 100644
--- a/src/interfaces/ecpg/include/ecpgerrno.h
+++ b/src/interfaces/ecpg/include/ecpgerrno.h
@@ -37,6 +37,7 @@
 #define ECPG_NOT_CONN			-221
 
 #define ECPG_INVALID_STMT		-230
+#define ECPG_INVALID_CURSOR		-231
 
 /* dynamic SQL related */
 #define ECPG_UNKNOWN_DESCRIPTOR		-240
diff --git a/src/interfaces/ecpg/include/ecpglib.h b/src/interfaces/ecpg/include/ecpglib.h
index 3b8ed4c..02f319d 100644
--- a/src/interfaces/ecpg/include/ecpglib.h
+++ b/src/interfaces/ecpg/include/ecpglib.h
@@ -52,7 +52,7 @@ bool		ECPGsetcommit(int, const char *, const char *);
 bool		ECPGsetconn(int, const char *);
 bool		ECPGconnect(int, int, const char *, const char *, const char *, const char *, int);
 bool		ECPGdo(const int, const int, const int, const char *, const bool, const int, const char *,...);
-bool		ECPGtrans(int, const char *, const char *);
+bool		ECPGtrans(int, const char *, const char *, bool, bool, bool, const char *);
 bool		ECPGdisconnect(int, const char *);
 bool		ECPGprepare(int, const char *, const bool, const char *, const char *);
 bool		ECPGdeallocate(int, int, const char *, const char *);
@@ -63,6 +63,16 @@ PGTransactionStatusType ECPGtransactionStatus(const char *);
 
 char	   *ECPGerrmsg(void);
 
+/* Cursor functions */
+bool		ECPGopen(const int, const int, const int, const char *, const bool, const bool,
+				const char *, const int, const char *, ...);
+bool		ECPGfetch(const int, const int, const int, const char *, const bool,
+				const char *, const int, const char *, ...);
+bool		ECPGcursor_dml(const int, const int, const int, const char *, const bool,
+				const char *, const int, const char *, ...);
+bool		ECPGclose(const int, const int, const int, const char *, const bool,
+				const char *, const int, const char *, ...);
+
  /* print an error message */
 void		sqlprint(void);
 
diff --git a/src/interfaces/ecpg/preproc/ecpg.addons b/src/interfaces/ecpg/preproc/ecpg.addons
index b3b36cf..ebc9b16 100644
--- a/src/interfaces/ecpg/preproc/ecpg.addons
+++ b/src/interfaces/ecpg/preproc/ecpg.addons
@@ -15,7 +15,7 @@ ECPG: stmtClosePortalStmt block
 			}
 		}
 
-		output_statement($1, 0, ECPGst_normal);
+		output_close_statement($1, 0, ECPGst_normal);
 	}
 ECPG: stmtDeallocateStmt block
 	{
@@ -24,13 +24,20 @@ ECPG: stmtDeallocateStmt block
 ECPG: stmtDeclareCursorStmt block
 	{ output_simple_statement($1); }
 ECPG: stmtDiscardStmt block
-ECPG: stmtFetchStmt block
 	{ output_statement($1, 1, ECPGst_normal); }
-ECPG: stmtDeleteStmt block
+ECPG: stmtFetchStmt block
+	{ output_fetch_statement($1, 1, ECPGst_normal); }
 ECPG: stmtInsertStmt block
 ECPG: stmtSelectStmt block
-ECPG: stmtUpdateStmt block
 	{ output_statement($1, 1, ECPGst_prepnormal); }
+ECPG: stmtDeleteStmt block
+ECPG: stmtUpdateStmt block
+	{
+		if (current_cursor)
+			output_cursor_dml_statement($1, 1, ECPGst_prepnormal);
+		else
+			output_statement($1, 1, ECPGst_prepnormal);
+	}
 ECPG: stmtExecuteStmt block
 	{ output_statement($1, 1, ECPGst_execute); }
 ECPG: stmtPrepareStmt block
@@ -42,10 +49,87 @@ ECPG: stmtPrepareStmt block
 	}
 ECPG: stmtTransactionStmt block
 	{
-		fprintf(yyout, "{ ECPGtrans(__LINE__, %s, \"%s\");", connection ? connection : "NULL", $1);
+		char *tr_name;
+
+		if (transact_name)
+		{
+			tr_name = mm_alloc(4 + strlen(transact_name));
+			sprintf(tr_name, "\"%s\"", transact_name);
+		}
+		else
+			tr_name = mm_strdup("NULL");
+
+		fprintf(yyout, "{ ECPGtrans(__LINE__, %s, \"%s\", %d, %d, %d, %s);",
+					connection ? connection : "NULL",
+					$1,
+					transact_prepared,
+					transact_start,
+					transact_rollback,
+					tr_name);
+		free(tr_name);
+		free(transact_name);
+		transact_name = NULL;
 		whenever_action(2);
 		free($1);
 	}
+ECPG: TransactionStmtABORT_Popt_transaction addon
+ECPG: TransactionStmtROLLBACKopt_transaction addon
+		transact_prepared = false;
+		transact_start = false;
+		transact_rollback = true;
+		transact_name = NULL;
+ECPG: TransactionStmtBEGIN_Popt_transactiontransaction_mode_list_or_empty addon
+ECPG: TransactionStmtSTARTTRANSACTIONtransaction_mode_list_or_empty addon
+		transact_prepared = false;
+		transact_start = true;
+		transact_rollback = false;
+		transact_name = NULL;
+ECPG: TransactionStmtCOMMITopt_transaction addon
+ECPG: TransactionStmtEND_Popt_transaction addon
+		transact_prepared = false;
+		transact_start = false;
+		transact_rollback = false;
+		transact_name = NULL;
+ECPG: TransactionStmtSAVEPOINTColId addon
+		transact_prepared = false;
+		transact_start = true;
+		transact_rollback = false;
+		transact_name = mm_strdup($2);
+ECPG: TransactionStmtRELEASESAVEPOINTColId addon
+		transact_prepared = false;
+		transact_start = false;
+		transact_rollback = false;
+		transact_name = mm_strdup($3);
+ECPG: TransactionStmtRELEASEColId addon
+		transact_prepared = false;
+		transact_start = false;
+		transact_rollback = false;
+		transact_name = mm_strdup($2);
+ECPG: TransactionStmtROLLBACKopt_transactionTOSAVEPOINTColId addon
+		transact_prepared = false;
+		transact_start = false;
+		transact_rollback = true;
+		transact_name = mm_strdup($5);
+ECPG: TransactionStmtROLLBACKopt_transactionTOColId addon
+		transact_prepared = false;
+		transact_start = false;
+		transact_rollback = true;
+		transact_name = mm_strdup($4);
+ECPG: TransactionStmtPREPARETRANSACTIONSconst addon
+		transact_prepared = true;
+		transact_start = true;
+		transact_rollback = false;
+		transact_name = NULL;
+ECPG: TransactionStmtCOMMITPREPAREDSconst addon
+		transact_prepared = true;
+		transact_start = false;
+		transact_rollback = false;
+		transact_name = NULL;
+ECPG: TransactionStmtROLLBACKPREPAREDSconst addon
+		transact_prepared = true;
+		transact_start = false;
+		transact_rollback = true;
+		transact_name = NULL;
 ECPG: stmtViewStmt rule
 	| ECPGAllocateDescr
 	{
@@ -132,7 +216,7 @@ ECPG: stmtViewStmt rule
 		if ((ptr = add_additional_variables($1, true)) != NULL)
 		{
 			connection = ptr->connection ? mm_strdup(ptr->connection) : NULL;
-			output_statement(mm_strdup(ptr->command), 0, ECPGst_normal);
+			output_open_statement(mm_strdup(ptr->command), 0, ECPGst_normal);
 			ptr->opened = true;
 		}
 	}
@@ -190,6 +274,16 @@ ECPG: stmtViewStmt rule
 ECPG: where_or_current_clauseWHERECURRENT_POFcursor_name block
 	{
 		char *cursor_marker = $4[0] == ':' ? mm_strdup("$0") : $4;
+		struct cursor *ptr;
+
+		for (ptr = cur; ptr != NULL; ptr = ptr->next)
+		{
+			if (strcmp(ptr->name, $4) == 0)
+				break;
+		}
+		if (!ptr)
+			mmfatal(PARSE_ERROR, "cursor \"%s\" does not exist", $4);
+
 		$$ = cat_str(2,mm_strdup("where current of"), cursor_marker);
 	}
 ECPG: CopyStmtCOPYopt_binaryqualified_nameopt_column_listopt_oidscopy_fromopt_programcopy_file_namecopy_delimiteropt_withcopy_options addon
@@ -262,13 +356,19 @@ ECPG: fetch_argsBACKWARDSignedIconstopt_from_incursor_name addon
 			free($2);
 			$2 = mm_strdup("$0");
 		}
-ECPG: cursor_namename rule
+ECPG: cursor_namename block
+		{
+			current_cursor = mm_strdup($1);
+			current_cursor_vartype = ECPGt_const;
+			$$ = $1;
+		}
 	| char_civar
 		{
 			char *curname = mm_alloc(strlen($1) + 2);
 			sprintf(curname, ":%s", $1);
 			free($1);
 			$1 = curname;
+			current_cursor = mm_strdup(curname);
 			$$ = $1;
 		}
 ECPG: PrepareStmtPREPAREprepared_nameprep_type_clauseASPreparableStmt block
@@ -310,6 +410,8 @@ ECPG: DeclareCursorStmtDECLAREcursor_namecursor_optionsCURSORopt_holdFORSelectSt
 		this->function = (current_function ? mm_strdup(current_function) : NULL);
 		this->connection = connection;
 		this->opened = false;
+		this->with_hold = (strncmp($5, "with ", 5) == 0);
+		this->vartype = current_cursor_vartype;
 		this->command =  cat_str(7, mm_strdup("declare"), cursor_marker, $3, mm_strdup("cursor"), $5, mm_strdup("for"), $7);
 		this->argsinsert = argsinsert;
 		this->argsinsert_oos = NULL;
diff --git a/src/interfaces/ecpg/preproc/ecpg.header b/src/interfaces/ecpg/preproc/ecpg.header
index 64e7600..eb3511c 100644
--- a/src/interfaces/ecpg/preproc/ecpg.header
+++ b/src/interfaces/ecpg/preproc/ecpg.header
@@ -35,6 +35,11 @@
 int struct_level = 0;
 int braces_open; /* brace level counter */
 char *current_function;
+char *current_cursor = NULL;
+bool transact_prepared = false;
+bool transact_start = false;
+bool transact_rollback = false;
+char *transact_name = NULL;
 int ecpg_internal_var = 0;
 char	*connection = NULL;
 char	*input_filename = NULL;
@@ -126,6 +131,25 @@ mmfatal(int error_code, const char *error, ...)
 }
 
 /*
+ * Find a cursor
+ */
+struct cursor *
+get_cursor(const char *curname)
+{
+	int (* strcmp_fn)(const char *, const char *) = ((curname[0] == ':' || curname[0] == '"') ? strcmp : pg_strcasecmp);
+	struct cursor *ptr;
+
+	for (ptr = cur; ptr != NULL; ptr = ptr->next)
+	{
+		if (strcmp_fn(ptr->name, curname) == 0)
+			break;
+	}
+	if (!ptr)
+		mmfatal(PARSE_ERROR, "cursor \"%s\" does not exist", curname);
+	return ptr;
+}
+
+/*
  * string concatenation
  */
 
diff --git a/src/interfaces/ecpg/preproc/ecpg.trailer b/src/interfaces/ecpg/preproc/ecpg.trailer
index 3b6d1e5..de77ece 100644
--- a/src/interfaces/ecpg/preproc/ecpg.trailer
+++ b/src/interfaces/ecpg/preproc/ecpg.trailer
@@ -315,6 +315,9 @@ ECPGCursorStmt:  DECLARE cursor_name cursor_options CURSOR opt_hold FOR prepared
 			this->name = $2;
 			this->function = (current_function ? mm_strdup(current_function) : NULL);
 			this->connection = connection;
+			this->opened = false;
+			this->with_hold = (strncmp($5, "with ", 5) == 0);
+			this->vartype = current_cursor_vartype;
 			this->command =  cat_str(6, mm_strdup("declare"), cursor_marker, $3, mm_strdup("cursor"), $5, mm_strdup("for $1"));
 			this->argsresult = NULL;
 			this->argsresult_oos = NULL;
@@ -1662,7 +1665,12 @@ char_civar: char_variable
 			char *ptr = strstr($1, ".arr");
 
 			if (ptr) /* varchar, we need the struct name here, not the struct element */
+			{
 				*ptr = '\0';
+				current_cursor_vartype = ECPGt_varchar;
+			}
+			else
+				current_cursor_vartype = ECPGt_char;
 			add_variable_to_head(&argsinsert, find_variable($1), &no_indicator);
 			$$ = $1;
 		}
diff --git a/src/interfaces/ecpg/preproc/extern.h b/src/interfaces/ecpg/preproc/extern.h
index 3bbb6a4..f3d39ce 100644
--- a/src/interfaces/ecpg/preproc/extern.h
+++ b/src/interfaces/ecpg/preproc/extern.h
@@ -30,6 +30,8 @@ extern int	braces_open,
 			struct_level,
 			ecpg_internal_var;
 extern char *current_function;
+extern char *current_cursor;
+enum ECPGttype current_cursor_vartype;
 extern char *descriptor_index;
 extern char *descriptor_name;
 extern char *connection;
@@ -67,6 +69,10 @@ extern void output_statement(char *, int, enum ECPG_statement_type);
 extern void output_prepare_statement(char *, char *);
 extern void output_deallocate_prepare_statement(char *);
 extern void output_simple_statement(char *);
+extern void output_open_statement(char *, int, enum ECPG_statement_type);
+extern void output_fetch_statement(char *, int, enum ECPG_statement_type);
+extern void output_cursor_dml_statement(char *, int, enum ECPG_statement_type);
+extern void output_close_statement(char *, int, enum ECPG_statement_type);
 extern char *hashline_number(void);
 extern int	base_yyparse(void);
 extern int	base_yylex(void);
@@ -104,6 +110,7 @@ extern void scanner_init(const char *);
 extern void parser_init(void);
 extern void scanner_finish(void);
 extern int	filtered_base_yylex(void);
+extern struct cursor *get_cursor(const char *);
 
 /* return codes */
 
diff --git a/src/interfaces/ecpg/preproc/output.c b/src/interfaces/ecpg/preproc/output.c
index 007c07c..a49b89c 100644
--- a/src/interfaces/ecpg/preproc/output.c
+++ b/src/interfaces/ecpg/preproc/output.c
@@ -125,10 +125,28 @@ static char *ecpg_statement_type_name[] = {
 	"ECPGst_prepnormal"
 };
 
-void
-output_statement(char *stmt, int whenever_mode, enum ECPG_statement_type st)
+static void output_cursor_name(struct cursor *ptr)
+{
+	if (current_cursor[0] == ':')
+	{
+		char *curname = current_cursor + 1;
+
+		fputs(curname, yyout);
+		if (ptr->vartype == ECPGt_varchar)
+			fputs(".arr", yyout);
+		fputs(", ", yyout);
+	}
+	else
+	{
+		fputs("\"", yyout);
+		output_escaped_str(current_cursor, false);
+		fputs("\", ", yyout);
+	}
+}
+
+static void
+output_statement_epilogue(char *stmt, int whenever_mode, enum ECPG_statement_type st)
 {
-	fprintf(yyout, "{ ECPGdo(__LINE__, %d, %d, %s, %d, ", compat, force_indicator, connection ? connection : "NULL", questionmarks);
 	if (st == ECPGst_execute || st == ECPGst_exec_immediate)
 	{
 		fprintf(yyout, "%s, %s, ", ecpg_statement_type_name[st], stmt);
@@ -153,11 +171,23 @@ output_statement(char *stmt, int whenever_mode, enum ECPG_statement_type st)
 
 	whenever_action(whenever_mode | 2);
 	free(stmt);
+	if (current_cursor)
+	{
+		free(current_cursor);
+		current_cursor = NULL;
+	}
 	if (connection != NULL)
 		free(connection);
 }
 
 void
+output_statement(char *stmt, int whenever_mode, enum ECPG_statement_type st)
+{
+	fprintf(yyout, "{ ECPGdo(__LINE__, %d, %d, %s, %d, ", compat, force_indicator, connection ? connection : "NULL", questionmarks);
+	output_statement_epilogue(stmt, whenever_mode, st);
+}
+
+void
 output_prepare_statement(char *name, char *stmt)
 {
 	fprintf(yyout, "{ ECPGprepare(__LINE__, %s, %d, ", connection ? connection : "NULL", questionmarks);
@@ -191,6 +221,46 @@ output_deallocate_prepare_statement(char *name)
 		free(connection);
 }
 
+void
+output_open_statement(char *stmt, int whenever_mode, enum ECPG_statement_type st)
+{
+	struct cursor *ptr = get_cursor(current_cursor);
+
+	fprintf(yyout, "{ ECPGopen(__LINE__, %d, %d, %s, %d, %d, ", compat, force_indicator, connection ? connection : "NULL", questionmarks, ptr->with_hold);
+	output_cursor_name(ptr);
+	output_statement_epilogue(stmt, whenever_mode, st);
+}
+
+void
+output_fetch_statement(char *stmt, int whenever_mode, enum ECPG_statement_type st)
+{
+	struct cursor *ptr = get_cursor(current_cursor);
+
+	fprintf(yyout, "{ ECPGfetch(__LINE__, %d, %d, %s, %d, ", compat, force_indicator, connection ? connection : "NULL", questionmarks);
+	output_cursor_name(ptr);
+	output_statement_epilogue(stmt, whenever_mode, st);
+}
+
+void
+output_cursor_dml_statement(char *stmt, int whenever_mode, enum ECPG_statement_type st)
+{
+	struct cursor *ptr = get_cursor(current_cursor);
+
+	fprintf(yyout, "{ ECPGcursor_dml(__LINE__, %d, %d, %s, %d, ", compat, force_indicator, connection ? connection : "NULL", questionmarks);
+	output_cursor_name(ptr);
+	output_statement_epilogue(stmt, whenever_mode, st);
+}
+
+void
+output_close_statement(char *stmt, int whenever_mode, enum ECPG_statement_type st)
+{
+	struct cursor *ptr = get_cursor(current_cursor);
+
+	fprintf(yyout, "{ ECPGclose(__LINE__, %d, %d, %s, %d, ", compat, force_indicator, connection ? connection : "NULL", questionmarks);
+	output_cursor_name(ptr);
+	output_statement_epilogue(stmt, whenever_mode, st);
+}
+
 static void
 output_escaped_str(char *str, bool quoted)
 {
diff --git a/src/interfaces/ecpg/preproc/type.h b/src/interfaces/ecpg/preproc/type.h
index cd0d1da..a293e9e 100644
--- a/src/interfaces/ecpg/preproc/type.h
+++ b/src/interfaces/ecpg/preproc/type.h
@@ -129,6 +129,8 @@ struct cursor
 	char	   *command;
 	char	   *connection;
 	bool		opened;
+	bool		with_hold;
+	enum ECPGttype	vartype;
 	struct arguments *argsinsert;
 	struct arguments *argsinsert_oos;
 	struct arguments *argsresult;
diff --git a/src/interfaces/ecpg/test/ecpg_schedule b/src/interfaces/ecpg/test/ecpg_schedule
index c07ea93..e4170cc 100644
--- a/src/interfaces/ecpg/test/ecpg_schedule
+++ b/src/interfaces/ecpg/test/ecpg_schedule
@@ -31,6 +31,7 @@ test: sql/array
 test: sql/binary
 test: sql/code100
 test: sql/copystdout
+test: sql/cursorsubxact
 test: sql/define
 test: sql/desc
 test: sql/sqlda
diff --git a/src/interfaces/ecpg/test/ecpg_schedule_tcp b/src/interfaces/ecpg/test/ecpg_schedule_tcp
index 77481b5..26a4bae 100644
--- a/src/interfaces/ecpg/test/ecpg_schedule_tcp
+++ b/src/interfaces/ecpg/test/ecpg_schedule_tcp
@@ -31,6 +31,7 @@ test: sql/array
 test: sql/binary
 test: sql/code100
 test: sql/copystdout
+test: sql/cursorsubxact
 test: sql/define
 test: sql/desc
 test: sql/sqlda
diff --git a/src/interfaces/ecpg/test/expected/compat_informix-describe.c b/src/interfaces/ecpg/test/expected/compat_informix-describe.c
index b4e1b47..2e02b41 100644
--- a/src/interfaces/ecpg/test/expected/compat_informix-describe.c
+++ b/src/interfaces/ecpg/test/expected/compat_informix-describe.c
@@ -135,7 +135,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 
 	strcpy(msg, "commit");
-	{ ECPGtrans(__LINE__, NULL, "commit");
+	{ ECPGtrans(__LINE__, NULL, "commit", 0, 0, 0, NULL);
 #line 42 "describe.pgc"
 
 if (sqlca.sqlcode < 0) exit (1);}
@@ -448,7 +448,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 
 	strcpy(msg, "commit");
-	{ ECPGtrans(__LINE__, NULL, "commit");
+	{ ECPGtrans(__LINE__, NULL, "commit", 0, 0, 0, NULL);
 #line 193 "describe.pgc"
 
 if (sqlca.sqlcode < 0) exit (1);}
diff --git a/src/interfaces/ecpg/test/expected/compat_informix-rnull.c b/src/interfaces/ecpg/test/expected/compat_informix-rnull.c
index e90a291..f164c3f 100644
--- a/src/interfaces/ecpg/test/expected/compat_informix-rnull.c
+++ b/src/interfaces/ecpg/test/expected/compat_informix-rnull.c
@@ -111,7 +111,7 @@ if (sqlca.sqlcode < 0) sqlprint ( );}
 if (sqlca.sqlcode < 0) sqlprint ( );}
 #line 33 "rnull.pgc"
 
-	{ ECPGtrans(__LINE__, NULL, "commit");
+	{ ECPGtrans(__LINE__, NULL, "commit", 0, 0, 0, NULL);
 #line 34 "rnull.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint ( );}
@@ -138,7 +138,7 @@ if (sqlca.sqlcode < 0) sqlprint ( );}
 if (sqlca.sqlcode < 0) sqlprint ( );}
 #line 38 "rnull.pgc"
 
-	{ ECPGtrans(__LINE__, NULL, "commit");
+	{ ECPGtrans(__LINE__, NULL, "commit", 0, 0, 0, NULL);
 #line 39 "rnull.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint ( );}
@@ -182,7 +182,7 @@ if (sqlca.sqlcode < 0) sqlprint ( );}
 if (sqlca.sqlcode < 0) sqlprint ( );}
 #line 54 "rnull.pgc"
 
-	{ ECPGtrans(__LINE__, NULL, "commit");
+	{ ECPGtrans(__LINE__, NULL, "commit", 0, 0, 0, NULL);
 #line 55 "rnull.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint ( );}
@@ -275,7 +275,7 @@ if (sqlca.sqlcode < 0) sqlprint ( );}
 if (sqlca.sqlcode < 0) sqlprint ( );}
 #line 91 "rnull.pgc"
 
-	{ ECPGtrans(__LINE__, NULL, "commit");
+	{ ECPGtrans(__LINE__, NULL, "commit", 0, 0, 0, NULL);
 #line 92 "rnull.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint ( );}
diff --git a/src/interfaces/ecpg/test/expected/compat_informix-sqlda.c b/src/interfaces/ecpg/test/expected/compat_informix-sqlda.c
index a013be9..e47b373 100644
--- a/src/interfaces/ecpg/test/expected/compat_informix-sqlda.c
+++ b/src/interfaces/ecpg/test/expected/compat_informix-sqlda.c
@@ -216,7 +216,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 
 	strcpy(msg, "commit");
-	{ ECPGtrans(__LINE__, NULL, "commit");
+	{ ECPGtrans(__LINE__, NULL, "commit", 0, 0, 0, NULL);
 #line 88 "sqlda.pgc"
 
 if (sqlca.sqlcode < 0) exit (1);}
@@ -241,7 +241,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 
 	strcpy(msg, "open");
-	{ ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "declare mycur1 cursor for $1", 
+	{ ECPGopen(__LINE__, 1, 1, NULL, 0, 0, "mycur1", ECPGst_normal, "declare mycur1 cursor for $1", 
 	ECPGt_char_variable,(ECPGprepared_statement(NULL, "st_id1", __LINE__)),(long)1,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
 #line 101 "sqlda.pgc"
@@ -258,7 +258,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 	while (1)
 	{
 		strcpy(msg, "fetch");
-		{ ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "fetch 1 from mycur1", ECPGt_EOIT, 
+		{ ECPGfetch(__LINE__, 1, 1, NULL, 0, "mycur1", ECPGst_normal, "fetch 1 from mycur1", ECPGt_EOIT, 
 	ECPGt_sqlda, &outp_sqlda, 0L, 0L, 0L, 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
 #line 109 "sqlda.pgc"
@@ -279,7 +279,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 
 	strcpy(msg, "close");
-	{ ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "close mycur1", ECPGt_EOIT, ECPGt_EORT);
+	{ ECPGclose(__LINE__, 1, 1, NULL, 0, "mycur1", ECPGst_normal, "close mycur1", ECPGt_EOIT, ECPGt_EORT);
 #line 118 "sqlda.pgc"
 
 if (sqlca.sqlcode < 0) exit (1);}
@@ -316,7 +316,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 
 	strcpy(msg, "open");
-	{ ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "declare mycur2 cursor for $1", 
+	{ ECPGopen(__LINE__, 1, 1, NULL, 0, 0, "mycur2", ECPGst_normal, "declare mycur2 cursor for $1", 
 	ECPGt_char_variable,(ECPGprepared_statement(NULL, "st_id2", __LINE__)),(long)1,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
 #line 138 "sqlda.pgc"
@@ -333,7 +333,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 	while (1)
 	{
 		strcpy(msg, "fetch");
-		{ ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "fetch from mycur2", ECPGt_EOIT, 
+		{ ECPGfetch(__LINE__, 1, 1, NULL, 0, "mycur2", ECPGst_normal, "fetch from mycur2", ECPGt_EOIT, 
 	ECPGt_sqlda, &outp_sqlda, 0L, 0L, 0L, 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
 #line 146 "sqlda.pgc"
@@ -354,7 +354,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 
 	strcpy(msg, "close");
-	{ ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "close mycur2", ECPGt_EOIT, ECPGt_EORT);
+	{ ECPGclose(__LINE__, 1, 1, NULL, 0, "mycur2", ECPGst_normal, "close mycur2", ECPGt_EOIT, ECPGt_EORT);
 #line 155 "sqlda.pgc"
 
 if (sqlca.sqlcode < 0) exit (1);}
@@ -473,7 +473,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 	dump_sqlda(outp_sqlda);
 
 	strcpy(msg, "commit");
-	{ ECPGtrans(__LINE__, "con2", "commit");
+	{ ECPGtrans(__LINE__, "con2", "commit", 0, 0, 0, NULL);
 #line 226 "sqlda.pgc"
 
 if (sqlca.sqlcode < 0) exit (1);}
@@ -511,7 +511,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 
 	strcpy(msg, "commit");
-	{ ECPGtrans(__LINE__, NULL, "commit");
+	{ ECPGtrans(__LINE__, NULL, "commit", 0, 0, 0, NULL);
 #line 244 "sqlda.pgc"
 
 if (sqlca.sqlcode < 0) exit (1);}
diff --git a/src/interfaces/ecpg/test/expected/compat_informix-test_informix.c b/src/interfaces/ecpg/test/expected/compat_informix-test_informix.c
index d357c77..f88f9f2 100644
--- a/src/interfaces/ecpg/test/expected/compat_informix-test_informix.c
+++ b/src/interfaces/ecpg/test/expected/compat_informix-test_informix.c
@@ -80,7 +80,7 @@ if (sqlca.sqlcode < 0) dosqlprint ( );}
 if (sqlca.sqlcode < 0) dosqlprint ( );}
 #line 28 "test_informix.pgc"
 
-	{ ECPGtrans(__LINE__, NULL, "commit");
+	{ ECPGtrans(__LINE__, NULL, "commit", 0, 0, 0, NULL);
 #line 29 "test_informix.pgc"
 
 if (sqlca.sqlcode < 0) dosqlprint ( );}
@@ -95,7 +95,7 @@ if (sqlca.sqlcode < 0) dosqlprint ( );}
 #line 32 "test_informix.pgc"
 
 	printf("INSERT: %ld=%s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc);
-	if (sqlca.sqlcode != 0) { ECPGtrans(__LINE__, NULL, "rollback");
+	if (sqlca.sqlcode != 0) { ECPGtrans(__LINE__, NULL, "rollback", 0, 0, 1, NULL);
 #line 34 "test_informix.pgc"
 
 if (sqlca.sqlcode < 0) dosqlprint ( );}
@@ -110,7 +110,7 @@ if (sqlca.sqlcode < 0) dosqlprint ( );}
 if (sqlca.sqlcode < 0) dosqlprint ( );}
 #line 36 "test_informix.pgc"
 
-	{ ECPGtrans(__LINE__, NULL, "commit");
+	{ ECPGtrans(__LINE__, NULL, "commit", 0, 0, 0, NULL);
 #line 37 "test_informix.pgc"
 
 if (sqlca.sqlcode < 0) dosqlprint ( );}
@@ -124,7 +124,7 @@ if (sqlca.sqlcode < 0) dosqlprint ( );}
 if (sqlca.sqlcode < 0) dosqlprint ( );}
 #line 40 "test_informix.pgc"
 
-	{ ECPGtrans(__LINE__, NULL, "rollback");
+	{ ECPGtrans(__LINE__, NULL, "rollback", 0, 0, 1, NULL);
 #line 41 "test_informix.pgc"
 
 if (sqlca.sqlcode < 0) dosqlprint ( );}
@@ -139,7 +139,7 @@ if (sqlca.sqlcode < 0) dosqlprint ( );}
 #line 44 "test_informix.pgc"
 
 	printf("SELECT: %ld=%s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc);
-	if (sqlca.sqlcode != 0) { ECPGtrans(__LINE__, NULL, "rollback");
+	if (sqlca.sqlcode != 0) { ECPGtrans(__LINE__, NULL, "rollback", 0, 0, 1, NULL);
 #line 46 "test_informix.pgc"
 
 if (sqlca.sqlcode < 0) dosqlprint ( );}
@@ -158,7 +158,7 @@ if (sqlca.sqlcode < 0) dosqlprint ( );}
 
 	while (1)
 	{
-		{ ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "fetch forward c", ECPGt_EOIT, 
+		{ ECPGfetch(__LINE__, 1, 1, NULL, 0, "c", ECPGst_normal, "fetch forward c", ECPGt_EOIT, 
 	ECPGt_int,&(i),(long)1,(long)1,sizeof(int), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_decimal,&(j),(long)1,(long)1,sizeof(decimal), 
@@ -213,7 +213,7 @@ if (sqlca.sqlcode < 0) dosqlprint ( );}
 
 	printf("Does not exist: %ld\n", sqlca.sqlcode);
 
-	{ ECPGtrans(__LINE__, NULL, "commit");
+	{ ECPGtrans(__LINE__, NULL, "commit", 0, 0, 0, NULL);
 #line 84 "test_informix.pgc"
 
 if (sqlca.sqlcode < 0) dosqlprint ( );}
@@ -225,7 +225,7 @@ if (sqlca.sqlcode < 0) dosqlprint ( );}
 if (sqlca.sqlcode < 0) dosqlprint ( );}
 #line 85 "test_informix.pgc"
 
-	{ ECPGtrans(__LINE__, NULL, "commit");
+	{ ECPGtrans(__LINE__, NULL, "commit", 0, 0, 0, NULL);
 #line 86 "test_informix.pgc"
 
 if (sqlca.sqlcode < 0) dosqlprint ( );}
@@ -244,7 +244,7 @@ if (sqlca.sqlcode < 0) dosqlprint ( );}
 
 static void openit(void)
 {
-	{ ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "declare c cursor for select * from test where i <= $1 ", 
+	{ ECPGopen(__LINE__, 1, 1, NULL, 0, 0, "c", ECPGst_normal, "declare c cursor for select * from test where i <= $1 ", 
 	ECPGt_int,&(*( int  *)(ECPGget_var( 0))),(long)1,(long)1,sizeof(int), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
 #line 95 "test_informix.pgc"
diff --git a/src/interfaces/ecpg/test/expected/compat_informix-test_informix2.c b/src/interfaces/ecpg/test/expected/compat_informix-test_informix2.c
index c1a4891..9bd62ca 100644
--- a/src/interfaces/ecpg/test/expected/compat_informix-test_informix2.c
+++ b/src/interfaces/ecpg/test/expected/compat_informix-test_informix2.c
@@ -114,7 +114,7 @@ static void sql_check(char *fn, char *caller, int ignore)
       printf("%s\n", errorstring);
 
       /* attempt a ROLLBACK */
-      { ECPGtrans(__LINE__, NULL, "rollback");}
+      { ECPGtrans(__LINE__, NULL, "rollback", 0, 0, 1, NULL);}
 #line 27 "test_informix2.pgc"
 
 
@@ -245,7 +245,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 
 	sql_check("main", "update", 0);
 
-	{ ECPGtrans(__LINE__, NULL, "commit");
+	{ ECPGtrans(__LINE__, NULL, "commit", 0, 0, 0, NULL);
 #line 100 "test_informix2.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
@@ -260,7 +260,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 
 	sql_check("main", "drop", 0);
 
-	{ ECPGtrans(__LINE__, NULL, "commit");
+	{ ECPGtrans(__LINE__, NULL, "commit", 0, 0, 0, NULL);
 #line 105 "test_informix2.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
diff --git a/src/interfaces/ecpg/test/expected/pgtypeslib-dt_test.c b/src/interfaces/ecpg/test/expected/pgtypeslib-dt_test.c
index 78f6b3d..713748e 100644
--- a/src/interfaces/ecpg/test/expected/pgtypeslib-dt_test.c
+++ b/src/interfaces/ecpg/test/expected/pgtypeslib-dt_test.c
@@ -436,7 +436,7 @@ if (sqlca.sqlcode < 0) sqlprint ( );}
 	printf("timestamp_defmt_asc(%s, %s) = %s, error: %d\n", in, fmt, text, i);
 	free(text);
 
-	{ ECPGtrans(__LINE__, NULL, "rollback");
+	{ ECPGtrans(__LINE__, NULL, "rollback", 0, 0, 1, NULL);
 #line 365 "dt_test.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint ( );}
diff --git a/src/interfaces/ecpg/test/expected/pgtypeslib-nan_test.c b/src/interfaces/ecpg/test/expected/pgtypeslib-nan_test.c
index 077c0be..715f960 100644
--- a/src/interfaces/ecpg/test/expected/pgtypeslib-nan_test.c
+++ b/src/interfaces/ecpg/test/expected/pgtypeslib-nan_test.c
@@ -82,7 +82,7 @@ if (sqlca.sqlcode < 0) sqlprint ( );}
 	/* declare cur cursor for select id , d , d from nantest1 */
 #line 33 "nan_test.pgc"
 
-	{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur cursor for select id , d , d from nantest1", ECPGt_EOIT, ECPGt_EORT);
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, "cur", ECPGst_normal, "declare cur cursor for select id , d , d from nantest1", ECPGt_EOIT, ECPGt_EORT);
 #line 34 "nan_test.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint ( );}
@@ -90,7 +90,7 @@ if (sqlca.sqlcode < 0) sqlprint ( );}
 
 	while (1)
 	{
-		{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch from cur", ECPGt_EOIT, 
+		{ ECPGfetch(__LINE__, 0, 1, NULL, 0, "cur", ECPGst_normal, "fetch from cur", ECPGt_EOIT, 
 	ECPGt_int,&(id),(long)1,(long)1,sizeof(int), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_double,&(d),(long)1,(long)1,sizeof(double), 
@@ -130,14 +130,14 @@ if (sqlca.sqlcode < 0) sqlprint ( );}
 #line 46 "nan_test.pgc"
 
 	}
-	{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur", ECPGt_EOIT, ECPGt_EORT);
+	{ ECPGclose(__LINE__, 0, 1, NULL, 0, "cur", ECPGst_normal, "close cur", ECPGt_EOIT, ECPGt_EORT);
 #line 48 "nan_test.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint ( );}
 #line 48 "nan_test.pgc"
 
 
-	{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur cursor for select id , d , d from nantest1", ECPGt_EOIT, ECPGt_EORT);
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, "cur", ECPGst_normal, "declare cur cursor for select id , d , d from nantest1", ECPGt_EOIT, ECPGt_EORT);
 #line 50 "nan_test.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint ( );}
@@ -145,7 +145,7 @@ if (sqlca.sqlcode < 0) sqlprint ( );}
 
 	while (1)
 	{
-		{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch from cur", ECPGt_EOIT, 
+		{ ECPGfetch(__LINE__, 0, 1, NULL, 0, "cur", ECPGst_normal, "fetch from cur", ECPGt_EOIT, 
 	ECPGt_int,&(id),(long)1,(long)1,sizeof(int), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_double,&(d),(long)1,(long)1,sizeof(double), 
@@ -164,7 +164,7 @@ if (sqlca.sqlcode < 0) sqlprint ( );}
 		if (isnan(d))
 			printf("%d  NaN '%s'\n", id, val);
 	}
-	{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur", ECPGt_EOIT, ECPGt_EORT);
+	{ ECPGclose(__LINE__, 0, 1, NULL, 0, "cur", ECPGst_normal, "close cur", ECPGt_EOIT, ECPGt_EORT);
 #line 61 "nan_test.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint ( );}
@@ -221,7 +221,7 @@ if (sqlca.sqlcode < 0) sqlprint ( );}
 	/* declare cur1 cursor for select id , d , d from nantest2 */
 #line 75 "nan_test.pgc"
 
-	{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur1 cursor for select id , d , d from nantest2", ECPGt_EOIT, ECPGt_EORT);
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, "cur1", ECPGst_normal, "declare cur1 cursor for select id , d , d from nantest2", ECPGt_EOIT, ECPGt_EORT);
 #line 76 "nan_test.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint ( );}
@@ -229,7 +229,7 @@ if (sqlca.sqlcode < 0) sqlprint ( );}
 
 	while (1)
 	{
-		{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch from cur1", ECPGt_EOIT, 
+		{ ECPGfetch(__LINE__, 0, 1, NULL, 0, "cur1", ECPGst_normal, "fetch from cur1", ECPGt_EOIT, 
 	ECPGt_int,&(id),(long)1,(long)1,sizeof(int), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_numeric,&(num),(long)1,(long)0,sizeof(numeric), 
@@ -245,7 +245,7 @@ if (sqlca.sqlcode < 0) sqlprint ( );}
 			break;
 		printf("%d %s '%s'\n", id, (num->sign == NUMERIC_NAN ? "NaN" : "not NaN"), val);
 	}
-	{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur1", ECPGt_EOIT, ECPGt_EORT);
+	{ ECPGclose(__LINE__, 0, 1, NULL, 0, "cur1", ECPGst_normal, "close cur1", ECPGt_EOIT, ECPGt_EORT);
 #line 84 "nan_test.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint ( );}
@@ -254,7 +254,7 @@ if (sqlca.sqlcode < 0) sqlprint ( );}
 
 	PGTYPESnumeric_free(num);
 
-	{ ECPGtrans(__LINE__, NULL, "rollback");
+	{ ECPGtrans(__LINE__, NULL, "rollback", 0, 0, 1, NULL);
 #line 88 "nan_test.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint ( );}
diff --git a/src/interfaces/ecpg/test/expected/pgtypeslib-num_test.c b/src/interfaces/ecpg/test/expected/pgtypeslib-num_test.c
index 6144034..c139e41 100644
--- a/src/interfaces/ecpg/test/expected/pgtypeslib-num_test.c
+++ b/src/interfaces/ecpg/test/expected/pgtypeslib-num_test.c
@@ -144,7 +144,7 @@ if (sqlca.sqlcode < 0) sqlprint ( );}
 	PGTYPESnumeric_free(value2);
 	PGTYPESnumeric_free(res);
 
-	{ ECPGtrans(__LINE__, NULL, "rollback");
+	{ ECPGtrans(__LINE__, NULL, "rollback", 0, 0, 1, NULL);
 #line 93 "num_test.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint ( );}
diff --git a/src/interfaces/ecpg/test/expected/preproc-autoprep.c b/src/interfaces/ecpg/test/expected/preproc-autoprep.c
index cf5c702..8872986 100644
--- a/src/interfaces/ecpg/test/expected/preproc-autoprep.c
+++ b/src/interfaces/ecpg/test/expected/preproc-autoprep.c
@@ -133,7 +133,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 #line 35 "autoprep.pgc"
 
 
-  { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare C cursor for select Item1 from T", ECPGt_EOIT, ECPGt_EORT);
+  { ECPGopen(__LINE__, 0, 1, NULL, 0, 0, "C", ECPGst_normal, "declare C cursor for select Item1 from T", ECPGt_EOIT, ECPGt_EORT);
 #line 37 "autoprep.pgc"
 
 if (sqlca.sqlwarn[0] == 'W') sqlprint();
@@ -143,7 +143,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 #line 37 "autoprep.pgc"
 
 
-  { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch 1 in C", ECPGt_EOIT, 
+  { ECPGfetch(__LINE__, 0, 1, NULL, 0, "C", ECPGst_normal, "fetch 1 in C", ECPGt_EOIT, 
 	ECPGt_int,&(i),(long)1,(long)1,sizeof(int), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
 #line 39 "autoprep.pgc"
@@ -156,7 +156,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 
   printf("i = %d\n", i);
 
-  { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close C", ECPGt_EOIT, ECPGt_EORT);
+  { ECPGclose(__LINE__, 0, 1, NULL, 0, "C", ECPGst_normal, "close C", ECPGt_EOIT, ECPGt_EORT);
 #line 42 "autoprep.pgc"
 
 if (sqlca.sqlwarn[0] == 'W') sqlprint();
@@ -180,7 +180,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 #line 46 "autoprep.pgc"
 
 
-  { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur1 cursor for $1", 
+  { ECPGopen(__LINE__, 0, 1, NULL, 0, 0, "cur1", ECPGst_normal, "declare cur1 cursor for $1", 
 	ECPGt_char_variable,(ECPGprepared_statement(NULL, "stmt1", __LINE__)),(long)1,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
 #line 48 "autoprep.pgc"
@@ -199,7 +199,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
   i = 0;
   while (1)
   {
-	{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur1", ECPGt_EOIT, 
+	{ ECPGfetch(__LINE__, 0, 1, NULL, 0, "cur1", ECPGst_normal, "fetch cur1", ECPGt_EOIT, 
 	ECPGt_int,&(item1),(long)1,(long)1,sizeof(int), 
 	ECPGt_int,&(ind1),(long)1,(long)1,sizeof(int), ECPGt_EORT);
 #line 55 "autoprep.pgc"
@@ -217,7 +217,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 	i++;
   }
 
-  { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur1", ECPGt_EOIT, ECPGt_EORT);
+  { ECPGclose(__LINE__, 0, 1, NULL, 0, "cur1", ECPGst_normal, "close cur1", ECPGt_EOIT, ECPGt_EORT);
 #line 60 "autoprep.pgc"
 
 if (sqlca.sqlwarn[0] == 'W') sqlprint();
diff --git a/src/interfaces/ecpg/test/expected/preproc-cursor.c b/src/interfaces/ecpg/test/expected/preproc-cursor.c
index 150fc9a..6f92797 100644
--- a/src/interfaces/ecpg/test/expected/preproc-cursor.c
+++ b/src/interfaces/ecpg/test/expected/preproc-cursor.c
@@ -165,13 +165,13 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 
 	strcpy(msg, "commit");
-	{ ECPGtrans(__LINE__, "test1", "commit");
+	{ ECPGtrans(__LINE__, "test1", "commit", 0, 0, 0, NULL);
 #line 57 "cursor.pgc"
 
 if (sqlca.sqlcode < 0) exit (1);}
 #line 57 "cursor.pgc"
 
-	{ ECPGtrans(__LINE__, "test2", "commit");
+	{ ECPGtrans(__LINE__, "test2", "commit", 0, 0, 0, NULL);
 #line 58 "cursor.pgc"
 
 if (sqlca.sqlcode < 0) exit (1);}
@@ -187,7 +187,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 
 	strcpy(msg, "open");
-	{ ECPGdo(__LINE__, 0, 1, "test1", 0, ECPGst_normal, "declare $0 cursor for select id , t from t1", 
+	{ ECPGopen(__LINE__, 0, 1, "test1", 0, 0, curname1, ECPGst_normal, "declare $0 cursor for select id , t from t1", 
 	ECPGt_char,&(curname1),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
 #line 67 "cursor.pgc"
@@ -197,7 +197,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 
 	strcpy(msg, "fetch from");
-	{ ECPGdo(__LINE__, 0, 1, "test1", 0, ECPGst_normal, "fetch forward from $0", 
+	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, curname1, ECPGst_normal, "fetch forward from $0", 
 	ECPGt_char,&(curname1),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, 
 	ECPGt_int,&(id),(long)1,(long)1,sizeof(int), 
@@ -212,7 +212,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 	printf("%d %s\n", id, t);
 
 	strcpy(msg, "fetch");
-	{ ECPGdo(__LINE__, 0, 1, "test1", 0, ECPGst_normal, "fetch forward $0", 
+	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, curname1, ECPGst_normal, "fetch forward $0", 
 	ECPGt_char,&(curname1),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, 
 	ECPGt_int,&(id),(long)1,(long)1,sizeof(int), 
@@ -227,7 +227,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 	printf("%d %s\n", id, t);
 
 	strcpy(msg, "fetch 1 from");
-	{ ECPGdo(__LINE__, 0, 1, "test1", 0, ECPGst_normal, "fetch 1 from $0", 
+	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, curname1, ECPGst_normal, "fetch 1 from $0", 
 	ECPGt_char,&(curname1),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, 
 	ECPGt_int,&(id),(long)1,(long)1,sizeof(int), 
@@ -243,7 +243,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 	strcpy(msg, "fetch :count from");
 	count = 1;
-	{ ECPGdo(__LINE__, 0, 1, "test1", 0, ECPGst_normal, "fetch $0 from $0", 
+	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, curname1, ECPGst_normal, "fetch $0 from $0", 
 	ECPGt_int,&(count),(long)1,(long)1,sizeof(int), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_char,&(curname1),(long)0,(long)1,(1)*sizeof(char), 
@@ -260,7 +260,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 	printf("%d %s\n", id, t);
 
 	strcpy(msg, "move in");
-	{ ECPGdo(__LINE__, 0, 1, "test1", 0, ECPGst_normal, "move absolute 0 in $0", 
+	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, curname1, ECPGst_normal, "move absolute 0 in $0", 
 	ECPGt_char,&(curname1),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
 #line 87 "cursor.pgc"
@@ -270,7 +270,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 
 	strcpy(msg, "fetch 1");
-	{ ECPGdo(__LINE__, 0, 1, "test1", 0, ECPGst_normal, "fetch 1 $0", 
+	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, curname1, ECPGst_normal, "fetch 1 $0", 
 	ECPGt_char,&(curname1),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, 
 	ECPGt_int,&(id),(long)1,(long)1,sizeof(int), 
@@ -286,7 +286,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 	strcpy(msg, "fetch :count");
 	count = 1;
-	{ ECPGdo(__LINE__, 0, 1, "test1", 0, ECPGst_normal, "fetch $0 $0", 
+	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, curname1, ECPGst_normal, "fetch $0 $0", 
 	ECPGt_int,&(count),(long)1,(long)1,sizeof(int), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_char,&(curname1),(long)0,(long)1,(1)*sizeof(char), 
@@ -303,7 +303,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 	printf("%d %s\n", id, t);
 
 	strcpy(msg, "close");
-	{ ECPGdo(__LINE__, 0, 1, "test1", 0, ECPGst_normal, "close $0", 
+	{ ECPGclose(__LINE__, 0, 1, "test1", 0, curname1, ECPGst_normal, "close $0", 
 	ECPGt_char,&(curname1),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
 #line 99 "cursor.pgc"
@@ -323,7 +323,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 
 	strcpy(msg, "open");
-	{ ECPGdo(__LINE__, 0, 1, "test1", 0, ECPGst_normal, "declare $0 cursor for select id , t from t1", 
+	{ ECPGopen(__LINE__, 0, 1, "test1", 0, 0, curname2, ECPGst_normal, "declare $0 cursor for select id , t from t1", 
 	ECPGt_char,&(curname2),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, 
 	ECPGt_int,&(id),(long)1,(long)1,sizeof(int), 
@@ -337,7 +337,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 
 	strcpy(msg, "fetch from");
-	{ ECPGdo(__LINE__, 0, 1, "test1", 0, ECPGst_normal, "fetch from $0", 
+	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, curname2, ECPGst_normal, "fetch from $0", 
 	ECPGt_char,&(curname2),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, 
 	ECPGt_int,&(id),(long)1,(long)1,sizeof(int), 
@@ -352,7 +352,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 	printf("%d %s\n", id, t);
 
 	strcpy(msg, "fetch");
-	{ ECPGdo(__LINE__, 0, 1, "test1", 0, ECPGst_normal, "fetch $0", 
+	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, curname2, ECPGst_normal, "fetch $0", 
 	ECPGt_char,&(curname2),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, 
 	ECPGt_int,&(id),(long)1,(long)1,sizeof(int), 
@@ -367,7 +367,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 	printf("%d %s\n", id, t);
 
 	strcpy(msg, "fetch 1 from");
-	{ ECPGdo(__LINE__, 0, 1, "test1", 0, ECPGst_normal, "fetch 1 from $0", 
+	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, curname2, ECPGst_normal, "fetch 1 from $0", 
 	ECPGt_char,&(curname2),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, 
 	ECPGt_int,&(id),(long)1,(long)1,sizeof(int), 
@@ -383,7 +383,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 	strcpy(msg, "fetch :count from");
 	count = 1;
-	{ ECPGdo(__LINE__, 0, 1, "test1", 0, ECPGst_normal, "fetch $0 from $0", 
+	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, curname2, ECPGst_normal, "fetch $0 from $0", 
 	ECPGt_int,&(count),(long)1,(long)1,sizeof(int), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_char,&(curname2),(long)0,(long)1,(1)*sizeof(char), 
@@ -400,7 +400,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 	printf("%d %s\n", id, t);
 
 	strcpy(msg, "move");
-	{ ECPGdo(__LINE__, 0, 1, "test1", 0, ECPGst_normal, "move absolute 0 $0", 
+	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, curname2, ECPGst_normal, "move absolute 0 $0", 
 	ECPGt_char,&(curname2),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, 
 	ECPGt_int,&(id),(long)1,(long)1,sizeof(int), 
@@ -414,7 +414,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 
 	strcpy(msg, "fetch 1");
-	{ ECPGdo(__LINE__, 0, 1, "test1", 0, ECPGst_normal, "fetch 1 $0", 
+	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, curname2, ECPGst_normal, "fetch 1 $0", 
 	ECPGt_char,&(curname2),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, 
 	ECPGt_int,&(id),(long)1,(long)1,sizeof(int), 
@@ -430,7 +430,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 	strcpy(msg, "fetch :count");
 	count = 1;
-	{ ECPGdo(__LINE__, 0, 1, "test1", 0, ECPGst_normal, "fetch $0 $0", 
+	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, curname2, ECPGst_normal, "fetch $0 $0", 
 	ECPGt_int,&(count),(long)1,(long)1,sizeof(int), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_char,&(curname2),(long)0,(long)1,(1)*sizeof(char), 
@@ -447,7 +447,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 	printf("%d %s\n", id, t);
 
 	strcpy(msg, "close");
-	{ ECPGdo(__LINE__, 0, 1, "test1", 0, ECPGst_normal, "close $0", 
+	{ ECPGclose(__LINE__, 0, 1, "test1", 0, curname2, ECPGst_normal, "close $0", 
 	ECPGt_char,&(curname2),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
 #line 140 "cursor.pgc"
@@ -483,7 +483,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 
 	strcpy(msg, "open");
-	{ ECPGdo(__LINE__, 0, 1, "test1", 0, ECPGst_normal, "declare $0 cursor for $1", 
+	{ ECPGopen(__LINE__, 0, 1, "test1", 0, 0, curname3, ECPGst_normal, "declare $0 cursor for $1", 
 	ECPGt_char,&(curname3),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_char_variable,(ECPGprepared_statement("test1", "st_id1", __LINE__)),(long)1,(long)1,(1)*sizeof(char), 
@@ -493,7 +493,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 if (sqlca.sqlcode < 0) exit (1);}
 #line 153 "cursor.pgc"
 
-	{ ECPGdo(__LINE__, 0, 1, "test2", 0, ECPGst_normal, "declare $0 cursor for $1", 
+	{ ECPGopen(__LINE__, 0, 1, "test2", 0, 0, curname5, ECPGst_normal, "declare $0 cursor for $1", 
 	ECPGt_char,&(curname5),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_char_variable,(ECPGprepared_statement("test2", "st_id1", __LINE__)),(long)1,(long)1,(1)*sizeof(char), 
@@ -505,7 +505,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 
 	strcpy(msg, "fetch");
-	{ ECPGdo(__LINE__, 0, 1, "test2", 0, ECPGst_normal, "fetch $0", 
+	{ ECPGfetch(__LINE__, 0, 1, "test2", 0, curname5, ECPGst_normal, "fetch $0", 
 	ECPGt_char,&(curname5),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, 
 	ECPGt_int,&(id),(long)1,(long)1,sizeof(int), 
@@ -520,7 +520,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 	printf("%d %s\n", id, t);
 
 	strcpy(msg, "fetch from");
-	{ ECPGdo(__LINE__, 0, 1, "test1", 0, ECPGst_normal, "fetch from $0", 
+	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, curname3, ECPGst_normal, "fetch from $0", 
 	ECPGt_char,&(curname3),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, 
 	ECPGt_int,&(id),(long)1,(long)1,sizeof(int), 
@@ -535,7 +535,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 	printf("%d %s\n", id, t);
 
 	strcpy(msg, "fetch 1 from");
-	{ ECPGdo(__LINE__, 0, 1, "test1", 0, ECPGst_normal, "fetch 1 from $0", 
+	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, curname3, ECPGst_normal, "fetch 1 from $0", 
 	ECPGt_char,&(curname3),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, 
 	ECPGt_int,&(id),(long)1,(long)1,sizeof(int), 
@@ -551,7 +551,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 	strcpy(msg, "fetch :count from");
 	count = 1;
-	{ ECPGdo(__LINE__, 0, 1, "test1", 0, ECPGst_normal, "fetch $0 from $0", 
+	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, curname3, ECPGst_normal, "fetch $0 from $0", 
 	ECPGt_int,&(count),(long)1,(long)1,sizeof(int), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_char,&(curname3),(long)0,(long)1,(1)*sizeof(char), 
@@ -568,7 +568,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 	printf("%d %s\n", id, t);
 
 	strcpy(msg, "move");
-	{ ECPGdo(__LINE__, 0, 1, "test1", 0, ECPGst_normal, "move absolute 0 $0", 
+	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, curname3, ECPGst_normal, "move absolute 0 $0", 
 	ECPGt_char,&(curname3),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
 #line 174 "cursor.pgc"
@@ -578,7 +578,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 
 	strcpy(msg, "fetch 1");
-	{ ECPGdo(__LINE__, 0, 1, "test1", 0, ECPGst_normal, "fetch 1 $0", 
+	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, curname3, ECPGst_normal, "fetch 1 $0", 
 	ECPGt_char,&(curname3),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, 
 	ECPGt_int,&(id),(long)1,(long)1,sizeof(int), 
@@ -594,7 +594,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 	strcpy(msg, "fetch :count");
 	count = 1;
-	{ ECPGdo(__LINE__, 0, 1, "test1", 0, ECPGst_normal, "fetch $0 $0", 
+	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, curname3, ECPGst_normal, "fetch $0 $0", 
 	ECPGt_int,&(count),(long)1,(long)1,sizeof(int), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_char,&(curname3),(long)0,(long)1,(1)*sizeof(char), 
@@ -611,7 +611,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 	printf("%d %s\n", id, t);
 
 	strcpy(msg, "close");
-	{ ECPGdo(__LINE__, 0, 1, "test1", 0, ECPGst_normal, "close $0", 
+	{ ECPGclose(__LINE__, 0, 1, "test1", 0, curname3, ECPGst_normal, "close $0", 
 	ECPGt_char,&(curname3),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
 #line 186 "cursor.pgc"
@@ -619,7 +619,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 if (sqlca.sqlcode < 0) exit (1);}
 #line 186 "cursor.pgc"
 
-	{ ECPGdo(__LINE__, 0, 1, "test2", 0, ECPGst_normal, "close $0", 
+	{ ECPGclose(__LINE__, 0, 1, "test2", 0, curname5, ECPGst_normal, "close $0", 
 	ECPGt_char,&(curname5),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
 #line 187 "cursor.pgc"
@@ -663,7 +663,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 
 	strcpy(msg, "open");
-	{ ECPGdo(__LINE__, 0, 1, "test1", 0, ECPGst_normal, "declare $0 cursor for $1", 
+	{ ECPGopen(__LINE__, 0, 1, "test1", 0, 0, curname4.arr, ECPGst_normal, "declare $0 cursor for $1", 
 	ECPGt_varchar,&(curname4),(long)50,(long)1,sizeof(struct varchar_1), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_char_variable,(ECPGprepared_statement("test1", "st_id2", __LINE__)),(long)1,(long)1,(1)*sizeof(char), 
@@ -675,7 +675,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 
 	strcpy(msg, "fetch from");
-	{ ECPGdo(__LINE__, 0, 1, "test1", 0, ECPGst_normal, "fetch from $0", 
+	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, curname4.arr, ECPGst_normal, "fetch from $0", 
 	ECPGt_varchar,&(curname4),(long)50,(long)1,sizeof(struct varchar_1), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, 
 	ECPGt_int,&(id),(long)1,(long)1,sizeof(int), 
@@ -690,7 +690,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 	printf("%d %s\n", id, t);
 
 	strcpy(msg, "fetch");
-	{ ECPGdo(__LINE__, 0, 1, "test1", 0, ECPGst_normal, "fetch $0", 
+	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, curname4.arr, ECPGst_normal, "fetch $0", 
 	ECPGt_varchar,&(curname4),(long)50,(long)1,sizeof(struct varchar_1), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, 
 	ECPGt_int,&(id),(long)1,(long)1,sizeof(int), 
@@ -705,7 +705,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 	printf("%d %s\n", id, t);
 
 	strcpy(msg, "fetch 1 from");
-	{ ECPGdo(__LINE__, 0, 1, "test1", 0, ECPGst_normal, "fetch 1 from $0", 
+	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, curname4.arr, ECPGst_normal, "fetch 1 from $0", 
 	ECPGt_varchar,&(curname4),(long)50,(long)1,sizeof(struct varchar_1), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, 
 	ECPGt_int,&(id),(long)1,(long)1,sizeof(int), 
@@ -721,7 +721,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 	strcpy(msg, "fetch :count from");
 	count = 1;
-	{ ECPGdo(__LINE__, 0, 1, "test1", 0, ECPGst_normal, "fetch $0 from $0", 
+	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, curname4.arr, ECPGst_normal, "fetch $0 from $0", 
 	ECPGt_int,&(count),(long)1,(long)1,sizeof(int), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_varchar,&(curname4),(long)50,(long)1,sizeof(struct varchar_1), 
@@ -738,7 +738,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 	printf("%d %s\n", id, t);
 
 	strcpy(msg, "move");
-	{ ECPGdo(__LINE__, 0, 1, "test1", 0, ECPGst_normal, "move absolute 0 $0", 
+	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, curname4.arr, ECPGst_normal, "move absolute 0 $0", 
 	ECPGt_varchar,&(curname4),(long)50,(long)1,sizeof(struct varchar_1), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
 #line 226 "cursor.pgc"
@@ -748,7 +748,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 
 	strcpy(msg, "fetch 1");
-	{ ECPGdo(__LINE__, 0, 1, "test1", 0, ECPGst_normal, "fetch 1 $0", 
+	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, curname4.arr, ECPGst_normal, "fetch 1 $0", 
 	ECPGt_varchar,&(curname4),(long)50,(long)1,sizeof(struct varchar_1), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, 
 	ECPGt_int,&(id),(long)1,(long)1,sizeof(int), 
@@ -764,7 +764,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 	strcpy(msg, "fetch :count");
 	count = 1;
-	{ ECPGdo(__LINE__, 0, 1, "test1", 0, ECPGst_normal, "fetch $0 $0", 
+	{ ECPGfetch(__LINE__, 0, 1, "test1", 0, curname4.arr, ECPGst_normal, "fetch $0 $0", 
 	ECPGt_int,&(count),(long)1,(long)1,sizeof(int), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_varchar,&(curname4),(long)50,(long)1,sizeof(struct varchar_1), 
@@ -781,7 +781,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 	printf("%d %s\n", id, t);
 
 	strcpy(msg, "close");
-	{ ECPGdo(__LINE__, 0, 1, "test1", 0, ECPGst_normal, "close $0", 
+	{ ECPGclose(__LINE__, 0, 1, "test1", 0, curname4.arr, ECPGst_normal, "close $0", 
 	ECPGt_varchar,&(curname4),(long)50,(long)1,sizeof(struct varchar_1), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
 #line 238 "cursor.pgc"
@@ -815,7 +815,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 
 	strcpy(msg, "commit");
-	{ ECPGtrans(__LINE__, "test1", "commit");
+	{ ECPGtrans(__LINE__, "test1", "commit", 0, 0, 0, NULL);
 #line 250 "cursor.pgc"
 
 if (sqlca.sqlcode < 0) exit (1);}
diff --git a/src/interfaces/ecpg/test/expected/preproc-define.c b/src/interfaces/ecpg/test/expected/preproc-define.c
index 43df19c..4151571 100644
--- a/src/interfaces/ecpg/test/expected/preproc-define.c
+++ b/src/interfaces/ecpg/test/expected/preproc-define.c
@@ -83,7 +83,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 if (sqlca.sqlcode < 0) sqlprint();}
 #line 36 "define.pgc"
 
-	{ ECPGtrans(__LINE__, NULL, "commit");
+	{ ECPGtrans(__LINE__, NULL, "commit", 0, 0, 0, NULL);
 #line 37 "define.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
@@ -102,7 +102,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 if (sqlca.sqlcode < 0) sqlprint();}
 #line 40 "define.pgc"
 
-	{ ECPGtrans(__LINE__, NULL, "commit");
+	{ ECPGtrans(__LINE__, NULL, "commit", 0, 0, 0, NULL);
 #line 41 "define.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
@@ -151,7 +151,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 if (sqlca.sqlcode < 0) sqlprint();}
 #line 57 "define.pgc"
 
-	{ ECPGtrans(__LINE__, NULL, "commit");
+	{ ECPGtrans(__LINE__, NULL, "commit", 0, 0, 0, NULL);
 #line 58 "define.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
diff --git a/src/interfaces/ecpg/test/expected/preproc-outofscope.c b/src/interfaces/ecpg/test/expected/preproc-outofscope.c
index 2438911..99d181e 100644
--- a/src/interfaces/ecpg/test/expected/preproc-outofscope.c
+++ b/src/interfaces/ecpg/test/expected/preproc-outofscope.c
@@ -201,7 +201,7 @@ get_var1(MYTYPE **myvar0, MYNULLTYPE **mynullvar0)
 static void
 open_cur1(void)
 {
-	{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare mycur cursor for select * from a1", ECPGt_EOIT, 
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, "mycur", ECPGst_normal, "declare mycur cursor for select * from a1", ECPGt_EOIT, 
 	ECPGt_int,&((*( MYTYPE  *)(ECPGget_var( 0)) ).id),(long)1,(long)1,sizeof(int), 
 	ECPGt_int,&((*( MYNULLTYPE  *)(ECPGget_var( 1)) ).id),(long)1,(long)1,sizeof(int), 
 	ECPGt_char,&((*( MYTYPE  *)(ECPGget_var( 0)) ).t),(long)64,(long)1,(64)*sizeof(char), 
@@ -225,7 +225,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 static void
 get_record1(void)
 {
-	{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch mycur", ECPGt_EOIT, 
+	{ ECPGfetch(__LINE__, 0, 1, NULL, 0, "mycur", ECPGst_normal, "fetch mycur", ECPGt_EOIT, 
 	ECPGt_int,&((*( MYTYPE  *)(ECPGget_var( 0)) ).id),(long)1,(long)1,sizeof(int), 
 	ECPGt_int,&((*( MYNULLTYPE  *)(ECPGget_var( 1)) ).id),(long)1,(long)1,sizeof(int), 
 	ECPGt_char,&((*( MYTYPE  *)(ECPGget_var( 0)) ).t),(long)64,(long)1,(64)*sizeof(char), 
@@ -249,7 +249,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 static void
 close_cur1(void)
 {
-	{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close mycur", ECPGt_EOIT, ECPGt_EORT);
+	{ ECPGclose(__LINE__, 0, 1, NULL, 0, "mycur", ECPGst_normal, "close mycur", ECPGt_EOIT, ECPGt_EORT);
 #line 58 "outofscope.pgc"
 
 if (sqlca.sqlcode < 0) exit (1);}
@@ -315,7 +315,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 
 	strcpy(msg, "commit");
-	{ ECPGtrans(__LINE__, NULL, "commit");
+	{ ECPGtrans(__LINE__, NULL, "commit", 0, 0, 0, NULL);
 #line 89 "outofscope.pgc"
 
 if (sqlca.sqlcode < 0) exit (1);}
@@ -359,7 +359,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 
 	strcpy(msg, "commit");
-	{ ECPGtrans(__LINE__, NULL, "commit");
+	{ ECPGtrans(__LINE__, NULL, "commit", 0, 0, 0, NULL);
 #line 121 "outofscope.pgc"
 
 if (sqlca.sqlcode < 0) exit (1);}
diff --git a/src/interfaces/ecpg/test/expected/preproc-variable.c b/src/interfaces/ecpg/test/expected/preproc-variable.c
index 32e9778..67d66a5 100644
--- a/src/interfaces/ecpg/test/expected/preproc-variable.c
+++ b/src/interfaces/ecpg/test/expected/preproc-variable.c
@@ -182,7 +182,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 
 	strcpy(msg, "commit");
-	{ ECPGtrans(__LINE__, NULL, "commit");
+	{ ECPGtrans(__LINE__, NULL, "commit", 0, 0, 0, NULL);
 #line 60 "variable.pgc"
 
 if (sqlca.sqlcode < 0) exit (1);}
@@ -190,7 +190,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 
 	strcpy(msg, "open");
-	{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur cursor for select name , born , age , married , children from family", ECPGt_EOIT, ECPGt_EORT);
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, "cur", ECPGst_normal, "declare cur cursor for select name , born , age , married , children from family", ECPGt_EOIT, ECPGt_EORT);
 #line 63 "variable.pgc"
 
 if (sqlca.sqlcode < 0) exit (1);}
@@ -206,7 +206,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 	memset(i, 0, sizeof(ind_personal));
 	while (1) {
 		strcpy(msg, "fetch");
-		{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur", ECPGt_EOIT, 
+		{ ECPGfetch(__LINE__, 0, 1, NULL, 0, "cur", ECPGst_normal, "fetch cur", ECPGt_EOIT, 
 	ECPGt_varchar,&(p->name),(long)BUFFERSIZ,(long)1,sizeof(struct varchar_1), 
 	ECPGt_int,&(i->ind_name),(long)1,(long)1,sizeof(int), 
 	ECPGt_long,&(p->birth.born),(long)1,(long)1,sizeof(long), 
@@ -241,7 +241,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 	}
 
 	strcpy(msg, "close");
-	{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur", ECPGt_EOIT, ECPGt_EORT);
+	{ ECPGclose(__LINE__, 0, 1, NULL, 0, "cur", ECPGst_normal, "close cur", ECPGt_EOIT, ECPGt_EORT);
 #line 89 "variable.pgc"
 
 if (sqlca.sqlcode < 0) exit (1);}
@@ -257,7 +257,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 
 	strcpy(msg, "commit");
-	{ ECPGtrans(__LINE__, NULL, "commit");
+	{ ECPGtrans(__LINE__, NULL, "commit", 0, 0, 0, NULL);
 #line 95 "variable.pgc"
 
 if (sqlca.sqlcode < 0) exit (1);}
diff --git a/src/interfaces/ecpg/test/expected/preproc-whenever.c b/src/interfaces/ecpg/test/expected/preproc-whenever.c
index 03f596a..d07171b 100644
--- a/src/interfaces/ecpg/test/expected/preproc-whenever.c
+++ b/src/interfaces/ecpg/test/expected/preproc-whenever.c
@@ -93,7 +93,7 @@ if (sqlca.sqlwarn[0] == 'W') warn ( );
 if (sqlca.sqlcode < 0) sqlprint();}
 #line 36 "whenever.pgc"
 
-	{ ECPGtrans(__LINE__, NULL, "rollback");
+	{ ECPGtrans(__LINE__, NULL, "rollback", 0, 0, 1, NULL);
 #line 37 "whenever.pgc"
 
 if (sqlca.sqlwarn[0] == 'W') warn ( );
@@ -114,7 +114,7 @@ if (sqlca.sqlwarn[0] == 'W') warn ( );
 if (sqlca.sqlcode < 0) sqlprint();}
 #line 39 "whenever.pgc"
 
-	{ ECPGtrans(__LINE__, NULL, "rollback");
+	{ ECPGtrans(__LINE__, NULL, "rollback", 0, 0, 1, NULL);
 #line 40 "whenever.pgc"
 
 if (sqlca.sqlwarn[0] == 'W') warn ( );
@@ -138,7 +138,7 @@ if (sqlca.sqlwarn[0] == 'W') warn ( );
 if (sqlca.sqlcode < 0) print ( "select" );}
 #line 43 "whenever.pgc"
 
-	{ ECPGtrans(__LINE__, NULL, "rollback");
+	{ ECPGtrans(__LINE__, NULL, "rollback", 0, 0, 1, NULL);
 #line 44 "whenever.pgc"
 
 if (sqlca.sqlwarn[0] == 'W') warn ( );
@@ -162,7 +162,7 @@ if (sqlca.sqlwarn[0] == 'W') warn ( );
 if (sqlca.sqlcode < 0) print2 ( );}
 #line 47 "whenever.pgc"
 
-	{ ECPGtrans(__LINE__, NULL, "rollback");
+	{ ECPGtrans(__LINE__, NULL, "rollback", 0, 0, 1, NULL);
 #line 48 "whenever.pgc"
 
 if (sqlca.sqlwarn[0] == 'W') warn ( );
@@ -183,7 +183,7 @@ if (sqlca.sqlcode < 0) print2 ( );}
 if (sqlca.sqlwarn[0] == 'W') warn ( );}
 #line 51 "whenever.pgc"
 
-	{ ECPGtrans(__LINE__, NULL, "rollback");
+	{ ECPGtrans(__LINE__, NULL, "rollback", 0, 0, 1, NULL);
 #line 52 "whenever.pgc"
 
 if (sqlca.sqlwarn[0] == 'W') warn ( );}
@@ -207,7 +207,7 @@ if (sqlca.sqlcode < 0) goto error;}
 	printf("Should not be reachable\n");
 
 	error:
-	{ ECPGtrans(__LINE__, NULL, "rollback");
+	{ ECPGtrans(__LINE__, NULL, "rollback", 0, 0, 1, NULL);
 #line 59 "whenever.pgc"
 
 if (sqlca.sqlwarn[0] == 'W') warn ( );
@@ -233,7 +233,7 @@ if (sqlca.sqlwarn[0] == 'W') warn ( );
 if (sqlca.sqlcode < 0) exit (1);}
 #line 64 "whenever.pgc"
 
-	{ ECPGtrans(__LINE__, NULL, "rollback");
+	{ ECPGtrans(__LINE__, NULL, "rollback", 0, 0, 1, NULL);
 #line 65 "whenever.pgc"
 
 if (sqlca.sqlwarn[0] == 'W') warn ( );
diff --git a/src/interfaces/ecpg/test/expected/sql-array.c b/src/interfaces/ecpg/test/expected/sql-array.c
index 3c87956..f770c09 100644
--- a/src/interfaces/ecpg/test/expected/sql-array.c
+++ b/src/interfaces/ecpg/test/expected/sql-array.c
@@ -148,7 +148,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 #line 29 "array.pgc"
 
 
-	{ ECPGtrans(__LINE__, NULL, "begin work");
+	{ ECPGtrans(__LINE__, NULL, "begin work", 0, 1, 0, NULL);
 #line 31 "array.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
@@ -193,14 +193,14 @@ if (sqlca.sqlcode < 0) sqlprint();}
 #line 39 "array.pgc"
 
 
-	{ ECPGtrans(__LINE__, NULL, "commit");
+	{ ECPGtrans(__LINE__, NULL, "commit", 0, 0, 0, NULL);
 #line 41 "array.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
 #line 41 "array.pgc"
 
 
-	{ ECPGtrans(__LINE__, NULL, "begin work");
+	{ ECPGtrans(__LINE__, NULL, "begin work", 0, 1, 0, NULL);
 #line 43 "array.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
@@ -259,7 +259,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 #line 70 "array.pgc"
 
 
-	{ ECPGtrans(__LINE__, NULL, "commit");
+	{ ECPGtrans(__LINE__, NULL, "commit", 0, 0, 0, NULL);
 #line 72 "array.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
diff --git a/src/interfaces/ecpg/test/expected/sql-binary.c b/src/interfaces/ecpg/test/expected/sql-binary.c
index 9aa11d6..8826cca 100644
--- a/src/interfaces/ecpg/test/expected/sql-binary.c
+++ b/src/interfaces/ecpg/test/expected/sql-binary.c
@@ -111,12 +111,12 @@ main (void)
  /* declare C cursor for select name , accs , byte from empl where idnum = $1  */
 #line 58 "binary.pgc"
 
-  { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare C cursor for select name , accs , byte from empl where idnum = $1 ", 
+  { ECPGopen(__LINE__, 0, 1, NULL, 0, 0, "C", ECPGst_normal, "declare C cursor for select name , accs , byte from empl where idnum = $1 ", 
 	ECPGt_long,&(empl.idnum),(long)1,(long)1,sizeof(long), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
 #line 59 "binary.pgc"
 
-  { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch C", ECPGt_EOIT, 
+  { ECPGfetch(__LINE__, 0, 1, NULL, 0, "C", ECPGst_normal, "fetch C", ECPGt_EOIT, 
 	ECPGt_char,(empl.name),(long)21,(long)1,(21)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_short,&(empl.accs),(long)1,(long)1,sizeof(short), 
@@ -133,7 +133,7 @@ main (void)
 
   printf ("name=%s, accs=%d byte=%s\n", empl.name, empl.accs, empl.byte);
 
-  { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close C", ECPGt_EOIT, ECPGt_EORT);}
+  { ECPGclose(__LINE__, 0, 1, NULL, 0, "C", ECPGst_normal, "close C", ECPGt_EOIT, ECPGt_EORT);}
 #line 69 "binary.pgc"
 
 
@@ -142,12 +142,12 @@ main (void)
  /* declare B binary cursor for select name , accs , byte from empl where idnum = $1  */
 #line 72 "binary.pgc"
 
-  { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare B binary cursor for select name , accs , byte from empl where idnum = $1 ", 
+  { ECPGopen(__LINE__, 0, 1, NULL, 0, 0, "B", ECPGst_normal, "declare B binary cursor for select name , accs , byte from empl where idnum = $1 ", 
 	ECPGt_long,&(empl.idnum),(long)1,(long)1,sizeof(long), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
 #line 73 "binary.pgc"
 
-  { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch B", ECPGt_EOIT, 
+  { ECPGfetch(__LINE__, 0, 1, NULL, 0, "B", ECPGst_normal, "fetch B", ECPGt_EOIT, 
 	ECPGt_char,(empl.name),(long)21,(long)1,(21)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_short,&(empl.accs),(long)1,(long)1,sizeof(short), 
@@ -162,7 +162,7 @@ main (void)
       exit (sqlca.sqlcode);
     }
 
-  { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close B", ECPGt_EOIT, ECPGt_EORT);}
+  { ECPGclose(__LINE__, 0, 1, NULL, 0, "B", ECPGst_normal, "close B", ECPGt_EOIT, ECPGt_EORT);}
 #line 81 "binary.pgc"
 
 
@@ -176,12 +176,12 @@ main (void)
  /* declare A binary cursor for select byte from empl where idnum = $1  */
 #line 89 "binary.pgc"
 
-  { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare A binary cursor for select byte from empl where idnum = $1 ", 
+  { ECPGopen(__LINE__, 0, 1, NULL, 0, 0, "A", ECPGst_normal, "declare A binary cursor for select byte from empl where idnum = $1 ", 
 	ECPGt_long,&(empl.idnum),(long)1,(long)1,sizeof(long), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
 #line 90 "binary.pgc"
 
-  { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch A", ECPGt_EOIT, 
+  { ECPGfetch(__LINE__, 0, 1, NULL, 0, "A", ECPGst_normal, "fetch A", ECPGt_EOIT, 
 	ECPGt_char,&(pointer),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
 #line 91 "binary.pgc"
@@ -192,7 +192,7 @@ main (void)
       exit (sqlca.sqlcode);
     }
 
-  { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close A", ECPGt_EOIT, ECPGt_EORT);}
+  { ECPGclose(__LINE__, 0, 1, NULL, 0, "A", ECPGst_normal, "close A", ECPGt_EOIT, ECPGt_EORT);}
 #line 98 "binary.pgc"
 
 
diff --git a/src/interfaces/ecpg/test/expected/sql-code100.c b/src/interfaces/ecpg/test/expected/sql-code100.c
index 051fc38..dda2c55 100644
--- a/src/interfaces/ecpg/test/expected/sql-code100.c
+++ b/src/interfaces/ecpg/test/expected/sql-code100.c
@@ -114,7 +114,7 @@ int main()
 #line 20 "code100.pgc"
 
    if (sqlca.sqlcode) printf("%ld:%s\n",sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
-   { ECPGtrans(__LINE__, NULL, "commit work");}
+   { ECPGtrans(__LINE__, NULL, "commit work", 0, 0, 0, NULL);}
 #line 22 "code100.pgc"
 
    if (sqlca.sqlcode) printf("%ld:%s\n",sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
@@ -127,7 +127,7 @@ int main()
 
       if (sqlca.sqlcode) printf("%ld:%s\n",sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
    }
-   { ECPGtrans(__LINE__, NULL, "commit work");}
+   { ECPGtrans(__LINE__, NULL, "commit work", 0, 0, 0, NULL);}
 #line 31 "code100.pgc"
 
    if (sqlca.sqlcode) printf("%ld:%s\n",sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
@@ -151,7 +151,7 @@ int main()
 #line 44 "code100.pgc"
 
    if (sqlca.sqlcode) printf("%ld:%s\n",sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
-   { ECPGtrans(__LINE__, NULL, "commit work");}
+   { ECPGtrans(__LINE__, NULL, "commit work", 0, 0, 0, NULL);}
 #line 46 "code100.pgc"
 
    if (sqlca.sqlcode) printf("%ld:%s\n",sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
diff --git a/src/interfaces/ecpg/test/expected/sql-cursorsubxact.c b/src/interfaces/ecpg/test/expected/sql-cursorsubxact.c
new file mode 100644
index 0000000..0592a6f
--- /dev/null
+++ b/src/interfaces/ecpg/test/expected/sql-cursorsubxact.c
@@ -0,0 +1,573 @@
+/* Processed by ecpg (regression mode) */
+/* These include files are added by the preprocessor */
+#include <ecpglib.h>
+#include <ecpgerrno.h>
+#include <sqlca.h>
+/* End of automatic include section */
+#define ECPGdebug(X,Y) ECPGdebug((X)+100,(Y))
+
+#line 1 "cursorsubxact.pgc"
+#include <stdlib.h>
+#include <string.h>
+
+
+#line 1 "regression.h"
+
+
+
+
+
+
+#line 4 "cursorsubxact.pgc"
+
+
+/* exec sql whenever sqlerror  sqlprint ; */
+#line 6 "cursorsubxact.pgc"
+
+
+#define CURNAME "MyCur"
+#define CURNAME_BAD "myCur"
+
+#define QUOTED_CURNAME "\"MyCur\""
+#define QUOTED_CURNAME_BAD "\"myCur\""
+
+int main(void)
+{
+/* exec sql begin declare section */
+		
+		
+		
+
+#line 17 "cursorsubxact.pgc"
+ char * curname ;
+ 
+#line 18 "cursorsubxact.pgc"
+ int id [ 3 ] ;
+ 
+#line 19 "cursorsubxact.pgc"
+  struct varchar_1  { int len; char arr[ 50 ]; }  t [ 3 ] ;
+/* exec sql end declare section */
+#line 20 "cursorsubxact.pgc"
+
+
+	ECPGdebug(1, stderr);
+
+	{ ECPGconnect(__LINE__, 0, "regress1" , NULL, NULL , NULL, 0); 
+#line 24 "cursorsubxact.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 24 "cursorsubxact.pgc"
+
+
+	{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "create table t1 ( id serial primary key , t text )", ECPGt_EOIT, ECPGt_EORT);
+#line 26 "cursorsubxact.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 26 "cursorsubxact.pgc"
+
+	{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into t1 ( t ) values ( 'a' ) , ( 'b' ) , ( 'c' )", ECPGt_EOIT, ECPGt_EORT);
+#line 27 "cursorsubxact.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 27 "cursorsubxact.pgc"
+
+	{ ECPGtrans(__LINE__, NULL, "commit", 0, 0, 0, NULL);
+#line 28 "cursorsubxact.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 28 "cursorsubxact.pgc"
+
+
+	/*
+	 * Cursor name passed in a variable unquoted.
+	 * It has to be treated as case-insensitive.
+	 */
+
+	printf("test case insensitive cursor name\n\n");
+
+	curname = CURNAME;
+
+	ECPGset_var( 0, &( curname ), __LINE__);\
+ /* declare $0 cursor for select id , t from t1 */
+#line 39 "cursorsubxact.pgc"
+
+
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, curname, ECPGst_normal, "declare $0 cursor for select id , t from t1", 
+	ECPGt_char,&(curname),(long)0,(long)1,(1)*sizeof(char), 
+	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
+#line 41 "cursorsubxact.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 41 "cursorsubxact.pgc"
+
+	if (sqlca.sqlcode < 0)
+		printf("open %s (case insensitive) failed with SQLSTATE %5s\n", curname, sqlca.sqlstate);
+	else
+		printf("open %s (case insensitive) succeeded\n", curname);
+
+	curname = CURNAME_BAD;
+
+	{ ECPGclose(__LINE__, 0, 1, NULL, 0, curname, ECPGst_normal, "close $0", 
+	ECPGt_char,&(curname),(long)0,(long)1,(1)*sizeof(char), 
+	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
+#line 49 "cursorsubxact.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 49 "cursorsubxact.pgc"
+
+	if (sqlca.sqlcode < 0)
+		printf("close %s (case insensitive)  failed with SQLSTATE %5s\n", curname, sqlca.sqlstate);
+	else
+		printf("close %s (case insensitive) succeeded\n", curname);
+
+	/*
+	 * Cursor name passed in a variable quoted.
+	 * It has to be treated as case-sensitive.
+	 */
+
+	printf("\ntest case sensitive cursor name\n\n");
+
+	curname = QUOTED_CURNAME;
+
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, curname, ECPGst_normal, "declare $0 cursor for select id , t from t1", 
+	ECPGt_char,&(curname),(long)0,(long)1,(1)*sizeof(char), 
+	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
+#line 64 "cursorsubxact.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 64 "cursorsubxact.pgc"
+
+	if (sqlca.sqlcode < 0)
+		printf("open %s (case sensitive) failed with SQLSTATE %5s\n", curname, sqlca.sqlstate);
+	else
+		printf("open %s (case sensitive) succeeded\n", curname);
+
+	curname = QUOTED_CURNAME_BAD;
+
+	/* Try to close the wrong cursor name, it has to fail with 34000. */
+	{ ECPGclose(__LINE__, 0, 1, NULL, 0, curname, ECPGst_normal, "close $0", 
+	ECPGt_char,&(curname),(long)0,(long)1,(1)*sizeof(char), 
+	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
+#line 73 "cursorsubxact.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 73 "cursorsubxact.pgc"
+
+	if (sqlca.sqlcode < 0)
+		printf("close %s (case sensitive) failed with SQLSTATE %5s (expected 34000)\n", curname, sqlca.sqlstate);
+	else
+		printf("close %s (case sensitive) succeeded\n", curname);
+
+	/* Try to close the right cursor name, it has to fail with 25P02 */
+	curname = QUOTED_CURNAME;
+	{ ECPGclose(__LINE__, 0, 1, NULL, 0, curname, ECPGst_normal, "close $0", 
+	ECPGt_char,&(curname),(long)0,(long)1,(1)*sizeof(char), 
+	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
+#line 81 "cursorsubxact.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 81 "cursorsubxact.pgc"
+
+	if (sqlca.sqlcode < 0)
+		printf("close %s (case sensitive) failed with SQLSTATE %5s (expected 25P02)\n", curname, sqlca.sqlstate);
+	else
+		printf("close %s (case sensitive) succeeded\n", curname);
+
+	{ ECPGtrans(__LINE__, NULL, "rollback", 0, 0, 1, NULL);
+#line 87 "cursorsubxact.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 87 "cursorsubxact.pgc"
+
+
+	/*
+	 * Try a new transaction and watch the cursor name disappear
+	 * after ROLLBACK TO SAVEPOINT.
+	 */
+
+	printf("\ntest case sensitive cursor name in savepoint\n\n");
+
+	curname = QUOTED_CURNAME;
+
+	{ ECPGtrans(__LINE__, NULL, "savepoint a", 0, 1, 0, "a");
+#line 98 "cursorsubxact.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 98 "cursorsubxact.pgc"
+
+
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, curname, ECPGst_normal, "declare $0 cursor for select id , t from t1", 
+	ECPGt_char,&(curname),(long)0,(long)1,(1)*sizeof(char), 
+	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
+#line 100 "cursorsubxact.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 100 "cursorsubxact.pgc"
+
+	if (sqlca.sqlcode < 0)
+		printf("open %s (case sensitive) failed with SQLSTATE %5s\n", curname, sqlca.sqlstate);
+	else
+		printf("close %s (case sensitive) succeeded\n", curname);
+
+	/* The cursor name must be forgotten */
+	{ ECPGtrans(__LINE__, NULL, "rollback to a", 0, 0, 1, "a");
+#line 107 "cursorsubxact.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 107 "cursorsubxact.pgc"
+
+
+	/* It has to fail with 34000 */
+	{ ECPGclose(__LINE__, 0, 1, NULL, 0, curname, ECPGst_normal, "close $0", 
+	ECPGt_char,&(curname),(long)0,(long)1,(1)*sizeof(char), 
+	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
+#line 110 "cursorsubxact.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 110 "cursorsubxact.pgc"
+
+	if (sqlca.sqlcode < 0)
+		printf("close %s failed with SQLSTATE %5s (expected 34000)\n", curname, sqlca.sqlstate);
+	else
+		printf("close %s succeeded unexpectedly, expected sqlstate 34000\n", curname);
+
+	{ ECPGtrans(__LINE__, NULL, "rollback", 0, 0, 1, NULL);
+#line 116 "cursorsubxact.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 116 "cursorsubxact.pgc"
+
+
+	/*
+	 * Try a new transaction and play games with savepoints.
+	 */
+
+	printf("\ntest savepoint handling\n\n");
+
+	{ ECPGtrans(__LINE__, NULL, "savepoint a", 0, 1, 0, "a");
+#line 124 "cursorsubxact.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 124 "cursorsubxact.pgc"
+
+	if (sqlca.sqlcode < 0)
+		printf("\"savepoint a\" failed with SQLSTATE %5s\n", sqlca.sqlstate);
+	else
+		printf("\"savepoint a\" succeeded\n");
+
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, curname, ECPGst_normal, "declare $0 cursor for select id , t from t1", 
+	ECPGt_char,&(curname),(long)0,(long)1,(1)*sizeof(char), 
+	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
+#line 130 "cursorsubxact.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 130 "cursorsubxact.pgc"
+
+	if (sqlca.sqlcode < 0)
+		printf("open %s (case sensitive) failed with SQLSTATE %5s\n", curname, sqlca.sqlstate);
+	else
+		printf("open %s (case sensitive) succeeded\n", curname);
+
+	{ ECPGtrans(__LINE__, NULL, "savepoint b", 0, 1, 0, "b");
+#line 136 "cursorsubxact.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 136 "cursorsubxact.pgc"
+
+	if (sqlca.sqlcode < 0)
+		printf("\"savepoint a\" failed with SQLSTATE %5s\n", sqlca.sqlstate);
+	else
+		printf("\"savepoint a\" succeeded\n");
+
+	/* Try to rollback to an unknown savepoint */
+
+	{ ECPGtrans(__LINE__, NULL, "rollback to c", 0, 0, 1, "c");
+#line 144 "cursorsubxact.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 144 "cursorsubxact.pgc"
+
+	if (sqlca.sqlcode < 0)
+		printf("\"rollback to c\" failed with SQLSTATE %5s (expected 3B001)\n", sqlca.sqlstate);
+	else
+		printf("\"rollback to c\" succeeded unexpectedly (expected 3B001)\n");
+
+	/* "rollback to a" implicitly rolls back "b" */
+
+	{ ECPGtrans(__LINE__, NULL, "rollback to a", 0, 0, 1, "a");
+#line 152 "cursorsubxact.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 152 "cursorsubxact.pgc"
+
+	if (sqlca.sqlcode < 0)
+		printf("\"rollback to a\" failed with SQLSTATE %5s\n", sqlca.sqlstate);
+	else
+		printf("\"rollback to a\" succeeded\n");
+
+	/* savepoint "b" is now unknown, fails with 3B001 */
+	{ ECPGtrans(__LINE__, NULL, "rollback to b", 0, 0, 1, "b");
+#line 159 "cursorsubxact.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 159 "cursorsubxact.pgc"
+
+	if (sqlca.sqlcode < 0)
+		printf("\"rollback to b\" failed with SQLSTATE %5s (expected 3B001)\n", sqlca.sqlstate);
+	else
+		printf("\"rollback to b\" succeeded unexpectedly (expected 3B001)\n");
+
+	/* "rollback to a" has to succeed again, it's still alive */
+
+	{ ECPGtrans(__LINE__, NULL, "rollback to a", 0, 0, 1, "a");
+#line 167 "cursorsubxact.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 167 "cursorsubxact.pgc"
+
+	if (sqlca.sqlcode < 0)
+		printf("\"rollback to a\" failed with SQLSTATE %5s\n", sqlca.sqlstate);
+	else
+		printf("\"rollback to a\" succeeded\n");
+
+	/* the cursor was declared under savepoint "a", was forgotten */
+
+	{ ECPGfetch(__LINE__, 0, 1, NULL, 0, curname, ECPGst_normal, "fetch from $0", 
+	ECPGt_char,&(curname),(long)0,(long)1,(1)*sizeof(char), 
+	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, 
+	ECPGt_int,&(id[0]),(long)1,(long)1,sizeof(int), 
+	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
+	ECPGt_varchar,&(t[0]),(long)50,(long)1,sizeof(struct varchar_1), 
+	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
+#line 175 "cursorsubxact.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 175 "cursorsubxact.pgc"
+
+	if (sqlca.sqlcode < 0)
+		printf("fetch from %s (case sensitive) failed with SQLSTATE %5s (expected 34000)\n", curname, sqlca.sqlstate);
+	else
+		printf("fetch from %s (case sensitive) succeeded unexpectedly (expected 34000)\n", curname);
+
+	/* "rollback to a" has to succeed again, it's still alive */
+
+	{ ECPGtrans(__LINE__, NULL, "rollback to a", 0, 0, 1, "a");
+#line 183 "cursorsubxact.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 183 "cursorsubxact.pgc"
+
+	if (sqlca.sqlcode < 0)
+		printf("\"rollback to a\" failed with SQLSTATE %5s\n", sqlca.sqlstate);
+	else
+		printf("\"rollback to a\" succeeded\n");
+
+	/* "release savepoint a" forgets about the savepoint name */
+
+	{ ECPGtrans(__LINE__, NULL, "release savepoint a", 0, 0, 0, "a");
+#line 191 "cursorsubxact.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 191 "cursorsubxact.pgc"
+
+	if (sqlca.sqlcode < 0)
+		printf("\"release savepoint a\" failed with SQLSTATE %5s\n", sqlca.sqlstate);
+	else
+		printf("\"release savepoint a\" succeeded\n");
+
+	/* prove the above */
+
+	{ ECPGtrans(__LINE__, NULL, "rollback to a", 0, 0, 1, "a");
+#line 199 "cursorsubxact.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 199 "cursorsubxact.pgc"
+
+	if (sqlca.sqlcode < 0)
+		printf("\"rollback to a\" failed with SQLSTATE %5s (expected 3B001)\n", sqlca.sqlstate);
+	else
+		printf("\"rollback to a\" succeeded unexpectedly (expected 3B001)\n");
+
+	{ ECPGtrans(__LINE__, NULL, "rollback", 0, 0, 1, NULL);
+#line 205 "cursorsubxact.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 205 "cursorsubxact.pgc"
+
+
+	/*
+	 * Test the implicit RELEASE SAVEPOINT if a SAVEPOINT
+	 * is used with an already existing name.
+	 */
+
+	printf("\ntest implicit \"release savepoint a\" for a second \"savepoint a\"\n\n");
+
+	{ ECPGtrans(__LINE__, NULL, "savepoint a", 0, 1, 0, "a");
+#line 214 "cursorsubxact.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 214 "cursorsubxact.pgc"
+
+	if (sqlca.sqlcode < 0)
+		printf("\"savepoint a\" failed with SQLSTATE %5s\n", sqlca.sqlstate);
+	else
+		printf("\"savepoint a\" succeeded\n");
+
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, curname, ECPGst_normal, "declare $0 cursor for select id , t from t1", 
+	ECPGt_char,&(curname),(long)0,(long)1,(1)*sizeof(char), 
+	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
+#line 220 "cursorsubxact.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 220 "cursorsubxact.pgc"
+
+	if (sqlca.sqlcode < 0)
+		printf("open %s (case sensitive) failed with SQLSTATE %5s\n", curname, sqlca.sqlstate);
+	else
+		printf("open %s (case sensitive) succeeded\n", curname);
+
+	{ ECPGfetch(__LINE__, 0, 1, NULL, 0, curname, ECPGst_normal, "fetch from $0", 
+	ECPGt_char,&(curname),(long)0,(long)1,(1)*sizeof(char), 
+	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, 
+	ECPGt_int,&(id[0]),(long)1,(long)1,sizeof(int), 
+	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
+	ECPGt_varchar,&(t[0]),(long)50,(long)1,sizeof(struct varchar_1), 
+	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
+#line 226 "cursorsubxact.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 226 "cursorsubxact.pgc"
+
+	if (sqlca.sqlcode < 0)
+		printf("fetch from %s (case sensitive) failed with SQLSTATE %5s\n", curname, sqlca.sqlstate);
+	else
+		printf("fetch from %s (case sensitive) result %d '%s'\n", curname, id[0], t[0].arr);
+
+	{ ECPGtrans(__LINE__, NULL, "rollback to a", 0, 0, 1, "a");
+#line 232 "cursorsubxact.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 232 "cursorsubxact.pgc"
+
+	if (sqlca.sqlcode < 0)
+		printf("\"rollback to a\" failed with SQLSTATE %5s\n", sqlca.sqlstate);
+	else
+		printf("\"rollback to a\" succeeded\n");
+
+	/* there's no cursor now */
+
+	{ ECPGfetch(__LINE__, 0, 1, NULL, 0, curname, ECPGst_normal, "fetch from $0", 
+	ECPGt_char,&(curname),(long)0,(long)1,(1)*sizeof(char), 
+	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, 
+	ECPGt_int,&(id[1]),(long)1,(long)1,sizeof(int), 
+	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
+	ECPGt_varchar,&(t[1]),(long)50,(long)1,sizeof(struct varchar_1), 
+	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
+#line 240 "cursorsubxact.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 240 "cursorsubxact.pgc"
+
+	if (sqlca.sqlcode < 0)
+		printf("fetch from %s (case sensitive) failed with SQLSTATE %5s (expected 34000)\n", curname, sqlca.sqlstate);
+	else
+		printf("fetch from %s (case sensitive) unexpectedly succeeded (expected 34000)\n", curname);
+
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, curname, ECPGst_normal, "declare $0 cursor for select id , t from t1", 
+	ECPGt_char,&(curname),(long)0,(long)1,(1)*sizeof(char), 
+	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
+#line 246 "cursorsubxact.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 246 "cursorsubxact.pgc"
+
+	if (sqlca.sqlcode < 0)
+		printf("open %s (case sensitive) failed with SQLSTATE %5s (expected 25P02)\n", curname, sqlca.sqlstate);
+	else
+		printf("open %s (case sensitive) succeeded unexpectedly\n", curname);
+
+	{ ECPGtrans(__LINE__, NULL, "rollback to a", 0, 0, 1, "a");
+#line 252 "cursorsubxact.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 252 "cursorsubxact.pgc"
+
+	if (sqlca.sqlcode < 0)
+		printf("\"rollback to a\" failed with SQLSTATE %5s\n", sqlca.sqlstate);
+	else
+		printf("\"rollback to a\" succeeded\n");
+
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, curname, ECPGst_normal, "declare $0 cursor for select id , t from t1", 
+	ECPGt_char,&(curname),(long)0,(long)1,(1)*sizeof(char), 
+	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
+#line 258 "cursorsubxact.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 258 "cursorsubxact.pgc"
+
+	if (sqlca.sqlcode < 0)
+		printf("open %s (case sensitive) failed with SQLSTATE %5s\n", curname, sqlca.sqlstate);
+	else
+		printf("open %s (case sensitive) succeeded\n", curname);
+
+	{ ECPGtrans(__LINE__, NULL, "release savepoint a", 0, 0, 0, "a");
+#line 264 "cursorsubxact.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 264 "cursorsubxact.pgc"
+
+	if (sqlca.sqlcode < 0)
+		printf("\"release savepoint a\" failed with SQLSTATE %5s\n", sqlca.sqlstate);
+	else
+		printf("\"release savepoint a\" succeeded\n");
+
+	/* release savepoint propagated the cursor to the toplevel transaction */
+
+	{ ECPGfetch(__LINE__, 0, 1, NULL, 0, curname, ECPGst_normal, "fetch from $0", 
+	ECPGt_char,&(curname),(long)0,(long)1,(1)*sizeof(char), 
+	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, 
+	ECPGt_int,&(id[2]),(long)1,(long)1,sizeof(int), 
+	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
+	ECPGt_varchar,&(t[2]),(long)50,(long)1,sizeof(struct varchar_1), 
+	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
+#line 272 "cursorsubxact.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 272 "cursorsubxact.pgc"
+
+	if (sqlca.sqlcode < 0)
+		printf("fetch %s (case sensitive) failed with SQLSTATE %5s\n", curname, sqlca.sqlstate);
+	else
+		printf("fetch %s (case sensitive) result %d '%s'\n", curname, id[2], t[2].arr);
+
+	{ ECPGtrans(__LINE__, NULL, "rollback", 0, 0, 1, NULL);
+#line 278 "cursorsubxact.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 278 "cursorsubxact.pgc"
+
+
+	/* Drop the test table */
+
+	{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "drop table t1", ECPGt_EOIT, ECPGt_EORT);
+#line 282 "cursorsubxact.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 282 "cursorsubxact.pgc"
+
+	{ ECPGtrans(__LINE__, NULL, "commit", 0, 0, 0, NULL);
+#line 283 "cursorsubxact.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 283 "cursorsubxact.pgc"
+
+
+	{ ECPGdisconnect(__LINE__, "ALL");
+#line 285 "cursorsubxact.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 285 "cursorsubxact.pgc"
+
+
+	return 0;
+}
diff --git a/src/interfaces/ecpg/test/expected/sql-cursorsubxact.stderr b/src/interfaces/ecpg/test/expected/sql-cursorsubxact.stderr
new file mode 100644
index 0000000..188f4bf
--- /dev/null
+++ b/src/interfaces/ecpg/test/expected/sql-cursorsubxact.stderr
@@ -0,0 +1,161 @@
+[NO_PID]: ECPGdebug: set to 1
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ECPGconnect: opening database regress1 on <DEFAULT> port <DEFAULT>  
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 26: query: create table t1 ( id serial primary key , t text ); with 0 parameter(s) on connection regress1
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 26: using PQexec
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_process_output on line 26: OK: CREATE TABLE
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 27: query: insert into t1 ( t ) values ( 'a' ) , ( 'b' ) , ( 'c' ); with 0 parameter(s) on connection regress1
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 27: using PQexec
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_process_output on line 27: OK: INSERT 0 3
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ECPGtrans on line 28: action "commit"; connection "regress1"
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 41: query: declare MyCur cursor for select id , t from t1; with 0 parameter(s) on connection regress1
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 41: using PQexec
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_process_output on line 41: OK: DECLARE CURSOR
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 49: query: close myCur; with 0 parameter(s) on connection regress1
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 49: using PQexec
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_process_output on line 49: OK: CLOSE CURSOR
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 64: query: declare "MyCur" cursor for select id , t from t1; with 0 parameter(s) on connection regress1
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 64: using PQexec
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_process_output on line 64: OK: DECLARE CURSOR
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: raising sqlcode -231 on line 73: invalid cursorname ""myCur"" on line 73
+[NO_PID]: sqlca: code: -231, state: 34000
+SQL error: invalid cursorname ""myCur"" on line 73
+[NO_PID]: raising sqlcode -401 on line 81: current transaction is aborted, commands ignored until end of transaction block on line 81
+[NO_PID]: sqlca: code: -401, state: 25P02
+SQL error: current transaction is aborted, commands ignored until end of transaction block on line 81
+[NO_PID]: ECPGtrans on line 87: action "rollback"; connection "regress1"
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ECPGtrans on line 98: action "savepoint a"; connection "regress1"
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 100: query: declare "MyCur" cursor for select id , t from t1; with 0 parameter(s) on connection regress1
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 100: using PQexec
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_process_output on line 100: OK: DECLARE CURSOR
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ECPGtrans on line 107: action "rollback to a"; connection "regress1"
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: raising sqlcode -231 on line 110: invalid cursorname ""MyCur"" on line 110
+[NO_PID]: sqlca: code: -231, state: 34000
+SQL error: invalid cursorname ""MyCur"" on line 110
+[NO_PID]: ECPGtrans on line 116: action "rollback"; connection "regress1"
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ECPGtrans on line 124: action "savepoint a"; connection "regress1"
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 130: query: declare "MyCur" cursor for select id , t from t1; with 0 parameter(s) on connection regress1
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 130: using PQexec
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_process_output on line 130: OK: DECLARE CURSOR
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ECPGtrans on line 136: action "savepoint b"; connection "regress1"
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ECPGtrans on line 144: action "rollback to c"; connection "regress1"
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_check_PQresult on line 144: bad response - ERROR:  no such savepoint
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: raising sqlstate 3B001 (sqlcode -400): no such savepoint on line 144
+[NO_PID]: sqlca: code: -400, state: 3B001
+SQL error: no such savepoint on line 144
+[NO_PID]: ECPGtrans on line 152: action "rollback to a"; connection "regress1"
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ECPGtrans on line 159: action "rollback to b"; connection "regress1"
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_check_PQresult on line 159: bad response - ERROR:  no such savepoint
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: raising sqlstate 3B001 (sqlcode -400): no such savepoint on line 159
+[NO_PID]: sqlca: code: -400, state: 3B001
+SQL error: no such savepoint on line 159
+[NO_PID]: ECPGtrans on line 167: action "rollback to a"; connection "regress1"
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: raising sqlcode -231 on line 175: invalid cursorname ""MyCur"" on line 175
+[NO_PID]: sqlca: code: -231, state: 34000
+SQL error: invalid cursorname ""MyCur"" on line 175
+[NO_PID]: ECPGtrans on line 183: action "rollback to a"; connection "regress1"
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ECPGtrans on line 191: action "release savepoint a"; connection "regress1"
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ECPGtrans on line 199: action "rollback to a"; connection "regress1"
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_check_PQresult on line 199: bad response - ERROR:  no such savepoint
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: raising sqlstate 3B001 (sqlcode -400): no such savepoint on line 199
+[NO_PID]: sqlca: code: -400, state: 3B001
+SQL error: no such savepoint on line 199
+[NO_PID]: ECPGtrans on line 205: action "rollback"; connection "regress1"
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ECPGtrans on line 214: action "savepoint a"; connection "regress1"
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 220: query: declare "MyCur" cursor for select id , t from t1; with 0 parameter(s) on connection regress1
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 220: using PQexec
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_process_output on line 220: OK: DECLARE CURSOR
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 226: query: fetch from "MyCur"; with 0 parameter(s) on connection regress1
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 226: using PQexec
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_process_output on line 226: correctly got 1 tuples with 2 fields
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 226: RESULT: 1 offset: -1; array: no
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 226: RESULT: a offset: -1; array: no
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ECPGtrans on line 232: action "rollback to a"; connection "regress1"
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: raising sqlcode -231 on line 240: invalid cursorname ""MyCur"" on line 240
+[NO_PID]: sqlca: code: -231, state: 34000
+SQL error: invalid cursorname ""MyCur"" on line 240
+[NO_PID]: raising sqlcode -401 on line 246: current transaction is aborted, commands ignored until end of transaction block on line 246
+[NO_PID]: sqlca: code: -401, state: 25P02
+SQL error: current transaction is aborted, commands ignored until end of transaction block on line 246
+[NO_PID]: ECPGtrans on line 252: action "rollback to a"; connection "regress1"
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 258: query: declare "MyCur" cursor for select id , t from t1; with 0 parameter(s) on connection regress1
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 258: using PQexec
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_process_output on line 258: OK: DECLARE CURSOR
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ECPGtrans on line 264: action "release savepoint a"; connection "regress1"
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 272: query: fetch from "MyCur"; with 0 parameter(s) on connection regress1
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 272: using PQexec
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_process_output on line 272: correctly got 1 tuples with 2 fields
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 272: RESULT: 1 offset: -1; array: no
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 272: RESULT: a offset: -1; array: no
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ECPGtrans on line 278: action "rollback"; connection "regress1"
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 282: query: drop table t1; with 0 parameter(s) on connection regress1
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 282: using PQexec
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_process_output on line 282: OK: DROP TABLE
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ECPGtrans on line 283: action "commit"; connection "regress1"
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_finish: connection regress1 closed
+[NO_PID]: sqlca: code: 0, state: 00000
diff --git a/src/interfaces/ecpg/test/expected/sql-cursorsubxact.stdout b/src/interfaces/ecpg/test/expected/sql-cursorsubxact.stdout
new file mode 100644
index 0000000..6e8baec
--- /dev/null
+++ b/src/interfaces/ecpg/test/expected/sql-cursorsubxact.stdout
@@ -0,0 +1,42 @@
+test case insensitive cursor name
+
+open MyCur (case insensitive) succeeded
+close myCur (case insensitive) succeeded
+
+test case sensitive cursor name
+
+open "MyCur" (case sensitive) succeeded
+close "myCur" (case sensitive) failed with SQLSTATE 34000 (expected 34000)
+close "MyCur" (case sensitive) failed with SQLSTATE 25P02 (expected 25P02)
+
+test case sensitive cursor name in savepoint
+
+close "MyCur" (case sensitive) succeeded
+close "MyCur" failed with SQLSTATE 34000 (expected 34000)
+
+test savepoint handling
+
+"savepoint a" succeeded
+open "MyCur" (case sensitive) succeeded
+"savepoint a" succeeded
+"rollback to c" failed with SQLSTATE 3B001 (expected 3B001)
+"rollback to a" succeeded
+"rollback to b" failed with SQLSTATE 3B001 (expected 3B001)
+"rollback to a" succeeded
+fetch from "MyCur" (case sensitive) failed with SQLSTATE 34000 (expected 34000)
+"rollback to a" succeeded
+"release savepoint a" succeeded
+"rollback to a" failed with SQLSTATE 3B001 (expected 3B001)
+
+test implicit "release savepoint a" for a second "savepoint a"
+
+"savepoint a" succeeded
+open "MyCur" (case sensitive) succeeded
+fetch from "MyCur" (case sensitive) result 1 'a'
+"rollback to a" succeeded
+fetch from "MyCur" (case sensitive) failed with SQLSTATE 34000 (expected 34000)
+open "MyCur" (case sensitive) failed with SQLSTATE 25P02 (expected 25P02)
+"rollback to a" succeeded
+open "MyCur" (case sensitive) succeeded
+"release savepoint a" succeeded
+fetch "MyCur" (case sensitive) result 1 'a'
diff --git a/src/interfaces/ecpg/test/expected/sql-desc.c b/src/interfaces/ecpg/test/expected/sql-desc.c
index 8fc527a..6999768 100644
--- a/src/interfaces/ecpg/test/expected/sql-desc.c
+++ b/src/interfaces/ecpg/test/expected/sql-desc.c
@@ -245,7 +245,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 	/* declare c1 cursor for $1 */
 #line 57 "desc.pgc"
 
-	{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare c1 cursor for $1", 
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, "c1", ECPGst_normal, "declare c1 cursor for $1", 
 	ECPGt_char_variable,(ECPGprepared_statement(NULL, "foo2", __LINE__)),(long)1,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_descriptor, "indesc", 0L, 0L, 0L, 
@@ -256,7 +256,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 #line 58 "desc.pgc"
 
 
-	{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch next from c1", ECPGt_EOIT, 
+	{ ECPGfetch(__LINE__, 0, 1, NULL, 0, "c1", ECPGst_normal, "fetch next from c1", ECPGt_EOIT, 
 	ECPGt_int,&(val1output),(long)1,(long)1,sizeof(int), 
 	ECPGt_int,&(ind1),(long)1,(long)1,sizeof(int), 
 	ECPGt_char,(val2output),(long)sizeof("AAA"),(long)1,(sizeof("AAA"))*sizeof(char), 
@@ -269,7 +269,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 	printf("val1=%d (ind1: %d) val2=%s (ind2: %d)\n",
 		val1output, ind1, val2output, ind2);
 
-	{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close c1", ECPGt_EOIT, ECPGt_EORT);
+	{ ECPGclose(__LINE__, 0, 1, NULL, 0, "c1", ECPGst_normal, "close c1", ECPGt_EOIT, ECPGt_EORT);
 #line 64 "desc.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
@@ -295,7 +295,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 	/* declare c2 cursor for $1 */
 #line 69 "desc.pgc"
 
-	{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare c2 cursor for $1", 
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, "c2", ECPGst_normal, "declare c2 cursor for $1", 
 	ECPGt_char_variable,(ECPGprepared_statement(NULL, "foo3", __LINE__)),(long)1,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_descriptor, "indesc", 0L, 0L, 0L, 
@@ -306,7 +306,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 #line 70 "desc.pgc"
 
 
-	{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch next from c2", ECPGt_EOIT, 
+	{ ECPGfetch(__LINE__, 0, 1, NULL, 0, "c2", ECPGst_normal, "fetch next from c2", ECPGt_EOIT, 
 	ECPGt_int,&(val1output),(long)1,(long)1,sizeof(int), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_char,(val2output),(long)sizeof("AAA"),(long)1,(sizeof("AAA"))*sizeof(char), 
@@ -318,7 +318,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 
 	printf("val1=%d val2=%s\n", val1output, val2i ? "null" : val2output);
 
-	{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close c2", ECPGt_EOIT, ECPGt_EORT);
+	{ ECPGclose(__LINE__, 0, 1, NULL, 0, "c2", ECPGst_normal, "close c2", ECPGt_EOIT, ECPGt_EORT);
 #line 75 "desc.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
diff --git a/src/interfaces/ecpg/test/expected/sql-describe.c b/src/interfaces/ecpg/test/expected/sql-describe.c
index fd46a29..77cee81 100644
--- a/src/interfaces/ecpg/test/expected/sql-describe.c
+++ b/src/interfaces/ecpg/test/expected/sql-describe.c
@@ -133,7 +133,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 
 	strcpy(msg, "commit");
-	{ ECPGtrans(__LINE__, NULL, "commit");
+	{ ECPGtrans(__LINE__, NULL, "commit", 0, 0, 0, NULL);
 #line 42 "describe.pgc"
 
 if (sqlca.sqlcode < 0) exit (1);}
@@ -446,7 +446,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 
 	strcpy(msg, "commit");
-	{ ECPGtrans(__LINE__, NULL, "commit");
+	{ ECPGtrans(__LINE__, NULL, "commit", 0, 0, 0, NULL);
 #line 193 "describe.pgc"
 
 if (sqlca.sqlcode < 0) exit (1);}
diff --git a/src/interfaces/ecpg/test/expected/sql-dynalloc2.c b/src/interfaces/ecpg/test/expected/sql-dynalloc2.c
index 3f200ff..a0d0a2e 100644
--- a/src/interfaces/ecpg/test/expected/sql-dynalloc2.c
+++ b/src/interfaces/ecpg/test/expected/sql-dynalloc2.c
@@ -240,7 +240,7 @@ if (sqlca.sqlcode < 0) sqlprint ( );}
 if (sqlca.sqlcode < 0) sqlprint ( );
 #line 51 "dynalloc2.pgc"
 
-   { ECPGtrans(__LINE__, NULL, "rollback");
+   { ECPGtrans(__LINE__, NULL, "rollback", 0, 0, 1, NULL);
 #line 52 "dynalloc2.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint ( );}
diff --git a/src/interfaces/ecpg/test/expected/sql-dyntest.c b/src/interfaces/ecpg/test/expected/sql-dyntest.c
index 1871e13..7856a51 100644
--- a/src/interfaces/ecpg/test/expected/sql-dyntest.c
+++ b/src/interfaces/ecpg/test/expected/sql-dyntest.c
@@ -261,7 +261,7 @@ if (sqlca.sqlcode < 0) error ( );}
 #line 58 "dyntest.pgc"
 
 
-  { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare MYCURS cursor for $1", 
+  { ECPGopen(__LINE__, 0, 1, NULL, 0, 0, "MYCURS", ECPGst_normal, "declare MYCURS cursor for $1", 
 	ECPGt_char_variable,(ECPGprepared_statement(NULL, "myquery", __LINE__)),(long)1,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
 #line 60 "dyntest.pgc"
@@ -272,7 +272,7 @@ if (sqlca.sqlcode < 0) error ( );}
 
   while (1)
     {
-      { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch in MYCURS", ECPGt_EOIT, 
+      { ECPGfetch(__LINE__, 0, 1, NULL, 0, "MYCURS", ECPGst_normal, "fetch in MYCURS", ECPGt_EOIT, 
 	ECPGt_descriptor, "MYDESC", 0L, 0L, 0L, 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
 #line 64 "dyntest.pgc"
@@ -468,7 +468,7 @@ if (sqlca.sqlcode < 0) error ( );}
 	}
     }
 
-  { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close MYCURS", ECPGt_EOIT, ECPGt_EORT);
+  { ECPGclose(__LINE__, 0, 1, NULL, 0, "MYCURS", ECPGst_normal, "close MYCURS", ECPGt_EOIT, ECPGt_EORT);
 #line 194 "dyntest.pgc"
 
 if (sqlca.sqlcode < 0) error ( );}
diff --git a/src/interfaces/ecpg/test/expected/sql-execute.c b/src/interfaces/ecpg/test/expected/sql-execute.c
index cc0fd70..326a3c3 100644
--- a/src/interfaces/ecpg/test/expected/sql-execute.c
+++ b/src/interfaces/ecpg/test/expected/sql-execute.c
@@ -70,7 +70,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 if (sqlca.sqlcode < 0) sqlprint();}
 #line 25 "execute.pgc"
 
-	{ ECPGtrans(__LINE__, NULL, "commit");
+	{ ECPGtrans(__LINE__, NULL, "commit", 0, 0, 0, NULL);
 #line 26 "execute.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
@@ -121,7 +121,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 
 	printf("Inserted %ld tuples via prepared execute\n", sqlca.sqlerrd[2]);
 
-	{ ECPGtrans(__LINE__, NULL, "commit");
+	{ ECPGtrans(__LINE__, NULL, "commit", 0, 0, 0, NULL);
 #line 45 "execute.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
@@ -140,7 +140,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 #line 50 "execute.pgc"
 
 
-	{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare CUR cursor for $1", 
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, "CUR", ECPGst_normal, "declare CUR cursor for $1", 
 	ECPGt_char_variable,(ECPGprepared_statement(NULL, "f", __LINE__)),(long)1,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
 #line 52 "execute.pgc"
@@ -148,7 +148,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 if (sqlca.sqlcode < 0) sqlprint();}
 #line 52 "execute.pgc"
 
-	{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch 8 in CUR", ECPGt_EOIT, 
+	{ ECPGfetch(__LINE__, 0, 1, NULL, 0, "CUR", ECPGst_normal, "fetch 8 in CUR", ECPGt_EOIT, 
 	ECPGt_char,(name),(long)8,(long)8,(8)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_int,(amount),(long)1,(long)8,sizeof(int), 
@@ -180,7 +180,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 		printf("name[%d]=%8.8s\tamount[%d]=%d\tletter[%d]=%c\n", i, n, i, a, i, l);
 	}
 
-	{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close CUR", ECPGt_EOIT, ECPGt_EORT);
+	{ ECPGclose(__LINE__, 0, 1, NULL, 0, "CUR", ECPGst_normal, "close CUR", ECPGt_EOIT, ECPGt_EORT);
 #line 66 "execute.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
@@ -205,7 +205,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 #line 72 "execute.pgc"
 
 
-	{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare CUR2 cursor for $1", 
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, "CUR2", ECPGst_normal, "declare CUR2 cursor for $1", 
 	ECPGt_char_variable,(ECPGprepared_statement(NULL, "f", __LINE__)),(long)1,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_const,"1",(long)1,(long)1,strlen("1"), 
@@ -215,7 +215,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 if (sqlca.sqlcode < 0) sqlprint();}
 #line 74 "execute.pgc"
 
-	{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch in CUR2", ECPGt_EOIT, 
+	{ ECPGfetch(__LINE__, 0, 1, NULL, 0, "CUR2", ECPGst_normal, "fetch in CUR2", ECPGt_EOIT, 
 	ECPGt_char,(name),(long)8,(long)8,(8)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_int,(amount),(long)1,(long)8,sizeof(int), 
@@ -247,7 +247,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 		printf("name[%d]=%8.8s\tamount[%d]=%d\tletter[%d]=%c\n", i, n, i, a, i, l);
 	}
 
-	{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close CUR2", ECPGt_EOIT, ECPGt_EORT);
+	{ ECPGclose(__LINE__, 0, 1, NULL, 0, "CUR2", ECPGst_normal, "close CUR2", ECPGt_EOIT, ECPGt_EORT);
 #line 88 "execute.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
@@ -314,7 +314,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 if (sqlca.sqlcode < 0) sqlprint();}
 #line 108 "execute.pgc"
 
-	{ ECPGtrans(__LINE__, NULL, "commit");
+	{ ECPGtrans(__LINE__, NULL, "commit", 0, 0, 0, NULL);
 #line 109 "execute.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
diff --git a/src/interfaces/ecpg/test/expected/sql-fetch.c b/src/interfaces/ecpg/test/expected/sql-fetch.c
index c6be49c..48bdaaf 100644
--- a/src/interfaces/ecpg/test/expected/sql-fetch.c
+++ b/src/interfaces/ecpg/test/expected/sql-fetch.c
@@ -99,7 +99,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 #line 26 "fetch.pgc"
 
 
-  { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare C cursor for select * from My_Table", ECPGt_EOIT, ECPGt_EORT);
+  { ECPGopen(__LINE__, 0, 1, NULL, 0, 0, "C", ECPGst_normal, "declare C cursor for select * from My_Table", ECPGt_EOIT, ECPGt_EORT);
 #line 28 "fetch.pgc"
 
 if (sqlca.sqlwarn[0] == 'W') sqlprint();
@@ -113,7 +113,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 #line 30 "fetch.pgc"
 
   while (1) {
-	{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch 1 in C", ECPGt_EOIT, 
+	{ ECPGfetch(__LINE__, 0, 1, NULL, 0, "C", ECPGst_normal, "fetch 1 in C", ECPGt_EOIT, 
 	ECPGt_int,&(i),(long)1,(long)1,sizeof(int), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_char,(str),(long)25,(long)1,(25)*sizeof(char), 
@@ -135,7 +135,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
   /* exec sql whenever not found  continue ; */
 #line 36 "fetch.pgc"
 
-  { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "move backward 2 in C", ECPGt_EOIT, ECPGt_EORT);
+  { ECPGfetch(__LINE__, 0, 1, NULL, 0, "C", ECPGst_normal, "move backward 2 in C", ECPGt_EOIT, ECPGt_EORT);
 #line 37 "fetch.pgc"
 
 if (sqlca.sqlwarn[0] == 'W') sqlprint();
@@ -145,7 +145,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 #line 37 "fetch.pgc"
 
 
-  { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch $0 in C", 
+  { ECPGfetch(__LINE__, 0, 1, NULL, 0, "C", ECPGst_normal, "fetch $0 in C", 
 	ECPGt_int,&(count),(long)1,(long)1,sizeof(int), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, 
 	ECPGt_int,&(i),(long)1,(long)1,sizeof(int), 
@@ -162,7 +162,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 
   printf("%d: %s\n", i, str);
 
-  { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close C", ECPGt_EOIT, ECPGt_EORT);
+  { ECPGclose(__LINE__, 0, 1, NULL, 0, "C", ECPGst_normal, "close C", ECPGt_EOIT, ECPGt_EORT);
 #line 42 "fetch.pgc"
 
 if (sqlca.sqlwarn[0] == 'W') sqlprint();
@@ -176,7 +176,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 #line 44 "fetch.pgc"
 
 
-  { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare D cursor for select * from My_Table where Item1 = $1", 
+  { ECPGopen(__LINE__, 0, 1, NULL, 0, 0, "D", ECPGst_normal, "declare D cursor for select * from My_Table where Item1 = $1", 
 	ECPGt_const,"1",(long)1,(long)1,strlen("1"), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
 #line 46 "fetch.pgc"
@@ -192,7 +192,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 #line 48 "fetch.pgc"
 
   while (1) {
-	{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch 1 in D", ECPGt_EOIT, 
+	{ ECPGfetch(__LINE__, 0, 1, NULL, 0, "D", ECPGst_normal, "fetch 1 in D", ECPGt_EOIT, 
 	ECPGt_int,&(i),(long)1,(long)1,sizeof(int), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_char,(str),(long)25,(long)1,(25)*sizeof(char), 
@@ -210,7 +210,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 
 	printf("%d: %s\n", i, str);
   }
-  { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close D", ECPGt_EOIT, ECPGt_EORT);
+  { ECPGclose(__LINE__, 0, 1, NULL, 0, "D", ECPGst_normal, "close D", ECPGt_EOIT, ECPGt_EORT);
 #line 53 "fetch.pgc"
 
 if (sqlca.sqlwarn[0] == 'W') sqlprint();
diff --git a/src/interfaces/ecpg/test/expected/sql-indicators.c b/src/interfaces/ecpg/test/expected/sql-indicators.c
index e805e4e..22aacc1 100644
--- a/src/interfaces/ecpg/test/expected/sql-indicators.c
+++ b/src/interfaces/ecpg/test/expected/sql-indicators.c
@@ -118,7 +118,7 @@ int main()
 	{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "create table indicator_test ( \"id\" int primary key , \"str\" text not null , val int null )", ECPGt_EOIT, ECPGt_EORT);}
 #line 21 "indicators.pgc"
 
-	{ ECPGtrans(__LINE__, NULL, "commit work");}
+	{ ECPGtrans(__LINE__, NULL, "commit work", 0, 0, 0, NULL);}
 #line 22 "indicators.pgc"
 
 
@@ -138,7 +138,7 @@ int main()
 	ECPGt_int,&(nullind),(long)1,(long)1,sizeof(int), ECPGt_EOIT, ECPGt_EORT);}
 #line 29 "indicators.pgc"
 
-	{ ECPGtrans(__LINE__, NULL, "commit work");}
+	{ ECPGtrans(__LINE__, NULL, "commit work", 0, 0, 0, NULL);}
 #line 30 "indicators.pgc"
 
 
@@ -178,7 +178,7 @@ int main()
 	{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "drop table indicator_test", ECPGt_EOIT, ECPGt_EORT);}
 #line 45 "indicators.pgc"
 
-	{ ECPGtrans(__LINE__, NULL, "commit work");}
+	{ ECPGtrans(__LINE__, NULL, "commit work", 0, 0, 0, NULL);}
 #line 46 "indicators.pgc"
 
 
diff --git a/src/interfaces/ecpg/test/expected/sql-oldexec.c b/src/interfaces/ecpg/test/expected/sql-oldexec.c
index 0c0239c..a3f8948 100644
--- a/src/interfaces/ecpg/test/expected/sql-oldexec.c
+++ b/src/interfaces/ecpg/test/expected/sql-oldexec.c
@@ -70,7 +70,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 if (sqlca.sqlcode < 0) sqlprint();}
 #line 25 "oldexec.pgc"
 
-	{ ECPGtrans(__LINE__, NULL, "commit");
+	{ ECPGtrans(__LINE__, NULL, "commit", 0, 0, 0, NULL);
 #line 26 "oldexec.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
@@ -121,7 +121,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 
 	printf("Inserted %ld tuples via prepared execute\n", sqlca.sqlerrd[2]);
 
-	{ ECPGtrans(__LINE__, NULL, "commit");
+	{ ECPGtrans(__LINE__, NULL, "commit", 0, 0, 0, NULL);
 #line 45 "oldexec.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
@@ -140,7 +140,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 #line 50 "oldexec.pgc"
 
 
-	{ ECPGdo(__LINE__, 0, 1, NULL, 1, ECPGst_normal, "declare CUR cursor for $1", 
+	{ ECPGopen(__LINE__, 0, 1, NULL, 1, 0, "CUR", ECPGst_normal, "declare CUR cursor for $1", 
 	ECPGt_char_variable,(ECPGprepared_statement(NULL, "f", __LINE__)),(long)1,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
 #line 52 "oldexec.pgc"
@@ -148,7 +148,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 if (sqlca.sqlcode < 0) sqlprint();}
 #line 52 "oldexec.pgc"
 
-	{ ECPGdo(__LINE__, 0, 1, NULL, 1, ECPGst_normal, "fetch 8 in CUR", ECPGt_EOIT, 
+	{ ECPGfetch(__LINE__, 0, 1, NULL, 1, "CUR", ECPGst_normal, "fetch 8 in CUR", ECPGt_EOIT, 
 	ECPGt_char,(name),(long)8,(long)8,(8)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_int,(amount),(long)1,(long)8,sizeof(int), 
@@ -180,7 +180,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 		printf("name[%d]=%8.8s\tamount[%d]=%d\tletter[%d]=%c\n", i, n, i, a, i, l);
 	}
 
-	{ ECPGdo(__LINE__, 0, 1, NULL, 1, ECPGst_normal, "close CUR", ECPGt_EOIT, ECPGt_EORT);
+	{ ECPGclose(__LINE__, 0, 1, NULL, 1, "CUR", ECPGst_normal, "close CUR", ECPGt_EOIT, ECPGt_EORT);
 #line 66 "oldexec.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
@@ -199,7 +199,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 #line 71 "oldexec.pgc"
 
 
-	{ ECPGdo(__LINE__, 0, 1, NULL, 1, ECPGst_normal, "declare CUR3 cursor for $1", 
+	{ ECPGopen(__LINE__, 0, 1, NULL, 1, 0, "CUR3", ECPGst_normal, "declare CUR3 cursor for $1", 
 	ECPGt_char_variable,(ECPGprepared_statement(NULL, "f", __LINE__)),(long)1,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_const,"1",(long)1,(long)1,strlen("1"), 
@@ -209,7 +209,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 if (sqlca.sqlcode < 0) sqlprint();}
 #line 73 "oldexec.pgc"
 
-	{ ECPGdo(__LINE__, 0, 1, NULL, 1, ECPGst_normal, "fetch in CUR3", ECPGt_EOIT, 
+	{ ECPGfetch(__LINE__, 0, 1, NULL, 1, "CUR3", ECPGst_normal, "fetch in CUR3", ECPGt_EOIT, 
 	ECPGt_char,(name),(long)8,(long)8,(8)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_int,(amount),(long)1,(long)8,sizeof(int), 
@@ -241,7 +241,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 		printf("name[%d]=%8.8s\tamount[%d]=%d\tletter[%d]=%c\n", i, n, i, a, i, l);
 	}
 
-	{ ECPGdo(__LINE__, 0, 1, NULL, 1, ECPGst_normal, "close CUR3", ECPGt_EOIT, ECPGt_EORT);
+	{ ECPGclose(__LINE__, 0, 1, NULL, 1, "CUR3", ECPGst_normal, "close CUR3", ECPGt_EOIT, ECPGt_EORT);
 #line 87 "oldexec.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
@@ -253,7 +253,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 if (sqlca.sqlcode < 0) sqlprint();}
 #line 88 "oldexec.pgc"
 
-	{ ECPGtrans(__LINE__, NULL, "commit");
+	{ ECPGtrans(__LINE__, NULL, "commit", 0, 0, 0, NULL);
 #line 89 "oldexec.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
diff --git a/src/interfaces/ecpg/test/expected/sql-quote.c b/src/interfaces/ecpg/test/expected/sql-quote.c
index 43f1eec..6c4d84f 100644
--- a/src/interfaces/ecpg/test/expected/sql-quote.c
+++ b/src/interfaces/ecpg/test/expected/sql-quote.c
@@ -149,7 +149,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 #line 40 "quote.pgc"
 
 
-  { ECPGtrans(__LINE__, NULL, "begin");
+  { ECPGtrans(__LINE__, NULL, "begin", 0, 1, 0, NULL);
 #line 42 "quote.pgc"
 
 if (sqlca.sqlwarn[0] == 'W') sqlprint();
@@ -162,7 +162,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 #line 43 "quote.pgc"
 
 
-  { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare C cursor for select * from \"My_Table\"", ECPGt_EOIT, ECPGt_EORT);
+  { ECPGopen(__LINE__, 0, 1, NULL, 0, 0, "C", ECPGst_normal, "declare C cursor for select * from \"My_Table\"", ECPGt_EOIT, ECPGt_EORT);
 #line 45 "quote.pgc"
 
 if (sqlca.sqlwarn[0] == 'W') sqlprint();
@@ -178,7 +178,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 
   while (true)
   {
-	{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch C", ECPGt_EOIT, 
+	{ ECPGfetch(__LINE__, 0, 1, NULL, 0, "C", ECPGst_normal, "fetch C", ECPGt_EOIT, 
 	ECPGt_int,&(i),(long)1,(long)1,sizeof(int), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_char,(var),(long)25,(long)1,(25)*sizeof(char), 
@@ -197,7 +197,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
 	printf("value: %d %s\n", i, var);
   }
 
-  { ECPGtrans(__LINE__, NULL, "rollback");
+  { ECPGtrans(__LINE__, NULL, "rollback", 0, 0, 1, NULL);
 #line 55 "quote.pgc"
 
 if (sqlca.sqlwarn[0] == 'W') sqlprint();
diff --git a/src/interfaces/ecpg/test/expected/sql-sqlda.c b/src/interfaces/ecpg/test/expected/sql-sqlda.c
index e0c35b2..83804f5 100644
--- a/src/interfaces/ecpg/test/expected/sql-sqlda.c
+++ b/src/interfaces/ecpg/test/expected/sql-sqlda.c
@@ -226,7 +226,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 
 	strcpy(msg, "commit");
-	{ ECPGtrans(__LINE__, NULL, "commit");
+	{ ECPGtrans(__LINE__, NULL, "commit", 0, 0, 0, NULL);
 #line 90 "sqlda.pgc"
 
 if (sqlca.sqlcode < 0) exit (1);}
@@ -251,7 +251,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 
 	strcpy(msg, "open");
-	{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare mycur1 cursor for $1", 
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, "mycur1", ECPGst_normal, "declare mycur1 cursor for $1", 
 	ECPGt_char_variable,(ECPGprepared_statement(NULL, "st_id1", __LINE__)),(long)1,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
 #line 103 "sqlda.pgc"
@@ -268,7 +268,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 	while (1)
 	{
 		strcpy(msg, "fetch");
-		{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch 1 from mycur1", ECPGt_EOIT, 
+		{ ECPGfetch(__LINE__, 0, 1, NULL, 0, "mycur1", ECPGst_normal, "fetch 1 from mycur1", ECPGt_EOIT, 
 	ECPGt_sqlda, &outp_sqlda, 0L, 0L, 0L, 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
 #line 111 "sqlda.pgc"
@@ -289,7 +289,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 
 	strcpy(msg, "close");
-	{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close mycur1", ECPGt_EOIT, ECPGt_EORT);
+	{ ECPGclose(__LINE__, 0, 1, NULL, 0, "mycur1", ECPGst_normal, "close mycur1", ECPGt_EOIT, ECPGt_EORT);
 #line 120 "sqlda.pgc"
 
 if (sqlca.sqlcode < 0) exit (1);}
@@ -324,7 +324,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 
 	strcpy(msg, "open");
-	{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare mycur2 cursor for $1", 
+	{ ECPGopen(__LINE__, 0, 1, NULL, 0, 0, "mycur2", ECPGst_normal, "declare mycur2 cursor for $1", 
 	ECPGt_char_variable,(ECPGprepared_statement(NULL, "st_id2", __LINE__)),(long)1,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
 #line 138 "sqlda.pgc"
@@ -334,7 +334,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 
 	strcpy(msg, "fetch");
-	{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch all from mycur2", ECPGt_EOIT, 
+	{ ECPGfetch(__LINE__, 0, 1, NULL, 0, "mycur2", ECPGst_normal, "fetch all from mycur2", ECPGt_EOIT, 
 	ECPGt_sqlda, &outp_sqlda, 0L, 0L, 0L, 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
 #line 141 "sqlda.pgc"
@@ -357,7 +357,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 	}
 
 	strcpy(msg, "close");
-	{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close mycur2", ECPGt_EOIT, ECPGt_EORT);
+	{ ECPGclose(__LINE__, 0, 1, NULL, 0, "mycur2", ECPGst_normal, "close mycur2", ECPGt_EOIT, ECPGt_EORT);
 #line 157 "sqlda.pgc"
 
 if (sqlca.sqlcode < 0) exit (1);}
@@ -475,7 +475,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 	dump_sqlda(outp_sqlda);
 
 	strcpy(msg, "commit");
-	{ ECPGtrans(__LINE__, "con2", "commit");
+	{ ECPGtrans(__LINE__, "con2", "commit", 0, 0, 0, NULL);
 #line 227 "sqlda.pgc"
 
 if (sqlca.sqlcode < 0) exit (1);}
@@ -512,7 +512,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 
 	strcpy(msg, "commit");
-	{ ECPGtrans(__LINE__, NULL, "commit");
+	{ ECPGtrans(__LINE__, NULL, "commit", 0, 0, 0, NULL);
 #line 244 "sqlda.pgc"
 
 if (sqlca.sqlcode < 0) exit (1);}
diff --git a/src/interfaces/ecpg/test/expected/thread-thread.c b/src/interfaces/ecpg/test/expected/thread-thread.c
index 485f9dd..08a5811 100644
--- a/src/interfaces/ecpg/test/expected/thread-thread.c
+++ b/src/interfaces/ecpg/test/expected/thread-thread.c
@@ -72,13 +72,13 @@ int main()
   { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "drop table test_thread", ECPGt_EOIT, ECPGt_EORT);}
 #line 47 "thread.pgc"
  /* DROP might fail */
-  { ECPGtrans(__LINE__, NULL, "commit");}
+  { ECPGtrans(__LINE__, NULL, "commit", 0, 0, 0, NULL);}
 #line 48 "thread.pgc"
 
   { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "create table test_thread ( tstamp timestamp not null default cast ( timeofday ( ) as timestamp ) , thread text not null , iteration integer not null , primary key ( thread , iteration ) )", ECPGt_EOIT, ECPGt_EORT);}
 #line 53 "thread.pgc"
 
-  { ECPGtrans(__LINE__, NULL, "commit");}
+  { ECPGtrans(__LINE__, NULL, "commit", 0, 0, 0, NULL);}
 #line 54 "thread.pgc"
 
   { ECPGdisconnect(__LINE__, "CURRENT");}
@@ -121,7 +121,7 @@ int main()
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
 #line 86 "thread.pgc"
 
-  { ECPGtrans(__LINE__, NULL, "commit");}
+  { ECPGtrans(__LINE__, NULL, "commit", 0, 0, 0, NULL);}
 #line 87 "thread.pgc"
 
   { ECPGdisconnect(__LINE__, "CURRENT");}
@@ -171,7 +171,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
       printf("%s: ERROR: cannot connect to database!\n", l_connection);
       return( NULL );
     }
-  { ECPGtrans(__LINE__, l_connection, "begin");
+  { ECPGtrans(__LINE__, l_connection, "begin", 0, 1, 0, NULL);
 #line 118 "thread.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
@@ -196,7 +196,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
     }
 
   /* all done */
-  { ECPGtrans(__LINE__, l_connection, "commit");
+  { ECPGtrans(__LINE__, l_connection, "commit", 0, 0, 0, NULL);
 #line 129 "thread.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
diff --git a/src/interfaces/ecpg/test/expected/thread-thread_implicit.c b/src/interfaces/ecpg/test/expected/thread-thread_implicit.c
index f91a098..cae6ee9 100644
--- a/src/interfaces/ecpg/test/expected/thread-thread_implicit.c
+++ b/src/interfaces/ecpg/test/expected/thread-thread_implicit.c
@@ -73,13 +73,13 @@ int main()
   { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "drop table test_thread", ECPGt_EOIT, ECPGt_EORT);}
 #line 48 "thread_implicit.pgc"
  /* DROP might fail */
-  { ECPGtrans(__LINE__, NULL, "commit");}
+  { ECPGtrans(__LINE__, NULL, "commit", 0, 0, 0, NULL);}
 #line 49 "thread_implicit.pgc"
 
   { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "create table test_thread ( tstamp timestamp not null default cast ( timeofday ( ) as timestamp ) , thread text not null , iteration integer not null , primary key ( thread , iteration ) )", ECPGt_EOIT, ECPGt_EORT);}
 #line 54 "thread_implicit.pgc"
 
-  { ECPGtrans(__LINE__, NULL, "commit");}
+  { ECPGtrans(__LINE__, NULL, "commit", 0, 0, 0, NULL);}
 #line 55 "thread_implicit.pgc"
 
   { ECPGdisconnect(__LINE__, "CURRENT");}
@@ -122,7 +122,7 @@ int main()
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
 #line 87 "thread_implicit.pgc"
 
-  { ECPGtrans(__LINE__, NULL, "commit");}
+  { ECPGtrans(__LINE__, NULL, "commit", 0, 0, 0, NULL);}
 #line 88 "thread_implicit.pgc"
 
   { ECPGdisconnect(__LINE__, "CURRENT");}
@@ -172,7 +172,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
       printf("%s: ERROR: cannot connect to database!\n", l_connection);
       return( NULL );
     }
-  { ECPGtrans(__LINE__, NULL, "begin");
+  { ECPGtrans(__LINE__, NULL, "begin", 0, 1, 0, NULL);
 #line 119 "thread_implicit.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
@@ -197,7 +197,7 @@ if (sqlca.sqlcode < 0) sqlprint();}
     }
 
   /* all done */
-  { ECPGtrans(__LINE__, NULL, "commit");
+  { ECPGtrans(__LINE__, NULL, "commit", 0, 0, 0, NULL);
 #line 130 "thread_implicit.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
diff --git a/src/interfaces/ecpg/test/sql/.gitignore b/src/interfaces/ecpg/test/sql/.gitignore
index cd6f342..4458eb3 100644
--- a/src/interfaces/ecpg/test/sql/.gitignore
+++ b/src/interfaces/ecpg/test/sql/.gitignore
@@ -6,6 +6,8 @@
 /code100.c
 /copystdout
 /copystdout.c
+/cursorsubxact
+/cursorsubxact.c
 /define
 /define.c
 /desc
diff --git a/src/interfaces/ecpg/test/sql/Makefile b/src/interfaces/ecpg/test/sql/Makefile
index 18c37b6..f3fdff2 100644
--- a/src/interfaces/ecpg/test/sql/Makefile
+++ b/src/interfaces/ecpg/test/sql/Makefile
@@ -7,6 +7,7 @@ TESTS = array array.c \
 	binary binary.c \
 	code100 code100.c \
         copystdout copystdout.c \
+        cursorsubxact cursorsubxact.c \
 	define define.c \
         desc desc.c \
         sqlda sqlda.c \
diff --git a/src/interfaces/ecpg/test/sql/cursorsubxact.pgc b/src/interfaces/ecpg/test/sql/cursorsubxact.pgc
new file mode 100644
index 0000000..93111ce
--- /dev/null
+++ b/src/interfaces/ecpg/test/sql/cursorsubxact.pgc
@@ -0,0 +1,288 @@
+#include <stdlib.h>
+#include <string.h>
+
+EXEC SQL INCLUDE ../regression;
+
+exec sql whenever sqlerror sqlprint;
+
+#define CURNAME "MyCur"
+#define CURNAME_BAD "myCur"
+
+#define QUOTED_CURNAME "\"MyCur\""
+#define QUOTED_CURNAME_BAD "\"myCur\""
+
+int main(void)
+{
+exec sql begin declare section;
+	char	*curname;
+	int	id[3];
+	varchar	t[3][50];
+exec sql end declare section;
+
+	ECPGdebug(1, stderr);
+
+	exec sql connect to REGRESSDB1;
+
+	exec sql create table t1 (id serial primary key, t text);
+	exec sql insert into t1 (t) values ('a'), ('b'), ('c');
+	exec sql commit;
+
+	/*
+	 * Cursor name passed in a variable unquoted.
+	 * It has to be treated as case-insensitive.
+	 */
+
+	printf("test case insensitive cursor name\n\n");
+
+	curname = CURNAME;
+
+	exec sql declare :curname cursor for select id, t from t1;
+
+	exec sql open :curname;
+	if (sqlca.sqlcode < 0)
+		printf("open %s (case insensitive) failed with SQLSTATE %5s\n", curname, sqlca.sqlstate);
+	else
+		printf("open %s (case insensitive) succeeded\n", curname);
+
+	curname = CURNAME_BAD;
+
+	exec sql close :curname;
+	if (sqlca.sqlcode < 0)
+		printf("close %s (case insensitive)  failed with SQLSTATE %5s\n", curname, sqlca.sqlstate);
+	else
+		printf("close %s (case insensitive) succeeded\n", curname);
+
+	/*
+	 * Cursor name passed in a variable quoted.
+	 * It has to be treated as case-sensitive.
+	 */
+
+	printf("\ntest case sensitive cursor name\n\n");
+
+	curname = QUOTED_CURNAME;
+
+	exec sql open :curname;
+	if (sqlca.sqlcode < 0)
+		printf("open %s (case sensitive) failed with SQLSTATE %5s\n", curname, sqlca.sqlstate);
+	else
+		printf("open %s (case sensitive) succeeded\n", curname);
+
+	curname = QUOTED_CURNAME_BAD;
+
+	/* Try to close the wrong cursor name, it has to fail with 34000. */
+	exec sql close :curname;
+	if (sqlca.sqlcode < 0)
+		printf("close %s (case sensitive) failed with SQLSTATE %5s (expected 34000)\n", curname, sqlca.sqlstate);
+	else
+		printf("close %s (case sensitive) succeeded\n", curname);
+
+	/* Try to close the right cursor name, it has to fail with 25P02 */
+	curname = QUOTED_CURNAME;
+	exec sql close :curname;
+	if (sqlca.sqlcode < 0)
+		printf("close %s (case sensitive) failed with SQLSTATE %5s (expected 25P02)\n", curname, sqlca.sqlstate);
+	else
+		printf("close %s (case sensitive) succeeded\n", curname);
+
+	exec sql rollback;
+
+	/*
+	 * Try a new transaction and watch the cursor name disappear
+	 * after ROLLBACK TO SAVEPOINT.
+	 */
+
+	printf("\ntest case sensitive cursor name in savepoint\n\n");
+
+	curname = QUOTED_CURNAME;
+
+	exec sql savepoint a;
+
+	exec sql open :curname;
+	if (sqlca.sqlcode < 0)
+		printf("open %s (case sensitive) failed with SQLSTATE %5s\n", curname, sqlca.sqlstate);
+	else
+		printf("close %s (case sensitive) succeeded\n", curname);
+
+	/* The cursor name must be forgotten */
+	exec sql rollback to a;
+
+	/* It has to fail with 34000 */
+	exec sql close :curname;
+	if (sqlca.sqlcode < 0)
+		printf("close %s failed with SQLSTATE %5s (expected 34000)\n", curname, sqlca.sqlstate);
+	else
+		printf("close %s succeeded unexpectedly, expected sqlstate 34000\n", curname);
+
+	exec sql rollback;
+
+	/*
+	 * Try a new transaction and play games with savepoints.
+	 */
+
+	printf("\ntest savepoint handling\n\n");
+
+	exec sql savepoint a;
+	if (sqlca.sqlcode < 0)
+		printf("\"savepoint a\" failed with SQLSTATE %5s\n", sqlca.sqlstate);
+	else
+		printf("\"savepoint a\" succeeded\n");
+
+	exec sql open :curname;
+	if (sqlca.sqlcode < 0)
+		printf("open %s (case sensitive) failed with SQLSTATE %5s\n", curname, sqlca.sqlstate);
+	else
+		printf("open %s (case sensitive) succeeded\n", curname);
+
+	exec sql savepoint b;
+	if (sqlca.sqlcode < 0)
+		printf("\"savepoint a\" failed with SQLSTATE %5s\n", sqlca.sqlstate);
+	else
+		printf("\"savepoint a\" succeeded\n");
+
+	/* Try to rollback to an unknown savepoint */
+
+	exec sql rollback to c;
+	if (sqlca.sqlcode < 0)
+		printf("\"rollback to c\" failed with SQLSTATE %5s (expected 3B001)\n", sqlca.sqlstate);
+	else
+		printf("\"rollback to c\" succeeded unexpectedly (expected 3B001)\n");
+
+	/* "rollback to a" implicitly rolls back "b" */
+
+	exec sql rollback to a;
+	if (sqlca.sqlcode < 0)
+		printf("\"rollback to a\" failed with SQLSTATE %5s\n", sqlca.sqlstate);
+	else
+		printf("\"rollback to a\" succeeded\n");
+
+	/* savepoint "b" is now unknown, fails with 3B001 */
+	exec sql rollback to b;
+	if (sqlca.sqlcode < 0)
+		printf("\"rollback to b\" failed with SQLSTATE %5s (expected 3B001)\n", sqlca.sqlstate);
+	else
+		printf("\"rollback to b\" succeeded unexpectedly (expected 3B001)\n");
+
+	/* "rollback to a" has to succeed again, it's still alive */
+
+	exec sql rollback to a;
+	if (sqlca.sqlcode < 0)
+		printf("\"rollback to a\" failed with SQLSTATE %5s\n", sqlca.sqlstate);
+	else
+		printf("\"rollback to a\" succeeded\n");
+
+	/* the cursor was declared under savepoint "a", was forgotten */
+
+	exec sql fetch from :curname into :id[0], :t[0];
+	if (sqlca.sqlcode < 0)
+		printf("fetch from %s (case sensitive) failed with SQLSTATE %5s (expected 34000)\n", curname, sqlca.sqlstate);
+	else
+		printf("fetch from %s (case sensitive) succeeded unexpectedly (expected 34000)\n", curname);
+
+	/* "rollback to a" has to succeed again, it's still alive */
+
+	exec sql rollback to a;
+	if (sqlca.sqlcode < 0)
+		printf("\"rollback to a\" failed with SQLSTATE %5s\n", sqlca.sqlstate);
+	else
+		printf("\"rollback to a\" succeeded\n");
+
+	/* "release savepoint a" forgets about the savepoint name */
+
+	exec sql release savepoint a;
+	if (sqlca.sqlcode < 0)
+		printf("\"release savepoint a\" failed with SQLSTATE %5s\n", sqlca.sqlstate);
+	else
+		printf("\"release savepoint a\" succeeded\n");
+
+	/* prove the above */
+
+	exec sql rollback to a;
+	if (sqlca.sqlcode < 0)
+		printf("\"rollback to a\" failed with SQLSTATE %5s (expected 3B001)\n", sqlca.sqlstate);
+	else
+		printf("\"rollback to a\" succeeded unexpectedly (expected 3B001)\n");
+
+	exec sql rollback;
+
+	/*
+	 * Test the implicit RELEASE SAVEPOINT if a SAVEPOINT
+	 * is used with an already existing name.
+	 */
+
+	printf("\ntest implicit \"release savepoint a\" for a second \"savepoint a\"\n\n");
+
+	exec sql savepoint a;
+	if (sqlca.sqlcode < 0)
+		printf("\"savepoint a\" failed with SQLSTATE %5s\n", sqlca.sqlstate);
+	else
+		printf("\"savepoint a\" succeeded\n");
+
+	exec sql open :curname;
+	if (sqlca.sqlcode < 0)
+		printf("open %s (case sensitive) failed with SQLSTATE %5s\n", curname, sqlca.sqlstate);
+	else
+		printf("open %s (case sensitive) succeeded\n", curname);
+
+	exec sql fetch from :curname into :id[0], :t[0];
+	if (sqlca.sqlcode < 0)
+		printf("fetch from %s (case sensitive) failed with SQLSTATE %5s\n", curname, sqlca.sqlstate);
+	else
+		printf("fetch from %s (case sensitive) result %d '%s'\n", curname, id[0], t[0].arr);
+
+	exec sql rollback to a;
+	if (sqlca.sqlcode < 0)
+		printf("\"rollback to a\" failed with SQLSTATE %5s\n", sqlca.sqlstate);
+	else
+		printf("\"rollback to a\" succeeded\n");
+
+	/* there's no cursor now */
+
+	exec sql fetch from :curname into :id[1], :t[1];
+	if (sqlca.sqlcode < 0)
+		printf("fetch from %s (case sensitive) failed with SQLSTATE %5s (expected 34000)\n", curname, sqlca.sqlstate);
+	else
+		printf("fetch from %s (case sensitive) unexpectedly succeeded (expected 34000)\n", curname);
+
+	exec sql open :curname;
+	if (sqlca.sqlcode < 0)
+		printf("open %s (case sensitive) failed with SQLSTATE %5s (expected 25P02)\n", curname, sqlca.sqlstate);
+	else
+		printf("open %s (case sensitive) succeeded unexpectedly\n", curname);
+
+	exec sql rollback to a;
+	if (sqlca.sqlcode < 0)
+		printf("\"rollback to a\" failed with SQLSTATE %5s\n", sqlca.sqlstate);
+	else
+		printf("\"rollback to a\" succeeded\n");
+
+	exec sql open :curname;
+	if (sqlca.sqlcode < 0)
+		printf("open %s (case sensitive) failed with SQLSTATE %5s\n", curname, sqlca.sqlstate);
+	else
+		printf("open %s (case sensitive) succeeded\n", curname);
+
+	exec sql release savepoint a;
+	if (sqlca.sqlcode < 0)
+		printf("\"release savepoint a\" failed with SQLSTATE %5s\n", sqlca.sqlstate);
+	else
+		printf("\"release savepoint a\" succeeded\n");
+
+	/* release savepoint propagated the cursor to the toplevel transaction */
+
+	exec sql fetch from :curname into :id[2], :t[2];
+	if (sqlca.sqlcode < 0)
+		printf("fetch %s (case sensitive) failed with SQLSTATE %5s\n", curname, sqlca.sqlstate);
+	else
+		printf("fetch %s (case sensitive) result %d '%s'\n", curname, id[2], t[2].arr);
+
+	exec sql rollback;
+
+	/* Drop the test table */
+
+	exec sql drop table t1;
+	exec sql commit;
+
+	exec sql disconnect all;
+
+	return 0;
+}
